001/* 002 * (C) Copyright 2006-2012 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 */ 020 021package org.nuxeo.template.listeners; 022 023import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.ABOUT_TO_CREATE; 024import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.BEFORE_DOC_UPDATE; 025 026import java.util.ArrayList; 027import java.util.List; 028 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031import org.nuxeo.ecm.core.api.Blob; 032import org.nuxeo.ecm.core.api.DocumentModel; 033import org.nuxeo.ecm.core.api.DocumentRef; 034import org.nuxeo.ecm.core.api.IdRef; 035import org.nuxeo.ecm.core.api.LifeCycleConstants; 036import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 037import org.nuxeo.ecm.core.api.model.Property; 038import org.nuxeo.ecm.core.event.Event; 039import org.nuxeo.ecm.core.event.EventContext; 040import org.nuxeo.ecm.core.event.EventListener; 041import org.nuxeo.ecm.core.event.impl.DocumentEventContext; 042import org.nuxeo.ecm.core.utils.BlobsExtractor; 043import org.nuxeo.runtime.api.Framework; 044import org.nuxeo.template.api.TemplateInput; 045import org.nuxeo.template.api.TemplateProcessorService; 046import org.nuxeo.template.api.adapters.TemplateBasedDocument; 047import org.nuxeo.template.api.adapters.TemplateSourceDocument; 048 049/** 050 * Listener to manage initialization : 051 * <ul> 052 * <li>of the TemplateSourceDocument : init the parameters</li> 053 * <li>of the other DocumentModels if they need to be automatically associated to a template</li> 054 * </ul> 055 * 056 * @author Tiry (tdelprat@nuxeo.com) 057 */ 058public class TemplateInitListener implements EventListener { 059 060 private static final Log log = LogFactory.getLog(TemplateInitListener.class); 061 062 @Override 063 public void handleEvent(Event event) { 064 065 EventContext ctx = event.getContext(); 066 067 if (ABOUT_TO_CREATE.equals(event.getName()) || BEFORE_DOC_UPDATE.equals(event.getName())) { 068 if (ctx instanceof DocumentEventContext) { 069 DocumentEventContext docCtx = (DocumentEventContext) ctx; 070 071 DocumentModel targetDoc = docCtx.getSourceDocument(); 072 073 if (targetDoc.isVersion()) { 074 return; 075 } 076 077 TemplateSourceDocument templateDoc = targetDoc.getAdapter(TemplateSourceDocument.class); 078 if (templateDoc != null) { 079 // init types bindings 080 templateDoc.initTypesBindings(); 081 082 // init template source 083 List<TemplateInput> params = templateDoc.getParams(); 084 if (params == null || params.size() == 0 || isBlobDirty(targetDoc)) { 085 templateDoc.initTemplate(false); 086 } 087 } else { 088 TemplateBasedDocument tmplBased = targetDoc.getAdapter(TemplateBasedDocument.class); 089 if (tmplBased == null) { 090 // if not templateBased see if we must add the facet 091 // because of the type binding 092 // or template selection as main file 093 TemplateProcessorService tps = Framework.getLocalService(TemplateProcessorService.class); 094 095 String targetTemplateUid = (String) targetDoc.getContextData("templateId"); 096 if ("none".equals(targetTemplateUid)) { 097 targetTemplateUid = null; 098 } 099 List<String> templatesUids = new ArrayList<String>(); 100 101 if (targetTemplateUid != null) { 102 templatesUids.add(targetTemplateUid); 103 } 104 105 List<String> tuids = tps.getTypeMapping().get(targetDoc.getType()); 106 if (tuids != null) { 107 for (String tuid : tuids) { 108 // let's be paranoid 109 if (!templatesUids.contains(tuid)) { 110 templatesUids.add(tuid); 111 } 112 } 113 } 114 115 // do the association 116 if (templatesUids.size() > 0) { 117 for (String tuid : templatesUids) { 118 DocumentRef templateRef = new IdRef(tuid); 119 // check if source template is visible 120 if (docCtx.getCoreSession().exists(templateRef)) { 121 DocumentModel sourceTemplateDoc = docCtx.getCoreSession().getDocument(templateRef); 122 if (!LifeCycleConstants.DELETED_STATE.equals(sourceTemplateDoc.getCurrentLifeCycleState())) { 123 tps.makeTemplateBasedDocument(targetDoc, sourceTemplateDoc, false); 124 } 125 } 126 } 127 } 128 } 129 } 130 } 131 } 132 } 133 134 protected boolean isBlobDirty(DocumentModel targetDoc) { 135 BlobHolder bh = targetDoc.getAdapter(BlobHolder.class); 136 Blob mainBlob = bh.getBlob(); 137 if (mainBlob != null && mainBlob.getDigest() == null) { 138 // Blobs that have not changed should be SQL Blobs and have a digest 139 return true; 140 } else { 141 // newly uploaded Blob should be FileBlob, and anyway Digest can not 142 // have been computed so far 143 return false; 144 } 145 } 146}