1 22 23 package org.xquark.mapper.storage; 24 25 import java.io.*; 26 import java.net.MalformedURLException ; 27 import java.net.URL ; 28 29 import javax.xml.parsers.SAXParserFactory ; 30 31 import org.w3c.dom.Document ; 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 43 public class SchemaSavingFilter extends HandlerDecorator 44 implements SchemaConstants, SAXConstants, XMLDocumentFiler 45 { 46 private static final String RCSRevision = "$Revision: 1.1 $"; 47 private static final String 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 baseURL = null; 55 private SAXParserFactory 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 parserFactory, XMLDocumentFiler handler, boolean topMost, URL 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 str, String str1) throws SAXException 74 { 75 if (topMost || !firstElement) 77 super.startPrefixMapping(str, str1); 78 } 79 80 public void endPrefixMapping(String str) throws SAXException 81 { 82 if (topMost || !firstElement) 84 super.endPrefixMapping(str); 85 } 86 87 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) 88 throws SAXException 89 { 90 if (namespaceURI.equals(XMLSCHEMA_URI) && localName.equals(INCLUDE_TAG)) 92 { 93 String 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 if (topMost) 100 { 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 { super.startElement(namespaceURI, localName, qName, atts); 112 } 113 } 114 115 public void endElement (String namespaceURI, String localName, String qName) 116 throws SAXException 117 { 118 if (!(namespaceURI.equals(XMLSCHEMA_URI) && localName.endsWith(INCLUDE_TAG)) && (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 schemaLocation) throws SAXException 143 { 144 InputSource source = null; 145 URL fileURL =null; 146 147 try { fileURL = new URL (baseURL, schemaLocation); 149 fileURL.openConnection().connect(); 150 } 151 catch(Exception e) { 152 try { File file = new File(schemaLocation); 154 fileURL = file.toURL(); 155 fileURL.openConnection().connect(); 156 } 157 catch (Exception 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 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 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 e) { 185 } 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 url = locator.getSystemId(); 205 try { 206 if (url != null) 207 baseURL = new URL (baseURL, url); 208 } 209 catch (MalformedURLException e) { 210 } 212 super.setDocumentLocator(locator); 213 } 214 215 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 id) 232 throws XMLDBCException, SAXException 233 { 234 return handler.insertDocument(input, id); 235 } 236 237 public XMLDocument insertDocument(XMLReader parser, InputSource input, String id) 238 throws XMLDBCException, SAXException 239 { 240 return handler.insertDocument(parser, input, id); 241 } 242 243 public XMLDocument insertDocument(String doc) 244 throws XMLDBCException, SAXException 245 { 246 return handler.insertDocument(doc); 247 } 248 249 public XMLDocument insertDocument(String doc, String id) throws XMLDBCException, org.xml.sax.SAXException 250 { 251 return handler.insertDocument(doc, id); 252 } 253 254 public XMLDocument insertDocument(Document doc, String id) throws XMLDBCException 255 { 256 return handler.insertDocument(doc, id); 257 } 258 259 public XMLDocument insertDocument(Document doc) throws XMLDBCException 260 { 261 return handler.insertDocument(doc); 262 } 263 264 public void setDocumentId(String 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 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 [] getFeatureList() 315 { 316 return handler.getFeatureList(); 317 } 318 319 public String [] getPropertyList() 320 { 321 return handler.getPropertyList(); 322 } 323 324 public boolean getFeature(String featureId) throws XMLDBCNotRecognizedException 325 { 326 return handler.getFeature(featureId); 327 } 328 329 public void setFeature(String featureId, boolean state) throws XMLDBCNotRecognizedException, XMLDBCNotSupportedException 330 { 331 handler.setFeature(featureId, state); 332 } 333 334 public Object getProperty(String propertyId) throws XMLDBCNotRecognizedException 335 { 336 return handler.getProperty(propertyId); 337 } 338 339 public void setProperty(String propertyId, Object value) throws XMLDBCNotRecognizedException, XMLDBCNotSupportedException 340 { 341 handler.setProperty(propertyId, value); 342 } 343 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 |