package eu.dnetlib.xml.database.exist;

import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.exist.collections.Collection;
import org.exist.collections.CollectionConfigurationException;
import org.exist.storage.DBBroker;
import org.exist.xmldb.XmldbURI;
import org.w3c.dom.Document;

import eu.dnetlib.xml.database.Trigger;

/**
 * this trigger delegates diffs for CRUDE events to an non-exist dependent eu.dnetlib.xml.database.Trigger instance.
 * 
 * Since eXist triggers are instantiated by eXist, we need to locate the Trigger instances which are registered to the
 * database instance.
 * 
 * @author marko
 * 
 */
public class DelegatingDiffTrigger extends AbstractDiffTrigger {
	/**
	 * logger.
	 */
	private static final Log log = LogFactory.getLog(DelegatingDiffTrigger.class); // NOPMD by marko on 11/24/08 5:02 PM

	/**
	 * trigger identifier, from configuration.
	 */
	private String triggerName;

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.exist.collections.triggers.FilteringTrigger#configure(org.exist.storage.DBBroker,
	 *      org.exist.collections.Collection, java.util.Map)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void configure(final DBBroker broker, final Collection parent, final Map parameters) throws CollectionConfigurationException {
		super.configure(broker, parent, parameters);

		if (parameters == null)
			return;

		final Map<String, String> params = parameters;
		setTriggerName(params.get("triggerName"));
		if (getTriggerName() == null) {
			log.fatal("trigger id not configured");
			throw new CollectionConfigurationException("trigger name not configured");
		}
	}

	/**
	 * find the trigger instance associated with this delegation.
	 * 
	 * @return trigger instance
	 */
	protected Trigger getTrigger() {
		final Trigger trigger = ExistTriggerRegistry.defaultInstance().getTrigger(getTriggerName());
		if (trigger == null) {
			log.fatal("no trigger " + triggerName + " but there is a registered callback for it");
			return null;
		}

		return trigger;
	}

	/** 
	 * {@inheritDoc}
	 * @see eu.dnetlib.xml.database.exist.AbstractDiffTrigger#triggerUpdate(org.exist.xmldb.XmldbURI, org.w3c.dom.Document, org.w3c.dom.Document)
	 */
	@Override
	protected void triggerUpdate(final XmldbURI uri, final Document oldDoc, final Document newDoc) {
		final Trigger trigger = getTrigger();
		if (trigger != null)
			trigger.updated(uri.lastSegment().toString(), uri.removeLastSegment().toString(), oldDoc, newDoc);
	}

	/** 
	 * {@inheritDoc}
	 * @see eu.dnetlib.xml.database.exist.AbstractDiffTrigger#triggerCreate(org.exist.xmldb.XmldbURI, org.w3c.dom.Document)
	 */
	@Override
	protected void triggerCreate(final XmldbURI uri, final Document newDoc) {
		final Trigger trigger = getTrigger();
		if (trigger != null)
			trigger.created(uri.lastSegment().toString(), uri.removeLastSegment().toString(), newDoc);
	}

	/** 
	 * {@inheritDoc}
	 * @see eu.dnetlib.xml.database.exist.AbstractDiffTrigger#triggerDelete(org.exist.xmldb.XmldbURI, org.w3c.dom.Document)
	 */
	@Override
	protected void triggerDelete(final XmldbURI uri, final Document oldDoc) {
		final Trigger trigger = getTrigger();
		if (trigger != null)
			trigger.deleted(uri.lastSegment().toString(), uri.removeLastSegment().toString(), oldDoc);
	}

	public String getTriggerName() {
		return triggerName;
	}

	public void setTriggerName(final String triggerId) {
		this.triggerName = triggerId;
	}
}
