KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > util > DefaultPropertiesPersister


1 /*
2  * Copyright 2002-2005 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.util;
18
19 import java.io.BufferedReader JavaDoc;
20 import java.io.BufferedWriter JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.io.Reader JavaDoc;
25 import java.io.Writer JavaDoc;
26 import java.lang.reflect.InvocationTargetException JavaDoc;
27 import java.lang.reflect.Method JavaDoc;
28 import java.util.Date JavaDoc;
29 import java.util.Enumeration JavaDoc;
30 import java.util.Properties JavaDoc;
31
32 /**
33  * Default implementation of the PropertiesPersister interface.
34  * Follows the native parsing of <code>java.util.Properties</code>.
35  *
36  * <p>Allows for reading from any Reader and writing to any Writer, for example
37  * to specify a charset for a properties file. This is a capability that standard
38  * <code>java.util.Properties</code> unfortunately lacks: You can only load files
39  * using the ISO-8859-1 charset there.
40  *
41  * <p>Loading from and storing to a stream delegates to <code>Properties.load</code>
42  * and <code>Properties.store</code>, respectively, to be fully compatible with
43  * the Unicode conversion as implemented by the JDK Properties class.
44  *
45  * <p>The persistence code that works with Reader/Writer follows the JDK's parsing
46  * strategy but does not implement Unicode conversion, because the Reader/Writer
47  * should already apply proper decoding/encoding of characters. If you use prefer
48  * to escape unicode characters in your properties files, do <i>not</i> specify
49  * an encoding for a Reader/Writer (like ReloadableResourceBundleMessageSource's
50  * "defaultEncoding" and "fileEncodings" properties).
51  *
52  * <p>As of Spring 1.2.2, this implementation also supports properties XML files,
53  * through the <code>loadFromXml</code> and <code>storeToXml</code> methods.
54  * The default implementations delegate to JDK 1.5's corresponding methods,
55  * throwing an exception if running on an older JDK. Those implementations
56  * could be subclassed to apply custom XML handling on JDK 1.4, for example.
57  *
58  * @author Juergen Hoeller
59  * @since 10.03.2004
60  * @see java.util.Properties
61  * @see java.util.Properties#load
62  * @see java.util.Properties#store
63  * @see org.springframework.context.support.ReloadableResourceBundleMessageSource#setPropertiesPersister
64  * @see org.springframework.context.support.ReloadableResourceBundleMessageSource#setDefaultEncoding
65  * @see org.springframework.context.support.ReloadableResourceBundleMessageSource#setFileEncodings
66  */

