001/* 002 * Copyright 2010 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.skin; 017 018import java.io.File; 019import java.io.FileInputStream; 020import java.io.InputStream; 021import java.util.Date; 022import java.util.LinkedHashMap; 023import java.util.Map; 024 025import org.apache.avalon.framework.configuration.Configuration; 026import org.apache.avalon.framework.configuration.ConfigurationException; 027import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031import org.ametys.runtime.i18n.I18nizableText; 032 033/** 034 * Represent a skin template. 035 */ 036public class SkinTemplate 037{ 038 private static Logger _logger = LoggerFactory.getLogger(SkinTemplate.class); 039 040 /** The skin id */ 041 protected String _skinId; 042 /** Template id (e.g. the directory name) */ 043 protected String _id; 044 /** The template directory */ 045 protected File _file; 046 /** Template label */ 047 protected I18nizableText _label; 048 /** Template description */ 049 protected I18nizableText _description; 050 /** Template thumbnail 16px */ 051 protected String _smallImage; 052 /** Template thumbnail 32px */ 053 protected String _mediumImage; 054 /** Template thumbnail 48px */ 055 protected String _largeImage; 056 /** Template zones. the key is the zone id */ 057 protected Map<String, SkinTemplateZone> _zones; 058 059 /** The last time the file was loaded */ 060 protected long _lastConfUpdate; 061 062 /** 063 * Creates a template 064 * @param skinId The skin id 065 * @param templateId The template id 066 * @param file The template file 067 */ 068 public SkinTemplate(String skinId, String templateId, File file) 069 { 070 this._skinId = skinId; 071 this._id = templateId; 072 this._file = file; 073 } 074 075 /** 076 * The configuration default values (if configuration file does not exist or is unreadable) 077 */ 078 protected void _defaultValues() 079 { 080 _lastConfUpdate = new Date().getTime(); 081 082 this._label = new I18nizableText(this._id); 083 this._description = new I18nizableText(""); 084 this._smallImage = "/plugins/web/resources/img/skin/template_16.png"; 085 this._mediumImage = "/plugins/web/resources/img/skin/template_32.png"; 086 this._largeImage = "/plugins/web/resources/img/skin/template_48.png"; 087 this._zones = new LinkedHashMap<>(); 088 } 089 090 /** 091 * Refresh the conf values 092 */ 093 public void refreshValues() 094 { 095 File configurationFile = null; 096 try 097 { 098 configurationFile = new File (_file, "/template.xml"); 099 if (configurationFile.exists()) 100 { 101 if (_lastConfUpdate < configurationFile.lastModified()) 102 { 103 _defaultValues(); 104 105 _lastConfUpdate = configurationFile.lastModified(); 106 try (InputStream is = new FileInputStream(configurationFile)) 107 { 108 Configuration configuration = new DefaultConfigurationBuilder().build(is); 109 110 this._label = _configureI18n(configuration.getChild("label", false), this._label); 111 this._description = _configureI18n(configuration.getChild("description", false), this._description); 112 this._smallImage = _configureThumbnail(configuration.getChild("thumbnail").getChild("small").getValue(null), this._smallImage); 113 this._mediumImage = _configureThumbnail(configuration.getChild("thumbnail").getChild("medium").getValue(null), this._mediumImage); 114 this._largeImage = _configureThumbnail(configuration.getChild("thumbnail").getChild("marge").getValue(null), this._largeImage); 115 116 this._zones = new LinkedHashMap<>(); 117 for (Configuration zoneConfiguration : configuration.getChild("zones").getChildren("zone")) 118 { 119 String zoneId = zoneConfiguration.getAttribute("id"); 120 String zoneType = zoneConfiguration.getAttribute("type", SkinTemplateZone.TYPE_PRIMARY); 121 I18nizableText label = _configureI18n(zoneConfiguration.getChild("label", false), new I18nizableText(zoneId)); 122 I18nizableText description = _configureI18n(zoneConfiguration.getChild("description", false), new I18nizableText(zoneId)); 123 String smallImage = _configureThumbnail(zoneConfiguration.getChild("thumbnail").getChild("small").getValue(null), "/plugins/web/resources/img/skin/zone_16.png"); 124 String mediumImage = _configureThumbnail(zoneConfiguration.getChild("thumbnail").getChild("medium").getValue(null), "/plugins/web/resources/img/skin/zone_32.png"); 125 String largeImage = _configureThumbnail(zoneConfiguration.getChild("thumbnail").getChild("marge").getValue(null), "/plugins/web/resources/img/skin/zone_48.png"); 126 127 String inheritanceString = zoneConfiguration.getAttribute("inherit", null); 128 129 SkinTemplateZone zone = new SkinTemplateZone(this._skinId, this._id, zoneId, zoneType, label, description, smallImage, mediumImage, largeImage, inheritanceString); 130 _zones.put(zoneId, zone); 131 } 132 } 133 } 134 } 135 else 136 { 137 _defaultValues(); 138 } 139 } 140 catch (Exception e) 141 { 142 _defaultValues(); 143 if (_logger.isWarnEnabled()) 144 { 145 _logger.warn("Cannot read the configuration file templates/" + this._id + "/template.xml for the skin '" + this._id + "'. Continue as if file was not existing", e); 146 } 147 } 148 } 149 150 private String _configureThumbnail(String value, String defaultImage) 151 { 152 if (value == null) 153 { 154 return defaultImage; 155 } 156 else 157 { 158 return "/skins/" + this._skinId + "/templates/" + this._id + "/resources/" + value; 159 } 160 } 161 162 private I18nizableText _configureI18n(Configuration child, I18nizableText defaultValue) throws ConfigurationException 163 { 164 if (child != null) 165 { 166 String value = child.getValue(); 167 if (child.getAttributeAsBoolean("i18n", false)) 168 { 169 return new I18nizableText("skin." + this._skinId, value); 170 } 171 else 172 { 173 return new I18nizableText(value); 174 } 175 } 176 else 177 { 178 return defaultValue; 179 } 180 } 181 182 /** 183 * The template id 184 * @return the id 185 */ 186 public String getId() 187 { 188 return _id; 189 } 190 191 /** 192 * The template label 193 * @return The label 194 */ 195 public I18nizableText getLabel() 196 { 197 return _label; 198 } 199 /** 200 * The template description 201 * @return The description. Can not be null but can be empty 202 */ 203 public I18nizableText getDescription() 204 { 205 return _description; 206 } 207 208 /** 209 * The small image file uri 210 * @return The small image file uri 211 */ 212 public String getSmallImage() 213 { 214 return _smallImage; 215 } 216 217 /** 218 * The medium image file uri 219 * @return The medium image file uri 220 */ 221 public String getMediumImage() 222 { 223 return _mediumImage; 224 } 225 226 /** 227 * The large image file uri 228 * @return The large image file uri 229 */ 230 public String getLargeImage() 231 { 232 return _largeImage; 233 } 234 235 /** 236 * The zones defined in by the template def 237 * @return The zones 238 */ 239 public Map<String, SkinTemplateZone> getZones() 240 { 241 return _zones; 242 } 243 244 /** 245 * The zone identifier by its id 246 * @param zoneId The id of the zone definition to get 247 * @return The zone or null if no zone has this name 248 */ 249 public SkinTemplateZone getZone(String zoneId) 250 { 251 return _zones.get(zoneId); 252 } 253 254 /** 255 * Get the template's file directory 256 * @return the template's file directory 257 */ 258 public File getFile () 259 { 260 return _file; 261 } 262 263 /** 264 * Get the primary default zone. 265 * That is the first primary zone, or the 'default' zone if it exists and is primary 266 * @return The default zone or null if there is no primary zone 267 */ 268 public String getDefaultZoneId() 269 { 270 String defaultZoneId = null; 271 272 Map<String, SkinTemplateZone> zones = this.getZones(); 273 for (SkinTemplateZone zone : zones.values()) 274 { 275 if (SkinTemplateZone.TYPE_PRIMARY.equals(zone.getType()) 276 && ("default".equals(zone.getId()) || defaultZoneId == null)) 277 { 278 defaultZoneId = zone.getId(); 279 } 280 } 281 282 return defaultZoneId; 283 } 284} 285