001/* 002 * (C) Copyright 2006-2016 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_CREATED_BY_COPY; 028import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.DOCUMENT_PUBLISHED; 029import static org.nuxeo.ecm.core.schema.FacetNames.SYSTEM_DOCUMENT; 030 031import java.io.Serializable; 032import java.util.Calendar; 033import java.util.Date; 034 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037import org.nuxeo.ecm.core.api.CoreSession; 038import org.nuxeo.ecm.core.api.DocumentModel; 039import org.nuxeo.ecm.core.api.DocumentRef; 040import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; 041import org.nuxeo.ecm.core.api.event.CoreEventConstants; 042import org.nuxeo.ecm.core.event.Event; 043import org.nuxeo.ecm.core.event.EventListener; 044import org.nuxeo.ecm.core.event.impl.DocumentEventContext; 045import org.nuxeo.ecm.platform.dublincore.NXDublinCore; 046import org.nuxeo.ecm.platform.dublincore.service.DublinCoreStorageService; 047import org.nuxeo.runtime.api.Framework; 048import org.nuxeo.runtime.services.config.ConfigurationService; 049 050/** 051 * Core Event Listener for updating DublinCore. 052 * 053 * @author <a href="mailto:td@nuxeo.com">Thierry Delprat</a> 054 * @author <a href="mailto:rspivak@nuxeo.com">Ruslan Spivak</a> 055 */ 056public class DublinCoreListener implements EventListener { 057 058 private static final Log log = LogFactory.getLog(DublinCoreListener.class); 059 060 public static final String DISABLE_DUBLINCORE_LISTENER = "disableDublinCoreListener"; 061 062 private static final String RESET_CREATOR_PROPERTY = "nuxeo.dclistener.reset-creator-on-copy"; 063 064 /** 065 * Core event notification. 066 * <p> 067 * Gets core events and updates DublinCore if needed. 068 * 069 * @param event event fired at core layer 070 */ 071 @Override 072 public void handleEvent(Event event) { 073 074 DocumentEventContext docCtx; 075 if (event.getContext() instanceof DocumentEventContext) { 076 docCtx = (DocumentEventContext) event.getContext(); 077 } else { 078 return; 079 } 080 String eventId = event.getName(); 081 082 if (!eventId.equals(DOCUMENT_CREATED) && !eventId.equals(BEFORE_DOC_UPDATE) 083 && !eventId.equals(TRANSITION_EVENT) && !eventId.equals(DOCUMENT_PUBLISHED) 084 && !eventId.equals(DOCUMENT_CREATED_BY_COPY)) { 085 return; 086 } 087 088 DublinCoreStorageService service = NXDublinCore.getDublinCoreStorageService(); 089 if (service == null) { 090 log.error("DublinCoreStorage service not found ... !"); 091 return; 092 } 093 094 Boolean block = (Boolean) event.getContext().getProperty(DISABLE_DUBLINCORE_LISTENER); 095 if (Boolean.TRUE.equals(block)) { 096 // ignore the event - we are blocked by the caller 097 return; 098 } 099 100 DocumentModel doc = docCtx.getSourceDocument(); 101 102 if (doc.isVersion()) { 103 log.debug("No DublinCore update on versions except for the issued date"); 104 return; 105 } 106 107 if (doc.hasFacet(SYSTEM_DOCUMENT)) { 108 // ignore the event for System documents 109 return; 110 } 111 112 Date eventDate = new Date(event.getTime()); 113 Calendar cEventDate = Calendar.getInstance(); 114 cEventDate.setTime(eventDate); 115 116 if (doc.isProxy()) { 117 if (eventId.equals(DOCUMENT_PUBLISHED)) { 118 CoreSession session = event.getContext().getCoreSession(); 119 UnrestrictedPropertySetter setter = new UnrestrictedPropertySetter(session, doc.getRef(), "dc:issued", 120 cEventDate); 121 setter.runUnrestricted(); 122 } 123 if (doc.isImmutable()) { 124 // proxies with attached schemas can be changed 125 // (and therefore saved), but they're still mostly 126 // immutable, so don't attempt to set modification dates 127 // on them 128 return; 129 } 130 // live proxies may be updated normally, except at creation time (don't update the live doc) 131 if (eventId.equals(DOCUMENT_CREATED)) { 132 return; 133 } 134 } 135 136 Boolean resetCreator = (Boolean) event.getContext().getProperty(CoreEventConstants.RESET_CREATOR); 137 boolean resetCreatorProperty = Framework.getService(ConfigurationService.class).isBooleanPropertyTrue( 138 RESET_CREATOR_PROPERTY); 139 Boolean dirty = (Boolean) event.getContext().getProperty(CoreEventConstants.DOCUMENT_DIRTY); 140 if ((eventId.equals(BEFORE_DOC_UPDATE) && Boolean.TRUE.equals(dirty)) 141 || (eventId.equals(TRANSITION_EVENT) && !doc.isImmutable())) { 142 service.setModificationDate(doc, cEventDate, event); 143 service.addContributor(doc, event); 144 } else if (eventId.equals(DOCUMENT_CREATED)) { 145 service.setCreationDate(doc, cEventDate, event); 146 service.setModificationDate(doc, cEventDate, event); 147 service.addContributor(doc, event); 148 } else if (eventId.equals(DOCUMENT_CREATED_BY_COPY) 149 && (resetCreatorProperty || Boolean.TRUE.equals(resetCreator))) { 150 doc.setProperty("dublincore", "creator", null); 151 doc.setProperty("dublincore", "contributors", null); 152 service.setCreationDate(doc, cEventDate, event); 153 service.setModificationDate(doc, cEventDate, event); 154 service.addContributor(doc, event); 155 } 156 } 157 158 protected class UnrestrictedPropertySetter extends UnrestrictedSessionRunner { 159 160 DocumentRef docRef; 161 162 String xpath; 163 164 Serializable value; 165 166 protected UnrestrictedPropertySetter(CoreSession session, DocumentRef docRef, String xpath, Serializable value) { 167 super(session); 168 this.docRef = docRef; 169 this.xpath = xpath; 170 this.value = value; 171 } 172 173 @Override 174 public void run() { 175 DocumentModel doc = session.getSourceDocument(docRef); 176 if (doc != null) { 177 doc.setPropertyValue(xpath, value); 178 session.saveDocument(doc); 179 } 180 181 } 182 183 } 184 185}