KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > xquery > metadata > MetaParser


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.xquery.metadata;
24
25 import java.io.IOException JavaDoc;
26 import java.util.ArrayList JavaDoc;
27
28 import javax.xml.parsers.ParserConfigurationException JavaDoc;
29 import javax.xml.parsers.SAXParser JavaDoc;
30 import javax.xml.parsers.SAXParserFactory JavaDoc;
31
32 import org.xml.sax.*;
33 import org.xml.sax.helpers.AttributesImpl JavaDoc;
34 import org.xml.sax.helpers.DefaultHandler JavaDoc;
35 import org.xquark.schema.Schema;
36 import org.xquark.schema.loader.Loader;
37 import org.xquark.schema.validation.SchemaValidationContext;
38 import org.xquark.schema.validation.ValidatingSchemaFilter;
39
40
41 // ***************************************************************************
42
// * Class 'MetaParser'
43
// ***************************************************************************
44
/**
45  * Class to use to parse metadata represented as an XML file conforming to
46  * schema /org/xquark/xml/xdbc/resources/XMLDBCMetaData.xsd
47  *
48  */

49 public class MetaParser
50 extends DefaultHandler JavaDoc {
51     
52     // **********************************************************************
53
// * Constant
54
// **********************************************************************
55
private static final String JavaDoc RCSRevision = "$Revision: 1.3 $";
56     private static final String JavaDoc RCSName = "$Name: $";
57     // labels and attributes name of tag that we parse.
58
private final static String JavaDoc TAG_SOURCE = "metadata";
59     private final static String JavaDoc TAG_SCHEMAS = "schemas";
60     private final static String JavaDoc TAG_SCHEMA = "schema";
61     private final static String JavaDoc TAG_SCHEMADEFINITION = "schemadefinition";
62     private final static String JavaDoc TAG_COLLECTIONS = "collections";
63     private final static String JavaDoc TAG_COLLECTION = "collection";
64     private final static String JavaDoc TAG_STEP = "step";
65     private final static String JavaDoc ATT_SOURCE_NAME = "source";
66     private final static String JavaDoc ATT_COLLECTION_NAME = "name";
67     private final static String JavaDoc ATT_STEP_NS = "ns";
68     private final static String JavaDoc ATT_STEP_NAME = "name";
69     private final static String JavaDoc ATT_STEP_TYPE = "type";
70     private final static String JavaDoc ATT_STEP_TYPE_ATT = "attribute";
71     private final static String JavaDoc ATT_STEP_TYPE_ELEMENT = "element";
72     
73     // **********************************************************************
74
// * Fields
75
// **********************************************************************
76
// a reference of the metadata where we will insert metawrapper
77
// and new schema we are going to discover.
78
private MetaDataImpl metadata = null;
79     
80     // the current metacollection we arre parsing.
81
private MetaCollection metacollection = null;
82     
83     // the current metawrapper we are parsing.
84
private MetaWrapper metawrapper = null;
85     
86     // the source name of the wrapper.
87
private String JavaDoc sourcename = null;
88     
89     // use during the parsing to see if we are in the context that we are
90
// inside the parsing of a schema
91
private boolean inSchema = false;
92     
93     // facilities when parsing schemas contained in the XMLDocument.
94
// As prefix mapping are callbacked, *before* the callback
95
// 'startElement' "schema", we should keep it for when we will see
96
// the startElement 'schema'. In the preix mapping, we consider
97
// prefixes and uri's. So we need 2 arraylist of strings to
98
// keep them.
99
private ArrayList JavaDoc tmppref = null;
100     private ArrayList JavaDoc tmpuri = null;
101     
102     // probably temporary as well as schema doesn't correcty serialize.
103
// keep the string representation of the schemas that we will parse.
104
// private String strschema = null ;
105
private StringBuffer JavaDoc bufSchema = new StringBuffer JavaDoc();
106     
107     // for generic and static use of SAX parser.
108
private static SAXParserFactory JavaDoc spf = null;
109     static {
110         // Create a JAXP SAXParserFactory and configure it
111
spf = SAXParserFactory.newInstance() ;
112         spf.setNamespaceAware(true);
113         spf.setValidating(false);
114     }
115     
116     private XMLReader reader = null;
117     private Loader loader = null;
118     private static SchemaValidationContext svContext = null;
119     
120     
121     // **********************************************************************
122
// * Constructor
123
// **********************************************************************
124
/**
125      * Construct the metaparser of a wrapper XML description.
126      * As a wrapper has to be inserted into a metadata, keep a reference
127      * on metadata.
128      */

129     public MetaParser(MetaDataImpl metadata) {
130         this.metadata = metadata;
131         svContext = new SchemaValidationContext(metadata.getLoadingManager()) ;
132         tmppref = new ArrayList JavaDoc() ;
133         tmpuri = new ArrayList JavaDoc() ;
134     }
135     
136     
137     // **********************************************************************
138
// * Methods
139
// **********************************************************************
140
public void error(SAXParseException spe) {
141         System.err.println("Caught SAXParseException : " + spe.getMessage());
142     }
143     
144     private void createReader() throws SAXException, ParserConfigurationException JavaDoc {
145         // Create a JAXP SAXParser
146
SAXParser JavaDoc saxParser = spf.newSAXParser();
147         
148         // Get the encapsulated SAX XMLReader
149
reader = saxParser.getXMLReader();
150     }
151     
152     
153     // **********************************************************************
154
// Create a MetaWrapper
155
// **********************************************************************
156
/**
157      * Create a wrapper from the SAX callbacks.
158      */

159     public MetaWrapper createWrapper(String JavaDoc uri, boolean validate) throws MetadataException {
160         try {
161             metawrapper = new MetaWrapper(metadata);
162             createReader() ;
163             
164             ValidatingSchemaFilter filter = new ValidatingSchemaFilter(reader, svContext);
165             filter.setContentHandler(this);
166             filter.setErrorHandler(this);
167             
168             filter.parse(uri);
169             
170             return metawrapper;
171         }
172         catch (org.xml.sax.SAXParseException JavaDoc e) {}
173         catch (SAXException e) {}
174         catch (IOException JavaDoc e) {}
175         catch (ParserConfigurationException JavaDoc e) {}
176         throw new MetadataException();
177     }
178     
179     
180     /**
181      * Create a wrapper from the SAX callbacks.
182      */

183     public MetaWrapper createWrapper(InputSource inputSource, boolean validate) throws MetadataException {
184         try {
185             metawrapper = new MetaWrapper(metadata);
186             createReader() ;
187             
188             ValidatingSchemaFilter filter = new ValidatingSchemaFilter(reader, svContext);
189             filter.setContentHandler(this);
190             filter.setErrorHandler(this);
191             filter.parse(inputSource);
192             return metawrapper;
193         }
194         catch (org.xml.sax.SAXParseException JavaDoc e) {}
195         catch (SAXException e) {}
196         catch (IOException JavaDoc e) {}
197         catch (ParserConfigurationException JavaDoc e) {}
198         throw new MetadataException();
199     }
200     
201     
202     public MetaWrapper createWrapper(boolean validate) throws MetadataException {
203         try {
204             metawrapper = new MetaWrapper(metadata);
205             createReader() ;
206             
207             ValidatingSchemaFilter filter = new ValidatingSchemaFilter(reader, svContext);
208             filter.setContentHandler(this);
209             filter.setErrorHandler(this);
210             
211             return metawrapper;
212         }
213         catch (org.xml.sax.SAXParseException JavaDoc e) {}
214         catch (SAXException e) {}
215         catch (ParserConfigurationException JavaDoc e) {}
216         throw new MetadataException();
217     }
218     
219     // **********************************************************************
220
/**
221      * Receive notification of the beginning of a document.
222      *
223      * <p>The SAX reader will invoke this method only once, before any
224      * other methods in this interface or in DTDHandler (except for
225      * setDocumentLocator).</p>
226      *
227      * @exception SAXException Any SAX exception, possibly
228      * wrapping another exception.
229      */

230     public void startDocument()
231     throws SAXException {
232     }
233     
234     
235     public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri) throws SAXException {
236         if (loader != null && inSchema) {
237             loader.startPrefixMapping(prefix, uri);
238         }
239         else {
240             tmppref.add(prefix) ;
241             tmpuri.add(uri) ;
242         }
243     }
244     
245     
246     public void endPrefixMapping(String JavaDoc prefix)
247     throws SAXException {
248         if (loader != null && inSchema) {
249             loader.endPrefixMapping(prefix);
250         }
251     }
252     
253     
254     /**
255      * Receive notification of the beginning of an element.
256      */

