1 package org.apache.maven.scm.provider.accurev.util;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.util.HashMap;
23 import java.util.Map;
24
25 /**
26 * @author ggardner
27 */
28 public final class QuotedPropertyParser
29 {
30
31 private QuotedPropertyParser()
32 {
33
34 }
35
36 public static Map<String, String> parse( CharSequence seq )
37 {
38 Map<String, String> hashMap = new HashMap<String, String>();
39
40 parse( seq, hashMap );
41 return hashMap;
42 }
43
44 public static void parse( CharSequence string, Map<? super String, ? super String> propertyMap )
45 {
46
47 QuotedParseState state = QuotedParseState.KEY;
48 char quote = '\0';
49 StringBuilder buffer = new StringBuilder();
50 String propertyKey = "";
51
52 int i = 0; // where we are up to in the scan
53 int pos = 0; // where we have consumed into the buffer
54 while ( i < string.length() )
55 {
56 char current = string.charAt( i );
57 switch ( state )
58 {
59 case KEY:
60 switch ( current )
61 {
62 case '"':
63 case '\'':
64 quote = current;
65 state = QuotedParseState.IN_QUOTED_KEY;
66 if ( i >= pos )
67 {
68 buffer.append( string.subSequence( pos, i ) );
69 }
70 pos = i + 1;
71 break;
72 case '=':
73 if ( i >= pos )
74 {
75 buffer.append( string.subSequence( pos, i ) );
76 }
77 propertyKey = buffer.toString();
78 buffer = new StringBuilder();
79 state = QuotedParseState.VALUE;
80 pos = i + 1;
81 break;
82 default:
83 }
84 break;
85
86 case VALUE:
87 switch ( current )
88 {
89 case '"':
90 case '\'':
91 quote = current;
92 state = QuotedParseState.IN_QUOTED_VALUE;
93 if ( i >= pos )
94 {
95 buffer.append( string.subSequence( pos, i ) );
96 }
97 pos = i + 1;
98 break;
99 case '&':
100 if ( i >= pos )
101 {
102 buffer.append( string.subSequence( pos, i ) );
103 }
104 propertyMap.put( propertyKey, buffer.toString() );
105 pos = i + 1;
106 buffer = new StringBuilder();
107 state = QuotedParseState.KEY;
108 break;
109 default:
110 }
111
112 break;
113 case IN_QUOTED_KEY:
114 case IN_QUOTED_VALUE:
115 if ( current == quote )
116 {
117 state =
118 ( state == QuotedParseState.IN_QUOTED_KEY ) ? QuotedParseState.KEY : QuotedParseState.VALUE;
119 if ( i >= pos )
120 {
121 buffer.append( string.subSequence( pos, i ) );
122 }
123 pos = i + 1;
124 }
125 break;
126 default:
127 break;
128 }
129
130 i++;
131 }
132
133 if ( state == QuotedParseState.VALUE )
134 {
135 if ( i >= pos )
136 {
137 buffer.append( string.subSequence( pos, i ) );
138 }
139 propertyMap.put( propertyKey, buffer.toString() );
140 }
141 }
142
143 /**
144 *
145 */
146 // Has to be down here to avoid a QDOX exception
147 public static enum QuotedParseState
148 {
149 KEY, IN_QUOTED_KEY, IN_QUOTED_VALUE, VALUE
150 }
151
152 }