1 22 23 package org.xquark.mapper.storage; 24 25 import java.sql.SQLException ; 26 27 import org.xml.sax.*; 28 import org.xml.sax.ext.LexicalHandler ; 29 import org.xml.sax.helpers.DefaultHandler ; 30 import org.xquark.mapper.RepositoryException; 31 import org.xquark.mapper.dbms.AbstractConnection; 32 import org.xquark.mapper.metadata.PathNode; 33 import org.xquark.mapper.metadata.RepositoryConstants; 34 import org.xquark.mapper.metadata.StoragePathMetadata; 35 import org.xquark.mapper.util.RepositoryProperties; 36 import org.xquark.schema.SchemaConstants; 37 import org.xquark.util.SAXConstants; 38 import org.xquark.xml.xdbc.XMLDBCException; 39 import org.xquark.xml.xdbc.XMLErrorHandler; 40 import org.xquark.xpath.NodeKind; 41 42 50 public class SAXHandler extends DefaultHandler 51 implements RepositoryConstants, LexicalHandler 52 { 53 private static final String RCSRevision = "$Revision: 1.1 $"; 54 private static final String RCSName = "$Name: $"; 55 56 60 64 65 protected AbstractConnection connection; 66 protected boolean performCommit; 68 protected boolean removeWhitespace = false; 73 74 public static final short UNKNOWN = 0; 75 static final short START = 0; 76 static final short END =1; 77 protected short lastEvent = UNKNOWN; protected boolean textBetweenTransitions = false; protected PathIterator context; protected StringBuffer textData; 81 protected AbstractModelBuilder builder; 82 protected Locator locator; 83 private boolean nsFeatureNotTested = true; 85 86 88 public SAXHandler(PathIterator metadataContext, AbstractConnection connection, AbstractModelBuilder builder) 89 throws XMLDBCException 90 { 91 context = metadataContext; 92 this.connection = connection; 93 this.builder = builder; 94 textData = new StringBuffer (256); 95 } 96 97 103 public void setRemoveWhitespace(boolean value) 104 { 105 this.removeWhitespace = value; 106 } 107 108 public void reset() throws RepositoryException 109 { 110 context.reset(); 111 try { 112 builder.reset(); 113 } 114 catch (SQLException e) { 115 throw new RepositoryException(RepositoryException.DB_ERROR, 116 "JDBC error while resetting dbms resources", e); 117 } 118 lastEvent = UNKNOWN; 119 textData.setLength(0); 120 textBetweenTransitions = false; 121 nsFeatureNotTested = true; 122 } 123 124 private void clear() throws XMLDBCException 125 { 126 reset(); 127 builder.clearBuffer(); 128 } 129 130 public void close() throws XMLDBCException 131 { 132 if (context != null) 133 { 134 context = null; 135 try 136 { 137 builder.close(); 138 } 139 catch (SQLException e) 140 { 141 throw new RepositoryException(RepositoryException.DB_ERROR, "JDBC error while closing storage buffer.", e); 142 } 143 builder = null; 144 } 145 } 146 147 155 public void clean() 156 throws SQLException 157 { 158 } 160 161 public void warning(SAXParseException ex) throws SAXException 165 { 166 processFatalError(new SAXException("Warning at line " + ex.getLineNumber() 167 + " in " + ex.getSystemId() + ": " + ex.getMessage())); 168 } 169 170 public void error(SAXParseException ex) throws SAXException 171 { 172 processFatalError(new SAXException("Error at line " + ex.getLineNumber() 173 + " in " + ex.getSystemId() + ": " + ex.getMessage())); 174 } 175 176 public void fatalError(SAXParseException ex) throws SAXException 177 { 178 processFatalError(new SAXException("Fatal error at line " + ex.getLineNumber() 179 + " in " + ex.getSystemId() + ": " + ex.getMessage())); 180 } 181 182 public void startDTD(String name, String publicId, String systemId) throws SAXException 186 { 187 } 189 190 public void endDTD()throws SAXException 191 { 192 } 194 195 public void startEntity(String name) throws SAXException 196 { 197 } 199 200 public void endEntity(String name) throws SAXException 201 { 202 } 204 205 public void startCDATA() throws SAXException 206 { 207 } 209 210 public void endCDATA() throws SAXException 211 { 212 } 214 215 public void comment(char ch[], int start, int length) throws SAXException 216 { 217 } 219 220 public void startDocument() throws SAXException 224 { 225 try 227 { 228 performCommit = connection.getConnection().getAutoCommit(); 229 if (performCommit) 230 connection.start(); startParsing(); 232 } 233 catch(Exception e) 234 { 235 processFatalError(e); 236 } 237 238 } 239 240 public void endDocument() throws SAXException 241 { 242 245 try 246 { 247 builder.endModel(); 248 endParsing(); 249 if (performCommit) 250 { 251 flushBuffer(); 252 connection.commit(); 253 } 254 reset(); 256 } 257 catch(Exception e) 258 { 259 processFatalError(e); 260 } 261 } 262 263 public void startPrefixMapping(String prefix, String uri) 264 throws SAXException 265 { 266 } 268 269 public void startElement(String namespaceURI,String localName,String qName,Attributes atts) 270 throws SAXException 271 { 272 if (nsFeatureNotTested) 274 { 275 if (localName.length() == 0) 276 throw new SAXException("Your XML parser does not provide namespaces support. If you are using JAXP, make sure that setNamespaceAware(true) has been called on your parser factory."); 277 nsFeatureNotTested = false; 278 } 279 280 281 PathNode tmpPath; 283 284 try 285 { 286 if (textBetweenTransitions()) 287 { 288 builder.leafNode(NodeKind.TEXT, context.getStoragePathMetadata(), textData.toString(), locator); 290 textData.setLength(0); 291 textBetweenTransitions = false; 292 } 293 294 builder.newNode(context.push(namespaceURI, localName), locator); 297 if (context.getStoragePathMetadata() != null) { 299 processPrefixes(); 303 304 int nbAtt = atts.getLength(); 308 StoragePathMetadata attNode; 309 String uri; 311 for(int i = 0; i < nbAtt; i++) 313 { 314 uri = atts.getURI(i); 315 316 if (uri.equals(SAXConstants.XMLNS_URI)) 318 continue; 319 320 if (uri.equals(SchemaConstants.XSI_URI)) 322 builder.setXSIinfo(atts.getLocalName(i), atts.getValue(i)); else { 325 attNode = context.createNode(uri, atts.getLocalName(i), NodeKind.ATTRIBUTE); 327 328 if (attNode != null) builder.leafNode(NodeKind.ATTRIBUTE, attNode, atts.getValue(i), locator); 331 } 332 } 333 lastEvent = START; 334 } 335 } 336 catch(Exception e) 337 { 338 processFatalError(e); 339 } 340 } 341 342 345 protected StoragePathMetadata push(String namespaceURI, String localName) 346 throws SAXException, RepositoryException 347 { 348 return context.push(namespaceURI, localName); 349 } 350 351 352 protected void processPrefixes() 353 throws XMLDBCException, SQLException 354 { 355 } 357 358 public void endElement(String namespaceURI,String localName,String qName) throws SAXException 359 { 360 try 361 { 362 if (context.getStoragePathMetadata() != null) 363 { 364 if (textBetweenTransitions()) 365 { 366 switch (lastEvent) 367 { 368 case START: 369 builder.setData(textData.toString()); 370 break; 371 case END: 372 builder.leafNode(NodeKind.TEXT, context.getStoragePathMetadata(), 374 textData.toString(), locator); 375 break; 376 default: 377 } 378 379 textData.setLength(0); 380 textBetweenTransitions = false; 381 } 382 383 builder.finalizeNode(locator); 385 } 386 context.pop(); 387 lastEvent = END; 388 } 389 catch(Exception e) 390 { 391 processFatalError(e); 392 } 393 394 } 395 396 public void characters(char ch[], int start, int length) 397 throws SAXException 398 { 399 if (context.getStoragePathMetadata() != null) 400 { 401 403 textData.append(ch, start, length); 406 407 textBetweenTransitions=true; 409 builder.incCharOffset(length); 410 } 411 } 412 413 protected boolean textBetweenTransitions() 414 { 415 return textBetweenTransitions; 416 } 417 418 public void processingInstruction(String target, String data) throws SAXException 419 { 420 } 422 423 public void setDocumentLocator(Locator locator) 424 { 425 this.locator = locator; 427 } 428 429 442 protected void startParsing() throws RepositoryException, SQLException 443 { 444 setRemoveWhitespace(RepositoryProperties.getBooleanProperty(CONF_TRIM_WS)); 445 } 446 447 protected void endParsing() throws Exception 448 { 449 } 450 451 protected void processFatalError(Exception e) throws SAXException 452 { 453 try 454 { 455 connection.rollback(); 456 if (performCommit) 458 connection.getConnection().setAutoCommit(performCommit); 459 } 460 catch (SQLException ex) 461 { 462 } 464 finally 465 { 466 try 467 { 468 clear(); } 470 catch (XMLDBCException exc) 471 { 472 } 474 } 475 if (e instanceof SAXException) 476 throw (SAXException)e; 477 if (e instanceof RepositoryException) 478 throw new SAXException("Application error during document storage.", e); 479 else if (e instanceof SQLException ) 480 throw new SAXException("JDBC error during document storage.", e); 481 else throw new SAXException("Runtime error during document storage.", e); 483 } 484 485 486 490 public void setErrorHandler(XMLErrorHandler handler) 491 { 492 if (handler == null) 493 throw new NullPointerException ("An error handler must be provided if you use the setErrorHandler() method."); 494 builder.setErrorHandler(handler); 495 } 496 497 public void flushBuffer() throws XMLDBCException 498 { 499 builder.flushBuffer(); 500 } 501 502 public void clearBuffer() throws XMLDBCException 503 { 504 builder.clearBuffer(); 505 } 506 507 public void setAutoFlush(boolean mode) throws XMLDBCException 508 { 509 builder.setAutoFlush(mode); 510 } 511 512 public boolean getAutoFlush() 513 { 514 return builder.getAutoFlush(); 515 } 516 517 public XMLErrorHandler getXMLErrorHandler() 518 { 519 return builder.getXMLErrorHandler(); 520 } 521 } 522 523 524 | Popular Tags |