1 10 package org.mmbase.applications.xmlimporter; 11 12 import java.io.*; 13 import java.util.HashMap ; 14 15 import javax.xml.parsers.*; 16 17 import org.mmbase.module.*; 18 import org.mmbase.module.core.*; 19 import org.mmbase.util.logging.*; 20 import org.xml.sax.*; 21 import org.xml.sax.helpers.DefaultHandler ; 22 23 35 36 public class TransactionsParser extends DefaultHandler { 37 38 39 private final static String ELEMENT_TRANSACTIONS = "transactions"; 40 private final static String ATTRIBUTE_EXCEPTION_PAGE = "exceptionPage"; 41 private final static String ATTRIBUTE_REPORT_FILE = "reportFile"; 42 private final static String ATTRIBUTE_KEY = "key"; 43 private final static String ELEMENT_CREATE = "create"; 44 private final static String ATTRIBUTE_ID = "id"; 45 private final static String ATTRIBUTE_COMMIT_ON_CLOSE = "commit"; 46 private final static String ATTRIBUTE_TIME_OUT = "timeOut"; 47 private final static String ELEMENT_OPEN = "open"; 48 private final static String ELEMENT_COMMIT = "commit"; 49 private final static String ELEMENT_DELETE = "delete"; 50 private final static String ELEMENT_CREATE_OBJECT = "createObject"; 51 private final static String ATTRIBUTE_TYPE = "type"; 52 private final static String ATTRIBUTE_DISPOSE = "disposeWhenNotReferenced"; 53 private final static String ELEMENT_OPEN_OBJECT = "openObject"; 54 private final static String ELEMENT_DELETE_OBJECT = "deleteObject"; 55 private final static String ELEMENT_ACCESS_OBJECT = "accessObject"; 56 private final static String ATTRIBUTE_MMBASE_ID = "mmbaseId"; 57 private final static String ELEMENT_MARK_OBJECT_DELETE = "markObjectDelete"; 58 private final static String ATTRIBUTE_NAME = "name"; 59 private final static String ELEMENT_CREATE_RELATION = "createRelation"; 60 private final static String ATTRIBUTE_SOURCE = "source"; 61 private final static String ATTRIBUTE_DESTINATION = "destination"; 62 private final static String ATTRIBUTE_DELETE_RELATIONS = "deleteRelations"; 63 private final static String ELEMENT_MERGE_OBJECTS = "mergeObjects"; 64 private final static String ELEMENT_OBJECT_MERGER = "objectMerger"; 65 private final static String ELEMENT_OBJECT_MATCHER = "objectMatcher"; 66 private final static String ATTRIBUTE_CLASS = "class"; 67 private final static String ELEMENT_PARAM = "param"; 68 private final static String ATTRIBUTE_VALUE = "value"; 69 private final static String ELEMENT_SET_FIELD = "setField"; 70 private final static String ATTRIBUTE_URL = "url"; 71 72 75 public final static String ENCODING = "ISO-8859-1"; 76 77 80 public final String xmlHeader = 81 "<?xml version='1.0' encoding='" 82 + ENCODING 83 + "'?>\n" 84 + "<!DOCTYPE transactions " 85 + "PUBLIC '-//MMBase/DTD transactions config 1.0//EN' " 86 + "'http://www.mmbase.org/dtd/transactions_1_0.dtd'>\n"; 87 88 89 private static Logger log = Logging.getLoggerInstance(TransactionsParser.class.getName()); 90 91 92 private static MMBase mmbase = null; 93 94 95 private static TransactionHandler transactionHandler = null; 96 97 98 100 101 private TransactionManagerInterface transactionManager; 102 103 104 private TemporaryNodeManagerInterface tmpObjectManager; 105 106 107 private String dtdDirectory; 108 109 110 private String reportDirectory; 111 112 113 private UserTransactionInfo uti; 114 115 116 private Consultant consultant; 117 118 119 private String exceptionPage; 120 121 122 private File reportFile; 123 124 125 private Transaction transaction; 126 127 128 private TmpObject tmpObject; 129 130 131 private String fieldName; 132 133 134 private StringBuffer fieldValue; 135 136 137 private String url; 138 139 140 private String type; 141 142 143 private ObjectMerger objectMerger; 144 145 146 private SimilarObjectFinder objectFinder; 147 148 149 private String className; 150 151 153 private HashMap params; 154 155 161 public TransactionsParser(UserTransactionInfo uti, Consultant consultant) { 162 this(uti); 163 this.consultant = consultant; 164 } 165 166 171 public TransactionsParser(UserTransactionInfo uti) { 172 this.uti = uti; 173 mmbase = (MMBase)Module.getModule("MMBASEROOT"); 174 transactionHandler = (TransactionHandler)TransactionHandler.getModule("transactionhandler"); 175 dtdDirectory = MMBaseContext.getConfigPath() + File.separator + "dtd" + File.separator; 177 reportDirectory = MMBaseContext.getConfigPath() + File.separator + "import" + File.separator + "report" + File.separator; 178 tmpObjectManager = new TemporaryNodeManager(mmbase); 179 transactionManager = new TransactionManager(mmbase, tmpObjectManager); 180 } 181 182 193 public void startElement(String nameSpaceURI, String localName, String name, Attributes attributes) throws SAXException { 194 195 StringBuffer sb = new StringBuffer ("<" + name); 197 for (int i = 0; i < attributes.getLength(); i++) { 198 sb.append(" " + attributes.getQName(i) + "=\"" + attributes.getValue(i) + "\""); 199 } 200 sb.append(">"); 201 String parsedLine = sb.toString(); 202 203 if (log.isDebugEnabled()) { 205 log.debug(parsedLine); 206 } 207 208 try { 209 if (name.equals(ELEMENT_TRANSACTIONS)) { String attrExceptionPage = attributes.getValue(ATTRIBUTE_EXCEPTION_PAGE); 212 String attrReportFile = attributes.getValue(ATTRIBUTE_REPORT_FILE); 213 String attrKey = attributes.getValue(ATTRIBUTE_KEY); 214 215 transactionHandler.checkKey(attrKey); 217 if (attrExceptionPage != null) { 219 exceptionPage = attrExceptionPage; 220 } 221 222 try { 224 if (attrReportFile != null) { 225 reportFile = new File(reportDirectory, attrReportFile); 226 227 if (reportFile.exists()) { 229 reportFile.delete(); 230 } else { 231 reportFile.getParentFile().mkdirs(); 233 } 234 235 appendReportFile(xmlHeader + parsedLine + "\n"); 236 } 237 238 } catch (Exception e) { 239 throw new SAXException("Failed to create reportFile " + reportFile + ": " + e); 240 } 241 242 } else if (name.equals(ELEMENT_CREATE)) { String id = attributes.getValue(ATTRIBUTE_ID); boolean commit = Boolean.valueOf( attributes.getValue(ATTRIBUTE_COMMIT_ON_CLOSE)).booleanValue(); 247 long timeOut = Long.parseLong( attributes.getValue(ATTRIBUTE_TIME_OUT)); 249 250 transaction = Transaction.createTransaction(uti, id, commit, timeOut, reportFile, consultant); 252 } else if (name.equals(ELEMENT_OPEN)) { String id = attributes.getValue(ATTRIBUTE_ID); boolean commit = Boolean.valueOf( attributes.getValue(ATTRIBUTE_COMMIT_ON_CLOSE)).booleanValue(); 257 258 transaction = Transaction.openTransaction(uti, id, commit); 260 261 } else if (name.equals(ELEMENT_COMMIT)) { String id = attributes.getValue(ATTRIBUTE_ID); 265 transaction = Transaction.openTransaction(uti, id, false); 267 transaction.commit(); 268 269 } else if (name.equals(ELEMENT_DELETE)) { String id = attributes.getValue(ATTRIBUTE_ID); 272 273 transaction = Transaction.openTransaction(uti, id, false); 275 transaction.delete(); 276 277 } else if (name.equals(ELEMENT_CREATE_OBJECT)) { String id = attributes.getValue(ATTRIBUTE_ID); 280 String type = attributes.getValue(ATTRIBUTE_TYPE); 281 boolean dispose = Boolean.valueOf(attributes.getValue(ATTRIBUTE_DISPOSE)).booleanValue(); 283 284 tmpObject = transaction.createObject(id, type, dispose); 286 287 } else if (name.equals(ELEMENT_CREATE_RELATION)) { String id = attributes.getValue(ATTRIBUTE_ID); 290 String type = attributes.getValue(ATTRIBUTE_TYPE); 291 String source = attributes.getValue(ATTRIBUTE_SOURCE); 292 String destination = attributes.getValue(ATTRIBUTE_DESTINATION); 293 294 tmpObject = transaction.createRelation(id, type, source, destination); 296 297 } else if (name.equals(ELEMENT_OPEN_OBJECT)) { String id = attributes.getValue(ATTRIBUTE_ID); 301 tmpObject = transaction.openObject(id); 303 304 } else if (name.equals(ELEMENT_ACCESS_OBJECT)) { String id = attributes.getValue(ATTRIBUTE_ID); try { 308 int mmbaseId = Integer.parseInt(attributes.getValue(ATTRIBUTE_MMBASE_ID)); 310 tmpObject = transaction.accessObject(id, mmbaseId); 312 } catch (NumberFormatException e) { 313 throw new SAXException("invalid attribute mmbasid=\"" + attributes.getValue(ATTRIBUTE_MMBASE_ID) + "\""); 314 } 315 316 } else if (name.equals(ELEMENT_DELETE_OBJECT)) { String id = attributes.getValue(ATTRIBUTE_ID); 320 tmpObject = transaction.openObject(id); 322 transaction.deleteObject(tmpObject); 323 324 } else if (name.equals(ELEMENT_MARK_OBJECT_DELETE)) { try { 327 int mmbaseId = Integer.parseInt(attributes.getValue(ATTRIBUTE_MMBASE_ID)); boolean deleteRelations = Boolean.valueOf( attributes.getValue(ATTRIBUTE_DELETE_RELATIONS)).booleanValue(); 330 331 tmpObject = transaction.accessObject(null, mmbaseId); 333 transaction.markDeleteObject(tmpObject, deleteRelations); 334 } catch (NumberFormatException e) { 335 throw new SAXException("invalid attribute mmbasid=\"" + attributes.getValue(ATTRIBUTE_MMBASE_ID) + "\""); 336 } 337 338 } else if (name.equals(ELEMENT_MERGE_OBJECTS)) { type = attributes.getValue(ATTRIBUTE_TYPE); 341 342 } else if (name.equals(ELEMENT_OBJECT_MATCHER)) { className = attributes.getValue(ATTRIBUTE_CLASS); 345 346 params = new HashMap (); 348 349 } else if (name.equals(ELEMENT_OBJECT_MERGER)) { className = attributes.getValue(ATTRIBUTE_CLASS); 352 353 params = new HashMap (); 355 356 } else if (name.equals(ELEMENT_PARAM)) { String paramName = attributes.getValue(ATTRIBUTE_NAME); 359 String value = attributes.getValue(ATTRIBUTE_VALUE); 360 361 params.put(paramName, value); 363 364 } else if (name.equals(ELEMENT_SET_FIELD)) { 365 fieldName = attributes.getValue(ATTRIBUTE_NAME); url = attributes.getValue(ATTRIBUTE_URL); 369 376 377 } else { 378 throw new TransactionHandlerException("transaction operator \"" + name + "\" doesn't exist"); 379 } 380 381 } catch (TransactionHandlerException e) { 382 throw new SAXException(e); 383 } finally { 384 if (transaction != null) { 386 transaction.appendReportBuffer("\n" + parsedLine); 387 } 388 } 389 } 390 391 401 public void endElement(String nameSpaceURI, String localName, String name) throws org.xml.sax.SAXException { 402 403 if (log.isDebugEnabled()) { 405 log.debug("</" + name + ">"); 406 } 407 408 if (transaction != null) { 410 transaction.appendReportBuffer("</" + name + ">\n"); 411 } 412 413 try { 414 if (name.equals(ELEMENT_TRANSACTIONS)) { try { 417 appendReportFile("</" + ELEMENT_TRANSACTIONS + ">"); 418 } catch (Exception e) { 419 throw new SAXException("Failed to write to reportFile " + reportFile + ": " + e); 420 } 421 422 exceptionPage = null; 423 reportFile = null; 424 425 } else if (name.equals(ELEMENT_CREATE)) { transaction.leave(); 427 transaction = null; 428 429 } else if (name.equals(ELEMENT_OPEN)) { transaction.leave(); 431 transaction = null; 432 433 } else if (name.equals(ELEMENT_COMMIT)) { transaction = null; 435 436 } else if (name.equals(ELEMENT_DELETE)) { transaction = null; 438 439 } else if (name.equals(ELEMENT_CREATE_OBJECT)) { tmpObject = null; 441 442 } else if (name.equals(ELEMENT_CREATE_RELATION)) { tmpObject = null; 444 445 } else if (name.equals(ELEMENT_OPEN_OBJECT)) { tmpObject = null; 447 448 } else if (name.equals(ELEMENT_ACCESS_OBJECT)) { tmpObject = null; 450 451 } else if (name.equals(ELEMENT_DELETE_OBJECT)) { tmpObject = null; 453 454 } else if (name.equals(ELEMENT_MARK_OBJECT_DELETE)) { tmpObject = null; 456 457 } else if (name.equals(ELEMENT_MERGE_OBJECTS)) { transaction.mergeObjects(type, objectFinder, objectMerger); 459 460 type = null; 461 objectFinder = null; 462 objectMerger = null; 463 464 } else if (name.equals(ELEMENT_OBJECT_MATCHER)) { try { 467 objectFinder = (SimilarObjectFinder)Class.forName(className).newInstance(); 468 objectFinder.init(params); 469 } catch (Exception e) { 470 throw new SAXException(e); 471 } 472 473 params = null; 474 className = null; 475 476 } else if (name.equals(ELEMENT_OBJECT_MERGER)) { try { 479 objectMerger = (ObjectMerger)Class.forName(className).newInstance(); 480 objectMerger.init(params); 481 } catch (Exception e) { 482 throw new SAXException(e); 483 } 484 485 params = null; 486 className = null; 487 488 } else if (name.equals(ELEMENT_SET_FIELD)) { 489 if (fieldValue != null) { 490 tmpObject.setField(fieldName, fieldValue.toString()); 491 } 492 fieldName = null; 493 fieldValue = null; 494 if (url != null) { 495 url = null; 497 } 498 } 499 500 } catch (TransactionHandlerException e) { 501 throw new SAXException(e); 502 } 503 504 } 505 506 516 public void characters(char[] ch, int start, int length) throws org.xml.sax.SAXException { 517 518 String characters = new String (ch, start, length); 520 if (log.isDebugEnabled()) { 521 log.debug("\"" + characters + "\""); 522 } 523 524 if (transaction != null) { 526 transaction.appendReportBuffer(characters); 527 } 528 529 if (fieldName != null) { 531 if (url != null) { 533 throw new SAXException("Can not set field value from both url and element value."); 534 } 535 if (fieldValue == null) { 536 fieldValue = new StringBuffer (); 537 } 538 fieldValue.append(characters); 539 } 540 } 541 542 550 public void error(SAXParseException e) throws SAXException { 551 throw e; 552 } 553 554 561 public void warning(SAXParseException e) throws SAXException { 562 throw e; 563 } 564 565 571 public synchronized void parse(java.io.Reader input) throws IOException, TransactionHandlerException { 572 573 InputSource in = null; 574 SAXParser saxParser = null; 575 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); 576 try { 577 saxParser = saxParserFactory.newSAXParser(); 578 } catch (ParserConfigurationException ex) { 579 log.warn(Logging.stackTrace(ex)); 580 } catch (SAXException ex2) { 581 log.warn(Logging.stackTrace(ex2)); 582 } 583 584 in = new InputSource(input); 586 in.setSystemId(dtdDirectory); 588 log.service("Sax parser system id set to \"" + dtdDirectory + "\""); 589 590 try { 592 593 saxParserFactory.setValidating(true); 594 595 XMLReader reader = saxParser.getXMLReader(); 596 reader.setContentHandler(this); 597 598 reader.setDTDHandler(this); 599 reader.setEntityResolver(this); 600 reader.setErrorHandler(this); 601 reader.parse(in); 602 } catch (SAXException e2) { 603 if (transaction != null) { 605 if (log.isDebugEnabled()) { 606 log.debug("About to roll back transaction " + transaction.getKey() + " because an error occurred."); 607 } 608 try { 609 transaction.delete(); 610 } catch (Exception e4) { 611 log.debug("Failed to roll back transaction " + transaction.getKey() + " after an error occurred."); 612 } 613 } 614 615 Exception e3 = e2.getException(); 617 if (e3 != null && e3 instanceof TransactionHandlerException) { 618 throw (TransactionHandlerException)e3; 620 } else { 621 throw new TransactionHandlerException("Parse failed: \n" + e2); 623 } 624 } 625 } 626 627 631 String getExceptionPage() { 632 return exceptionPage; 633 } 634 635 641 private void appendReportFile(String text) throws IOException { 642 Writer out = null; 643 if (reportFile != null) { 644 try { 645 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(reportFile.getPath(), true), ENCODING)); 646 out.write(text); 647 } finally { 648 if (out != null) { 649 out.close(); 650 } 651 } 652 } 653 } 654 } 655 | Popular Tags |