1 package org.codehaus.mojo.appassembler.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 import java.io.BufferedReader;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.InputStreamReader;
31 import java.io.OutputStream;
32 import java.io.OutputStreamWriter;
33 import java.io.PrintWriter;
34 import java.util.ArrayList;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.Iterator;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Properties;
41 import java.util.Set;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
44
45 import org.codehaus.plexus.util.IOUtil;
46
47
48
49
50 public class FormattedProperties
51 {
52 private static final Pattern LIST_KEY_PATTERN = Pattern.compile( "^(.*)\\.[0-9]+$" );
53
54
55
56
57 private final Properties properties = new Properties();
58
59
60
61
62 private Map<String, Integer> propertyLines;
63
64
65
66
67 private List<String> fileLines;
68
69
70
71
72 private Map<String, List<String>> listProperties = new HashMap<String, List<String>>();
73
74
75
76
77 private Map<String, List<String>> afterProperties = new HashMap<String, List<String>>();
78
79 public void setProperty( String key, String value )
80 {
81 synchronized ( properties )
82 {
83 properties.setProperty( key, value );
84
85
86 Matcher m = LIST_KEY_PATTERN.matcher( key );
87 if ( m.matches() )
88 {
89 String listKey = m.group( 1 );
90
91
92 List<String> p = listProperties.get( listKey );
93 if ( p == null )
94 {
95 p = new ArrayList<String>();
96 listProperties.put( listKey, p );
97 }
98 p.add( key );
99 }
100 }
101 }
102
103 public String getProperty( String key )
104 {
105 synchronized ( properties )
106 {
107 return properties.getProperty( key );
108 }
109 }
110
111 public String getProperty( String key, String defaultValue )
112 {
113 synchronized ( properties )
114 {
115 return properties.getProperty( key, defaultValue );
116 }
117 }
118
119 public void removeProperty( String key )
120 {
121 synchronized ( properties )
122 {
123 properties.remove( key );
124 }
125 }
126
127
128
129
130
131
132
133
134
135 public void read( InputStream inputStream )
136 throws IOException
137 {
138 synchronized ( properties )
139 {
140 fileLines = new ArrayList<String>();
141 propertyLines = new HashMap<String, Integer>();
142
143 BufferedReader r = new BufferedReader( new InputStreamReader( inputStream ) );
144
145 try
146 {
147 int lineNo = 1;
148 String line = r.readLine();
149 while ( line != null )
150 {
151
152
153 String[] pair = line.split( "=", 2 );
154 String key = pair[0];
155 String value;
156 if ( pair.length > 1 )
157 {
158 value = pair[1].trim();
159
160
161 boolean commented = false;
162 if ( key.startsWith( "#" ) )
163 {
164 commented = true;
165 key = key.substring( 1 );
166 }
167
168 key = key.trim();
169
170
171 if ( !commented )
172 {
173
174 setProperty( key, value );
175 }
176
177
178
179 Matcher m = LIST_KEY_PATTERN.matcher( key );
180 if ( m.matches() )
181 {
182 key = m.group( 1 );
183 }
184
185 propertyLines.put( key, new Integer( lineNo ) );
186 }
187
188 fileLines.add( line );
189
190 line = r.readLine();
191 lineNo++;
192 }
193 }
194 finally
195 {
196 IOUtil.close( r );
197 }
198 }
199 }
200
201 public void save( OutputStream outputStream )
202 {
203 synchronized ( properties )
204 {
205 PrintWriter writer = new PrintWriter( new OutputStreamWriter( outputStream ) );
206
207
208 try
209 {
210 Set<String> writtenProperties = new HashSet<String>();
211
212
213 for ( int i = 0; i < fileLines.size(); i++ )
214 {
215 String line = fileLines.get( i );
216
217
218 if ( line.trim().length() > 0 )
219 {
220 String[] pair = line.split( "=", 2 );
221 String key = pair[0];
222 if ( key.startsWith( "#" ) )
223 {
224
225
226 key = key.substring( 1 );
227 writer.println( line );
228 }
229
230 key = key.trim();
231
232
233 if ( new Integer( i + 1 ).equals( propertyLines.get( key ) ) )
234 {
235 String value = properties.getProperty( key );
236 if ( value != null )
237 {
238 writer.println( key + "=" + value );
239 writtenProperties.add( key );
240 }
241 }
242
243
244 if ( afterProperties.containsKey( key ) )
245 {
246 List<String> p = afterProperties.get( key );
247 for ( String pKey : p )
248 {
249 String value = properties.getProperty( pKey );
250 if ( value != null && !writtenProperties.contains( pKey ) )
251 {
252 writer.println( pKey + "=" + value );
253 writtenProperties.add( pKey );
254 }
255 }
256 }
257
258
259 Matcher m = LIST_KEY_PATTERN.matcher( key );
260 if ( m.matches() )
261 {
262 key = m.group( 1 );
263
264 if ( new Integer( i + 1 ).equals( propertyLines.get( key ) ) )
265 {
266 List<String> p = listProperties.get( key );
267 if ( p != null )
268 {
269 for ( String itemKey : p )
270 {
271 if ( !writtenProperties.contains( itemKey ) )
272 {
273 String value = properties.getProperty( itemKey );
274 if ( value != null )
275 {
276 writer.println( itemKey + "=" + value );
277 writtenProperties.add( itemKey );
278 }
279 }
280 }
281 }
282 }
283 }
284 }
285 else
286 {
287 writer.println( line );
288 }
289 }
290
291 for ( Iterator i = properties.keySet().iterator(); i.hasNext(); )
292 {
293 String key = (String) i.next();
294 if ( !writtenProperties.contains( key ) )
295 {
296 String value = properties.getProperty( key );
297 if ( value != null )
298 {
299 writer.println( key + "=" + value );
300 }
301 }
302 }
303 }
304 finally
305 {
306 IOUtil.close( writer );
307 }
308 }
309 }
310
311 public void setPropertyAfter( String key, String value, String afterProperty )
312 {
313 List<String> p = afterProperties.get( afterProperty );
314 if ( p == null )
315 {
316 p = new ArrayList<String>();
317 afterProperties.put( afterProperty, p );
318 }
319 p.add( key );
320
321 setProperty( key, value );
322 }
323 }