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