/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-2010 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
*
* $Id$
*/
package org.exist.examples.triggers;
import java.io.StringReader;
import java.net.URISyntaxException;
import java.util.Map;
import org.apache.log4j.Logger;
import org.exist.collections.Collection;
import org.exist.collections.IndexInfo;
import org.exist.collections.triggers.DocumentTrigger;
import org.exist.collections.triggers.FilteringTrigger;
import org.exist.collections.triggers.TriggerException;
import org.exist.dom.DefaultDocumentSet;
import org.exist.dom.DocumentImpl;
import org.exist.security.xacml.AccessContext;
import org.exist.storage.DBBroker;
import org.exist.storage.txn.Txn;
import org.exist.xmldb.XmldbURI;
import org.exist.xupdate.Modification;
import org.exist.xupdate.XUpdateProcessor;
import org.xml.sax.InputSource;
/**
* This trigger maintains a file "contents.xml", containing a list of all
* documents added to a collection.
* It uses XUpdate to update "contents.xml" whenever a document is added or
* removed.
* Usage
* Put the collection.xconf document in the selected collection under
* /db/system/config/db/, eg /db/system/config/db/test and make sure the
* examples.jar is built and available. Put some files into the collection
* /db/test and see that the contents.xml document gets updated with the
* files you add or remove.
* Read the triggers documentation if in need of more information.
*
* @author wolf
*/
public class ExampleTrigger extends FilteringTrigger implements DocumentTrigger {
protected Logger LOG = Logger.getLogger(getClass());
private DocumentImpl doc;
/* (non-Javadoc)
* @see org.exist.collections.Trigger#configure(org.exist.storage.DBBroker, org.exist.collections.Collection, java.util.Map)
*/
@Override
public void configure(DBBroker broker, Collection parent, Map parameters)
throws TriggerException {
super.configure(broker, parent, parameters);
// the name of the contents file can be set through parameters
XmldbURI contentsFile = null;
String contentsName = (String)parameters.get("contents");
if(contentsName == null) {
contentsFile = XmldbURI.create("contents.xml");
} else {
try{
contentsFile = XmldbURI.xmldbUriFor(contentsName);
} catch(URISyntaxException e) {
throw new TriggerException(e);
}
}
// try to retrieve the contents file
try {
this.doc = parent.getDocument(broker, contentsFile);
if(this.doc == null)
// doesn't exist yet: create it
LOG.debug("creating new file for collection contents");
// IMPORTANT: temporarily disable triggers on the collection.
// We would end up in infinite recursion if we don't do that
parent.setTriggersEnabled(false);
IndexInfo info = parent.validateXMLResource(null, broker, contentsFile, "<?xml version=\"1.0\"?><contents></contents>");
//TODO : unlock the collection here ?
parent.store(null, broker, info, "<?xml version=\"1.0\"?><contents></contents>", false);
this.doc = info.getDocument();
} catch (Exception e) {
throw new TriggerException(e.getMessage(), e);
} finally {
parent.setTriggersEnabled(true);
}
}
private void addRecord(DBBroker broker, String xupdate) throws TriggerException {
LOG.debug(xupdate);
// create a document set containing "contents.xml"
DefaultDocumentSet docs = new DefaultDocumentSet();
docs.add(doc);
try {
// IMPORTANT: temporarily disable triggers on the collection.
// We would end up in infinite recursion if we don't do that
getCollection().setTriggersEnabled(false);
// create the XUpdate processor
XUpdateProcessor processor = new XUpdateProcessor(broker, docs, AccessContext.TRIGGER);
// process the XUpdate
Modification modifications[] = processor.parse(new InputSource(new StringReader(xupdate)));
for(int i = 0; i < modifications.length; i++)
modifications[i].process(null);
broker.flush();
} catch (Exception e) {
e.printStackTrace();
throw new TriggerException(e.getMessage(), e);
} finally {
// IMPORTANT: re-enable trigger processing for the collection.
getCollection().setTriggersEnabled(true);
}
}
@Override
public void beforeCreateDocument(DBBroker broker, Txn transaction, XmldbURI uri) throws TriggerException {
String xupdate = "<?xml version=\"1.0\"?>" +
"<xu:modifications version=\"1.0\" xmlns:xu=\"" + XUpdateProcessor.XUPDATE_NS + "\">" +
"<xu:append select='/contents'><xu:element name='file'>" +
uri.toString() +
"</xu:element></xu:append></xu:modifications>";
addRecord(broker, xupdate);
}
@Override
public void afterCreateDocument(DBBroker broker, Txn transaction, DocumentImpl document) throws TriggerException {
}
@Override
public void beforeUpdateDocument(DBBroker broker, Txn transaction, DocumentImpl document) throws TriggerException {
// TODO Auto-generated method stub
}
@Override
public void afterUpdateDocument(DBBroker broker, Txn transaction, DocumentImpl document) throws TriggerException {
}
@Override
public void beforeMoveDocument(DBBroker broker, Txn transaction, DocumentImpl document, XmldbURI newUri) throws TriggerException {
}
@Override
public void afterMoveDocument(DBBroker broker, Txn transaction, DocumentImpl document, XmldbURI newUri) throws TriggerException {
}
@Override
public void beforeCopyDocument(DBBroker broker, Txn transaction, DocumentImpl document, XmldbURI newUri) throws TriggerException {
}
@Override
public void afterCopyDocument(DBBroker broker, Txn transaction, DocumentImpl document, XmldbURI newUri) throws TriggerException {
}
@Override
public void beforeDeleteDocument(DBBroker broker, Txn transaction, DocumentImpl document) throws TriggerException {
String xupdate = "<?xml version=\"1.0\"?>" +
"<xu:modifications version=\"1.0\" xmlns:xu=\""+ XUpdateProcessor.XUPDATE_NS + "\">" +
"<xu:remove select=\"//file[text()='" + document.getURI().toString() + "']\"></xu:remove>" +
"</xu:modifications>";
addRecord(broker, xupdate);
}
@Override
public void afterDeleteDocument(DBBroker broker, Txn transaction, XmldbURI uri) throws TriggerException {
}
@Override
public void beforeUpdateDocumentMetadata(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException {
}
@Override
public void afterUpdateDocumentMetadata(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException {
}
}