source: release-kits/lirk3/resources/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 14.1 KB
Line 
1/*
2 * Copyright 2002-2004 The Apache Software Foundation
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 */
17package org.apache.tools.ant.taskdefs.optional;
18
19import java.io.ByteArrayOutputStream;
20import java.io.File;
21import java.io.FileInputStream;
22import java.io.FileNotFoundException;
23import java.io.FileOutputStream;
24import java.io.IOException;
25import java.io.OutputStream;
26import java.io.OutputStreamWriter;
27import java.io.Writer;
28import java.util.Enumeration;
29import java.util.Hashtable;
30import java.util.Properties;
31import java.util.Vector;
32import javax.xml.parsers.DocumentBuilder;
33import javax.xml.parsers.DocumentBuilderFactory;
34import org.apache.tools.ant.BuildException;
35import org.apache.tools.ant.Project;
36import org.apache.tools.ant.Task;
37import org.apache.tools.ant.types.EnumeratedAttribute;
38import org.apache.tools.ant.types.PropertySet;
39import org.apache.tools.ant.util.CollectionUtils;
40import org.apache.tools.ant.util.DOMElementWriter;
41import org.w3c.dom.Document;
42import org.w3c.dom.Element;
43
44/**
45 * Displays all the current properties in the build. The output can be sent to
46 * a file if desired. <P>
47 *
48 * Attribute "destfile" defines a file to send the properties to. This can be
49 * processed as a standard property file later. <P>
50 *
51 * Attribute "prefix" defines a prefix which is used to filter the properties
52 * only those properties starting with this prefix will be echoed. <P>
53 *
54 * By default, the "failonerror" attribute is enabled. If an error occurs while
55 * writing the properties to a file, and this attribute is enabled, then a
56 * BuildException will be thrown. If disabled, then IO errors will be reported
57 * as a log statement, but no error will be thrown. <P>
58 *
59 * Examples: <pre>
60 * &lt;echoproperties /&gt;
61 * </pre> Report the current properties to the log. <P>
62 *
63 * <pre>
64 * &lt;echoproperties destfile="my.properties" /&gt;
65 * </pre> Report the current properties to the file "my.properties", and will
66 * fail the build if the file could not be created or written to. <P>
67 *
68 * <pre>
69 * &lt;echoproperties destfile="my.properties" failonerror="false"
70 * prefix="ant" /&gt;
71 * </pre> Report all properties beginning with 'ant' to the file
72 * "my.properties", and will log a message if the file could not be created or
73 * written to, but will still allow the build to continue.
74 *
75 *@since Ant 1.5
76 */
77public class EchoProperties extends Task {
78
79 /**
80 * the properties element.
81 */
82 private static final String PROPERTIES = "properties";
83
84 /**
85 * the property element.
86 */
87 private static final String PROPERTY = "property";
88
89 /**
90 * name attribute for property, testcase and testsuite elements.
91 */
92 private static final String ATTR_NAME = "name";
93
94 /**
95 * value attribute for property elements.
96 */
97 private static final String ATTR_VALUE = "value";
98
99 /**
100 * the input file.
101 */
102 private File inFile = null;
103
104 /**
105 * File object pointing to the output file. If this is null, then
106 * we output to the project log, not to a file.
107 */
108 private File destfile = null;
109
110 /**
111 * If this is true, then errors generated during file output will become
112 * build errors, and if false, then such errors will be logged, but not
113 * thrown.
114 */
115 private boolean failonerror = true;
116
117 private Vector propertySets = new Vector();
118
119 private String format = "text";
120
121 /**
122 * Sets the input file.
123 *
124 * @param file the input file
125 */
126 public void setSrcfile(File file) {
127 inFile = file;
128 }
129
130 /**
131 * Set a file to store the property output. If this is never specified,
132 * then the output will be sent to the Ant log.
133 *
134 *@param destfile file to store the property output
135 */
136 public void setDestfile(File destfile) {
137 this.destfile = destfile;
138 }
139
140
141 /**
142 * If true, the task will fail if an error occurs writing the properties
143 * file, otherwise errors are just logged.
144 *
145 *@param failonerror <tt>true</tt> if IO exceptions are reported as build
146 * exceptions, or <tt>false</tt> if IO exceptions are ignored.
147 */
148 public void setFailOnError(boolean failonerror) {
149 this.failonerror = failonerror;
150 }
151
152
153 /**
154 * If the prefix is set, then only properties which start with this
155 * prefix string will be recorded. If this is never set, or it is set
156 * to an empty string or <tt>null</tt>, then all properties will be
157 * recorded. <P>
158 *
159 * For example, if the property is set as:
160 * <PRE>&lt;echoproperties prefix="ant." /&gt;</PRE>
161 * then the property "ant.home" will be recorded, but "ant-example"
162 * will not.
163 *
164 *@param prefix The new prefix value
165 */
166 public void setPrefix(String prefix) {
167 PropertySet ps = new PropertySet();
168 ps.setProject(getProject());
169 ps.appendPrefix(prefix);
170 addPropertyset(ps);
171 }
172
173 /**
174 * A set of properties to write.
175 *
176 * @since Ant 1.6
177 */
178 public void addPropertyset(PropertySet ps) {
179 propertySets.addElement(ps);
180 }
181
182 public void setFormat(FormatAttribute ea) {
183 format = ea.getValue();
184 }
185
186 public static class FormatAttribute extends EnumeratedAttribute {
187 private String [] formats = new String[]{"xml", "text"};
188
189 public String[] getValues() {
190 return formats;
191 }
192 }
193
194 /**
195 * Run the task.
196 *
197 *@exception BuildException trouble, probably file IO
198 */
199 public void execute() throws BuildException {
200 //copy the properties file
201 Hashtable allProps = new Hashtable();
202
203 /* load properties from file if specified, otherwise
204 use Ant's properties */
205 if (inFile == null && propertySets.size() == 0) {
206 // add ant properties
207 CollectionUtils.putAll(allProps, getProject().getProperties());
208 } else if (inFile != null) {
209 if (inFile.exists() && inFile.isDirectory()) {
210 String message = "srcfile is a directory!";
211 if (failonerror) {
212 throw new BuildException(message, getLocation());
213 } else {
214 log(message, Project.MSG_ERR);
215 }
216 return;
217 }
218
219 if (inFile.exists() && !inFile.canRead()) {
220 String message = "Can not read from the specified srcfile!";
221 if (failonerror) {
222 throw new BuildException(message, getLocation());
223 } else {
224 log(message, Project.MSG_ERR);
225 }
226 return;
227 }
228
229 FileInputStream in = null;
230 try {
231 in = new FileInputStream(inFile);
232 Properties props = new Properties();
233 props.load(in);
234 CollectionUtils.putAll(allProps, props);
235 } catch (FileNotFoundException fnfe) {
236 String message =
237 "Could not find file " + inFile.getAbsolutePath();
238 if (failonerror) {
239 throw new BuildException(message, fnfe, getLocation());
240 } else {
241 log(message, Project.MSG_WARN);
242 }
243 return;
244 } catch (IOException ioe) {
245 String message =
246 "Could not read file " + inFile.getAbsolutePath();
247 if (failonerror) {
248 throw new BuildException(message, ioe, getLocation());
249 } else {
250 log(message, Project.MSG_WARN);
251 }
252 return;
253 } finally {
254 try {
255 if (null != in) {
256 in.close();
257 }
258 } catch (IOException ioe) {
259 //ignore
260 }
261 }
262 }
263
264 Enumeration e = propertySets.elements();
265 while (e.hasMoreElements()) {
266 PropertySet ps = (PropertySet) e.nextElement();
267 CollectionUtils.putAll(allProps, ps.getProperties());
268 }
269
270 OutputStream os = null;
271 try {
272 if (destfile == null) {
273 os = new ByteArrayOutputStream();
274 saveProperties(allProps, os);
275 log(os.toString(), Project.MSG_INFO);
276 } else {
277 if (destfile.exists() && destfile.isDirectory()) {
278 String message = "destfile is a directory!";
279 if (failonerror) {
280 throw new BuildException(message, getLocation());
281 } else {
282 log(message, Project.MSG_ERR);
283 }
284 return;
285 }
286
287 if (destfile.exists() && !destfile.canWrite()) {
288 String message =
289 "Can not write to the specified destfile!";
290 if (failonerror) {
291 throw new BuildException(message, getLocation());
292 } else {
293 log(message, Project.MSG_ERR);
294 }
295 return;
296 }
297 os = new FileOutputStream(this.destfile);
298 saveProperties(allProps, os);
299 }
300 } catch (IOException ioe) {
301 if (failonerror) {
302 throw new BuildException(ioe, getLocation());
303 } else {
304 log(ioe.getMessage(), Project.MSG_INFO);
305 }
306 } finally {
307 if (os != null) {
308 try {
309 os.close();
310 } catch (IOException ex) {
311 //ignore
312 }
313 }
314 }
315 }
316
317
318 /**
319 * Send the key/value pairs in the hashtable to the given output stream.
320 * Only those properties matching the <tt>prefix</tt> constraint will be
321 * sent to the output stream.
322 * The output stream will be closed when this method returns.
323 *
324 *@param allProps propfile to save
325 *@param os output stream
326 *@exception IOException trouble
327 */
328 protected void saveProperties(Hashtable allProps, OutputStream os)
329 throws IOException, BuildException {
330 Properties props = new Properties();
331 Enumeration e = allProps.keys();
332 while (e.hasMoreElements()) {
333 String name = e.nextElement().toString();
334 String value = allProps.get(name).toString();
335 props.put(name, value);
336 }
337
338 if ("text".equals(format)) {
339 jdkSaveProperties(props, os, "Ant properties");
340 } else if ("xml".equals(format)) {
341 xmlSaveProperties(props, os);
342 }
343 }
344
345 protected void xmlSaveProperties(Properties props,
346 OutputStream os) throws IOException {
347 // create XML document
348 Document doc = getDocumentBuilder().newDocument();
349 Element rootElement = doc.createElement(PROPERTIES);
350
351 // output properties
352 String name;
353 Enumeration e = props.propertyNames();
354 while (e.hasMoreElements()) {
355 name = (String) e.nextElement();
356 Element propElement = doc.createElement(PROPERTY);
357 propElement.setAttribute(ATTR_NAME, name);
358 propElement.setAttribute(ATTR_VALUE, props.getProperty(name));
359 rootElement.appendChild(propElement);
360 }
361
362 Writer wri = null;
363 try {
364 wri = new OutputStreamWriter(os, "UTF8");
365 wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
366 (new DOMElementWriter()).write(rootElement, wri, 0, "\t");
367 wri.flush();
368 } catch (IOException ioe) {
369 throw new BuildException("Unable to write XML file", ioe);
370 } finally {
371 if (wri != null) {
372 wri.close();
373 }
374 }
375 }
376
377 /**
378 * JDK 1.2 allows for the safer method
379 * <tt>Properties.store(OutputStream, String)</tt>, which throws an
380 * <tt>IOException</tt> on an output error.
381 *
382 *@param props the properties to record
383 *@param os record the properties to this output stream
384 *@param header prepend this header to the property output
385 *@exception IOException on an I/O error during a write.
386 */
387 protected void jdkSaveProperties(Properties props, OutputStream os,
388 String header) throws IOException {
389 try {
390 props.store(os, header);
391
392 } catch (IOException ioe) {
393 throw new BuildException(ioe, getLocation());
394 } finally {
395 if (os != null) {
396 try {
397 os.close();
398 } catch (IOException ioex) {
399 log("Failed to close output stream");
400 }
401 }
402 }
403 }
404
405
406 /**
407 * Uses the DocumentBuilderFactory to get a DocumentBuilder instance.
408 *
409 * @return The DocumentBuilder instance
410 */
411 private static DocumentBuilder getDocumentBuilder() {
412 try {
413 return DocumentBuilderFactory.newInstance().newDocumentBuilder();
414 } catch (Exception e) {
415 throw new ExceptionInInitializerError(e);
416 }
417 }
418}
419
Note: See TracBrowser for help on using the repository browser.