001/* 002 * Copyright 2019 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.web.site; 017 018import java.util.Collection; 019import java.util.HashMap; 020import java.util.Iterator; 021import java.util.List; 022import java.util.Map; 023 024import org.apache.avalon.framework.activity.Disposable; 025import org.apache.avalon.framework.activity.Initializable; 026import org.apache.avalon.framework.component.Component; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030 031import org.ametys.plugins.repository.UnknownAmetysObjectException; 032import org.ametys.runtime.i18n.I18nizableText; 033import org.ametys.runtime.model.ElementDefinition; 034import org.ametys.runtime.model.ModelHelper; 035import org.ametys.runtime.model.View; 036import org.ametys.runtime.model.exception.UndefinedItemPathException; 037import org.ametys.runtime.plugin.component.AbstractLogEnabled; 038import org.ametys.web.repository.site.Site; 039import org.ametys.web.repository.site.SiteManager; 040import org.ametys.web.repository.site.SiteType; 041import org.ametys.web.repository.site.SiteTypesExtensionPoint; 042 043/** 044 * Helper component for managing sites configuration. 045 */ 046public class SiteConfigurationManager extends AbstractLogEnabled implements Component, Serviceable, Initializable, Disposable 047{ 048 /** Avalon Role */ 049 public static final String ROLE = SiteConfigurationManager.class.getName(); 050 051 /** The site manager. */ 052 protected SiteManager _siteManager; 053 /** The site type extension point. */ 054 protected SiteTypesExtensionPoint _siteTypesExtensionPoint; 055 056 /** Determines if all parameters are valued, by site. */ 057 protected Map<String, Boolean> _areSiteComplete; 058 059 public void service(ServiceManager manager) throws ServiceException 060 { 061 _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); 062 _siteTypesExtensionPoint = (SiteTypesExtensionPoint) manager.lookup(SiteTypesExtensionPoint.ROLE); 063 } 064 065 public void initialize() throws Exception 066 { 067 _areSiteComplete = new HashMap<>(); 068 } 069 070 public void dispose() 071 { 072 _areSiteComplete = new HashMap<>(); 073 } 074 075 /** 076 * Reload a site's configuration. 077 * @param siteName the site name. 078 * @throws UnknownAmetysObjectException if the site doesn't exist. 079 */ 080 public void reloadSiteConfiguration(String siteName) throws UnknownAmetysObjectException 081 { 082 // Check if the site exists. 083 Site site = _siteManager.getSite(siteName); 084 085 // Reload the site configuration. 086 reloadSiteConfiguration(site); 087 } 088 089 /** 090 * Reload a site's configuration. 091 * @param site the site. 092 * @throws UnknownAmetysObjectException if the site doesn't exist. 093 */ 094 public void reloadSiteConfiguration(Site site) throws UnknownAmetysObjectException 095 { 096 // Reload the site configuration. 097 _areSiteComplete.put(site.getName(), _isSiteConfigurationValid(site)); 098 } 099 100 /** 101 * Remove a site's configuration. 102 * @param site the site. 103 */ 104 public void removeSiteConfiguration(Site site) 105 { 106 removeSiteConfiguration(site.getName()); 107 } 108 109 /** 110 * Remove a site's configuration. 111 * @param siteName the site name. 112 */ 113 public void removeSiteConfiguration(String siteName) 114 { 115 if (_areSiteComplete.containsKey(siteName)) 116 { 117 _areSiteComplete.remove(siteName); 118 } 119 } 120 121 /** 122 * Validate the configuration of the given site. 123 * @param siteName the name of the site to check. 124 * @return <code>true</code> if the site is correctly configured, <code>false</code> otherwise. 125 * @throws UnknownAmetysObjectException if the site doesn't exist. 126 */ 127 public boolean isSiteConfigurationValid(String siteName) throws UnknownAmetysObjectException 128 { 129 if (siteName == null) 130 { 131 throw new IllegalArgumentException("Cannot determine if a null siteName is valid or not"); 132 } 133 134 // Check if the site exists. 135 if (!_siteManager.hasSite(siteName)) 136 { 137 throw new UnknownAmetysObjectException ("Unknown site '" + siteName + "'. Can not check configuration."); 138 } 139 140 // Validate the site configuration now if it's not already done. 141 Site site = _siteManager.getSite(siteName); 142 return isSiteConfigurationValid(site); 143 } 144 145 /** 146 * Validate the configuration of the given site. 147 * @param site the site to check. 148 * @return <code>true</code> if the site is correctly configured, <code>false</code> otherwise. 149 * @throws UnknownAmetysObjectException if the site doesn't exist. 150 */ 151 public boolean isSiteConfigurationValid(Site site) throws UnknownAmetysObjectException 152 { 153 if (site == null) 154 { 155 throw new IllegalArgumentException("Cannot determine if a null site is valid or not"); 156 } 157 158 // Validate the site configuration now if it's not already done. 159 if (!_areSiteComplete.containsKey(site.getName())) 160 { 161 _areSiteComplete.put(site.getName(), _isSiteConfigurationValid(site)); 162 } 163 164 return _areSiteComplete.get(site.getName()); 165 } 166 167 /** 168 * Validate the configuration of the given site. 169 * @param site the site to check. 170 * @return <code>true</code> if the site is correctly configured, <code>false</code> otherwise. 171 */ 172 protected boolean _isSiteConfigurationValid(Site site) 173 { 174 if (getLogger().isDebugEnabled()) 175 { 176 getLogger().debug("Validating the configuration of site '" + site + "'"); 177 } 178 179 SiteType siteType = _siteTypesExtensionPoint.getExtension(site.getType()); 180 if (siteType == null) 181 { 182 getLogger().error("Site " + site.getName() + " has the unknown type '" + site.getType() + "'"); 183 return false; 184 } 185 186 boolean areParametersValid = true; 187 188 Iterator<ElementDefinition> definitionsIterator = siteType.getModelItems().iterator(); 189 while (definitionsIterator.hasNext() && areParametersValid) 190 { 191 ElementDefinition item = definitionsIterator.next(); 192 areParametersValid = _isValidSiteParameter(item, site); 193 } 194 195 return areParametersValid; 196 } 197 198 /** 199 * Validate the the given site parameter 200 * @param parameter the site parameter to validate. 201 * @param site the site 202 * @return true if the parameter's value is valid, false otherwise. 203 */ 204 protected boolean _isValidSiteParameter(ElementDefinition parameter, Site site) 205 { 206 // TODO RUNTIME-2897: call the validateValue without boolean when multiple values are managed in enumerators 207 Object value = site.getValue(parameter.getName(), true, null); 208 List<I18nizableText> errors = ModelHelper.validateValue(parameter, value, false); 209 if (!errors.isEmpty()) 210 { 211 if (getLogger().isWarnEnabled()) 212 { 213 StringBuffer sb = new StringBuffer(); 214 215 sb.append("The parameter '") 216 .append(parameter.getPath()) 217 .append("' of site '") 218 .append(site.getName()) 219 .append("' is not valid with value '") 220 .append(parameter.getType().toString(value)) 221 .append("':"); 222 223 for (I18nizableText error : errors) 224 { 225 sb.append("\n* " + error.toString()); 226 } 227 228 sb.append("\nConfiguration is not initialized"); 229 230 getLogger().warn(sb.toString()); 231 } 232 233 return false; 234 } 235 236 return true; 237 } 238 239 /** 240 * Retrieves the parameters of the given site 241 * @param siteName the name of the site 242 * @return the site's parameters 243 */ 244 public Collection<ElementDefinition> getSiteParameters(String siteName) 245 { 246 Site site = _siteManager.getSite(siteName); 247 return getSiteParameters(site); 248 } 249 250 /** 251 * Retrieves the parameters of the given site 252 * @param site the site 253 * @return the site's parameters 254 */ 255 public Collection<ElementDefinition> getSiteParameters(Site site) 256 { 257 SiteType siteType = _siteTypesExtensionPoint.getExtension(site.getType()); 258 return siteType.getModelItems(); 259 } 260 261 /** 262 * Retrieves the parameter of the given site with the given name 263 * @param siteName the name of the site 264 * @param parameterName the name of the parameter to retrieve 265 * @return the site's parameter 266 * @throws UndefinedItemPathException if there is no site parameter defined with the given name 267 */ 268 public ElementDefinition getSiteParameter(String siteName, String parameterName) throws UndefinedItemPathException 269 { 270 Site site = _siteManager.getSite(siteName); 271 return getSiteParameter(site, parameterName); 272 } 273 274 /** 275 * Retrieves the parameter of the given site with the given name 276 * @param site the site 277 * @param parameterName the name of the parameter to retrieve 278 * @return the site's parameter 279 * @throws UndefinedItemPathException if there is no site parameter defined with the given name 280 */ 281 public ElementDefinition getSiteParameter(Site site, String parameterName) throws UndefinedItemPathException 282 { 283 SiteType siteType = _siteTypesExtensionPoint.getExtension(site.getType()); 284 return siteType.getModelItem(parameterName); 285 } 286 287 /** 288 * Retrieves the view of the site with the given name 289 * @param siteName the name of the site 290 * @return the site's view 291 */ 292 public View getSiteView(String siteName) 293 { 294 Site site = _siteManager.getSite(siteName); 295 return getSiteView(site); 296 } 297 298 /** 299 * Retrieves the view of the site with the given name 300 * @param site the site 301 * @return the site's view 302 */ 303 public View getSiteView(Site site) 304 { 305 SiteType siteType = _siteTypesExtensionPoint.getExtension(site.getType()); 306 return siteType.getView(); 307 } 308}