KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ant > internal > core > contentDescriber > AntHandler


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Philippe Ombredanne (pombredanne@nexb.com) - bug 125367
11  *******************************************************************************/

12 package org.eclipse.ant.internal.core.contentDescriber;
13
14 import java.io.IOException JavaDoc;
15 import java.io.StringReader JavaDoc;
16
17 import javax.xml.parsers.ParserConfigurationException JavaDoc;
18 import javax.xml.parsers.SAXParser JavaDoc;
19 import javax.xml.parsers.SAXParserFactory JavaDoc;
20
21 import org.xml.sax.Attributes JavaDoc;
22 import org.xml.sax.InputSource JavaDoc;
23 import org.xml.sax.SAXException JavaDoc;
24 import org.xml.sax.SAXNotRecognizedException JavaDoc;
25 import org.xml.sax.SAXNotSupportedException JavaDoc;
26 import org.xml.sax.XMLReader JavaDoc;
27 import org.xml.sax.helpers.DefaultHandler JavaDoc;
28
29 /**
30  * An xml event handler for detecting the project top-level element in an Ant buildfile.
31  * Also records whether a default attribute is present for the project and if any target
32  * or some other typical ant elements are present. There are still cases where we could
33  * ignore a valid ant buildfile though.
34  *
35  * @since 3.1
36  */

37 public final class AntHandler extends DefaultHandler JavaDoc {
38     /**
39      * An exception indicating that the parsing should stop.
40      *
41      * @since 3.1
42      */

43     private class StopParsingException extends SAXException JavaDoc {
44         /**
45          * All serializable objects should have a stable serialVersionUID
46          */

47         private static final long serialVersionUID = 1L;
48
49         /**
50          * Constructs an instance of <code>StopParsingException</code> with a
51          * <code>null</code> detail message.
52          */

53         public StopParsingException() {
54             super((String JavaDoc) null);
55         }
56     }
57
58     private static final String JavaDoc DEFAULT_ATTRIBUTE= "default"; //$NON-NLS-1$
59
private static final String JavaDoc PROJECT = "project"; //$NON-NLS-1$
60
private static final String JavaDoc TARGET= "target"; //$NON-NLS-1$
61
private static final String JavaDoc MACRODEF= "macrodef"; //$NON-NLS-1$
62
private static final String JavaDoc TASKDEF= "taskdef"; //$NON-NLS-1$
63
private static final String JavaDoc TYPEDEF= "typedef"; //$NON-NLS-1$
64
private static final String JavaDoc PROPERTY= "property"; //$NON-NLS-1$
65
private static final String JavaDoc CLASSPATH= "classpath"; //$NON-NLS-1$
66
private static final String JavaDoc PATH= "path"; //$NON-NLS-1$
67
private static final String JavaDoc IMPORT= "import"; //$NON-NLS-1$
68

69     /**
70      * This is the name of the top-level element found in the XML file. This
71      * member variable is <code>null</code> unless the file has been parsed
72      * successful to the point of finding the top-level element.
73      */

74     private String JavaDoc fTopElementFound = null;
75     private SAXParserFactory JavaDoc fFactory;
76
77     private boolean fDefaultAttributeFound= false;
78     private boolean fTargetFound = false;
79     private boolean fAntElementFound = false;
80
81     private int fLevel= -1;
82
83     /**
84      * Creates a new SAX parser for use within this instance.
85      *
86      * @return The newly created parser.
87      * @throws ParserConfigurationException
88      * If a parser of the given configuration cannot be created.
89      * @throws SAXException
90      * If something in general goes wrong when creating the parser.
91      */

92     private final SAXParser JavaDoc createParser(SAXParserFactory JavaDoc parserFactory) throws ParserConfigurationException JavaDoc, SAXException JavaDoc, SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
93         // Initialize the parser.
94
final SAXParser JavaDoc parser = parserFactory.newSAXParser();
95         final XMLReader JavaDoc reader = parser.getXMLReader();
96         // disable DTD validation (bug 63625)
97
try {
98             // be sure validation is "off" or the feature to ignore DTD's will not apply
99
reader.setFeature("http://xml.org/sax/features/validation", false); //$NON-NLS-1$
100
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
101
} catch (SAXNotRecognizedException JavaDoc e) {
102             // not a big deal if the parser does not recognize the features
103
} catch (SAXNotSupportedException JavaDoc e) {
104             // not a big deal if the parser does not support the features
105
}
106         return parser;
107     }
108
109     private SAXParserFactory JavaDoc getFactory() {
110         synchronized (this) {
111             if (fFactory != null) {
112                 return fFactory;
113             }
114             fFactory= SAXParserFactory.newInstance();
115             fFactory.setNamespaceAware(true);
116         }
117         return fFactory;
118     }
119
120     protected boolean parseContents(InputSource JavaDoc contents) throws IOException JavaDoc, ParserConfigurationException JavaDoc, SAXException JavaDoc {
121         // Parse the file into we have what we need (or an error occurs).
122
try {
123             fFactory = getFactory();
124             if (fFactory == null) {
125                 return false;
126             }
127             final SAXParser JavaDoc parser = createParser(fFactory);
128             // to support external entities specified as relative URIs (see bug 63298)
129
contents.setSystemId("/"); //$NON-NLS-1$
130
parser.parse(contents, this);
131         } catch (StopParsingException e) {
132             // Abort the parsing normally. Fall through...
133
}
134         return true;
135     }
136
137     /*
138      * Resolve external entity definitions to an empty string. This is to speed
139      * up processing of files with external DTDs. Not resolving the contents
140      * of the DTD is ok, as only the System ID of the DTD declaration is used.
141      * @see org.xml.sax.helpers.DefaultHandler#resolveEntity(java.lang.String, java.lang.String)
142      */

