/* * eXist Open Source Native XML Database * Copyright (C) 2001-2014 The eXist Project * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package org.exist.collections.triggers; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.exist.Indexer; import org.exist.collections.Collection; import org.exist.collections.CollectionConfiguration; import org.exist.dom.persistent.DocumentImpl; import org.exist.storage.DBBroker; import org.exist.storage.txn.Txn; import org.exist.xmldb.XmldbURI; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.ErrorHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.ext.LexicalHandler; /** * @author <a href="mailto:shabanovd@gmail.com">Dmitriy Shabanov</a> * */ public class DocumentTriggers implements DocumentTrigger, ContentHandler, LexicalHandler, ErrorHandler { private Indexer indexer; private ContentHandler contentHandler; private LexicalHandler lexicalHandler; private ErrorHandler errorHandler; private SAXTrigger last = null; private final List<DocumentTrigger> triggers; public DocumentTriggers(DBBroker broker) throws TriggerException { this(broker, null, null, null); } public DocumentTriggers(DBBroker broker, Collection collection) throws TriggerException { this(broker, null, collection, collection.isTriggersEnabled() ? collection.getConfiguration(broker) : null); } public DocumentTriggers(DBBroker broker, Indexer indexer, Collection collection, CollectionConfiguration config) throws TriggerException { List<TriggerProxy<? extends DocumentTrigger>> docTriggers = null; if (config != null) { docTriggers = config.documentTriggers(); } java.util.Collection<TriggerProxy<? extends DocumentTrigger>> masterTriggers = broker.getDatabase().getDocumentTriggers(); triggers = new ArrayList<DocumentTrigger>( masterTriggers.size() + (docTriggers == null ? 0 : docTriggers.size()) ); for (TriggerProxy<? extends DocumentTrigger> docTrigger : masterTriggers) { DocumentTrigger instance = docTrigger.newInstance(broker, collection); register(instance); } if (docTriggers != null) { for (TriggerProxy<? extends DocumentTrigger> docTrigger : docTriggers) { DocumentTrigger instance = docTrigger.newInstance(broker, collection); register(instance); } } if (indexer != null) { finishPreparation(indexer); } last = null; } private void finishPreparation(Indexer indexer) { if (last == null) { contentHandler = indexer; lexicalHandler = indexer; errorHandler = indexer; } else { last.next( indexer ); } this.indexer = indexer; } private void register(DocumentTrigger trigger) { if (trigger instanceof SAXTrigger) { SAXTrigger filteringTrigger = (SAXTrigger) trigger; if (last == null) { contentHandler = filteringTrigger; lexicalHandler = filteringTrigger; errorHandler = filteringTrigger; } else { last.next( filteringTrigger ); } last = filteringTrigger; } triggers.add(trigger); } @Override public void configure(DBBroker broker, Collection parent, Map<String, List<? extends Object>> parameters) throws TriggerException { } @Override public void setDocumentLocator(Locator locator) { contentHandler.setDocumentLocator(locator); } @Override public void startDocument() throws SAXException { contentHandler.startDocument(); } @Override public void endDocument() throws SAXException { contentHandler.endDocument(); } @Override public void startPrefixMapping(String prefix, String uri) throws SAXException { contentHandler.startPrefixMapping(prefix, uri); } @Override public void endPrefixMapping(String prefix) throws SAXException { contentHandler.endPrefixMapping(prefix); } @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { contentHandler.startElement(uri, localName, qName, atts); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { contentHandler.endElement(uri, localName, qName); } @Override public void characters(char[] ch, int start, int length) throws SAXException { contentHandler.characters(ch, start, length); } @Override public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { contentHandler.ignorableWhitespace(ch, start, length); } @Override public void processingInstruction(String target, String data) throws SAXException { contentHandler.processingInstruction(target, data); } @Override public void skippedEntity(String name) throws SAXException { contentHandler.skippedEntity(name); } @Override public void startDTD(String name, String publicId, String systemId) throws SAXException { lexicalHandler.startDTD(name, publicId, systemId); } @Override public void endDTD() throws SAXException { lexicalHandler.endDTD(); } @Override public void startEntity(String name) throws SAXException { lexicalHandler.startEntity(name); } @Override public void endEntity(String name) throws SAXException { lexicalHandler.endEntity(name); } @Override public void startCDATA() throws SAXException { lexicalHandler.startCDATA(); } @Override public void endCDATA() throws SAXException { lexicalHandler.endCDATA(); } @Override public void comment(char[] ch, int start, int length) throws SAXException { lexicalHandler.comment(ch, start, length); } @Override public void beforeCreateDocument(DBBroker broker, Txn txn, XmldbURI uri) throws TriggerException { for (DocumentTrigger trigger : triggers) { trigger.beforeCreateDocument(broker, txn, uri); } } @Override public void afterCreateDocument(DBBroker broker, Txn txn, DocumentImpl document) { for (DocumentTrigger trigger : triggers) { try { trigger.afterCreateDocument(broker, txn, document); } catch (Exception e) { Trigger.LOG.error(e.getMessage(), e); } } } @Override public void beforeUpdateDocument(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException { for (DocumentTrigger trigger : triggers) { trigger.beforeUpdateDocument(broker, txn, document); } } @Override public void afterUpdateDocument(DBBroker broker, Txn txn, DocumentImpl document) { for (DocumentTrigger trigger : triggers) { try { trigger.afterUpdateDocument(broker, txn, document); } catch (Exception e) { Trigger.LOG.error(e.getMessage(), e); } } } @Override public void beforeUpdateDocumentMetadata(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException { for (DocumentTrigger trigger : triggers) { trigger.beforeUpdateDocumentMetadata(broker, txn, document); } } @Override public void afterUpdateDocumentMetadata(DBBroker broker, Txn txn, DocumentImpl document) { for (DocumentTrigger trigger : triggers) { try { trigger.afterUpdateDocumentMetadata(broker, txn, document); } catch (Exception e) { Trigger.LOG.error(e.getMessage(), e); } } } @Override public void beforeCopyDocument(DBBroker broker, Txn txn, DocumentImpl document, XmldbURI newUri) throws TriggerException { for (DocumentTrigger trigger : triggers) { trigger.beforeCopyDocument(broker, txn, document, newUri); } } @Override public void afterCopyDocument(DBBroker broker, Txn txn, DocumentImpl document, XmldbURI oldUri) { for (DocumentTrigger trigger : triggers) { try { trigger.afterCopyDocument(broker, txn, document, oldUri); } catch (Exception e) { Trigger.LOG.error(e.getMessage(), e); } } } @Override public void beforeMoveDocument(DBBroker broker, Txn txn, DocumentImpl document, XmldbURI newUri) throws TriggerException { for (DocumentTrigger trigger : triggers) { trigger.beforeMoveDocument(broker, txn, document, newUri); } } @Override public void afterMoveDocument(DBBroker broker, Txn txn, DocumentImpl document, XmldbURI oldUri) { for (DocumentTrigger trigger : triggers) { try { trigger.afterMoveDocument(broker, txn, document, oldUri); } catch (Exception e) { Trigger.LOG.error(e.getMessage(), e); } } } @Override public void beforeDeleteDocument(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException { for (DocumentTrigger trigger : triggers) { trigger.beforeDeleteDocument(broker, txn, document); } } @Override public void afterDeleteDocument(DBBroker broker, Txn txn, XmldbURI uri) { for (DocumentTrigger trigger : triggers) { try { trigger.afterDeleteDocument(broker, txn, uri); } catch (Exception e) { Trigger.LOG.error(e.getMessage(), e); } } } @Override public boolean isValidating() { return false; } @Override public void setValidating(boolean validating) { for (DocumentTrigger trigger : triggers) { trigger.setValidating(validating); } indexer.setValidating(validating); } @Override public void warning(SAXParseException exception) throws SAXException { if (errorHandler != null) errorHandler.warning(exception); } @Override public void error(SAXParseException exception) throws SAXException { if (errorHandler != null) errorHandler.error(exception); } @Override public void fatalError(SAXParseException exception) throws SAXException { if (errorHandler != null) errorHandler.fatalError(exception); } }