KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > XmlProperty


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant.taskdefs;
20
21 import java.io.File JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.util.Hashtable JavaDoc;
24 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
25 import javax.xml.parsers.DocumentBuilder JavaDoc;
26 import javax.xml.parsers.ParserConfigurationException JavaDoc;
27 import org.apache.tools.ant.BuildException;
28 import org.apache.tools.ant.Project;
29 import org.apache.tools.ant.types.Path;
30 import org.apache.tools.ant.types.Resource;
31 import org.apache.tools.ant.types.ResourceCollection;
32 import org.apache.tools.ant.types.XMLCatalog;
33 import org.apache.tools.ant.types.resources.FileResource;
34 import org.apache.tools.ant.util.FileUtils;
35 import org.w3c.dom.Document JavaDoc;
36 import org.w3c.dom.Element JavaDoc;
37 import org.w3c.dom.NamedNodeMap JavaDoc;
38 import org.w3c.dom.Node JavaDoc;
39 import org.w3c.dom.NodeList JavaDoc;
40 import org.xml.sax.SAXException JavaDoc;
41 import org.xml.sax.EntityResolver JavaDoc;
42
43 /**
44  * Loads property values from a valid XML file, generating the
45  * property names from the file's element and attribute names.
46  *
47  * <p>Example:</p>
48  * <pre>
49  * &lt;root-tag myattr="true"&gt;
50  * &lt;inner-tag someattr="val"&gt;Text&lt;/inner-tag&gt;
51  * &lt;a2&gt;&lt;a3&gt;&lt;a4&gt;false&lt;/a4&gt;&lt;/a3&gt;&lt;/a2&gt;
52  * &lt;x&gt;x1&lt;/x&gt;
53  * &lt;x&gt;x2&lt;/x&gt;
54  * &lt;/root-tag&gt;
55  *</pre>
56  *
57  * <p>this generates the following properties:</p>
58  *
59  * <pre>
60  * root-tag(myattr)=true
61  * root-tag.inner-tag=Text
62  * root-tag.inner-tag(someattr)=val
63  * root-tag.a2.a3.a4=false
64  * root-tag.x=x1,x2
65  * </pre>
66  *
67  * <p>The <i>collapseAttributes</i> property of this task can be set
68  * to true (the default is false) which will instead result in the
69  * following properties (note the difference in names of properties
70  * corresponding to XML attributes):</p>
71  *
72  * <pre>
73  * root-tag.myattr=true
74  * root-tag.inner-tag=Text
75  * root-tag.inner-tag.someattr=val
76  * root-tag.a2.a3.a4=false
77  * root-tag.x=x1,x2
78  * </pre>
79  *
80  * <p>Optionally, to more closely mirror the abilities of the Property
81  * task, a selected set of attributes can be treated specially. To
82  * enable this behavior, the "semanticAttributes" property of this task
83  * must be set to true (it defaults to false). If this attribute is
84  * specified, the following attributes take on special meaning
85  * (setting this to true implicitly sets collapseAttributes to true as
86  * well):</p>
87  *
88  * <ul>
89  * <li><b>value</b>: Identifies a text value for a property.</li>
90  * <li><b>location</b>: Identifies a file location for a property.</li>
91  * <li><b>id</b>: Sets an id for a property</li>
92  * <li><b>refid</b>: Sets a property to the value of another property
93  * based upon the provided id</li>
94  * <li><b>pathid</b>: Defines a path rather than a property with
95  * the given id.</li>
96  * </ul>
97  *
98  * <p>For example, with keepRoot = false, the following properties file:</p>
99  *
100  * <pre>
101  * &lt;root-tag&gt;
102  * &lt;build&gt;
103  * &lt;build folder="build"&gt;
104  * &lt;classes id="build.classes" location="${build.folder}/classes"/&gt;
105  * &lt;reference refid="build.classes"/&gt;
106  * &lt;/build&gt;
107  * &lt;compile&gt;
108  * &lt;classpath pathid="compile.classpath"&gt;
109  * &lt;pathelement location="${build.classes}"/&gt;
110  * &lt;/classpath&gt;
111  * &lt;/compile&gt;
112  * &lt;run-time&gt;
113  * &lt;jars&gt;*.jar&lt;/jars&gt;
114  * &lt;classpath pathid="run-time.classpath"&gt;
115  * &lt;path refid="compile.classpath"/&gt;
116  * &lt;pathelement path="${run-time.jars}"/&gt;
117  * &lt;/classpath&gt;
118  * &lt;/run-time&gt;
119  * &lt;/root-tag&gt;
120  * </pre>
121  *
122  * <p>is equivalent to the following entries in a build file:</p>
123  *
124  * <pre>
125  * &lt;property name="build" location="build"/&gt;
126  * &lt;property name="build.classes" location="${build.location}/classes"/&gt;
127  * &lt;property name="build.reference" refid="build.classes"/&gt;
128  *
129  * &lt;property name="run-time.jars" value="*.jar/&gt;
130  *
131  * &lt;classpath id="compile.classpath"&gt;
132  * &lt;pathelement location="${build.classes}"/&gt;
133  * &lt;/classpath&gt;
134  *
135  * &lt;classpath id="run-time.classpath"&gt;
136  * &lt;path refid="compile.classpath"/&gt;
137  * &lt;pathelement path="${run-time.jars}"/&gt;
138  * &lt;/classpath&gt;
139  * </pre>
140  *
141  * <p> This task <i>requires</i> the following attributes:</p>
142  *
143  * <ul>
144  * <li><b>file</b>: The name of the file to load.</li>
145  * </ul>
146  *
147  * <p>This task supports the following attributes:</p>
148  *
149  * <ul>
150  * <li><b>prefix</b>: Optionally specify a prefix applied to
151  * all properties loaded. Defaults to an empty string.</li>
152  * <li><b>keepRoot</b>: Indicate whether the root xml element
153  * is kept as part of property name. Defaults to true.</li>
154  * <li><b>validate</b>: Indicate whether the xml file is validated.
155  * Defaults to false.</li>
156  * <li><b>collapseAttributes</b>: Indicate whether attributes are
157  * stored in property names with parens or with period
158  * delimiters. Defaults to false, meaning properties
159  * are stored with parens (i.e., foo(attr)).</li>
160  * <li><b>semanticAttributes</b>: Indicate whether attributes
161  * named "location", "value", "refid" and "path"
162  * are interpreted as ant properties. Defaults
163  * to false.</li>
164  * <li><b>rootDirectory</b>: Indicate the directory to use
165  * as the root directory for resolving location
166  * properties. Defaults to the directory
167  * of the project using the task.</li>
168  * <li><b>includeSemanticAttribute</b>: Indicate whether to include
169  * the semantic attribute ("location" or "value") as
170  * part of the property name. Defaults to false.</li>
171  * </ul>
172  *
173  * @ant.task name="xmlproperty" category="xml"
174  */

