KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > mapper > storage > SchemaSavingFilter


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.mapper.storage;
24
25 import java.io.*;
26 import java.net.MalformedURLException JavaDoc;
27 import java.net.URL JavaDoc;
28
29 import javax.xml.parsers.SAXParserFactory JavaDoc;
30
31 import org.w3c.dom.Document JavaDoc;
32 import org.xml.sax.*;
33 import org.xquark.mapper.RepositoryException;
34 import org.xquark.schema.SchemaConstants;
35 import org.xquark.util.HandlerDecorator;
36 import org.xquark.util.SAXConstants;
37 import org.xquark.xml.xdbc.*;
38
39 /**
40  * An XMLFilter implementation used to perform schema storage in a system repository
41  * processing storage of included schemas files.
42  */

43 public class SchemaSavingFilter extends HandlerDecorator
44 implements SchemaConstants, SAXConstants, XMLDocumentFiler
45 {
46     private static final String JavaDoc RCSRevision = "$Revision: 1.1 $";
47     private static final String JavaDoc RCSName = "$Name: $";
48     
49     private XMLReader schemaReader = null;
50     private boolean topMost;
51     private boolean firstElement = true;
52     private SchemaSavingFilter inlineFilter = null;
53     private XMLReader inlineReader = null;
54     private URL JavaDoc baseURL = null;
55     private SAXParserFactory JavaDoc parserFactory;
56     private XMLDocumentFiler handler;
57     
58     public SchemaSavingFilter(XMLDocumentFiler handler)
59     {
60         this(SAXParserFactory.newInstance(), handler, true, null);
61     }
62     
63     private SchemaSavingFilter(SAXParserFactory JavaDoc parserFactory, XMLDocumentFiler handler, boolean topMost, URL JavaDoc baseURL)
64     {
65         super(handler, handler);
66         this.handler = handler;
67         this.parserFactory = parserFactory;
68         parserFactory.setNamespaceAware(true);
69         this.topMost = topMost;
70         this.baseURL = baseURL;
71     }
72
73     public void startPrefixMapping(String JavaDoc str, String JavaDoc str1) throws SAXException
74     {
75        // for the moment discard the prefix mapping related to the discarded root element
76
if (topMost || !firstElement)
77             super.startPrefixMapping(str, str1);
78     }
79     
80     public void endPrefixMapping(String JavaDoc str) throws SAXException
81     {
82        // for the moment discard the prefix mapping related to the discarded root element
83
if (topMost || !firstElement)
84             super.endPrefixMapping(str);
85     }
86     
87     public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName, Attributes atts)
88     throws SAXException
89     {
90         // include processing
91
if (namespaceURI.equals(XMLSCHEMA_URI) && localName.equals(INCLUDE_TAG))
92         {
93             String JavaDoc schemaLocation = atts.getValue("", SCHEMA_LOCATION_ATTR);
94             if (schemaLocation == null)
95                 throw new SAXException("Incorrect include element in schema : no schemaLocation attribute found.");
96             processInlineParsing(schemaLocation);
97         }
98         else // not the XML schema include element
99
if (topMost)
100             { // remove schema root element for included schemas
101
if (firstElement)
102                 {
103                     if (!(namespaceURI.equals(XMLSCHEMA_URI) && localName.equals(SCHEMA_TAG)))
104                         throw new SAXException("This document is not a valid XML Schema.");
105                     firstElement = false;
106                 }
107                 super.startElement(namespaceURI, localName, qName, atts);
108             }
109             else if (!(namespaceURI.equals(XMLSCHEMA_URI) && localName.equals(SCHEMA_TAG)))
110             { // remove schema root element for included schemas
111
super.startElement(namespaceURI, localName, qName, atts);
112             }
113     }
114     
115     public void endElement (String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName)
116     throws SAXException
117     {
118         if (!(namespaceURI.equals(XMLSCHEMA_URI) && localName.endsWith(INCLUDE_TAG)) // BUG XERCES 1.1.x
119
&& (topMost || !(namespaceURI.equals(XMLSCHEMA_URI) && localName.endsWith(SCHEMA_TAG))))
120             super.endElement(namespaceURI, localName, qName);
121     }
122
123     public void startDocument() throws SAXException
124     {
125         if (topMost)
126             super.startDocument();
127     }
128     
129     public void endDocument() throws SAXException
130     {
131         if (topMost)
132         {
133             super.endDocument();
134             reset();
135         }
136     }
137
138     private void reset()
139     {
140         firstElement = true;
141     }
142     private void processInlineParsing(String JavaDoc schemaLocation) throws SAXException
143     {
144         InputSource source = null;
145         URL JavaDoc fileURL =null;
146         
147         try { // try to resolve include using the schemaLocation as an absolute or relative URL
148
fileURL = new URL JavaDoc(baseURL, schemaLocation);
149             fileURL.openConnection().connect();
150         }
151         catch(Exception JavaDoc e) {
152             try { // try to resolve include using the schemaLocation as a file name
153
File file = new File(schemaLocation);
154                 fileURL = file.toURL();
155                 fileURL.openConnection().connect();
156             }
157             catch (Exception JavaDoc ex) {
158                 if (baseURL == null)
159                     throw new SAXException("The following schema location couln't be resolved : " + schemaLocation +
160                                             ". If you are using relative URLs, please use the SAX interface and provide a system ID that will be used as a context.");
161                 else
162                     throw new SAXException("The following schema location couln't be resolved : " + schemaLocation);
163             }
164         }
165         /* create the SAX inputSource */
166         try {
167             source = new InputSource(new BufferedReader(new InputStreamReader(fileURL.openStream())));
168         }
169         catch (IOException e) {
170             throw new SAXException("The following schema include couln't be opened even if it was located : " + schemaLocation);
171         }
172         
173         if (inlineReader == null)
174         {
175             try {
176                 inlineReader = parserFactory.newSAXParser().getXMLReader();
177             }
178             catch(Exception JavaDoc e) {
179                 throw new SAXException("Couldn't instantiate a new parser for included schema files.", e);
180             }
181             try {
182                 configureXMLReader(inlineReader);
183             }
184             catch(Exception JavaDoc e) {
185                 // no op
186
}
187         }
188         if (inlineFilter == null)
189         {
190             inlineFilter = new SchemaSavingFilter(parserFactory, handler, false, baseURL);
191         }
192         inlineReader.setContentHandler(inlineFilter);
193         try {
194             inlineReader.setProperty(SAX_LEXICAL_PROPERTY, inlineFilter);
195             inlineReader.parse(source);
196         }
197         catch(IOException e) {
198             throw new SAXException("IO error while parsing included schema files.", e);
199         }
200     }
201     
202     public void setDocumentLocator(Locator locator)
203     {
204         String JavaDoc url = locator.getSystemId();
205         try {
206             if (url != null)
207                 baseURL = new URL JavaDoc(baseURL, url);
208         }
209         catch (MalformedURLException JavaDoc e) {
210             // no op : keep the base URL null
211
}
212         super.setDocumentLocator(locator);
213     }
214     
215     ///////////////////////////////////////////////////////////////////////////
216
// XMLDocumentFiler implementation
217
///////////////////////////////////////////////////////////////////////////
218

