eXistDB简单Tirgger示例03

  • XCONF文件中指定XQuery文件路径
  • XCONF文件中包含XQuery文件
  • XCONF文件中指定Java类

第三种方式,是用XCONF文件通知eXistDB要对哪个collection中的哪些操作做触发,然后触发器指向一个JAVA类。

1、首先,编写触发器的java类,打成jar包,放到%existdb_home%\lib\user路径下
TriggerTest.java

package com.neohope.existdb.test;


import org.exist.collections.Collection;
import org.exist.collections.IndexInfo;
import org.exist.collections.triggers.DocumentTrigger;
import org.exist.collections.triggers.SAXTrigger;
import org.exist.collections.triggers.TriggerException;
import org.exist.dom.DocumentImpl;
import org.exist.dom.NodeSet;
import org.exist.security.PermissionDeniedException;
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.xquery.CompiledXQuery;
import org.exist.xquery.XPathException;
import org.exist.xquery.XQueryContext;

import java.util.ArrayList;
import java.util.Map;

public class TriggerTest extends SAXTrigger implements DocumentTrigger {

    private String logCollection = "xmldb:exist:///db/Triggers";
    private String logFileName = "logj.xml";
    private String logUri;

    @Override
    public void configure(DBBroker broker, Collection parent, Map parameters)
            throws TriggerException {
        super.configure(broker, parent, parameters);

        ArrayList<String> objList =  (ArrayList<String>)parameters.get("LogFileName");
        if(objList!=null && objList.size()>0)
        {
            logFileName= objList.get(0);
        }

        logUri = logCollection+"/"+logFileName;
    }

    @Override
    public void beforeCreateDocument(DBBroker broker, Txn transaction, XmldbURI uri) throws TriggerException {
        LogEvent(broker,uri.toString(),"beforeCreateDocument");
    }

    @Override
    public void afterCreateDocument(DBBroker broker, Txn transaction, DocumentImpl document) throws TriggerException {
       LogEvent(broker, document.getDocumentURI(),"afterCreateDocument");
    }

    @Override
    public void beforeUpdateDocument(DBBroker broker, Txn transaction, DocumentImpl document) throws TriggerException {
       LogEvent(broker,document.getDocumentURI(), "beforeUpdateDocument");
    }

    @Override
    public void afterUpdateDocument(DBBroker broker, Txn transaction, DocumentImpl document) throws TriggerException {
       LogEvent(broker, document.getDocumentURI(),"afterUpdateDocument");
    }

    @Override
    public void beforeMoveDocument(DBBroker broker, Txn transaction, DocumentImpl document, XmldbURI newUri) throws TriggerException {
       LogEvent(broker, document.getDocumentURI(),"beforeMoveDocument");
    }

    @Override
    public void afterMoveDocument(DBBroker broker, Txn transaction, DocumentImpl document, XmldbURI newUri) throws TriggerException {
       LogEvent(broker, document.getDocumentURI(),"afterMoveDocument");
    }

    @Override
    public void beforeCopyDocument(DBBroker broker, Txn transaction, DocumentImpl document, XmldbURI newUri) throws TriggerException {
       LogEvent(broker, document.getDocumentURI(),"beforeCopyDocument");
    }

    @Override
    public void afterCopyDocument(DBBroker broker, Txn transaction, DocumentImpl document, XmldbURI newUri) throws TriggerException {
       LogEvent(broker, document.getDocumentURI(),"afterCopyDocument");
    }

    @Override
    public void beforeDeleteDocument(DBBroker broker, Txn transaction, DocumentImpl document) throws TriggerException {
       LogEvent(broker, document.getDocumentURI(),"beforeDeleteDocument");
    }

    @Override
    public void afterDeleteDocument(DBBroker broker, Txn transaction, XmldbURI uri) throws TriggerException {
       LogEvent(broker, uri.toString(),"afterDeleteDocument");
    }

    @Override
    public void beforeUpdateDocumentMetadata(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException {
       LogEvent(broker, document.getDocumentURI(),"beforeUpdateDocumentMetadata");
    }

    @Override
    public void afterUpdateDocumentMetadata(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException {
       LogEvent(broker, document.getDocumentURI(),"afterUpdateDocumentMetadata");
    }

    private void LogEvent(DBBroker broker,String uriFile, String logContent) throws TriggerException {
        String  xQuery = "update insert <trigger event=\""+logContent+"\" uri=\""+uriFile+"\" timestamp=\"{current-dateTime()}\"/> into doc(\""+logUri+"\")/TriggerLogs";

        try {
            XQueryContext  context  = broker.getXQueryService().newContext(AccessContext.TRIGGER);
            CreateLogFile(broker,context);
            CompiledXQuery compiled = broker.getXQueryService().compile(context,xQuery);
            broker.getXQueryService().execute(compiled, NodeSet.EMPTY_SET);
        } catch (XPathException e) {
            e.printStackTrace();
        } catch (PermissionDeniedException e) {
            e.printStackTrace();
        }
    }

    private void CreateLogFile(DBBroker broker,XQueryContext  context)
    {
        String  xQuery = "if (not(doc-available(\""+logUri+"\"))) then xmldb:store(\""+logCollection+"\", \""+logFileName+"\", <TriggerLogs/>) else ()";

        try {
            CompiledXQuery compiled = broker.getXQueryService().compile(context,xQuery);
            broker.getXQueryService().execute(compiled, NodeSet.EMPTY_SET);
        } catch (XPathException e) {
            e.printStackTrace();
        } catch (PermissionDeniedException e) {
            e.printStackTrace();
        }
    }
}

2、然后,在你需要触发的collection的对应配置collection中,增加一个xconf文件,文件名任意,官方推荐collection.xconf。配置collection与原collection的对应关系为,在/db/system/config/db下,建立/db下相同的collection。
比如,如果你希望监控/db/cda03路径,就需要在/db/system/config/db/cda03路径下,新增一个collection.xconf。
collection.xconf

<collection xmlns="http://exist-db.org/collection-config/1.0">
    <triggers>
        <trigger class="com.neohope.existdb.test.TriggerTest">
            <parameter name="LogFileName" value="log03.xml"/>
        </trigger>
    </triggers>
</collection>

3、保存时,eXide会询问你是否应用配置,点击应用。

4、这样,在/db/cda03路径下所有变更,都会通知到触发器了。触发器会将事件记录到/db/Triggers/log03.xml中。

Comments are closed.