make/tools/StripProperties/StripProperties.java

changeset 85
ae2bec597586
parent 1
0961a4a21176
equal deleted inserted replaced
84:d79f0d601c2b 85:ae2bec597586
1 /*
2 * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 import java.io.BufferedInputStream;
27 import java.io.BufferedWriter;
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.FileOutputStream;
31 import java.io.OutputStream;
32 import java.io.OutputStreamWriter;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.util.ArrayList;
36 import java.util.Enumeration;
37 import java.util.List;
38 import java.util.Properties;
39
40 /**
41 * Reads a properties file from standard input and writes an equivalent
42 * properties file without comments to standard output.
43 */
44 public class StripProperties {
45
46 public static void main(String[] args) {
47 StripProperties sp = new StripProperties();
48 boolean ok = sp.run(args);
49 if ( !ok ) {
50 System.exit(1);
51 }
52 }
53
54 static interface Log {
55 void info(String msg);
56 void verbose(String msg);
57 void error(String msg, Exception e);
58 }
59
60 private String propfiles[];
61 private String outfiles[] ;
62 private int stripCount = 0;
63 private boolean quiet = false;
64 private Log log;
65
66 public void setLog(Log log) {
67 this.log = log;
68 }
69
70 private boolean parseOptions(String args[]) {
71 boolean ok = true;
72 if ( stripCount > 0 ) {
73 String new_propfiles[] = new String[stripCount + args.length];
74 String new_outfiles[] = new String[stripCount + args.length];
75 System.arraycopy(propfiles, 0, new_propfiles, 0, stripCount);
76 System.arraycopy(outfiles, 0, new_outfiles, 0, stripCount);
77 propfiles = new_propfiles;
78 outfiles = new_outfiles;
79 } else {
80 propfiles = new String[args.length];
81 outfiles = new String[args.length];
82 }
83
84 for ( int i = 0; i < args.length ; i++ ) {
85 if ( "-strip".equals(args[i]) && i+2 < args.length ) {
86 propfiles[stripCount] = args[++i];
87 outfiles[stripCount] = args[++i];
88 stripCount++;
89 } else if ( "-optionsfile".equals(args[i]) && i+1 < args.length ) {
90 String filename = args[++i];
91 FileInputStream finput = null;
92 byte contents[] = null;
93 try {
94 finput = new FileInputStream(filename);
95 int byteCount = finput.available();
96 if ( byteCount <= 0 ) {
97 log.error("The -optionsfile file is empty", null);
98 ok = false;
99 } else {
100 contents = new byte[byteCount];
101 int bytesRead = finput.read(contents);
102 if ( byteCount != bytesRead ) {
103 log.error("Cannot read all of -optionsfile file", null);
104 ok = false;
105 }
106 }
107 } catch ( IOException e ) {
108 log.error("cannot open " + filename, e);
109 ok = false;
110 }
111 if ( finput != null ) {
112 try {
113 finput.close();
114 } catch ( IOException e ) {
115 ok = false;
116 log.error("cannot close " + filename, e);
117 }
118 }
119 if ( ok = true && contents != null ) {
120 String tokens[] = (new String(contents)).split("\\s+");
121 if ( tokens.length > 0 ) {
122 ok = parseOptions(tokens);
123 }
124 }
125 if ( !ok ) {
126 break;
127 }
128 } else if ( "-quiet".equals(args[i]) ) {
129 quiet = true;
130 } else {
131 log.error("argument error", null);
132 ok = false;
133 }
134 }
135 return ok;
136 }
137
138 private boolean stripFiles(String propertiesPath, String outputPath) {
139 boolean ok = true;
140 Properties prop = new Properties();
141 InputStream in = null;
142 try {
143 in = new BufferedInputStream(new FileInputStream(propertiesPath));
144 prop.load(in);
145 } catch ( FileNotFoundException e ) {
146 log.error("Cannot access file " + propertiesPath, e);
147 ok = false;
148 } catch ( IOException e ) {
149 log.error("IO exception processing file " + propertiesPath, e);
150 ok = false;
151 }
152 if ( in != null ) {
153 try {
154 in.close();
155 } catch ( IOException e ) {
156 log.error("IO exception closing file " + propertiesPath, e);
157 ok = false;
158 }
159 }
160
161 OutputStream out = null;
162 try {
163 out = new FileOutputStream(outputPath);
164 storeProperties(prop, out);
165 out.flush();
166 } catch ( IOException e ) {
167 log.error("IO exception processing file " + outputPath, e);
168 e.printStackTrace();
169 ok = false;
170 }
171 if ( out != null ) {
172 try {
173 out.close();
174 } catch ( IOException e ) {
175 log.error("IO exception closing file " + outputPath, e);
176 ok = false;
177 }
178 }
179 return ok;
180 }
181
182 /**
183 * Strip the properties filenames supplied, replacing their contents.
184 * @param args Names of properties files to process and replace contents
185 */
186 public boolean run(String args[]) {
187 if (log == null) {
188 log = new Log() {
189 public void error(String msg, Exception e) {
190 System.err.println("ERROR: StripProperties: " + msg);
191 if ( e != null ) {
192 System.err.println("EXCEPTION: " + e.toString());
193 e.printStackTrace();
194 }
195 }
196 public void info(String msg) {
197 System.out.println(msg);
198 }
199 public void verbose(String msg) {
200 if (!quiet)
201 System.out.println(msg);
202 }
203 };
204 }
205
206 boolean ok = true;
207 ok = parseOptions(args);
208 if ( ok && stripCount == 0 ) {
209 log.error("options parsed but no files to compile", null);
210 ok = false;
211 }
212 /* Need at least one file. */
213 if ( !ok ) {
214 //usage(log);
215 } else {
216 /* Process files */
217 for ( int i = 0; i < stripCount && ok ; i++ ) {
218 ok = stripFiles(propfiles[i], outfiles[i]);
219 }
220 }
221 return ok;
222 }
223
224 // --- code below here is adapted from java.util.Properties ---
225
226 private static final String specialSaveChars = "=: \t\r\n\f#!";
227
228 /*
229 * Converts unicodes to encoded &#92;uxxxx
230 * and writes out any of the characters in specialSaveChars
231 * with a preceding slash
232 */
233 private static String saveConvert(String theString, boolean escapeSpace) {
234 int len = theString.length();
235 StringBuffer outBuffer = new StringBuffer(len*2);
236
237 for(int x=0; x<len; x++) {
238 char aChar = theString.charAt(x);
239 switch(aChar) {
240 case ' ':
241 if (x == 0 || escapeSpace) {
242 outBuffer.append('\\');
243 }
244 outBuffer.append(' ');
245 break;
246 case '\\':
247 outBuffer.append('\\');
248 outBuffer.append('\\');
249 break;
250 case '\t':
251 outBuffer.append('\\');
252 outBuffer.append('t');
253 break;
254 case '\n':
255 outBuffer.append('\\');
256 outBuffer.append('n');
257 break;
258 case '\r':
259 outBuffer.append('\\');
260 outBuffer.append('r');
261 break;
262 case '\f':
263 outBuffer.append('\\');
264 outBuffer.append('f');
265 break;
266 default:
267 if ((aChar < 0x0020) || (aChar == 0x007e) || (aChar > 0x00ff)) {
268 outBuffer.append('\\');
269 outBuffer.append('u');
270 outBuffer.append(toHex((aChar >> 12) & 0xF));
271 outBuffer.append(toHex((aChar >> 8) & 0xF));
272 outBuffer.append(toHex((aChar >> 4) & 0xF));
273 outBuffer.append(toHex( aChar & 0xF));
274 } else {
275 if (specialSaveChars.indexOf(aChar) != -1) {
276 outBuffer.append('\\');
277 }
278 outBuffer.append(aChar);
279 }
280 }
281 }
282 return outBuffer.toString();
283 }
284
285 /**
286 * Writes the content of <code>properties</code> to <code>out</code>.
287 * The format is that of Properties.store with the following modifications:
288 * <ul>
289 * <li>No header or date is written
290 * <li>Latin-1 characters are written as single bytes, not escape sequences
291 * <li>Line breaks are indicated by a single \n independent of platform
292 * <ul>
293 */
294 private static void storeProperties(Properties properties, OutputStream out)
295 throws IOException {
296 BufferedWriter awriter;
297 awriter = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
298 for (Enumeration e = properties.keys(); e.hasMoreElements();) {
299 String key = (String)e.nextElement();
300 String val = (String)properties.get(key);
301 key = saveConvert(key, true);
302
303 /* No need to escape embedded and trailing spaces for value, hence
304 * pass false to flag.
305 */
306 val = saveConvert(val, false);
307 writeln(awriter, key + "=" + val);
308 }
309 awriter.flush();
310 }
311
312 private static void writeln(BufferedWriter bw, String s) throws IOException {
313 bw.write(s);
314 bw.write("\n");
315 }
316
317 /**
318 * Convert a nibble to a hex character
319 * @param nibble the nibble to convert.
320 */
321 private static char toHex(int nibble) {
322 return hexDigit[(nibble & 0xF)];
323 }
324
325 /** A table of hex digits */
326 private static final char[] hexDigit = {
327 '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
328 };
329 }

mercurial