KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > ide > model > PropertyParser


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

11 package org.eclipse.ui.internal.ide.model;
12
13 import java.io.File JavaDoc;
14 import java.io.StringReader JavaDoc;
15
16 import javax.xml.parsers.*;
17
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.QualifiedName;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.ui.IResourceActionFilter;
25 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
26
27 import org.xml.sax.Attributes JavaDoc;
28 import org.xml.sax.InputSource JavaDoc;
29 import org.xml.sax.SAXException JavaDoc;
30 import org.xml.sax.XMLReader JavaDoc;
31 import org.xml.sax.ext.LexicalHandler JavaDoc;
32 import org.xml.sax.helpers.DefaultHandler JavaDoc;
33
34 /*
35  * This PropertyParser is used to examine XML files in
36  * an effort to learn a bit more about their context.
37  * This will then help Eclipse determine, for example,
38  * what menu entries are really appropriate for this
39  * particular XML file. As an example, a plugin.xml file
40  * should not have context menu entries relating to
41  * running Ant scripts.
42  *
43  * Currently (Eclipse 3.0) this parser only looks for
44  * the root level tag and the name of the DTD (if any).
45  * This parser may be extended to look for other, relevant
46  * pieces of information. The information found is stored
47  * as a persistent property on this resource. This way,
48  * we only need to parse this file again if the file
49  * has changed. If no changes have occurred, we simply
50  * access the persistent property and do not parse.
51  *
52  * This parser should be aware of the environment in
53  * which it is being called in that it needs to be
54  * called a minimun number of times (we don't want to
55  * reparse every XML file each time someone asks for
56  * a context menu), it needs to do minimal computing/parsing,
57  * and it needs to handle any unexpected or error
58  * results cleanly.
59  *
60  * Current restrictions in XML parsing logic require that
61  * if a DTD is mentioned in and XML file, that DTD file
62  * must be present and accessible. The PropertyParser does
63  * not require this to be true, but the underlying XML
64  * parser does require this.
65  */

