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 }
83 break;
84
85 case VALUE:
86 switch ( current )
87 {
88 case '"':
89 case '\'':
90 quote = current;
91 state = QuotedParseState.IN_QUOTED_VALUE;
92 if ( i >= pos )
93 {
94 buffer.append( string.subSequence( pos, i ) );
95 }
96 pos = i + 1;
97 break;
98 case '&':
99 if ( i >= pos )
100 {
101 buffer.append( string.subSequence( pos, i ) );
102 }
103 propertyMap.put( propertyKey, buffer.toString() );
104 pos = i + 1;
105 buffer = new StringBuilder();
106 state = QuotedParseState.KEY;
107 break;
108 default:
109 }
110
111 break;
112 case IN_QUOTED_KEY:
113 case IN_QUOTED_VALUE:
114 if ( current == quote )
115 {
116 state =
117 ( state == QuotedParseState.IN_QUOTED_KEY ) ? QuotedParseState.KEY : QuotedParseState.VALUE;
118 if ( i >= pos )
119 {
120 buffer.append( string.subSequence( pos, i ) );
121 }
122 pos = i + 1;
123 }
124 break;
125 default:
126 break;
127 }
128
129 i++;
130 }
131
132 if ( state == QuotedParseState.VALUE )
133 {
134 if ( i >= pos )
135 {
136 buffer.append( string.subSequence( pos, i ) );
137 }
138 propertyMap.put( propertyKey, buffer.toString() );
139 }
140 }
141
142 // Has to be down here to avoid a QDOX exception
143 public static enum QuotedParseState
144 {
145 KEY, IN_QUOTED_KEY, IN_QUOTED_VALUE, VALUE
146 }
147
148 }