001/* 002 * Copyright 2015 Anyware Services 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 */ 016package org.ametys.plugins.contentstree; 017 018import java.io.InputStream; 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.HashSet; 022import java.util.Set; 023 024import org.apache.avalon.framework.configuration.Configurable; 025import org.apache.avalon.framework.configuration.Configuration; 026import org.apache.avalon.framework.configuration.ConfigurationException; 027import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.avalon.framework.service.Serviceable; 031import org.apache.commons.lang3.StringUtils; 032import org.apache.excalibur.source.Source; 033import org.apache.excalibur.source.SourceResolver; 034 035import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 036import org.ametys.runtime.plugin.component.PluginAware; 037 038/** 039 * Static implementation based on configuration. See doc for template. 040 */ 041public class StaticTreeConfiguration implements TreeConfiguration, Configurable, Serviceable, PluginAware 042{ 043 /** The ui tool role */ 044 protected String _uiToolRole; 045 /** The collection of elements */ 046 protected Set<TreeConfigurationElements> _elements; 047 /** The content type extension point */ 048 protected ContentTypeExtensionPoint _contentTypesEP; 049 /** The excalibur source resolver */ 050 protected SourceResolver _sourceResolver; 051 /** The plugin name */ 052 protected String _pluginName; 053 /** The extension id */ 054 protected String _id; 055 056 private Configuration _configuration; 057 058 @Override 059 public String getId() 060 { 061 return _id; 062 } 063 064 @Override 065 public void setPluginInfo(String pluginName, String featureName, String id) 066 { 067 _pluginName = pluginName; 068 } 069 070 @Override 071 public void service(ServiceManager manager) throws ServiceException 072 { 073 _contentTypesEP = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 074 _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 075 } 076 077 @Override 078 public void configure(Configuration initialConfiguration) throws ConfigurationException 079 { 080 _id = initialConfiguration.getAttribute("id"); 081 082 _configuration = _getDeportedConfiguration(initialConfiguration); 083 } 084 085 private void _lazyConfigure() 086 { 087 if (_configuration != null) 088 { 089 try 090 { 091 _uiToolRole = _configuration.getAttribute("id"); 092 _elements = new HashSet<>(); 093 094 for (Configuration contentTypeConfiguration : _configuration.getChild("elements").getChildren("content-type")) 095 { 096 Collection<TreeConfigurationContentType> contentTypesInfo = getContentTypesInfos(contentTypeConfiguration.getChild("ids")); 097 Collection<TreeConfigurationElementsChild> childNodes = getChildNodes(contentTypeConfiguration.getChild("children")); 098 099 TreeConfigurationElements element = new TreeConfigurationElements(contentTypesInfo, childNodes); 100 _elements.add(element); 101 } 102 103 _configuration = null; 104 } 105 catch (ConfigurationException e) 106 { 107 throw new IllegalStateException("An error occured while configuring tree '" + _id + "'", e); 108 } 109 } 110 } 111 112 private Configuration _getDeportedConfiguration(Configuration initialConfiguration) throws ConfigurationException 113 { 114 String treeConfigURL = initialConfiguration.getChild("tree-config").getValue(); 115 Source treeConfigSource = null; 116 try 117 { 118 treeConfigSource = _sourceResolver.resolveURI(treeConfigURL, "plugin:" + _pluginName + "://", null); 119 120 try (InputStream is = treeConfigSource.getInputStream()) 121 { 122 return new DefaultConfigurationBuilder().build(is); 123 } 124 } 125 catch (Exception e) 126 { 127 throw new ConfigurationException("Cannot open the file '" + treeConfigURL + "'", initialConfiguration, e); 128 } 129 finally 130 { 131 _sourceResolver.release(treeConfigSource); 132 } 133 } 134 135 /** 136 * Get the child nodes 137 * @param configuration The configuration 138 * @return the child nodes 139 * @throws ConfigurationException if configuration is invalid 140 */ 141 protected Collection<TreeConfigurationElementsChild> getChildNodes(Configuration configuration) throws ConfigurationException 142 { 143 Collection<TreeConfigurationElementsChild> childnodes = new ArrayList<>(); 144 145 for (Configuration childConfiguration : configuration.getChildren()) 146 { 147 if (StringUtils.equals(childConfiguration.getName(), "metadata")) 148 { 149 String id = childConfiguration.getAttribute("id"); 150 151 TreeConfigurationElementsChild child = new AttributeTreeConfigurationElementsChild(id); 152 childnodes.add(child); 153 } 154 else 155 { 156 throw new ConfigurationException("Unknown child of type '" + childConfiguration.getName() + "'", childConfiguration); 157 } 158 } 159 160 return childnodes; 161 } 162 163 /** 164 * Get the contents infos using a configuration 165 * @param configuration the configuration 166 * @return the contents infos using a configuration 167 * @throws ConfigurationException if an error occurred 168 */ 169 protected Collection<TreeConfigurationContentType> getContentTypesInfos(Configuration configuration) throws ConfigurationException 170 { 171 Collection<TreeConfigurationContentType> contentTypesInfo = new ArrayList<>(); 172 173 boolean elementsCanBeRoot = configuration.getAttributeAsBoolean("can-be-root", false); 174 boolean elementsAutoExpandTarget = configuration.getAttributeAsBoolean("auto-expand-target", false); 175 boolean elementsInherit = configuration.getAttributeAsBoolean("inherit", false); 176 String elementsBusMessageType = configuration.getAttribute("bus-message-type", "content"); 177 178 for (Configuration idConfiguration : configuration.getChildren("id")) 179 { 180 TreeConfigurationContentType contentTypeInfo = getContentTypeInfo(idConfiguration, elementsCanBeRoot, elementsAutoExpandTarget, elementsInherit, elementsBusMessageType); 181 contentTypesInfo.add(contentTypeInfo); 182 } 183 184 return contentTypesInfo; 185 } 186 187 /** 188 * Get the content info using a configuration 189 * @param configuration The configuration 190 * @param defaultCanBeRoot default value for root property 191 * @param defaultAutoExpandToIt default value for autoExpandToIt property 192 * @param defaultInherit default value for inherit property 193 * @param defaultBusMessageType default type of message 194 * @return the content info using a configuration 195 * @throws ConfigurationException if the configuration is invalid 196 */ 197 protected TreeConfigurationContentType getContentTypeInfo(Configuration configuration, boolean defaultCanBeRoot, boolean defaultAutoExpandToIt, boolean defaultInherit, String defaultBusMessageType) throws ConfigurationException 198 { 199 boolean canBeRoot = configuration.getAttributeAsBoolean("can-be-root", defaultCanBeRoot); 200 boolean autoExpandToIt = configuration.getAttributeAsBoolean("auto-expand-to-it", defaultAutoExpandToIt); 201 String mainContentTypeId = configuration.getValue(); 202 203 Collection<String> typesIds = new ArrayList<>(); 204 typesIds.add(mainContentTypeId); 205 206 boolean inherit = configuration.getAttributeAsBoolean("inherit", defaultInherit); 207 if (inherit) 208 { 209 typesIds.addAll(_contentTypesEP.getSubTypes(mainContentTypeId)); 210 } 211 212 String busMessageType = configuration.getAttribute("bus-message-type", defaultBusMessageType); 213 214 return new TreeConfigurationContentType(canBeRoot, autoExpandToIt, typesIds, busMessageType); 215 } 216 217 @Override 218 public String getUIToolRole() 219 { 220 _lazyConfigure(); 221 return _uiToolRole; 222 } 223 224 @Override 225 public Set<TreeConfigurationElements> getElements() 226 { 227 _lazyConfigure(); 228 return _elements; 229 } 230}