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