219     public XMLDocument insertDocument(XMLReader parser, InputSource input)
220     throws XMLDBCException, SAXException
221     {
222         return handler.insertDocument(parser, input);
223     }
224     
225     public XMLDocument insertDocument(InputSource input)
226     throws XMLDBCException, SAXException
227     {
228         return handler.insertDocument(input);
229     }
230     
231     public XMLDocument insertDocument(InputSource input, String JavaDoc id)
232     throws XMLDBCException, SAXException
233     {
234         return handler.insertDocument(input, id);
235     }
236     
237     public XMLDocument insertDocument(XMLReader parser, InputSource input, String JavaDoc id)
238     throws XMLDBCException, SAXException
239     {
240         return handler.insertDocument(parser, input, id);
241     }
242     
243     public XMLDocument insertDocument(String JavaDoc doc)
244     throws XMLDBCException, SAXException
245     {
246         return handler.insertDocument(doc);
247     }
248     
249     public XMLDocument insertDocument(String JavaDoc doc, String JavaDoc id) throws XMLDBCException, org.xml.sax.SAXException JavaDoc
250     {
251         return handler.insertDocument(doc, id);
252     }
253     
254     public XMLDocument insertDocument(Document JavaDoc doc, String JavaDoc id) throws XMLDBCException
255     {
256         return handler.insertDocument(doc, id);
257     }
258     
259     public XMLDocument insertDocument(Document JavaDoc doc) throws XMLDBCException
260     {
261         return handler.insertDocument(doc);
262     }
263     
264     public void setDocumentId(String JavaDoc id) throws XMLDBCException
265     {
266         handler.setDocumentId(id);
267     }
268     
269     public XMLCollection getCollection()
270     {
271         return handler.getCollection();
272     }
273     
274     public void flushBuffer() throws XMLDBCException
275     {
276         handler.flushBuffer();
277     }
278     
279     public String JavaDoc getDocumentId()
280     {
281         return handler.getDocumentId();
282     }
283     
284     public void setErrorHandler(XMLErrorHandler handler)
285     {
286         this.handler.setErrorHandler(handler);
287     }
288     
289     public XMLErrorHandler getErrorHandler()
290     {
291         return handler.getErrorHandler();
292     }
293     
294     public void clearBuffer() throws XMLDBCException
295     {
296         handler.clearBuffer();
297     }
298     
299     public void close() throws XMLDBCException
300     {
301         handler.close();
302     }
303     
304     public boolean getAutoFlush()
305     {
306         return handler.getAutoFlush();
307     }
308     
309     public void setAutoFlush(boolean mode) throws XMLDBCException
310     {
311         handler.setAutoFlush(mode);
312     }
313     
314     public String JavaDoc[] getFeatureList()
315     {
316         return handler.getFeatureList();
317     }
318     
319     public String JavaDoc[] getPropertyList()
320     {
321         return handler.getPropertyList();
322     }
323     
324     public boolean getFeature(String JavaDoc featureId) throws XMLDBCNotRecognizedException
325     {
326         return handler.getFeature(featureId);
327     }
328     
329     public void setFeature(String JavaDoc featureId, boolean state) throws XMLDBCNotRecognizedException, XMLDBCNotSupportedException
330     {
331         handler.setFeature(featureId, state);
332     }
333     
334     public Object JavaDoc getProperty(String JavaDoc propertyId) throws XMLDBCNotRecognizedException
335     {
336         return handler.getProperty(propertyId);
337     }
338     
339     public void setProperty(String JavaDoc propertyId, Object JavaDoc value) throws XMLDBCNotRecognizedException, XMLDBCNotSupportedException
340     {
341         handler.setProperty(propertyId, value);
342     }
343     ///////////////////////////////////////////////////////////////////////////
344
// PRIVATE UTILITIES
345
///////////////////////////////////////////////////////////////////////////
346
private XMLReader configureXMLReader(XMLReader reader) throws RepositoryException
347     {
348         try
349         {
350             reader.setFeature(SAX_NAMESPACE_FEATURE, true);
351             reader.setFeature(SAX_PREFIX_FEATURE, false);
352         }
353         catch(SAXException e)
354         {
355             throw new RepositoryException(RepositoryException.PARSER_ERROR, "The XML SAX Parser is not SAX 2.0 compliant");
356         }
357         return reader;
358     }
359     
360 }
361
Popular Tags