66
67 public class PropertyParser extends DefaultHandler JavaDoc implements LexicalHandler JavaDoc {
68
69     // model parser
70
private static SAXParser parser;
71     private static SAXParserFactory parserFactory;
72     
73     // The XML file/resource being parsed
74
private IResource parseResource = null;
75     int x = initializeParser();
76     
77     private int initializeParser() {
78         try {
79             parserFactory = SAXParserFactory.newInstance();
80             parserFactory.setNamespaceAware(true);
81             try {
82                 parserFactory.setFeature("http://xml.org/sax/features/string-interning", true); //$NON-NLS-1$
83
parserFactory.setValidating(false);
84             } catch (SAXException JavaDoc e) {
85                 IDEWorkbenchPlugin.log("Problem initializing parser", new Status(IStatus.ERROR,IDEWorkbenchPlugin.IDE_WORKBENCH, IStatus.ERROR, "Problem initializing parser", e)); //$NON-NLS-1$ //$NON-NLS-2$
86
}
87             parser = parserFactory.newSAXParser();
88             XMLReader JavaDoc reader = parser.getXMLReader();
89             reader.setProperty("http://xml.org/sax/properties/lexical-handler", this); //$NON-NLS-1$
90
} catch (Exception JavaDoc e) {
91             IDEWorkbenchPlugin.log("Problem initializing parser", new Status(IStatus.ERROR,IDEWorkbenchPlugin.IDE_WORKBENCH, IStatus.ERROR, "Problem initializing parser", e)); //$NON-NLS-1$ //$NON-NLS-2$
92
}
93         return 1;
94     }
95
96     /*
97      * Cause parsing to happen on the specified resource.
98      *
99      * @param resource the resource being parsed. This
100      * resource is assumed to be a valid XML file.
101      */

102     synchronized public void parseResource(IResource resource) throws Exception JavaDoc {
103         if (resource == null)
104             return;
105         parseResource = resource;
106         // Need to get a File version of this resource
107
IPath location = resource.getLocation();
108         if (location == null)
109             return;
110         File JavaDoc file = location.toFile();
111         if (file.length() == 0L) {
112             // Some SAX parsers will throw a SAXParseException for a
113
// zero-length file. We'll just decide there's nothing to
114
// do and return gracefully. First, set the last modification
115
// time so we don't have to check this again unless the file
116
// changes.
117
long modTime = parseResource.getModificationStamp();
118             QualifiedName modKey = new QualifiedName(IDEWorkbenchPlugin.IDE_WORKBENCH, WorkbenchResource.XML_LAST_MOD);
119             try {
120                 parseResource.setPersistentProperty(modKey, new Long JavaDoc(modTime).toString());
121             } catch (CoreException c) {
122                 IDEWorkbenchPlugin.log("Problem parsing element", c.getStatus()); //$NON-NLS-1$
123
}
124             return;
125         }
126         try {
127             parser.parse(file, this);
128         } catch (SAXException JavaDoc s) {
129             // If the SAXException is the one we threw
130
// to abort the parsing, just ignore it and
131
// continue processing.
132
if (!s.getMessage().equals("PropertyParser stop")) { //$NON-NLS-1$
133
// We got a real error, so log it but
134
// continue processing.
135
IDEWorkbenchPlugin.log("Problem parsing file", new Status(IStatus.ERROR,IDEWorkbenchPlugin.IDE_WORKBENCH, IStatus.ERROR, "Problem parsing file", s)); //$NON-NLS-1$ //$NON-NLS-2$
136
}
137         }
138     }
139     
140     /*
141      * (non-Javadoc)
142      * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
143      *
144      */

145
146     public void startElement(String JavaDoc uri, String JavaDoc elementName, String JavaDoc qName, Attributes JavaDoc attributes)
147     throws SAXException JavaDoc {
148
149         /* We have hit an XML element. We are only concerned
150          * with the root level element. Figure out what it
151          * is and store it as a persistent property. Once
152          * we have the root level element stored, no further
153          * parsing of this file is required. As a result,
154          * this method will then throw a SAXException (the
155          * recommended way of aborting parsing).
156          *
157          * This method is not intended to be called. It is
158          * only called from within the XML SAX parser being
159          * used.
160          */

161         long modTime = parseResource.getModificationStamp();
162         QualifiedName modKey = new QualifiedName(IDEWorkbenchPlugin.IDE_WORKBENCH, WorkbenchResource.XML_LAST_MOD);
163         try {
164             parseResource.setPersistentProperty(modKey, new Long JavaDoc(modTime).toString());
165         } catch (CoreException c) {
166             IDEWorkbenchPlugin.log("Problem parsing element", c.getStatus()); //$NON-NLS-1$
167
}
168         // We are only interested in the first element.
169
QualifiedName key;
170         String JavaDoc propertyName = IResourceActionFilter.XML_FIRST_TAG;
171         key = new QualifiedName(IDEWorkbenchPlugin.IDE_WORKBENCH, propertyName);
172         try {
173             parseResource.setPersistentProperty(key, elementName);
174         } catch (CoreException c) {
175             IDEWorkbenchPlugin.log("Problem parsing element", c.getStatus()); //$NON-NLS-1$
176
}
177         // And now we wish to abort the parsing. The only other thing
178
// we looked for was the dtd name. By definition, the dtd
179
// declaration must occur before the first element.
180
throw new SAXException JavaDoc("PropertyParser stop"); //$NON-NLS-1$
181
}
182     
183     
184     /* (non-Javadoc)
185      * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
186      */

187     public void comment(char[] ch, int start, int length) throws SAXException JavaDoc {
188         //No interesting behavior
189
}
190     
191     /* (non-Javadoc)
192      * @see org.xml.sax.ext.LexicalHandler#endCDATA()
193      */

194     public void endCDATA() throws SAXException JavaDoc {
195         //No interesting behavior
196
}
197     
198     /* (non-Javadoc)
199      * @see org.xml.sax.ext.LexicalHandler#endDTD()
200      */

201     public void endDTD() throws SAXException JavaDoc {
202         //No interesting behavior
203
}
204     
205     /* (non-Javadoc)
206      * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
207      */

208     public void endEntity(String JavaDoc name) throws SAXException JavaDoc {
209         //No interesting behavior
210
}
211     
212     /* (non-Javadoc)
213      * @see org.xml.sax.ext.LexicalHandler#startCDATA()
214      */

215     public void startCDATA() throws SAXException JavaDoc {
216         //No interesting behavior
217
}
218     
219     /* (non-Javadoc)
220      * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String, java.lang.String)
221      *
222      */

223     public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
224         throws SAXException JavaDoc {
225
226         /* We have hit an DTD request for this XML file.
227          * The name of the DTD wanted for this XML file will
228          * be stored as a persistent property.
229          *
230          * This method is not intended to be called. It is
231          * only called from within the XML SAX parser being
232          * used.
233          */

234         if (systemId == null)
235             return;
236         
237         QualifiedName qname = new QualifiedName(IDEWorkbenchPlugin.IDE_WORKBENCH, IResourceActionFilter.XML_DTD_NAME);
238         try {
239             parseResource.setPersistentProperty(qname, systemId);
240         } catch (CoreException c) {
241             IDEWorkbenchPlugin.log("Problem parsing dtd element", c.getStatus()); //$NON-NLS-1$
242
}
243     }
244     
245     /* (non-Javadoc)
246      * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
247      */

248     public void startEntity(String JavaDoc name) throws SAXException JavaDoc {
249         //No interesting behavior
250
}
251
252     /* (non-Javadoc)
253      * Resolve external entity definitions to an empty string. This is to speed
254      * up processing of files with external DTDs. Not resolving the contents of
255      * the DTD is ok, as only the System ID of the DTD declaration is used.
256      *
257      * @see org.xml.sax.helpers.DefaultHandler#resolveEntity(java.lang.String, java.lang.String)
258      */

259     public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
260             throws SAXException JavaDoc {
261         return new InputSource JavaDoc(new StringReader JavaDoc("")); //$NON-NLS-1$
262
}
263 }
264
Popular Tags