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"); 220 if (site.hasValue(parameter.getName())) 221 { 222 sb.append(" with value '"); 223 try 224 { 225 sb.append(parameter.getType().toString(value)); 226 } 227 catch (Exception e) 228 { 229 sb.append(value.toString()); 230 } 231 sb.append("'"); 232 } 233 else 234 { 235 sb.append(" with empty value"); 236 } 237 sb.append(":"); 238 239 for (I18nizableText error : errors) 240 { 241 sb.append("\n* " + error.toString()); 242 } 243 244 sb.append("\nConfiguration is not initialized"); 245 246 getLogger().warn(sb.toString()); 247 } 248 249 return false; 250 } 251 252 return true; 253 } 254 255 /** 256 * Retrieves the parameters of the given site 257 * @param siteName the name of the site 258 * @return the site's parameters 259 */ 260 public Collection<ElementDefinition> getSiteParameters(String siteName) 261 { 262 Site site = _siteManager.getSite(siteName); 263 return getSiteParameters(site); 264 } 265 266 /** 267 * Retrieves the parameters of the given site 268 * @param site the site 269 * @return the site's parameters 270 */ 271 public Collection<ElementDefinition> getSiteParameters(Site site) 272 { 273 SiteType siteType = _siteTypesExtensionPoint.getExtension(site.getType()); 274 return siteType.getModelItems(); 275 } 276 277 /** 278 * Retrieves the parameter of the given site with the given name 279 * @param siteName the name of the site 280 * @param parameterName the name of the parameter to retrieve 281 * @return the site's parameter 282 * @throws UndefinedItemPathException if there is no site parameter defined with the given name 283 */ 284 public ElementDefinition getSiteParameter(String siteName, String parameterName) throws UndefinedItemPathException 285 { 286 Site site = _siteManager.getSite(siteName); 287 return getSiteParameter(site, parameterName); 288 } 289 290 /** 291 * Retrieves the parameter of the given site with the given name 292 * @param site the site 293 * @param parameterName the name of the parameter to retrieve 294 * @return the site's parameter 295 * @throws UndefinedItemPathException if there is no site parameter defined with the given name 296 */ 297 public ElementDefinition getSiteParameter(Site site, String parameterName) throws UndefinedItemPathException 298 { 299 SiteType siteType = _siteTypesExtensionPoint.getExtension(site.getType()); 300 return siteType.getModelItem(parameterName); 301 } 302 303 /** 304 * Retrieves the view of the site with the given name 305 * @param siteName the name of the site 306 * @return the site's view 307 */ 308 public View getSiteView(String siteName) 309 { 310 Site site = _siteManager.getSite(siteName); 311 return getSiteView(site); 312 } 313 314 /** 315 * Retrieves the view of the site with the given name 316 * @param site the site 317 * @return the site's view 318 */ 319 public View getSiteView(Site site) 320 { 321 SiteType siteType = _siteTypesExtensionPoint.getExtension(site.getType()); 322 return siteType.getView(); 323 } 324}