001/* 002 * (C) Copyright 2006-2007 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 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.content.template.service; 023 024import java.util.HashMap; 025import java.util.Map; 026import java.util.Set; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.nuxeo.ecm.core.api.CoreSession; 031import org.nuxeo.ecm.core.api.DocumentModel; 032import org.nuxeo.ecm.core.repository.RepositoryInitializationHandler; 033import org.nuxeo.ecm.platform.content.template.listener.RepositoryInitializationListener; 034import org.nuxeo.runtime.model.ComponentContext; 035import org.nuxeo.runtime.model.ComponentInstance; 036import org.nuxeo.runtime.model.DefaultComponent; 037 038public class ContentTemplateServiceImpl extends DefaultComponent implements ContentTemplateService { 039 040 public static final String NAME = "org.nuxeo.ecm.platform.content.template.service.TemplateService"; 041 042 public static final String FACTORY_DECLARATION_EP = "factory"; 043 044 public static final String FACTORY_BINDING_EP = "factoryBinding"; 045 046 public static final String POST_CONTENT_CREATION_HANDLERS_EP = "postContentCreationHandlers"; 047 048 private static final Log log = LogFactory.getLog(ContentTemplateServiceImpl.class); 049 050 private final Map<String, ContentFactoryDescriptor> factories = new HashMap<String, ContentFactoryDescriptor>(); 051 052 private final Map<String, FactoryBindingDescriptor> factoryBindings = new HashMap<String, FactoryBindingDescriptor>(); 053 054 private PostContentCreationHandlerRegistry postContentCreationHandlers; 055 056 private RepositoryInitializationHandler initializationHandler; 057 058 @Override 059 public void activate(ComponentContext context) { 060 // register our Repo init listener 061 initializationHandler = new RepositoryInitializationListener(); 062 initializationHandler.install(); 063 064 postContentCreationHandlers = new PostContentCreationHandlerRegistry(); 065 } 066 067 @Override 068 public void deactivate(ComponentContext context) { 069 if (initializationHandler != null) { 070 initializationHandler.uninstall(); 071 } 072 } 073 074 @Override 075 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 076 077 if (extensionPoint.equals(FACTORY_DECLARATION_EP)) { 078 // store factories 079 ContentFactoryDescriptor descriptor = (ContentFactoryDescriptor) contribution; 080 factories.put(descriptor.getName(), descriptor); 081 } else if (extensionPoint.equals(FACTORY_BINDING_EP)) { 082 // store factories binding to types 083 FactoryBindingDescriptor descriptor = (FactoryBindingDescriptor) contribution; 084 if (factories.containsKey(descriptor.getFactoryName())) { 085 String targetType = descriptor.getTargetType(); 086 String targetFacet = descriptor.getTargetFacet(); 087 088 // merge binding 089 if (descriptor.getAppend()) { 090 descriptor = mergeFactoryBindingDescriptor(descriptor); 091 } 092 093 // check instantiation errors 094 if (getFactoryInstance(descriptor) == null) { 095 return; 096 } 097 098 // store binding 099 if (null != targetType) { 100 factoryBindings.put(targetType, descriptor); 101 } else { 102 factoryBindings.put(targetFacet, descriptor); 103 } 104 } else { 105 log.error("Factory Binding" + descriptor.getName() + " can not be registered since Factory " 106 + descriptor.getFactoryName() + " is not registered"); 107 } 108 } else if (POST_CONTENT_CREATION_HANDLERS_EP.equals(extensionPoint)) { 109 PostContentCreationHandlerDescriptor descriptor = (PostContentCreationHandlerDescriptor) contribution; 110 postContentCreationHandlers.addContribution(descriptor); 111 } 112 } 113 114 private FactoryBindingDescriptor mergeFactoryBindingDescriptor(FactoryBindingDescriptor newOne) { 115 FactoryBindingDescriptor old = null; 116 if (null != newOne.getTargetType()) { 117 old = factoryBindings.get(newOne.getTargetType()); 118 } else { 119 old = factoryBindings.get(newOne.getTargetFacet()); 120 } 121 122 if (old != null) { 123 log.info("FactoryBinding " + old.getName() + " is merging with " + newOne.getName()); 124 old.getOptions().putAll(newOne.getOptions()); 125 old.getRootAcl().addAll(newOne.getRootAcl()); 126 old.getTemplate().addAll(newOne.getTemplate()); 127 128 return old; 129 } 130 131 return newOne; 132 } 133 134 /* 135 * Instantiate a new factory for each caller, because factories are actually stateful, they contain the session of 136 * their root. 137 */ 138 @Override 139 public ContentFactory getFactoryForType(String documentType) { 140 FactoryBindingDescriptor descriptor = factoryBindings.get(documentType); 141 if (descriptor == null || !documentType.equals(descriptor.getTargetType())) { 142 return null; 143 } 144 return getFactoryInstance(descriptor); 145 } 146 147 /* 148 * Instantiate a new factory for each caller, because factories are actually stateful, they contain the session of 149 * their root. 150 */ 151 public ContentFactory getFactoryForFacet(String facet) { 152 FactoryBindingDescriptor descriptor = factoryBindings.get(facet); 153 if (descriptor == null || !facet.equals(descriptor.getTargetFacet())) { 154 return null; 155 } 156 return getFactoryInstance(descriptor); 157 } 158 159 protected ContentFactory getFactoryInstance(FactoryBindingDescriptor descriptor) { 160 ContentFactoryDescriptor factoryDescriptor = factories.get(descriptor.getFactoryName()); 161 try { 162 ContentFactory factory = factoryDescriptor.getClassName().newInstance(); 163 boolean factoryOK = factory.initFactory(descriptor.getOptions(), descriptor.getRootAcl(), 164 descriptor.getTemplate()); 165 if (!factoryOK) { 166 log.error("Error while initializing instance of factory " + factoryDescriptor.getName()); 167 return null; 168 } 169 return factory; 170 } catch (ReflectiveOperationException e) { 171 log.error( 172 "Error while creating instance of factory " + factoryDescriptor.getName() + " :" + e.getMessage()); 173 return null; 174 } 175 } 176 177 public void executeFactoryForType(DocumentModel createdDocument) { 178 ContentFactory factory = getFactoryForType(createdDocument.getType()); 179 if (factory != null) { 180 factory.createContentStructure(createdDocument); 181 } 182 Set<String> facets = createdDocument.getFacets(); 183 for (String facet : facets) { 184 factory = getFactoryForFacet(facet); 185 if (factory != null) { 186 factory.createContentStructure(createdDocument); 187 } 188 } 189 } 190 191 @Override 192 public void executePostContentCreationHandlers(CoreSession session) { 193 for (PostContentCreationHandler handler : postContentCreationHandlers.getOrderedHandlers()) { 194 handler.execute(session); 195 } 196 } 197 198 // for testing 199 public Map<String, ContentFactoryDescriptor> getFactories() { 200 return factories; 201 } 202 203 public Map<String, FactoryBindingDescriptor> getFactoryBindings() { 204 return factoryBindings; 205 } 206 207}