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