143     public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId) throws SAXException JavaDoc {
144         return new InputSource JavaDoc(new StringReader JavaDoc("")); //$NON-NLS-1$
145
}
146
147     /*
148      * (non-Javadoc)
149      *
150      * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
151      * java.lang.String, java.lang.String, org.xml.sax.Attributes)
152      */

153     public final void startElement(final String JavaDoc uri, final String JavaDoc elementName, final String JavaDoc qualifiedName, final Attributes JavaDoc attributes) throws SAXException JavaDoc {
154         fLevel++;
155         if (fTopElementFound == null) {
156             fTopElementFound = elementName;
157             if (!hasRootProjectElement()) {
158                 throw new StopParsingException();
159             }
160             if (attributes != null) {
161                 fDefaultAttributeFound= attributes.getValue(DEFAULT_ATTRIBUTE) != null;
162                 if (fDefaultAttributeFound) {
163                     throw new StopParsingException();
164                 }
165             }
166         }
167         if (fLevel == 1 && TARGET.equals(elementName)) {
168             fTargetFound= true;
169             throw new StopParsingException();
170         }
171         
172         //top level Ant elements
173
if (fLevel == 1 && (MACRODEF.equals(elementName)
174         || TASKDEF.equals(elementName) || TYPEDEF.equals(elementName)
175         || PROPERTY.equals(elementName)|| CLASSPATH.equals(elementName)
176         || PATH.equals(elementName) || IMPORT.equals(elementName))) {
177             fAntElementFound= true;
178             throw new StopParsingException();
179         }
180     }
181
182     /* (non-Javadoc)
183      * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
184      */

185     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc {
186         super.endElement(uri, localName, qName);
187         fLevel--;
188     }
189
190     protected boolean hasProjectDefaultAttribute() {
191         return fDefaultAttributeFound;
192     }
193
194     protected boolean hasRootProjectElement() {
195        return PROJECT.equals(fTopElementFound);
196     }
197     
198     protected boolean hasTargetElement() {
199         return fTargetFound;
200      }
201     
202     protected boolean hasAntElement() {
203         return fAntElementFound;
204      }
205 }
Popular Tags