001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Nuxeo - initial API and implementation
011 *
012 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
013 */
014
015package org.nuxeo.ecm.platform.dublincore.listener;
016
017import static org.nuxeo.ecm.core.api.LifeCycleConstants.TRANSITION_EVENT;
018import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.BEFORE_DOC_UPDATE;
019import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_CREATED;
020import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_PUBLISHED;
021import static org.nuxeo.ecm.core.schema.FacetNames.SYSTEM_DOCUMENT;
022
023import java.io.Serializable;
024import java.util.Calendar;
025import java.util.Date;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.nuxeo.ecm.core.api.CoreSession;
030import org.nuxeo.ecm.core.api.DocumentModel;
031import org.nuxeo.ecm.core.api.DocumentRef;
032import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner;
033import org.nuxeo.ecm.core.api.event.CoreEventConstants;
034import org.nuxeo.ecm.core.event.Event;
035import org.nuxeo.ecm.core.event.EventListener;
036import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
037import org.nuxeo.ecm.platform.dublincore.NXDublinCore;
038import org.nuxeo.ecm.platform.dublincore.service.DublinCoreStorageService;
039
040/**
041 * Core Event Listener for updating DublinCore.
042 *
043 * @author <a href="mailto:td@nuxeo.com">Thierry Delprat</a>
044 * @author <a href="mailto:rspivak@nuxeo.com">Ruslan Spivak</a>
045 */
046public class DublinCoreListener implements EventListener {
047
048    private static final Log log = LogFactory.getLog(DublinCoreListener.class);
049
050    public static final String DISABLE_DUBLINCORE_LISTENER = "disableDublinCoreListener";
051
052    /**
053     * Core event notification.
054     * <p>
055     * Gets core events and updates DublinCore if needed.
056     *
057     * @param event event fired at core layer
058     */
059    @Override
060    public void handleEvent(Event event) {
061
062        DocumentEventContext docCtx;
063        if (event.getContext() instanceof DocumentEventContext) {
064            docCtx = (DocumentEventContext) event.getContext();
065        } else {
066            return;
067        }
068        String eventId = event.getName();
069
070        if (!eventId.equals(DOCUMENT_CREATED) && !eventId.equals(BEFORE_DOC_UPDATE)
071                && !eventId.equals(TRANSITION_EVENT) && !eventId.equals(DOCUMENT_PUBLISHED)) {
072            return;
073        }
074
075        DublinCoreStorageService service = NXDublinCore.getDublinCoreStorageService();
076        if (service == null) {
077            log.error("DublinCoreStorage service not found ... !");
078            return;
079        }
080
081        Boolean block = (Boolean) event.getContext().getProperty(DISABLE_DUBLINCORE_LISTENER);
082        if (Boolean.TRUE.equals(block)) {
083            // ignore the event - we are blocked by the caller
084            return;
085        }
086
087        DocumentModel doc = docCtx.getSourceDocument();
088
089        if (doc.isVersion()) {
090            log.debug("No DublinCore update on versions except for the issued date");
091            return;
092        }
093
094        if (doc.hasFacet(SYSTEM_DOCUMENT)) {
095            // ignore the event for System documents
096            return;
097        }
098
099        Date eventDate = new Date(event.getTime());
100        Calendar cEventDate = Calendar.getInstance();
101        cEventDate.setTime(eventDate);
102
103        if (doc.isProxy()) {
104            if (eventId.equals(DOCUMENT_PUBLISHED)) {
105                CoreSession session = event.getContext().getCoreSession();
106                UnrestrictedPropertySetter setter = new UnrestrictedPropertySetter(session, doc.getRef(), "dc:issued",
107                        cEventDate);
108                setter.runUnrestricted();
109            }
110            if (doc.isImmutable()) {
111                // proxies with attached schemas can be changed
112                // (and therefore saved), but they're still mostly
113                // immutable, so don't attempt to set modification dates
114                // on them
115                return;
116            }
117            // live proxies may be updated normally
118        }
119
120        Boolean dirty = (Boolean) event.getContext().getProperty(CoreEventConstants.DOCUMENT_DIRTY);
121        if ((eventId.equals(BEFORE_DOC_UPDATE) && Boolean.TRUE.equals(dirty))
122                || (eventId.equals(TRANSITION_EVENT) && !doc.isImmutable())) {
123            service.setModificationDate(doc, cEventDate, event);
124            service.addContributor(doc, event);
125        } else if (eventId.equals(DOCUMENT_CREATED)) {
126            service.setCreationDate(doc, cEventDate, event);
127            service.setModificationDate(doc, cEventDate, event);
128            service.addContributor(doc, event);
129        }
130    }
131
132    protected class UnrestrictedPropertySetter extends UnrestrictedSessionRunner {
133
134        DocumentRef docRef;
135
136        String xpath;
137
138        Serializable value;
139
140        protected UnrestrictedPropertySetter(CoreSession session, DocumentRef docRef, String xpath, Serializable value) {
141            super(session);
142            this.docRef = docRef;
143            this.xpath = xpath;
144            this.value = value;
145        }
146
147        @Override
148        public void run() {
149            DocumentModel doc = session.getSourceDocument(docRef);
150            if (doc != null) {
151                doc.setPropertyValue(xpath, value);
152                session.saveDocument(doc);
153            }
154
155        }
156
157    }
158
159}