001/* 002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.platform.content.template.service; 021 022import java.util.HashMap; 023import java.util.Map; 024import java.util.Set; 025 026import org.apache.commons.logging.Log; 027import org.apache.commons.logging.LogFactory; 028import org.nuxeo.ecm.core.api.CoreSession; 029import org.nuxeo.ecm.core.api.DocumentModel; 030import org.nuxeo.ecm.core.repository.RepositoryInitializationHandler; 031import org.nuxeo.ecm.platform.content.template.listener.RepositoryInitializationListener; 032import org.nuxeo.runtime.model.ComponentContext; 033import org.nuxeo.runtime.model.ComponentInstance; 034import org.nuxeo.runtime.model.DefaultComponent; 035 036public class ContentTemplateServiceImpl extends DefaultComponent implements ContentTemplateService { 037 038 public static final String NAME = "org.nuxeo.ecm.platform.content.template.service.TemplateService"; 039 040 public static final String FACTORY_DECLARATION_EP = "factory"; 041 042 public static final String FACTORY_BINDING_EP = "factoryBinding"; 043 044 public static final String POST_CONTENT_CREATION_HANDLERS_EP = "postContentCreationHandlers"; 045 046 private static final Log log = LogFactory.getLog(ContentTemplateServiceImpl.class); 047 048 private final Map<String, ContentFactoryDescriptor> factories = new HashMap<String, ContentFactoryDescriptor>(); 049 050 private final Map<String, FactoryBindingDescriptor> factoryBindings = new HashMap<String, FactoryBindingDescriptor>(); 051 052 private final Map<String, ContentFactory> factoryInstancesByType = new HashMap<String, ContentFactory>(); 053 054 private final Map<String, ContentFactory> factoryInstancesByFacet = new HashMap<String, ContentFactory>(); 055 056 private PostContentCreationHandlerRegistry postContentCreationHandlers; 057 058 private RepositoryInitializationHandler initializationHandler; 059 060 @Override 061 public void activate(ComponentContext context) { 062 // register our Repo init listener 063 initializationHandler = new RepositoryInitializationListener(); 064 initializationHandler.install(); 065 066 postContentCreationHandlers = new PostContentCreationHandlerRegistry(); 067 } 068 069 @Override 070 public void deactivate(ComponentContext context) { 071 if (initializationHandler != null) { 072 initializationHandler.uninstall(); 073 } 074 } 075 076 @Override 077 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 078 079 if (extensionPoint.equals(FACTORY_DECLARATION_EP)) { 080 // store factories 081 ContentFactoryDescriptor descriptor = (ContentFactoryDescriptor) contribution; 082 factories.put(descriptor.getName(), descriptor); 083 } else if (extensionPoint.equals(FACTORY_BINDING_EP)) { 084 // store factories binding to types 085 FactoryBindingDescriptor descriptor = (FactoryBindingDescriptor) contribution; 086 if (factories.containsKey(descriptor.getFactoryName())) { 087 String targetType = descriptor.getTargetType(); 088 String targetFacet = descriptor.getTargetFacet(); 089 090 // merge binding 091 if (descriptor.getAppend()) { 092 descriptor = mergeFactoryBindingDescriptor(descriptor); 093 } 094 095 // store binding 096 if (null != targetType) { 097 factoryBindings.put(targetType, descriptor); 098 } else { 099 factoryBindings.put(targetFacet, descriptor); 100 } 101 102 // create factory instance : one instance per binding 103 ContentFactoryDescriptor factoryDescriptor = factories.get(descriptor.getFactoryName()); 104 try { 105 ContentFactory factory = factoryDescriptor.getClassName().newInstance(); 106 Boolean factoryOK = factory.initFactory(descriptor.getOptions(), descriptor.getRootAcl(), 107 descriptor.getTemplate()); 108 if (!factoryOK) { 109 log.error("Error while initializing instance of factory " + factoryDescriptor.getName()); 110 return; 111 } 112 113 // store initialized instance 114 if (null != targetType) { 115 factoryInstancesByType.put(targetType, factory); 116 } else { 117 factoryInstancesByFacet.put(targetFacet, factory); 118 } 119 120 } catch (InstantiationException e) { 121 log.error("Error while creating instance of factory " + factoryDescriptor.getName() + " :" 122 + e.getMessage()); 123 } catch (IllegalAccessException e) { 124 log.error("Error while creating instance of factory " + factoryDescriptor.getName() + " :" 125 + e.getMessage()); 126 } 127 } else { 128 log.error("Factory Binding" + descriptor.getName() + " can not be registered since Factory " 129 + descriptor.getFactoryName() + " is not registered"); 130 } 131 } else if (POST_CONTENT_CREATION_HANDLERS_EP.equals(extensionPoint)) { 132 PostContentCreationHandlerDescriptor descriptor = (PostContentCreationHandlerDescriptor) contribution; 133 postContentCreationHandlers.addContribution(descriptor); 134 } 135 } 136 137 private FactoryBindingDescriptor mergeFactoryBindingDescriptor(FactoryBindingDescriptor newOne) { 138 FactoryBindingDescriptor old = null; 139 if (null != newOne.getTargetType()) { 140 old = factoryBindings.get(newOne.getTargetType()); 141 } else { 142 old = factoryBindings.get(newOne.getTargetFacet()); 143 } 144 145 if (old != null) { 146 log.info("FactoryBinding " + old.getName() + " is merging with " + newOne.getName()); 147 old.getOptions().putAll(newOne.getOptions()); 148 old.getRootAcl().addAll(newOne.getRootAcl()); 149 old.getTemplate().addAll(newOne.getTemplate()); 150 151 return old; 152 } 153 154 return newOne; 155 } 156 157 public ContentFactory getFactoryForType(String documentType) { 158 return factoryInstancesByType.get(documentType); 159 } 160 161 public ContentFactory getFactoryForFacet(String facet) { 162 return factoryInstancesByFacet.get(facet); 163 } 164 165 public void executeFactoryForType(DocumentModel createdDocument) { 166 ContentFactory factory = getFactoryForType(createdDocument.getType()); 167 if (factory != null) { 168 factory.createContentStructure(createdDocument); 169 } 170 Set<String> facets = createdDocument.getFacets(); 171 for (String facet : facets) { 172 factory = getFactoryForFacet(facet); 173 if (factory != null) { 174 factory.createContentStructure(createdDocument); 175 } 176 } 177 } 178 179 @Override 180 public void executePostContentCreationHandlers(CoreSession session) { 181 for (PostContentCreationHandler handler : postContentCreationHandlers.getOrderedHandlers()) { 182 handler.execute(session); 183 } 184 } 185 186 // for testing 187 public Map<String, ContentFactoryDescriptor> getFactories() { 188 return factories; 189 } 190 191 public Map<String, FactoryBindingDescriptor> getFactoryBindings() { 192 return factoryBindings; 193 } 194 195 public Map<String, ContentFactory> getFactoryInstancesByType() { 196 return factoryInstancesByType; 197 } 198 199 public Map<String, ContentFactory> getFactoryInstancesByFacet() { 200 return factoryInstancesByFacet; 201 } 202 203}