257     public void startElement(String JavaDoc uri, String JavaDoc local, String JavaDoc raw, Attributes attrs)
258     throws SAXException {
259         
260         if (local.equalsIgnoreCase(TAG_SCHEMA)) {
261             bufSchema.setLength(0);
262             inSchema = true;
263             loader = new Loader(metadata.getSchemaManager());
264             loader.startDocument();
265             
266             
267             // <serialisation of the strschema to keep in the cache>
268
bufSchema.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>");
269             bufSchema.append("<");
270             if (uri != null) {
271                 int indexPref = tmpuri.indexOf(uri);
272                 if (indexPref >= 0) {
273                     String JavaDoc pref = (String JavaDoc)tmppref.get(indexPref);
274                     if (pref != null && pref.length() > 0) {
275                         bufSchema.append(pref);
276                         bufSchema.append(":");
277                     }
278                 }
279             }
280             bufSchema.append(local);
281             for (int i = 0 ; i < tmppref.size() ; i ++) {
282                 
283                 bufSchema.append(" xmlns");
284                 if (tmppref.get(i) != null && ((String JavaDoc)tmppref.get(i)).length() != 0) bufSchema.append(":");
285                 bufSchema.append(tmppref.get(i));
286                 bufSchema.append("=\"");
287                 bufSchema.append(tmpuri.get(i));
288                 bufSchema.append("\"");
289                 
290                 loader.startPrefixMapping((String JavaDoc) tmppref.get(i), (String JavaDoc) tmpuri.get(i));
291             }
292             for (int i = 0 ; i < attrs.getLength() ; i ++) {
293                 bufSchema.append(" ");
294                 bufSchema.append(attrs.getLocalName(i));
295                 bufSchema.append("=\"");
296                 bufSchema.append(attrs.getValue(i));
297                 bufSchema.append("\"");
298             }
299             bufSchema.append(">" );
300             // </serialisation of the strschema to keep in the cache>
301

302             loader.startElement(uri, local, (raw == null) ? "" : raw, (attrs == null) ? new AttributesImpl JavaDoc() : attrs);
303             
304             return;
305         }
306         
307         if (inSchema) {
308             bufSchema.append("<");
309             if (uri != null) {
310                 int indexPref = tmpuri.indexOf(uri);
311                 if (indexPref >= 0) {
312                     String JavaDoc pref = (String JavaDoc)tmppref.get(indexPref);
313                     if (pref != null && pref.length() > 0) {
314                         bufSchema.append(pref);
315                         bufSchema.append(":");
316                     }
317                 }
318             }
319             bufSchema.append(local);
320             for (int i = 0 ; i < attrs.getLength() ; i ++) {
321                 bufSchema.append(" ");
322                 bufSchema.append(attrs.getLocalName(i));
323                 bufSchema.append("=\"");
324                 bufSchema.append(attrs.getValue(i));
325                 bufSchema.append("\"");
326             }
327             bufSchema.append(">");
328             
329             loader.startElement(uri, local, (raw == null) ? "" : raw, (attrs ==
330             null) ? new AttributesImpl JavaDoc() : attrs);
331             return;
332         }
333         
334         if (local.equalsIgnoreCase(TAG_SOURCE)) {
335             sourcename = attrs.getValue("", ATT_SOURCE_NAME);
336             metawrapper.setSourceName(sourcename);
337         }
338         else {
339             if (local.equalsIgnoreCase(TAG_SCHEMAS)) {
340                 // do nothing
341
}
342             else {
343                 if (local.equalsIgnoreCase(TAG_COLLECTIONS)) {
344                     metawrapper.initMetaCollections();
345                 }
346                 else {
347                     if (local.equalsIgnoreCase(TAG_COLLECTION)) {
348                         metacollection = new MetaCollection(metadata, attrs.getValue("", ATT_COLLECTION_NAME));
349                     }
350                     else {
351                         if (local.equalsIgnoreCase(TAG_STEP)) {
352                             boolean isattribute = isAttribute(attrs.getValue("", ATT_STEP_TYPE));
353                             metacollection.addMetaElement(attrs.getValue("", ATT_STEP_NS), attrs.getValue("", ATT_STEP_NAME), isattribute);
354                         }
355                     }
356                 }
357             }
358         }
359     }
360     
361     
362     private boolean isAttribute(String JavaDoc name) {
363         if (name == null) {
364             return false;
365         }
366         if (name.equalsIgnoreCase(ATT_STEP_TYPE_ATT)) {
367             return true;
368         }
369         return false;
370     }
371     
372     
373     /**
374      * Receive notification of the end of an element.
375      *
376      * <p>The SAX reader will invoke this method at the end of every
377      * element in the XML document; there will be a corresponding
378      * startElement () event for every endElement () event (even when the
379      * element is empty).</p>
380      *
381      * <p>For information on the names, see startElement.</p>
382      *
383      * @param uri The Namespace URI, or the empty string if the
384      * element has no Namespace URI or if Namespace
385      * processing is not being performed.
386      * @param localName The local name (without prefix), or the
387      * empty string if Namespace processing is not being
388      * performed.
389      * @param rawName The raw XML 1.0 name (with prefix), or the
390      * empty string if raw names are not available.
391      * @exception SAXException Any SAX exception, possibly
392      * wrapping another exception.
393      */

