/* * Copyright (C) 2003-2007 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. */ package org.exoplatform.services.cms.templates.impl; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.security.AccessControlException; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Arrays; import javax.jcr.AccessDeniedException; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; import javax.jcr.ValueFormatException; import javax.jcr.nodetype.NodeType; import org.apache.commons.lang.StringUtils; import org.exoplatform.container.component.ComponentPlugin; import org.exoplatform.services.cache.CacheService; import org.exoplatform.services.cache.ExoCache; import org.exoplatform.services.cms.BasePath; import org.exoplatform.services.cms.impl.DMSConfiguration; import org.exoplatform.services.cms.impl.DMSRepositoryConfiguration; import org.exoplatform.services.cms.impl.Utils; import org.exoplatform.services.cms.templates.ContentTypeFilterPlugin; import org.exoplatform.services.cms.templates.ContentTypeFilterPlugin.FolderFilterConfig; import org.exoplatform.services.cms.templates.TemplateService; import org.exoplatform.services.context.DocumentContext; import org.exoplatform.services.jcr.RepositoryService; import org.exoplatform.services.jcr.access.DynamicIdentity; import org.exoplatform.services.jcr.core.ManageableRepository; import org.exoplatform.services.jcr.ext.common.SessionProvider; import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator; import org.exoplatform.services.jcr.impl.Constants; import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeImpl; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import org.exoplatform.services.resources.LocaleConfigService; import org.exoplatform.services.resources.Orientation; import org.exoplatform.services.security.Identity; import org.exoplatform.services.security.IdentityConstants; import org.exoplatform.services.security.IdentityRegistry; import org.exoplatform.services.security.MembershipEntry; import org.exoplatform.services.wcm.core.NodetypeConstant; import org.exoplatform.services.wcm.utils.WCMCoreUtils; import org.picocontainer.Startable; /** * @author benjaminmestrallet */ public class TemplateServiceImpl implements TemplateService, Startable { private RepositoryService repositoryService_; private IdentityRegistry identityRegistry_; private String cmsTemplatesBasePath_; private List<TemplatePlugin> plugins_ = new ArrayList<TemplatePlugin>(); private Set<String> configuredNodeTypes; /** * The key is a folder type, the value is the List of content types. */ private HashMap<String, List<String>> foldersFilterMap = null; /** * The key is a repository name, the value is the List of template names. */ private HashMap<String, List<String>> managedDocumentTypesMap = new HashMap<String, List<String>>(); private org.exoplatform.groovyscript.text.TemplateService templateService; private LocaleConfigService localeConfigService_; private static final Log LOG = ExoLogger.getLogger(TemplateService.class.getName()); /** * DMS configuration which used to store informations */ private DMSConfiguration dmsConfiguration_; private static final String NODETYPE_LIST = "nodeTypeList"; private static final String EDITED_CONFIGURED_NODE_TYPES = "EditedConfiguredNodeTypes"; private ExoCache nodeTypeListCached ; /** * Constructor method. * Init jcrService, nodeHierarchyCreator, identityRegistry, localeConfigService, caService, * dmsConfiguration * @param jcrService RepositoryService * @param nodeHierarchyCreator NodeHierarchyCreator * @param identityRegistry IdentityRegistry * @param localeConfigService LocaleConfigService * @param caService CacheService * @param dmsConfiguration DMSConfiguration * @throws Exception */ public TemplateServiceImpl(RepositoryService jcrService, NodeHierarchyCreator nodeHierarchyCreator, IdentityRegistry identityRegistry, org.exoplatform.groovyscript.text.TemplateService templateService, DMSConfiguration dmsConfiguration, LocaleConfigService localeConfigService, CacheService caService) throws Exception { identityRegistry_ = identityRegistry; repositoryService_ = jcrService; cmsTemplatesBasePath_ = nodeHierarchyCreator.getJcrPath(BasePath.CMS_TEMPLATES_PATH); this.templateService = templateService; dmsConfiguration_ = dmsConfiguration; localeConfigService_ = localeConfigService; nodeTypeListCached = caService.getCacheInstance(TemplateService.class.getName()); } /** * {@inheritDoc} */ public void start() { configuredNodeTypes = new HashSet<String>(); try { for (TemplatePlugin plugin : plugins_) { plugin.init(); configuredNodeTypes.addAll(plugin.getAllConfiguredNodeTypes()); } // Cached all nodetypes that is document type in the map getDocumentTemplates(); } catch (Exception e) { if (LOG.isErrorEnabled()) { LOG.error("An unexpected exception occurs when init plugins", e); } } } /** * {@inheritDoc} */ public void stop() { } /** * {@inheritDoc} */ public void addContentTypeFilterPlugin(ContentTypeFilterPlugin filterPlugin) { HashMap<String,List<String>> folderFilterMap = foldersFilterMap; if (folderFilterMap == null) { folderFilterMap = new HashMap<String,List<String>>(); } for (FolderFilterConfig filterConfig : filterPlugin.getFolderFilterConfigList()) { String folderType = filterConfig.getFolderType(); List<String> contentTypes = filterConfig.getContentTypes(); List<String> value = folderFilterMap.get(folderType); if (value == null) { folderFilterMap.put(folderType, contentTypes); } else { value.addAll(contentTypes); folderFilterMap.put(folderType, value); } } foldersFilterMap = folderFilterMap; } /** * {@inheritDoc} */ public Set<String> getAllowanceFolderType() { HashMap<String, List<String>> map = foldersFilterMap; if (map != null) return map.keySet(); return null; } /** * {@inheritDoc} */ public void addTemplates(ComponentPlugin plugin) { if (plugin instanceof TemplatePlugin) plugins_.add((TemplatePlugin) plugin); } /** * {@inheritDoc} */ public void init() throws Exception { for (TemplatePlugin plugin : plugins_) { plugin.init(); } } /** * {@inheritDoc} */ public Node getTemplatesHome(SessionProvider provider) throws Exception { try { Session session = getSession(provider); return (Node) session.getItem(cmsTemplatesBasePath_); } catch (AccessDeniedException ace) { if (LOG.isErrorEnabled()) { LOG.error("Access denied. You can not access to this template"); } return null; } } /** * {@inheritDoc} */ public List<String> getCreationableContentTypes(Node node) throws Exception { String folderType = node.getPrimaryNodeType().getName(); List<String> testContentTypes = null; HashMap<String,List<String>> folderFilterMap = foldersFilterMap; if (folderFilterMap != null) { List<String> list = folderFilterMap.get(folderType); if (list != null && list.size() != 0) { testContentTypes = list; } } if (testContentTypes == null) { testContentTypes = getDocumentTemplates(); } List<String> result = new ArrayList<String>(); for (String contentType : testContentTypes) { if (isChildNodePrimaryTypeAllowed(node, contentType)) { result.add(contentType); } } return result; } /** * {@inheritDoc} */ public boolean isChildNodePrimaryTypeAllowed(Node parent, String childNodeTypeName) throws Exception{ NodeType childNodeType = parent.getSession().getWorkspace().getNodeTypeManager().getNodeType(childNodeTypeName); //In some cases, the child node is mixins type of a nt:file example if(childNodeType.isMixin()) return true; List<NodeType> allNodeTypes = new ArrayList<NodeType>(); allNodeTypes.add(parent.getPrimaryNodeType()); for(NodeType mixin: parent.getMixinNodeTypes()) { allNodeTypes.add(mixin); } for (NodeType nodetype:allNodeTypes) { if (((NodeTypeImpl)nodetype).isChildNodePrimaryTypeAllowed( Constants.JCR_ANY_NAME, ((NodeTypeImpl)childNodeType).getQName())) { return true; } } return false; } /** * {@inheritDoc} */ public boolean isManagedNodeType(String nodeTypeName) throws RepositoryException { //check if the node type is document type first List<String> managedDocumentTypes = getManagedDocumentTypesMap(); if(managedDocumentTypes != null && managedDocumentTypes.contains(nodeTypeName)) return true; SessionProvider provider = SessionProvider.createSystemProvider(); Session session = getSession(provider); try { Node systemTemplatesHome = (Node) session.getItem(cmsTemplatesBasePath_); return systemTemplatesHome.hasNode(nodeTypeName); } finally { provider.close(); } } /** * {@inheritDoc} */ public String getTemplatePath(Node node, boolean isDialog) throws Exception { String userId = node.getSession().getUserID(); String templateType = null; if (node.isNodeType("exo:presentationable") && node.hasProperty("exo:presentationType")) { templateType = node.getProperty("exo:presentationType").getString(); } else if (node.isNodeType("nt:frozenNode")) { templateType = node.getProperty("jcr:frozenPrimaryType").getString(); } else { templateType = node.getPrimaryNodeType().getName(); } if (isManagedNodeType(templateType)) { return getTemplatePathByUser(isDialog, templateType, userId); } // Check if node's nodetype or its supper type has managed template type String managedTemplateType = getManagedTemplateType(node); if (StringUtils.isNotEmpty(managedTemplateType)) { return getTemplatePathByUser(isDialog, managedTemplateType, userId); } throw new Exception("The content type: " + templateType + " isn't supported by any template"); } /** * {@inheritDoc} */ public NodeIterator getAllTemplatesOfNodeType(boolean isDialog, String nodeTypeName, SessionProvider provider) throws Exception { Node nodeTypeHome = getTemplatesHome(provider).getNode(nodeTypeName); if (isDialog) { if(!nodeTypeHome.hasNode(DIALOGS)) return null; return nodeTypeHome.getNode(DIALOGS).getNodes(); } if(!nodeTypeHome.hasNode(VIEWS)) return null; return nodeTypeHome.getNode(VIEWS).getNodes(); } /** * {@inheritDoc} */ public String getDefaultTemplatePath(boolean isDialog, String nodeTypeName) { if (isDialog) return cmsTemplatesBasePath_ + "/" + nodeTypeName + DEFAULT_DIALOGS_PATH; return cmsTemplatesBasePath_ + "/" + nodeTypeName + DEFAULT_VIEWS_PATH; } /** * {@inheritDoc} */ public Node getTemplateNode(String type, String nodeTypeName, String templateName, SessionProvider provider) throws Exception { Node nodeTypeNode = getTemplatesHome(provider).getNode(nodeTypeName); return nodeTypeNode.getNode(type).getNode(templateName); } /** * {@inheritDoc} */ public String getTemplatePathByUser(boolean isDialog, String nodeTypeName, String userName) throws RepositoryException { if(IdentityConstants.ANONIM.equals(userName) || DynamicIdentity.DYNAMIC.equals(userName) || userName == null) { return getTemplatePathByAnonymous(isDialog, nodeTypeName); } Node templateHomeNode = (Node) getSession(WCMCoreUtils.getSystemSessionProvider()).getItem(cmsTemplatesBasePath_); String type = DIALOGS; if (!isDialog) type = VIEWS; Node nodeTypeNode = templateHomeNode.getNode(nodeTypeName); NodeIterator templateIter = nodeTypeNode.getNode(type).getNodes(); while (templateIter.hasNext()) { Node node = templateIter.nextNode(); String roles = getTemplateRoles(node); if(hasPermission(userName, roles, identityRegistry_)) { String templatePath = node.getPath() ; return templatePath ; } } throw new AccessControlException("You don't have permission to access any template"); } /** * {@inheritDoc} */ public String getTemplatePath(boolean isDialog, String nodeTypeName, String templateName) throws Exception { String type = DIALOGS; if (!isDialog) type = VIEWS; Node templateNode = getTemplateNode(type, nodeTypeName, templateName); String path = templateNode.getPath(); return path; } /** * {@inheritDoc} */ public String getTemplateLabel(String nodeTypeName) throws Exception { SessionProvider provider = SessionProvider.createSystemProvider(); try { Node templateHome = getTemplatesHome(provider); Node nodeType = templateHome.getNode(nodeTypeName); if (nodeType.hasProperty("label")) { return nodeType.getProperty("label").getString(); } } finally { provider.close(); } return ""; } /** * {@inheritDoc} */ public String getTemplate(String type, String nodeTypeName, String templateName) throws Exception { Node templateNode = getTemplateNode(type, nodeTypeName, templateName); return getTemplate(templateNode); } /** * {@inheritDoc} */ public void removeTemplate(String type, String nodeTypeName, String templateName) throws Exception { Node templatesHome = (Node) getSession(WCMCoreUtils.getSystemSessionProvider()).getItem(cmsTemplatesBasePath_); Node nodeTypeHome = templatesHome.getNode(nodeTypeName); Node specifiedTemplatesHome = nodeTypeHome.getNode(type); Node contentNode = specifiedTemplatesHome.getNode(templateName); contentNode.remove(); nodeTypeHome.save(); // Update list of changed template node type list addEditedConfiguredNodeType(nodeTypeName); } /** * {@inheritDoc} */ public void removeManagedNodeType(String nodeTypeName) throws Exception { Node templatesHome = (Node) getSession(WCMCoreUtils.getSystemSessionProvider()).getItem(cmsTemplatesBasePath_); Node managedNodeType = templatesHome.getNode(nodeTypeName); managedNodeType.remove(); templatesHome.save(); //Update managedDocumentTypeMap List<String> managedDocumentTypes = getManagedDocumentTypesMap(); managedDocumentTypes.remove(nodeTypeName); removeTemplateNodeTypeList(); // Add to edited predefined template node type list addEditedConfiguredNodeType(nodeTypeName); } /** * {@inheritDoc} */ public List<String> getDocumentTemplates() throws RepositoryException { List<String> templates = getManagedDocumentTypesMap(); if (templates != null) return new ArrayList<String>(templates); templates = getAllDocumentNodeTypes(); setManagedDocumentTypesMap(templates); return templates == null ? templates : new ArrayList<String>(templates); } /** * {@inheritDoc} */ public String getTemplatePathByAnonymous(boolean isDialog, String nodeTypeName) throws RepositoryException { String type = DIALOGS; if (!isDialog) type = VIEWS; Node homeNode = (Node) getSession(WCMCoreUtils.getSystemSessionProvider()).getItem(cmsTemplatesBasePath_); Node nodeTypeNode = homeNode.getNode(nodeTypeName); NodeIterator templateIter = nodeTypeNode.getNode(type).getNodes(); while (templateIter.hasNext()) { Node node = templateIter.nextNode(); String role = getTemplateRoles(node); if(hasPublicTemplate(role)) { String templatePath = node.getPath() ; return templatePath ; } } return null; } /** * {@inheritDoc} */ public void removeCacheTemplate(String name) throws Exception { try { templateService.reloadTemplate(name); } catch (IllegalArgumentException e) { return; } } /** * {@inheritDoc} */ public void removeAllTemplateCached() { templateService.reloadTemplates(); } @SuppressWarnings("unchecked") public List<String> getAllDocumentNodeTypes() throws PathNotFoundException, RepositoryException { List<String> nodeTypeList = (List<String>) nodeTypeListCached.get(NODETYPE_LIST); if(nodeTypeList != null && nodeTypeList.size() > 0) return nodeTypeList; List<String> contentTypes = new ArrayList<String>(); SessionProvider sessionProvider = SessionProvider.createSystemProvider(); try { Node templatesHome = (Node) getSession(sessionProvider).getItem(cmsTemplatesBasePath_); for (NodeIterator templateIter = templatesHome.getNodes(); templateIter.hasNext();) { Node template = templateIter.nextNode(); if (template.getProperty(DOCUMENT_TEMPLATE_PROP).getBoolean()) contentTypes.add(template.getName()); } nodeTypeListCached.put(NODETYPE_LIST, contentTypes); } finally { sessionProvider.close(); } return contentTypes; } /** * {@inheritDoc} */ public String getSkinPath(String nodeTypeName, String skinName, String locale) throws Exception { Node homeNode = (Node) getSession(WCMCoreUtils.getSystemSessionProvider()).getItem(cmsTemplatesBasePath_); Node nodeTypeNode = homeNode.getNode(nodeTypeName); Orientation orientation = getOrientation(locale); String skinPath = null; if(orientation.isLT()) { StringBuilder templateData = new StringBuilder("/**"); templateData.append("LTR stylesheet for "+nodeTypeNode.getName()+" template").append("*/"); skinPath = addNewSkinNode(homeNode, nodeTypeNode, skinName, "-lt", templateData.toString()); } else if(orientation.isRT()) { StringBuilder templateData = new StringBuilder("/**"); templateData.append("RTL stylesheet for "+nodeTypeNode.getName()+" template").append("*/"); skinPath = addNewSkinNode(homeNode, nodeTypeNode, skinName, "-rt", templateData.toString()); } return skinPath; } /** * {@inheritDoc} */ public String buildDialogForm(String nodeTypeName) throws Exception { if (plugins_ == null && plugins_.size() == 0) throw new Exception("Cannot find plugin for template"); TemplatePlugin templatePlugin = plugins_.get(0); ManageableRepository manageRepo = repositoryService_.getCurrentRepository(); NodeType nodeType = manageRepo.getNodeTypeManager().getNodeType(nodeTypeName); return templatePlugin.buildDialogForm(nodeType); } /** * {@inheritDoc} */ public String buildViewForm(String nodeTypeName) throws Exception { if (plugins_ == null && plugins_.size() == 0) throw new Exception("Cannot find plugin for template"); TemplatePlugin templatePlugin = plugins_.get(0); ManageableRepository manageRepo = repositoryService_.getCurrentRepository(); NodeType nodeType = manageRepo.getNodeTypeManager().getNodeType(nodeTypeName); return templatePlugin.buildViewForm(nodeType); } /** * {@inheritDoc} */ public String buildStyleSheet(String nodeTypeName) throws Exception { if (plugins_ == null && plugins_.size() == 0) throw new Exception("Cannot find plugin for template"); TemplatePlugin templatePlugin = plugins_.get(0); return templatePlugin.buildStyleSheet(null); } /** * Get template with the following specified params * @param session Session * @param templateType String * The value of template type * @param nodeTypeName String * The name of NodeType * @param templateName String * The name of template * @param repository String * The name of repository * @return * @throws Exception */ private Node getTemplateNode(String type, String nodeTypeName, String templateName) throws Exception { Node homeNode = (Node) getSession(WCMCoreUtils.getSystemSessionProvider()).getItem(cmsTemplatesBasePath_); Node nodeTypeNode = homeNode.getNode(nodeTypeName); return nodeTypeNode.getNode(type).getNode(templateName); } /** * Get content of the specified node * @param isDialog boolean * @param templatesHome Node * @param nodeTypeName String * The name of NodeType * @param label String * The label of template * @param isDocumentTemplate boolean * @param templateName String * The name of template * @see Node * @return * @throws Exception */ private String getContentNode(String templateType, Node templatesHome, String nodeTypeName, String label, boolean isDocumentTemplate, String templateName, String[] roles, InputStream templateFile) throws Exception { Node nodeTypeHome = null; if (!templatesHome.hasNode(nodeTypeName)) { nodeTypeHome = Utils.makePath(templatesHome, nodeTypeName, NT_UNSTRUCTURED); if (isDocumentTemplate) { nodeTypeHome.setProperty(DOCUMENT_TEMPLATE_PROP, true); } else nodeTypeHome.setProperty(DOCUMENT_TEMPLATE_PROP, false); nodeTypeHome.setProperty(TEMPLATE_LABEL, label); } else { nodeTypeHome = templatesHome.getNode(nodeTypeName); } Node specifiedTemplatesHome = null; try { specifiedTemplatesHome = nodeTypeHome.getNode(templateType); } catch(PathNotFoundException e) { specifiedTemplatesHome = Utils.makePath(nodeTypeHome, templateType, NT_UNSTRUCTURED); } String templatePath = null; if (specifiedTemplatesHome.hasNode(templateName)) { templatePath = specifiedTemplatesHome.getNode(templateName).getPath(); } else { templatePath = createTemplate(specifiedTemplatesHome, templateName, templateFile, roles); } templatesHome.save(); templatesHome.getSession().save(); return templatePath; } /** * Update document template * @param isDocumentTemplate boolean * @param nodeTypeName String * The name of NodeType * @throws RepositoryException * @see Node * @see NodeType */ private void updateDocumentsTemplate(boolean isDocumentTemplate, String nodeTypeName) throws RepositoryException{ if(isDocumentTemplate) { List<String> documentList = getManagedDocumentTypesMap(); if(documentList == null) { documentList = new ArrayList<String>(); documentList.add(nodeTypeName); setManagedDocumentTypesMap(documentList); } else { if(!documentList.contains(nodeTypeName)) { documentList.add(nodeTypeName); setManagedDocumentTypesMap(documentList); } } } } /** * Return session of the specified repository * @param provider SessionProvider * @return * @throws RepositoryException * @see SessionProvider * @see ManageableRepository * @see DMSRepositoryConfiguration * @throws Exception */ private Session getSession(SessionProvider provider) throws RepositoryException { ManageableRepository manageableRepository = repositoryService_.getCurrentRepository(); DMSRepositoryConfiguration dmsRepoConfig = dmsConfiguration_.getConfig(); return provider.getSession(dmsRepoConfig.getSystemWorkspace(), manageableRepository); } /** * Check permission of the user with roles * @param userId String * The specified user * @param roles Value[] * @param identityRegistry IdentityRegistry * @see MembershipEntry * @see IdentityRegistry * @return */ private boolean hasPermission(String userId, String roles, IdentityRegistry identityRegistry) { if(IdentityConstants.SYSTEM.equalsIgnoreCase(userId)) { return true ; } Identity identity = identityRegistry.getIdentity(userId) ; if(identity == null) { return false ; } String[] listRoles = roles.split(","); for (int i = 0; i < listRoles.length; i++) { String role = listRoles[i].trim(); if("*".equalsIgnoreCase(role)) return true ; MembershipEntry membershipEntry = MembershipEntry.parse(role) ; if(identity.isMemberOf(membershipEntry)) { return true ; } } return false ; } /** * Check public template with the roles * @param roles Value[] * @return */ private boolean hasPublicTemplate(String role) { String[] roles = role.split("; "); for (int i = 0; i < roles.length; i++) { if("*".equalsIgnoreCase(roles[i])) return true ; } return false ; } /** * Get orientation of current locate * @param locale String * The locale name which specified by user * @return * @throws Exception */ private Orientation getOrientation(String locale) throws Exception { return localeConfigService_.getLocaleConfig(locale).getOrientation(); } /** * Add new skin node if the locale specified is not existing * @param templatesHome * @param nodeTypeNode * @param skinName * @param orientation * @param templateData * @return * @throws Exception */ private String addNewSkinNode(Node templatesHome, Node nodeTypeNode, String skinName, String orientation, String templateData) throws Exception { String label = nodeTypeNode.getProperty(TEMPLATE_LABEL).getString(); return getContentNode(SKINS, templatesHome, nodeTypeNode.getName(), label, true, skinName + orientation, new String[] { "*" }, new ByteArrayInputStream(templateData.getBytes())); } private void removeTemplateNodeTypeList() throws Exception { nodeTypeListCached.clearCache(); } /** * {@inheritDoc} */ public String addTemplate(String templateType, String nodeTypeName, String label, boolean isDocumentTemplate, String templateName, String[] roles, InputStream templateFile) throws Exception { Session session = getSession(WCMCoreUtils.getSystemSessionProvider()); Node templatesHome = (Node) session.getItem(cmsTemplatesBasePath_); String templatePath = null; try { templatePath = templatesHome.getPath() + "/" + nodeTypeName + "/" + templateType + "/" + templateName; Node templateNode = (Node)session.getItem(templatePath); DocumentContext.getCurrent().getAttributes().put(DocumentContext.IS_SKIP_RAISE_ACT, true); updateTemplate(templateNode,templateFile, roles); session.save(); } catch(PathNotFoundException e) { DocumentContext.getCurrent().getAttributes().put(DocumentContext.IS_SKIP_RAISE_ACT, true); templatePath = getContentNode(templateType, templatesHome, nodeTypeName, label, isDocumentTemplate, templateName, roles, templateFile); } //Update managedDocumentTypesMap removeCacheTemplate(templatePath); removeTemplateNodeTypeList(); updateDocumentsTemplate(isDocumentTemplate, nodeTypeName); return templatePath; } /** * {@inheritDoc} */ public String addTemplate(String templateType, String nodeTypeName, String label, boolean isDocumentTemplate, String templateName, String[] roles, InputStream templateFile, Node templatesHome) throws Exception { String templatePath = null; try { templatePath = templatesHome.getPath() + "/" + nodeTypeName + "/" + templateType + "/" + templateName; Node templateNode = (Node)templatesHome.getSession().getItem(templatePath); updateTemplate(templateNode,templateFile, roles); templateNode.save(); } catch(PathNotFoundException e) { templatePath = getContentNode(templateType, templatesHome, nodeTypeName, label, isDocumentTemplate, templateName, roles, templateFile); } // Update managedDocumentTypesMap removeCacheTemplate(templatePath); removeTemplateNodeTypeList(); return templatePath; } /** * {@inheritDoc} */ @Deprecated public String createTemplate(Node templateFolder, String name, InputStream data, String[] roles) { return createTemplate(templateFolder, name, name, data, roles); } /** * {@inheritDoc} */ public String createTemplate(Node templateFolder, String title, String templateName, InputStream data, String[] roles) { try { Node contentNode = templateFolder.addNode(templateName, NodetypeConstant.NT_FILE); Node resourceNode = contentNode.addNode(NodetypeConstant.JCR_CONTENT, NodetypeConstant.EXO_RESOURCES); resourceNode.setProperty(NodetypeConstant.JCR_ENCODING, "UTF-8"); resourceNode.setProperty(NodetypeConstant.JCR_MIME_TYPE, "application/x-groovy+html"); resourceNode.setProperty(NodetypeConstant.JCR_LAST_MODIFIED, new GregorianCalendar()); resourceNode.setProperty(NodetypeConstant.JCR_DATA, data); if(!Arrays.equals(roles, getRoleNode(resourceNode))){ resourceNode.setProperty(NodetypeConstant.EXO_ROLES, roles); } if(!resourceNode.isNodeType(NodetypeConstant.DC_ELEMENT_SET)) { resourceNode.addMixin(NodetypeConstant.DC_ELEMENT_SET); } resourceNode.setProperty(NodetypeConstant.DC_TITLE, new String[] {title}); resourceNode.getSession().save(); return contentNode.getPath(); } catch (Exception e) { if (LOG.isErrorEnabled()) { LOG.error("An error has been occurred when adding template", e); } } return null; } /** * Get string array exo:roles of node * @param node * @return */ private String[] getRoleNode(Node node){ try { Value[] values = node.getProperty(NodetypeConstant.EXO_ROLES).getValues(); StringBuffer roles = new StringBuffer(); for (int i = 0; i < values.length; i++) { if (roles.length() > 0) roles.append(";"); roles.append(values[i].getString()); } return roles.toString().split(";"); }catch (RepositoryException re){ LOG.warn("Unable get role of node ", re); } return null; } /** * {@inheritDoc} */ public String updateTemplate(Node template, InputStream data, String[] roles) { try { Node resourceNode = template.getNode(NodetypeConstant.JCR_CONTENT); resourceNode.setProperty(NodetypeConstant.EXO_ROLES, roles); resourceNode.setProperty(NodetypeConstant.JCR_LAST_MODIFIED, new GregorianCalendar()); resourceNode.setProperty(NodetypeConstant.JCR_DATA, data); resourceNode.getSession().save(); // Add to edited predefined node type list addEditedConfiguredNodeType(template.getParent().getParent().getName()); return template.getPath(); } catch (Exception e) { if (LOG.isErrorEnabled()) { LOG.error("An error has been occurred when updating template", e); } } return null; } /** * {@inheritDoc} */ public String getTemplate(Node template) { Node resourceNode; try { resourceNode = template.getNode(NodetypeConstant.JCR_CONTENT); return resourceNode.getProperty(NodetypeConstant.JCR_DATA).getString(); } catch (ValueFormatException e) { if (LOG.isErrorEnabled()) { LOG.error("Wrong Value format ", e); } } catch (PathNotFoundException e) { if (LOG.isErrorEnabled()) { LOG.error("Can not found the template because of: ", e); } } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error("Repository failed ", e); } } return null; } /** * {@inheritDoc} */ public String getTemplateRoles(Node template) { try { Value[] values = template.getNode("jcr:content").getProperty(NodetypeConstant.EXO_ROLES).getValues(); StringBuffer roles = new StringBuffer(); for (int i = 0; i < values.length; i++) { if (roles.length() > 0) roles.append("; "); roles.append(values[i].getString()); } return roles.toString(); } catch (Exception e) { if (LOG.isErrorEnabled()) { LOG.error("An error has been occurred when getting template's roles", e); } } return null; } private String getRepoName() throws RepositoryException{ String repositoryName = repositoryService_.getCurrentRepository().getConfiguration().getName(); return repositoryName; } private List<String> getManagedDocumentTypesMap() throws RepositoryException{ return managedDocumentTypesMap.get(getRepoName()); } private void setManagedDocumentTypesMap(List<String> types) throws RepositoryException{ managedDocumentTypesMap.put(getRepoName(), types); } public Set<String> getAllConfiguredNodeTypes() { return configuredNodeTypes; } public Set<String> getAllEditedConfiguredNodeTypes() throws Exception { return Utils.getAllEditedConfiguredData(this.getClass().getSimpleName(), EDITED_CONFIGURED_NODE_TYPES, true); } private void addEditedConfiguredNodeType(String nodeType) throws Exception { Utils.addEditedConfiguredData(nodeType, this.getClass().getSimpleName(), EDITED_CONFIGURED_NODE_TYPES, true); } /** * Check if node's nodetype or its supper type has managed template type and return the template type. * * @param node * @return managed template type. Null value mean not exist template * @throws Exception */ private String getManagedTemplateType(Node node) throws Exception { // Check if the node type is document type first List<String> managedDocumentTypes = getManagedDocumentTypesMap(); for (String documentType : managedDocumentTypes) { if (node.getPrimaryNodeType().isNodeType(documentType)) { return documentType; } } // Check if node's nodetype or its supper type has managed template type SessionProvider provider = WCMCoreUtils.getSystemSessionProvider(); Session session = getSession(provider); Node systemTemplatesHome = (Node) session.getItem(cmsTemplatesBasePath_); NodeIterator templatesIter = systemTemplatesHome.getNodes(); while(templatesIter.hasNext()) { String templateName = templatesIter.nextNode().getName(); if (node.getPrimaryNodeType().isNodeType(templateName)) { return templateName; } } return null; } }