175
176 public class XmlProperty extends org.apache.tools.ant.Task {
177
178     private Resource src;
179     private String JavaDoc prefix = "";
180     private boolean keepRoot = true;
181     private boolean validate = false;
182     private boolean collapseAttributes = false;
183     private boolean semanticAttributes = false;
184     private boolean includeSemanticAttribute = false;
185     private File JavaDoc rootDirectory = null;
186     private Hashtable JavaDoc addedAttributes = new Hashtable JavaDoc();
187     private XMLCatalog xmlCatalog = new XMLCatalog();
188
189     private static final String JavaDoc ID = "id";
190     private static final String JavaDoc REF_ID = "refid";
191     private static final String JavaDoc LOCATION = "location";
192     private static final String JavaDoc VALUE = "value";
193     private static final String JavaDoc PATH = "path";
194     private static final String JavaDoc PATHID = "pathid";
195     private static final String JavaDoc[] ATTRIBUTES = new String JavaDoc[] {
196         ID, REF_ID, LOCATION, VALUE, PATH, PATHID
197     };
198     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
199
200     /**
201      * Constructor.
202      */

203     public XmlProperty() {
204         super();
205     }
206
207     /**
208      * Initializes the task.
209      */

210
211     public void init() {
212         super.init();
213         xmlCatalog.setProject(getProject());
214     }
215
216
217     /**
218      * @return the xmlCatalog as the entityresolver.
219      */

220     protected EntityResolver JavaDoc getEntityResolver() {
221         return xmlCatalog;
222     }
223
224     /**
225      * Run the task.
226      * @throws BuildException The exception raised during task execution.
227      * @todo validate the source file is valid before opening, print a better error message
228      * @todo add a verbose level log message listing the name of the file being loaded
229      */

230     public void execute()
231             throws BuildException {
232
233         Resource r = getResource();
234
235         if (r == null) {
236             String JavaDoc msg = "XmlProperty task requires a source resource";
237             throw new BuildException(msg);
238         }
239
240         try {
241             log("Loading " + src, Project.MSG_VERBOSE);
242
243             if (r.isExists()) {
244
245               DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
246               factory.setValidating(validate);
247               factory.setNamespaceAware(false);
248               DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
249               builder.setEntityResolver(getEntityResolver());
250               Document JavaDoc document = null;
251               if (src instanceof FileResource) {
252                   document = builder.parse(((FileResource) src).getFile());
253               } else {
254                   document = builder.parse(src.getInputStream());
255               }
256               Element JavaDoc topElement = document.getDocumentElement();
257
258               // Keep a hashtable of attributes added by this task.
259
// This task is allow to override its own properties
260
// but not other properties. So we need to keep track
261
// of which properties we've added.
262
addedAttributes = new Hashtable JavaDoc();
263
264               if (keepRoot) {
265                   addNodeRecursively(topElement, prefix, null);
266               } else {
267                   NodeList JavaDoc topChildren = topElement.getChildNodes();
268                   int numChildren = topChildren.getLength();
269                   for (int i = 0; i < numChildren; i++) {
270                     addNodeRecursively(topChildren.item(i), prefix, null);
271                   }
272               }
273
274             } else {
275                 log("Unable to find property resource: " + r,
276                     Project.MSG_VERBOSE);
277             }
278
279         } catch (SAXException JavaDoc sxe) {
280             // Error generated during parsing
281
Exception JavaDoc x = sxe;
282             if (sxe.getException() != null) {
283                 x = sxe.getException();
284             }
285             throw new BuildException("Failed to load " + src, x);
286
287         } catch (ParserConfigurationException JavaDoc pce) {
288             // Parser with specified options can't be built
289
throw new BuildException(pce);
290         } catch (IOException JavaDoc ioe) {
291             // I/O error
292
throw new BuildException("Failed to load " + src, ioe);
293         }
294     }
295
296     /** Iterate through all nodes in the tree. */
297     private void addNodeRecursively(Node JavaDoc node, String JavaDoc prefix,
298                                     Object JavaDoc container) {
299
300         // Set the prefix for this node to include its tag name.
301
String JavaDoc nodePrefix = prefix;
302         if (node.getNodeType() != Node.TEXT_NODE) {
303             if (prefix.trim().length() > 0) {
304                 nodePrefix += ".";
305             }
306             nodePrefix += node.getNodeName();
307         }
308
309         // Pass the container to the processing of this node,
310
Object JavaDoc nodeObject = processNode(node, nodePrefix, container);
311
312         // now, iterate through children.
313
if (node.hasChildNodes()) {
314
315             NodeList JavaDoc nodeChildren = node.getChildNodes();
316             int numChildren = nodeChildren.getLength();
317
318             for (int i = 0; i < numChildren; i++) {
319                 // For each child, pass the object added by
320
// processNode to its children -- in other word, each
321
// object can pass information along to its children.
322
addNodeRecursively(nodeChildren.item(i), nodePrefix,
323                                    nodeObject);
324             }
325         }
326     }
327
328     void addNodeRecursively(org.w3c.dom.Node JavaDoc node, String JavaDoc prefix) {
329         addNodeRecursively(node, prefix, null);
330     }
331
332     /**
333      * Process the given node, adding any required attributes from
334      * this child node alone -- but <em>not</em> processing any
335      * children.
336      *
337      * @param node the XML Node to parse
338      * @param prefix A string to prepend to any properties that get
339      * added by this node.
340      * @param container Optionally, an object that a parent node
341      * generated that this node might belong to. For example, this
342      * node could be within a node that generated a Path.
343      * @return the Object created by this node. Generally, this is
344      * either a String if this node resulted in setting an attribute,
345      * or a Path.
346      */

347     public Object JavaDoc processNode (Node JavaDoc node, String JavaDoc prefix, Object JavaDoc container) {
348
349         // Parse the attribute(s) and text of this node, adding
350
// properties for each.
351
// if the "path" attribute is specified, then return the created path
352
// which will be passed to the children of this node.
353
Object JavaDoc addedPath = null;
354
355         // The value of an id attribute of this node.
356
String JavaDoc id = null;
357
358         if (node.hasAttributes()) {
359
360             NamedNodeMap JavaDoc nodeAttributes = node.getAttributes();
361
362             // Is there an id attribute?
363
Node JavaDoc idNode = nodeAttributes.getNamedItem(ID);
364             id = (semanticAttributes && idNode != null
365                   ? idNode.getNodeValue() : null);
366
367             // Now, iterate through the attributes adding them.
368
for (int i = 0; i < nodeAttributes.getLength(); i++) {
369
370                 Node JavaDoc attributeNode = nodeAttributes.item(i);
371
372                 if (!semanticAttributes) {
373                     String JavaDoc attributeName = getAttributeName(attributeNode);
374                     String JavaDoc attributeValue = getAttributeValue(attributeNode);
375                     addProperty(prefix + attributeName, attributeValue, null);
376                 } else {
377
378                     String JavaDoc nodeName = attributeNode.getNodeName();
379                     String JavaDoc attributeValue = getAttributeValue(attributeNode);
380
381                     Path containingPath = (container != null
382                         && container instanceof Path ? (Path) container : null);
383
384                     /*
385                      * The main conditional logic -- if the attribute
386                      * is somehow "special" (i.e., it has known
387                      * semantic meaning) then deal with it
388                      * appropriately.
389                      */

390                     if (nodeName.equals(ID)) {
391                         // ID has already been found above.
392
continue;
393                     } else if (containingPath != null
394                                && nodeName.equals(PATH)) {
395                         // A "path" attribute for a node within a Path object.
396
containingPath.setPath(attributeValue);
397                     } else if (container instanceof Path
398                                && nodeName.equals(REF_ID)) {
399                         // A "refid" attribute for a node within a Path object.
400
containingPath.setPath(attributeValue);
401                     } else if (container instanceof Path
402                                && nodeName.equals(LOCATION)) {
403                         // A "location" attribute for a node within a
404
// Path object.
405
containingPath.setLocation(resolveFile(attributeValue));
406                     } else if (nodeName.equals(PATHID)) {
407                         // A node identifying a new path
408
if (container != null) {
409                             throw new BuildException("XmlProperty does not "
410                                                      + "support nested paths");
411                         }
412
413                         addedPath = new Path(getProject());
414                         getProject().addReference(attributeValue, addedPath);
415                     } else {
416                         // An arbitrary attribute.
417
String JavaDoc attributeName = getAttributeName(attributeNode);
418                         addProperty(prefix + attributeName, attributeValue, id);
419                     }
420                 }
421             }
422         }
423
424         String JavaDoc nodeText = null;
425         boolean emptyNode = false;
426         boolean semanticEmptyOverride = false;
427         if (node.getNodeType() == Node.ELEMENT_NODE
428             && semanticAttributes
429             && node.hasAttributes()
430             && (node.getAttributes().getNamedItem(VALUE) != null
431                 || node.getAttributes().getNamedItem(LOCATION) != null
432                 || node.getAttributes().getNamedItem(REF_ID) != null
433                 || node.getAttributes().getNamedItem(PATH) != null
434                 || node.getAttributes().getNamedItem(PATHID) != null)) {
435             semanticEmptyOverride = true;
436         }
437         if (node.getNodeType() == Node.TEXT_NODE) {
438             // For the text node, add a property.
439
nodeText = getAttributeValue(node);
440         } else if ((node.getNodeType() == Node.ELEMENT_NODE)
441             && (node.getChildNodes().getLength() == 1)
442             && (node.getFirstChild().getNodeType() == Node.CDATA_SECTION_NODE)) {
443
444             nodeText = node.getFirstChild().getNodeValue();
445             if ("".equals(nodeText) && !semanticEmptyOverride) {
446                 emptyNode = true;
447             }
448         } else if ((node.getNodeType() == Node.ELEMENT_NODE)
449                    && (node.getChildNodes().getLength() == 0)
450                    && !semanticEmptyOverride) {
451             nodeText = "";
452             emptyNode = true;
453         } else if ((node.getNodeType() == Node.ELEMENT_NODE)
454                    && (node.getChildNodes().getLength() == 1)
455                    && (node.getFirstChild().getNodeType() == Node.TEXT_NODE)
456                    && ("".equals(node.getFirstChild().getNodeValue()))
457                    && !semanticEmptyOverride) {
458             nodeText = "";
459             emptyNode = true;
460         }
461
462         if (nodeText != null) {
463             // If the containing object was a String, then use it as the ID.
464
if (semanticAttributes && id == null
465                 && container instanceof String JavaDoc) {
466                 id = (String JavaDoc) container;
467             }
468             if (nodeText.trim().length() != 0 || emptyNode) {
469                 addProperty(prefix, nodeText, id);
470             }
471         }
472
473         // Return the Path we added or the ID of this node for
474
// children to reference if needed. Path objects are
475
// definitely used by child path elements, and ID may be used
476
// for a child text node.
477
return (addedPath != null ? addedPath : id);
478     }
479
480     /**
481      * Actually add the given property/value to the project
482      * after writing a log message.
483      */

484     private void addProperty (String JavaDoc name, String JavaDoc value, String JavaDoc id) {
485         String JavaDoc msg = name + ":" + value;
486         if (id != null) {
487             msg += ("(id=" + id + ")");
488         }
489         log(msg, Project.MSG_DEBUG);
490
491         if (addedAttributes.containsKey(name)) {
492             // If this attribute was added by this task, then
493
// we append this value to the existing value.
494
// We use the setProperty method which will
495
// forcibly override the property if it already exists.
496
// We need to put these properties into the project
497
// when we read them, though (instead of keeping them
498
// outside of the project and batch adding them at the end)
499
// to allow other properties to reference them.
500
value = (String JavaDoc) addedAttributes.get(name) + "," + value;
501             getProject().setProperty(name, value);
502             addedAttributes.put(name, value);
503         } else if (getProject().getProperty(name) == null) {
504             getProject().setNewProperty(name, value);
505             addedAttributes.put(name, value);
506         } else {
507             log("Override ignored for property " + name, Project.MSG_VERBOSE);
508         }
509         if (id != null) {
510             getProject().addReference(id, value);
511         }
512     }
513
514     /**
515      * Return a reasonable attribute name for the given node.
516      * If we are using semantic attributes or collapsing
517      * attributes, the returned name is ".nodename".
518      * Otherwise, we return "(nodename)". This is long-standing
519      * (and default) &lt;xmlproperty&gt; behavior.
520      */

521     private String JavaDoc getAttributeName (Node JavaDoc attributeNode) {
522         String JavaDoc attributeName = attributeNode.getNodeName();
523
524         if (semanticAttributes) {
525             // Never include the "refid" attribute as part of the
526
// attribute name.
527
if (attributeName.equals(REF_ID)) {
528                 return "";
529             // Otherwise, return it appended unless property to hide it is set.
530
} else if (!isSemanticAttribute(attributeName)
531                        || includeSemanticAttribute) {
532                 return "." + attributeName;
533             } else {
534                 return "";
535             }
536         } else if (collapseAttributes) {
537             return "." + attributeName;
538         } else {
539             return "(" + attributeName + ")";
540         }
541     }
542
543     /**
544      * Return whether the provided attribute name is recognized or not.
545      */

546     private static boolean isSemanticAttribute (String JavaDoc attributeName) {
547         for (int i = 0; i < ATTRIBUTES.length; i++) {
548             if (attributeName.equals(ATTRIBUTES[i])) {
549                 return true;
550             }
551         }
552         return false;
553     }
554
555     /**
556      * Return the value for the given attribute.
557      * If we are not using semantic attributes, its just the
558      * literal string value of the attribute.
559      *
560      * <p>If we <em>are</em> using semantic attributes, then first
561      * dependent properties are resolved (i.e., ${foo} is resolved
562      * based on the foo property value), and then an appropriate data
563      * type is used. In particular, location-based properties are
564      * resolved to absolute file names. Also for refid values, look
565      * up the referenced object from the project.</p>
566      */

567     private String JavaDoc getAttributeValue (Node JavaDoc attributeNode) {
568         String JavaDoc nodeValue = attributeNode.getNodeValue().trim();
569         if (semanticAttributes) {
570             String JavaDoc attributeName = attributeNode.getNodeName();
571             nodeValue = getProject().replaceProperties(nodeValue);
572             if (attributeName.equals(LOCATION)) {
573                 File JavaDoc f = resolveFile(nodeValue);
574                 return f.getPath();
575             } else if (attributeName.equals(REF_ID)) {
576                 Object JavaDoc ref = getProject().getReference(nodeValue);
577                 if (ref != null) {
578                     return ref.toString();
579                 }
580             }
581         }
582         return nodeValue;
583     }
584
585     /**
586      * The XML file to parse; required.
587      * @param src the file to parse
588      */

589     public void setFile(File JavaDoc src) {
590         setSrcResource(new FileResource(src));
591     }
592
593     /**
594      * The resource to pack; required.
595      * @param src resource to expand
596      */

597     public void setSrcResource(Resource src) {
598         if (src.isDirectory()) {
599             throw new BuildException("the source can't be a directory");
600         }
601         if (src instanceof FileResource && !supportsNonFileResources()) {
602             throw new BuildException("Only FileSystem resources are"
603                                      + " supported.");
604         }
605         this.src = src;
606     }
607
608     /**
609      * Set the source resource.
610      * @param a the resource to pack as a single element Resource collection.
611      */

612     public void addConfigured(ResourceCollection a) {
613         if (a.size() != 1) {
614             throw new BuildException("only single argument resource collections"
615                                      + " are supported as archives");
616         }
617         setSrcResource((Resource) a.iterator().next());
618     }
619
620     /**
621      * the prefix to prepend to each property
622      * @param prefix the prefix to prepend to each property
623      */

624     public void setPrefix(String JavaDoc prefix) {
625         this.prefix = prefix.trim();
626     }
627
628     /**
629      * flag to include the xml root tag as a
630      * first value in the property name; optional,
631      * default is true
632      * @param keepRoot if true (default), include the xml root tag
633      */

634     public void setKeeproot(boolean keepRoot) {
635         this.keepRoot = keepRoot;
636     }
637
638     /**
639      * flag to validate the XML file; optional, default false
640      * @param validate if true validate the XML file, default false
641      */

642     public void setValidate(boolean validate) {
643         this.validate = validate;
644     }
645
646     /**
647      * flag to treat attributes as nested elements;
648      * optional, default false
649      * @param collapseAttributes if true treat attributes as nested elements
650      */

651     public void setCollapseAttributes(boolean collapseAttributes) {
652         this.collapseAttributes = collapseAttributes;
653     }
654
655     /**
656      * Attribute to enable special handling of attributes - see ant manual.
657      * @param semanticAttributes if true enable the special handling.
658      */

659     public void setSemanticAttributes(boolean semanticAttributes) {
660         this.semanticAttributes = semanticAttributes;
661     }
662
663     /**
664      * The directory to use for resolving file references.
665      * Ignored if semanticAttributes is not set to true.
666      * @param rootDirectory the directory.
667      */

668     public void setRootDirectory(File JavaDoc rootDirectory) {
669         this.rootDirectory = rootDirectory;
670     }
671
672     /**
673      * Include the semantic attribute name as part of the property name.
674      * Ignored if semanticAttributes is not set to true.
675      * @param includeSemanticAttribute if true include the sematic attribute
676      * name.
677      */

678     public void setIncludeSemanticAttribute(boolean includeSemanticAttribute) {
679         this.includeSemanticAttribute = includeSemanticAttribute;
680     }
681
682     /**
683      * add an XMLCatalog as a nested element; optional.
684      * @param catalog the XMLCatalog to use
685      */

686     public void addConfiguredXMLCatalog(XMLCatalog catalog) {
687         xmlCatalog.addConfiguredXMLCatalog(catalog);
688     }
689
690     /* Expose members for extensibility */
691
692     /**
693      * @return the file attribute.
694      */

695     protected File JavaDoc getFile () {
696         if (src instanceof FileResource) {
697             return ((FileResource) src).getFile();
698         } else {
699             return null;
700         }
701     }
702
703     /**
704      * @return the resource.
705      */

706     protected Resource getResource() {
707         // delegate this way around to support subclasses that
708
// overwrite getFile
709
File JavaDoc f = getFile();
710         if (f != null) {
711             return new FileResource(f);
712         } else {
713             return src;
714         }
715     }
716
717     /**
718      * @return the prefix attribute.
719      */

720     protected String JavaDoc getPrefix () {
721         return this.prefix;
722     }
723
724     /**
725      * @return the keeproot attribute.
726      */

727     protected boolean getKeeproot () {
728         return this.keepRoot;
729     }
730
731     /**
732      * @return the validate attribute.
733      */

734     protected boolean getValidate () {
735         return this.validate;
736     }
737
738     /**
739      * @return the collapse attributes attribute.
740      */

741     protected boolean getCollapseAttributes () {
742         return this.collapseAttributes;
743     }
744
745     /**
746      * @return the semantic attributes attribute.
747      */

748     protected boolean getSemanticAttributes () {
749         return this.semanticAttributes;
750     }
751
752     /**
753      * @return the root directory attribute.
754      */

755     protected File JavaDoc getRootDirectory () {
756         return this.rootDirectory;
757     }
758
759     /**
760      * @return the include semantic attribute.
761      */

762     protected boolean getIncludeSementicAttribute () {
763         return this.includeSemanticAttribute;
764     }
765
766     /**
767      * Let project resolve the file - or do it ourselves if
768      * rootDirectory has been set.
769      */

770     private File JavaDoc resolveFile(String JavaDoc fileName) {
771         if (rootDirectory == null) {
772             return FILE_UTILS.resolveFile(getProject().getBaseDir(), fileName);
773         }
774         return FILE_UTILS.resolveFile(rootDirectory, fileName);
775     }
776
777     /**
778      * Whether this task can deal with non-file resources.
779      *
780      * <p>This implementation returns true only if this task is
781      * &lt;xmlproperty&gt;. Any subclass of this class that also wants to
782      * support non-file resources needs to override this method. We
783      * need to do so for backwards compatibility reasons since we
784      * can't expect subclasses to support resources.</p>
785      * @return true for this task.
786      * @since Ant 1.7
787      */

788     protected boolean supportsNonFileResources() {
789         return getClass().equals(XmlProperty.class);
790     }
791 }
792
Popular Tags