001/* 002 * Copyright 2022 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.cms.model.properties; 017 018import org.apache.avalon.framework.configuration.Configurable; 019import org.apache.avalon.framework.configuration.Configuration; 020import org.apache.avalon.framework.configuration.ConfigurationException; 021import org.apache.avalon.framework.context.Context; 022import org.apache.avalon.framework.context.ContextException; 023import org.apache.avalon.framework.context.Contextualizable; 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.avalon.framework.service.Serviceable; 027 028import org.ametys.cms.data.ametysobject.ModelAwareDataAwareAmetysObject; 029import org.ametys.runtime.i18n.I18nizableText; 030import org.ametys.runtime.model.Enumerator; 031import org.ametys.runtime.model.ItemParserHelper; 032import org.ametys.runtime.model.ItemParserHelper.ConfigurationAndPluginName; 033import org.ametys.runtime.model.StaticEnumerator; 034import org.ametys.runtime.plugin.component.ThreadSafeComponentManager; 035 036/** 037 * Abstract class for single property 038 * @param <T> type of the property values 039 * @param <X> type of ametys object supported by this property 040 */ 041public abstract class AbstractStaticProperty<T, X extends ModelAwareDataAwareAmetysObject> extends AbstractProperty<T, X> implements Configurable, Serviceable, Contextualizable 042{ 043 /** The avalon context */ 044 protected Context _context; 045 046 public void service(ServiceManager manager) throws ServiceException 047 { 048 setServiceManager(manager); 049 } 050 051 public void contextualize(Context context) throws ContextException 052 { 053 _context = context; 054 } 055 056 public void configure(Configuration configuration) throws ConfigurationException 057 { 058 setName(_parseName(configuration)); 059 setLabel(_parseLabel(configuration)); 060 setDescription(_parseDescription(configuration)); 061 _parseAndSetEnumerator(configuration, getPluginName()); 062 setMultiple(configuration.getAttributeAsBoolean("multiple", false)); 063 } 064 065 /** 066 * Parses the name of the property 067 * @param configuration the property configuration to use. 068 * @return the name of the property. 069 * @throws ConfigurationException if the configuration is not valid. 070 */ 071 protected String _parseName(Configuration configuration) throws ConfigurationException 072 { 073 return ItemParserHelper.parseName(configuration, _getNameConfigurationAttribute()); 074 } 075 076 /** 077 * Retrieves the name of the configuration attribute that contains the name of the property 078 * @return the name of the configuration attribute that contains the name of the property 079 */ 080 protected String _getNameConfigurationAttribute() 081 { 082 return "name"; 083 } 084 085 /** 086 * Parses the label of the property 087 * @param configuration the property configuration to use. 088 * @return the label of the property. 089 * @throws ConfigurationException if the configuration is not valid. 090 */ 091 protected I18nizableText _parseLabel(Configuration configuration) throws ConfigurationException 092 { 093 return ItemParserHelper.parseI18nizableText(new ConfigurationAndPluginName(configuration, getPluginName()), "label", getName()); 094 } 095 096 /** 097 * Parses the description of the property 098 * @param configuration the property configuration to use. 099 * @return the description of the property. 100 * @throws ConfigurationException if the configuration is not valid. 101 */ 102 protected I18nizableText _parseDescription(Configuration configuration) throws ConfigurationException 103 { 104 return ItemParserHelper.parseI18nizableText(new ConfigurationAndPluginName(configuration, getPluginName()), "description"); 105 } 106 107 /** 108 * Parse the configuration to set the enumerator. 109 * @param configuration The configuration of the property 110 * @param pluginName The plugin name 111 * @throws ConfigurationException if an error occurs 112 */ 113 protected void _parseAndSetEnumerator(Configuration configuration, String pluginName) throws ConfigurationException 114 { 115 ThreadSafeComponentManager<Enumerator> enumeratorManager = new ThreadSafeComponentManager<>(); 116 try 117 { 118 enumeratorManager.setLogger(_logger); 119 enumeratorManager.contextualize(_context); 120 enumeratorManager.service(__serviceManager); 121 122 123 Configuration enumeratorConfig = configuration.getChild("enumeration", false); 124 if (enumeratorConfig != null) 125 { 126 Configuration customEnumerator = enumeratorConfig.getChild("custom-enumerator", false); 127 if (customEnumerator != null) 128 { 129 String enumeratorClassName = customEnumerator.getAttribute("class"); 130 String role = "enumerator"; 131 132 try 133 { 134 @SuppressWarnings("unchecked") 135 Class<Enumerator<T>> enumeratorClass = (Class<Enumerator<T>>) Class.forName(enumeratorClassName); 136 enumeratorManager.addComponent(pluginName, null, role, enumeratorClass, configuration); 137 } 138 catch (Exception e) 139 { 140 throw new ConfigurationException("Unable to instantiate enumerator for class: " + enumeratorClassName, e); 141 } 142 143 enumeratorManager.initialize(); 144 setEnumerator(enumeratorManager.lookup(role)); 145 146 // Add the custom enumerator information to the element definition 147 setCustomEnumerator(enumeratorClassName); 148 setEnumeratorConfiguration(customEnumerator); 149 } 150 else 151 { 152 StaticEnumerator<T> staticEnumerator = new StaticEnumerator<>(); 153 154 for (Configuration entryConfig : enumeratorConfig.getChildren("entry")) 155 { 156 Configuration valueConfiguration = entryConfig.getChild("value"); 157 T value = getType().parseConfiguration(valueConfiguration); 158 I18nizableText label = ItemParserHelper.parseI18nizableText(new ConfigurationAndPluginName(entryConfig, pluginName), "label", (I18nizableText) null); 159 staticEnumerator.add(label, value); 160 } 161 162 setEnumerator(staticEnumerator); 163 } 164 } 165 } 166 catch (Exception e) 167 { 168 throw new ConfigurationException("An error occured while configuring the enumerator of the property " + getName(), e); 169 } 170 finally 171 { 172 enumeratorManager.dispose(); 173 } 174 } 175}