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 @Override 064 public void handleEvent(Event event) { 065 066 EventContext ctx = event.getContext(); 067 068 if (ABOUT_TO_CREATE.equals(event.getName()) || BEFORE_DOC_UPDATE.equals(event.getName())) { 069 if (ctx instanceof DocumentEventContext) { 070 DocumentEventContext docCtx = (DocumentEventContext) ctx; 071 072 DocumentModel targetDoc = docCtx.getSourceDocument(); 073 074 if (targetDoc.isVersion()) { 075 return; 076 } 077 078 TemplateSourceDocument templateDoc = targetDoc.getAdapter(TemplateSourceDocument.class); 079 if (templateDoc != null) { 080 // init types bindings 081 templateDoc.initTypesBindings(); 082 083 // init template source 084 List<TemplateInput> params = templateDoc.getParams(); 085 if (params == null || params.size() == 0 || isBlobDirty(targetDoc)) { 086 templateDoc.initTemplate(false); 087 } 088 } else { 089 TemplateBasedDocument tmplBased = targetDoc.getAdapter(TemplateBasedDocument.class); 090 if (tmplBased == null) { 091 // if not templateBased see if we must add the facet 092 // because of the type binding 093 // or template selection as main file 094 TemplateProcessorService tps = Framework.getLocalService(TemplateProcessorService.class); 095 096 String targetTemplateUid = (String) targetDoc.getContextData().getScopedValue( 097 ScopeType.REQUEST, "templateId"); 098 if ("none".equals(targetTemplateUid)) { 099 targetTemplateUid = null; 100 } 101 List<String> templatesUids = new ArrayList<String>(); 102 103 if (targetTemplateUid != null) { 104 templatesUids.add(targetTemplateUid); 105 } 106 107 List<String> tuids = tps.getTypeMapping().get(targetDoc.getType()); 108 if (tuids != null) { 109 for (String tuid : tuids) { 110 // let's be paranoid 111 if (!templatesUids.contains(tuid)) { 112 templatesUids.add(tuid); 113 } 114 } 115 } 116 117 // do the association 118 if (templatesUids.size() > 0) { 119 for (String tuid : templatesUids) { 120 DocumentRef templateRef = new IdRef(tuid); 121 // check if source template is visible 122 if (docCtx.getCoreSession().exists(templateRef)) { 123 DocumentModel sourceTemplateDoc = docCtx.getCoreSession().getDocument(templateRef); 124 if (!LifeCycleConstants.DELETED_STATE.equals(sourceTemplateDoc.getCurrentLifeCycleState())) { 125 tps.makeTemplateBasedDocument(targetDoc, sourceTemplateDoc, false); 126 } 127 } 128 } 129 } 130 } 131 } 132 } 133 } 134 } 135 136 protected boolean isBlobDirty(DocumentModel targetDoc) { 137 BlobHolder bh = targetDoc.getAdapter(BlobHolder.class); 138 Blob mainBlob = bh.getBlob(); 139 if (mainBlob != null && mainBlob.getDigest() == null) { 140 // Blobs that have not changed should be SQL Blobs and have a digest 141 return true; 142 } else { 143 // newly uploaded Blob should be FileBlob, and anyway Digest can not 144 // have been computed so far 145 return false; 146 } 147 } 148}