394     public void endElement(String JavaDoc uri, String JavaDoc local, String JavaDoc raw) throws SAXException {
395         if (local.equalsIgnoreCase(TAG_SCHEMA)) {
396             bufSchema.append("</");
397             if (uri != null) {
398                 int indexPref = tmpuri.indexOf(uri);
399                 if (indexPref >= 0) {
400                     String JavaDoc pref = (String JavaDoc)tmppref.get(indexPref);
401                     if (pref != null && pref.length() > 0) {
402                         bufSchema.append(pref);
403                         bufSchema.append(":");
404                     }
405                 }
406             }
407             bufSchema.append(local);
408             bufSchema.append(">");
409             loader.endElement(uri, local, raw);
410             inSchema = false;
411             
412             tmppref.clear();
413             tmpuri.clear();
414             
415             if (loader != null) {
416                 loader.endDocument();
417                 Schema schema = loader.getSchema();
418                 if (metawrapper != null)
419                     metadata.putSchema(schema, bufSchema.toString());
420             }
421             return;
422         }
423         
424         if (inSchema) {
425             loader.endElement(uri, local, raw);
426             bufSchema.append("</");
427             if (uri != null) {
428                 int indexPref = tmpuri.indexOf(uri);
429                 if (indexPref >= 0) {
430                     String JavaDoc pref = (String JavaDoc)tmppref.get(indexPref);
431                     if (pref != null && pref.length() > 0) {
432                         bufSchema.append(pref);
433                         bufSchema.append(":");
434                     }
435                 }
436             }
437             bufSchema.append(local);
438             bufSchema.append(">");
439             return;
440         }
441         
442         if (local.equalsIgnoreCase(TAG_SOURCE)) {
443             // nothing to be done
444
}
445         else {
446             if (local.equalsIgnoreCase(TAG_SCHEMAS)) {
447                 // nothing to be done
448
}
449             else {
450                 if (local.equalsIgnoreCase(TAG_SCHEMADEFINITION)) {
451                     // attention, ici, transformer jusqu'\u00e0 la prochaine balise
452
// en XMLReader. (Utiliser le callback character pour cela suivant
453
// un etat boolean pour cela ?)
454
}
455                 else {
456                     if (local.equalsIgnoreCase(TAG_COLLECTIONS)) {
457                         // nothing to be done
458
}
459                     else {
460                         if (local.equalsIgnoreCase(TAG_COLLECTION)) {
461                             metawrapper.addMetaCollection(metacollection);
462                         }
463                         else {
464                             if (local.equalsIgnoreCase(TAG_STEP)) {
465                                 metacollection.addEndElement();
466                             }
467                         }
468                     }
469                 }
470             }
471         }
472     }
473     
474     
475     /**
476      * Receive notification of character data.
477      *
478      * <p>The Parser will call this method to report each chunk of
479      * character data. SAX readers may return all contiguous character
480      * data in a single chunk, or they may split it into several
481      * chunks; however, all of the characters in any single event
482      * must come from the same external entity so that the Locator
483      * provides useful information.</p>
484      *
485      * <p>The application must not attempt to read from the array
486      * outside of the specified range.</p>
487      *
488      * <p>Note that some readers will report whitespace using the
489      * ignorableWhitespace () method rather than this one (validating
490      * readers <em>must</em> do so).</p>
491      *
492      * @param ch The characters from the XML document.
493      * @param start The start position in the array.
494      * @param length The number of characters to read from the array.
495      * @exception SAXException Any SAX exception, possibly
496      * wrapping another exception.
497      * @see #ignorableWhitespace
498      * @see org.xml.sax.Locator
499      */

500     public void characters(char ch[], int start, int length)
501     throws SAXException {
502     }
503     
504     
505     /**
506      * Receive notification of the end of a document.
507      *
508      * <p>The SAX reader will invoke this method only once, and it will
509      * be the last method invoked during the parse. The reader shall
510      * not invoke this method until it has either abandoned parsing
511      * (because of an unrecoverable error) or reached the end of
512      * input.</p>
513      *
514      * @exception SAXException Any SAX exception, possibly
515      * wrapping another exception.
516      */

517     public void endDocument()
518     throws SAXException {
519     }
520 }
521
Popular Tags