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.common.collections.ScopeType; 032import org.nuxeo.ecm.core.api.Blob; 033import org.nuxeo.ecm.core.api.DocumentModel; 034import org.nuxeo.ecm.core.api.DocumentRef; 035import org.nuxeo.ecm.core.api.IdRef; 036import org.nuxeo.ecm.core.api.LifeCycleConstants; 037import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 038import org.nuxeo.ecm.core.api.model.Property; 039import org.nuxeo.ecm.core.event.Event; 040import org.nuxeo.ecm.core.event.EventContext; 041import org.nuxeo.ecm.core.event.EventListener; 042import org.nuxeo.ecm.core.event.impl.DocumentEventContext; 043import org.nuxeo.ecm.core.utils.BlobsExtractor; 044import org.nuxeo.runtime.api.Framework; 045import org.nuxeo.template.api.TemplateInput; 046import org.nuxeo.template.api.TemplateProcessorService; 047import org.nuxeo.template.api.adapters.TemplateBasedDocument; 048import org.nuxeo.template.api.adapters.TemplateSourceDocument; 049 050/** 051 * Listener to manage initialization : 052 * <ul> 053 * <li>of the TemplateSourceDocument : init the parameters</li> 054 * <li>of the other DocumentModels if they need to be automatically associated to a template</li> 055 * </ul> 056 * 057 * @author Tiry (tdelprat@nuxeo.com) 058 */ 059public class TemplateInitListener implements EventListener { 060 061 private static final Log log = LogFactory.getLog(TemplateInitListener.class); 062 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().getScopedValue( 096 ScopeType.REQUEST, "templateId"); 097 if ("none".equals(targetTemplateUid)) { 098 targetTemplateUid = null; 099 } 100 List<String> templatesUids = new ArrayList<String>(); 101 102 if (targetTemplateUid != null) { 103 templatesUids.add(targetTemplateUid); 104 } 105 106 List<String> tuids = tps.getTypeMapping().get(targetDoc.getType()); 107 if (tuids != null) { 108 for (String tuid : tuids) { 109 // let's be paranoid 110 if (!templatesUids.contains(tuid)) { 111 templatesUids.add(tuid); 112 } 113 } 114 } 115 116 // do the association 117 if (templatesUids.size() > 0) { 118 for (String tuid : templatesUids) { 119 DocumentRef templateRef = new IdRef(tuid); 120 // check if source template is visible 121 if (docCtx.getCoreSession().exists(templateRef)) { 122 DocumentModel sourceTemplateDoc = docCtx.getCoreSession().getDocument(templateRef); 123 if (!LifeCycleConstants.DELETED_STATE.equals(sourceTemplateDoc.getCurrentLifeCycleState())) { 124 tps.makeTemplateBasedDocument(targetDoc, sourceTemplateDoc, false); 125 } 126 } 127 } 128 } 129 } 130 } 131 } 132 } 133 } 134 135 protected boolean isBlobDirty(DocumentModel targetDoc) { 136 BlobHolder bh = targetDoc.getAdapter(BlobHolder.class); 137 Blob mainBlob = bh.getBlob(); 138 if (mainBlob.getDigest() == null) { 139 // Blobs that have not changed should be SQL Blobs and have a digest 140 return true; 141 } else { 142 // newly uploaded Blob should be FileBlob, and anyway Digest can not 143 // have been computed so far 144 return false; 145 } 146 } 147}