67 public class DefaultPropertiesPersister implements PropertiesPersister {
68
69     public void load(Properties JavaDoc props, InputStream JavaDoc is) throws IOException JavaDoc {
70         props.load(is);
71     }
72
73     public void load(Properties JavaDoc props, Reader JavaDoc reader) throws IOException JavaDoc {
74         BufferedReader JavaDoc in = new BufferedReader JavaDoc(reader);
75         while (true) {
76             String JavaDoc line = in.readLine();
77             if (line == null) {
78                 return;
79             }
80             line = StringUtils.trimLeadingWhitespace(line);
81             if (line.length() > 0) {
82                 char firstChar = line.charAt(0);
83                 if (firstChar != '#' && firstChar != '!') {
84                     while (endsWithContinuationMarker(line)) {
85                         String JavaDoc nextLine = in.readLine();
86                         line = line.substring(0, line.length() - 1);
87                         if (nextLine != null) {
88                             line += StringUtils.trimLeadingWhitespace(nextLine);
89                         }
90                     }
91                     int separatorIndex = line.indexOf("=");
92                     if (separatorIndex == -1) {
93                         separatorIndex = line.indexOf(":");
94                     }
95                     String JavaDoc key = (separatorIndex != -1 ? line.substring(0, separatorIndex) : line);
96                     String JavaDoc value = (separatorIndex != -1) ? line.substring(separatorIndex + 1) : "";
97                     key = StringUtils.trimTrailingWhitespace(key);
98                     value = StringUtils.trimLeadingWhitespace(value);
99                     props.put(unescape(key), unescape(value));
100                 }
101             }
102         }
103     }
104
105     protected boolean endsWithContinuationMarker(String JavaDoc line) {
106         boolean evenSlashCount = true;
107         int index = line.length() - 1;
108         while (index >= 0 && line.charAt(index) == '\\') {
109             evenSlashCount = !evenSlashCount;
110             index--;
111         }
112         return !evenSlashCount;
113     }
114
115     protected String JavaDoc unescape(String JavaDoc str) {
116         StringBuffer JavaDoc outBuffer = new StringBuffer JavaDoc(str.length());
117         for (int index = 0; index < str.length();) {
118             char c = str.charAt(index++);
119             if (c == '\\') {
120                 c = str.charAt(index++);
121                 if (c == 't') {
122                     c = '\t';
123                 }
124                 else if (c == 'r') {
125                     c = '\r';
126                 }
127                 else if (c == 'n') {
128                     c = '\n';
129                 }
130                 else if (c == 'f') {
131                     c = '\f';
132                 }
133             }
134             outBuffer.append(c);
135         }
136         return outBuffer.toString();
137     }
138
139
140     public void store(Properties JavaDoc props, OutputStream JavaDoc os, String JavaDoc header) throws IOException JavaDoc {
141         props.store(os, header);
142     }
143
144     public void store(Properties JavaDoc props, Writer JavaDoc writer, String JavaDoc header) throws IOException JavaDoc {
145         BufferedWriter JavaDoc out = new BufferedWriter JavaDoc(writer);
146         if (header != null) {
147             out.write("#" + header);
148             out.newLine();
149         }
150         out.write("#" + new Date JavaDoc());
151         out.newLine();
152         for (Enumeration JavaDoc keys = props.keys(); keys.hasMoreElements();) {
153             String JavaDoc key = (String JavaDoc) keys.nextElement();
154             String JavaDoc val = props.getProperty(key);
155             out.write(escape(key, true) + "=" + escape(val, false));
156             out.newLine();
157         }
158         out.flush();
159     }
160
161     protected String JavaDoc escape(String JavaDoc str, boolean isKey) {
162         int len = str.length();
163         StringBuffer JavaDoc outBuffer = new StringBuffer JavaDoc(len * 2);
164         for (int index = 0; index < len; index++) {
165             char c = str.charAt(index);
166             switch (c) {
167                 case ' ':
168                     if (index == 0 || isKey) {
169                         outBuffer.append('\\');
170                     }
171                     outBuffer.append(' ');
172                     break;
173                 case '\\':
174                     outBuffer.append("\\\\");
175                     break;
176                 case '\t':
177                     outBuffer.append("\\t");
178                     break;
179                 case '\n':
180                     outBuffer.append("\\n");
181                     break;
182                 case '\r':
183                     outBuffer.append("\\r");
184                     break;
185                 case '\f':
186                     outBuffer.append("\\f");
187                     break;
188                 default:
189                     if ("=: \t\r\n\f#!".indexOf(c) != -1) {
190                         outBuffer.append('\\');
191                     }
192                     outBuffer.append(c);
193             }
194         }
195         return outBuffer.toString();
196     }
197
198
199     public void loadFromXml(Properties JavaDoc props, InputStream JavaDoc is) throws IOException JavaDoc {
200         // props.loadFromXML(is);
201
try {
202             Method JavaDoc loadMethod = props.getClass().getMethod("loadFromXML", new Class JavaDoc[] {InputStream JavaDoc.class});
203             loadMethod.invoke(props, new Object JavaDoc[] {is});
204         }
205         catch (NoSuchMethodException JavaDoc ex) {
206             throw new IOException JavaDoc("Cannot load properties XML file - not running on JDK 1.5+: " + ex.getMessage());
207         }
208         catch (InvocationTargetException JavaDoc ex) {
209             if (ex.getTargetException() instanceof IOException JavaDoc) {
210                 throw (IOException JavaDoc) ex.getTargetException();
211             }
212             ReflectionUtils.handleInvocationTargetException(ex);
213         }
214         catch (Exception JavaDoc ex) {
215             ReflectionUtils.handleReflectionException(ex);
216         }
217     }
218
219     public void storeToXml(Properties JavaDoc props, OutputStream JavaDoc os, String JavaDoc header) throws IOException JavaDoc {
220         // props.storeToXML(os, header);
221
try {
222             Method JavaDoc storeMethod = props.getClass().getMethod(
223                     "storeToXML", new Class JavaDoc[] {OutputStream JavaDoc.class, String JavaDoc.class});
224             storeMethod.invoke(props, new Object JavaDoc[] {os, header});
225         }
226         catch (NoSuchMethodException JavaDoc ex) {
227             throw new IOException JavaDoc("Cannot store properties XML file - not running on JDK 1.5+: " + ex.getMessage());
228         }
229         catch (InvocationTargetException JavaDoc ex) {
230             if (ex.getTargetException() instanceof IOException JavaDoc) {
231                 throw (IOException JavaDoc) ex.getTargetException();
232             }
233             ReflectionUtils.handleInvocationTargetException(ex);
234         }
235         catch (Exception JavaDoc ex) {
236             ReflectionUtils.handleReflectionException(ex);
237         }
238     }
239
240     public void storeToXml(Properties JavaDoc props, OutputStream JavaDoc os, String JavaDoc header, String JavaDoc encoding) throws IOException JavaDoc {
241         // props.storeToXML(os, header, encoding);
242
try {
243             Method JavaDoc storeMethod = props.getClass().getMethod(
244                     "storeToXML", new Class JavaDoc[] {OutputStream JavaDoc.class, String JavaDoc.class, String JavaDoc.class});
245             storeMethod.invoke(props, new Object JavaDoc[] {os, header, encoding});
246         }
247         catch (NoSuchMethodException JavaDoc ex) {
248             throw new IOException JavaDoc("Cannot store properties XML file - not running on JDK 1.5+: " + ex.getMessage());
249         }
250         catch (InvocationTargetException JavaDoc ex) {
251             if (ex.getTargetException() instanceof IOException JavaDoc) {
252                 throw (IOException JavaDoc) ex.getTargetException();
253             }
254             ReflectionUtils.handleInvocationTargetException(ex);
255         }
256         catch (Exception JavaDoc ex) {
257             ReflectionUtils.handleReflectionException(ex);
258         }
259     }
260
261 }
262
Popular Tags