1 package org.apache.turbine.services.pull.tools; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import org.apache.commons.logging.Log; 23 import org.apache.commons.logging.LogFactory; 24 import org.apache.turbine.om.security.User; 25 import org.apache.turbine.pipeline.PipelineData; 26 import org.apache.turbine.services.pull.ApplicationTool; 27 import org.apache.turbine.services.ui.TurbineUI; 28 import org.apache.turbine.services.ui.UIService; 29 import org.apache.turbine.util.RunData; 30 import org.apache.turbine.util.ServerData; 31 32 /** 33 * Manages all UI elements for a Turbine Application. Any UI element can be 34 * accessed in any template using the $ui handle (assuming you use the default 35 * PullService configuration). So, for example, you could access the background 36 * color for your pages by using $ui.bgcolor 37 * <p> 38 * This implementation provides a single level of inheritance in that if a 39 * property does not exist in a non-default skin, the value from the default 40 * skin will be used. By only requiring values different to those stored in 41 * the default skin to appear in the non-default skins the amount of memory 42 * consumed in cases where the UserManager instance is used at a non-global 43 * scope will potentially be reduced due to the fact that a shared instance of 44 * the default skin properties can be used. Note that this inheritance only 45 * applies to property values - it does not apply to any images or stylesheets 46 * that may form part of your skins. 47 * <p> 48 * This is an application pull tool for the template system. You should not 49 * use it in a normal application! Within Java code you should use TurbineUI. 50 * <p> 51 * 52 * This is an application pull tool for the template system. You should 53 * <strong>only</strong> use it in a normal application to set the skin 54 * attribute for a user (setSkin(User user, String skin)) and to initialize it 55 * for the user, otherwise use TurbineUI is probably the way to go. 56 * 57 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a> 58 * @author <a href="mailto:james_coltman@majorband.co.uk">James Coltman</a> 59 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 60 * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a> 61 * @version $Id$ 62 * @see UIService 63 */ 64 public class UITool implements ApplicationTool 65 { 66 /** Logging */ 67 private static Log log = LogFactory.getLog(UITool.class); 68 69 /** 70 * Attribute name of skinName value in User's temp hashmap. 71 */ 72 public static final String SKIN_ATTRIBUTE = UITool.class.getName()+ ".skin"; 73 74 /** 75 * The actual skin being used for the webapp. 76 */ 77 private String skinName; 78 79 /** 80 * Refresh the tool. 81 */ 82 @Override 83 public void refresh() 84 { 85 TurbineUI.refresh(getSkin()); 86 log.debug("UITool refreshed for skin: " + getSkin()); 87 } 88 89 /** 90 * Provide access to the list of available skin names. 91 * 92 * @return the available skin names. 93 */ 94 public String[] getSkinNames() 95 { 96 return TurbineUI.getSkinNames(); 97 } 98 99 /** 100 * Get the name of the default skin name for the web application from the 101 * TurbineResources.properties file. If the property is not present the 102 * name of the default skin will be returned. Note that the web application 103 * skin name may be something other than default, in which case its 104 * properties will default to the skin with the name "default". 105 * 106 * @return the name of the default skin for the web application. 107 */ 108 public String getWebappSkinName() 109 { 110 return TurbineUI.getWebappSkinName(); 111 } 112 113 /** 114 * Retrieve a skin property. If the property is not defined in the current 115 * skin the value for the default skin will be provided. If the current 116 * skin does not exist then the skin configured for the webapp will be used. 117 * If the webapp skin does not exist the default skin will be used. If the 118 * default skin does not exist then <code>null</code> will be returned. 119 * 120 * @param key the key to retrieve from the skin. 121 * @return the value of the property for the named skin (defaulting to the 122 * default skin), the webapp skin, the default skin or <code>null</code>, 123 * depending on whether or not the property or skins exist. 124 */ 125 public String get(String key) 126 { 127 return TurbineUI.get(getSkin(), key); 128 } 129 130 /** 131 * Retrieve the skin name. 132 * @return the selected skin name 133 */ 134 public String getSkin() 135 { 136 return skinName; 137 } 138 139 /** 140 * Set the skin name to the skin from the TurbineResources.properties file. 141 * If the property is not present use the "default" skin. 142 */ 143 public void setSkin() 144 { 145 skinName = TurbineUI.getWebappSkinName(); 146 } 147 148 /** 149 * Set the skin name to the specified skin. 150 * 151 * @param skinName the skin name to use. 152 */ 153 public void setSkin(String skinName) 154 { 155 this.skinName = skinName; 156 } 157 158 /** 159 * Set the skin name when the tool is configured to be loaded on a 160 * per-request basis. By default it calls getSkin to return the skin 161 * specified in TurbineResources.properties. Developers can write a subclass 162 * of UITool that overrides this method to determine the skin to use based 163 * on information held in the request. 164 * 165 * @param data a RunData instance 166 */ 167 protected void setSkin(RunData data) 168 { 169 setSkin(); 170 } 171 172 /** 173 * Set the skin name when the tool is configured to be loaded on a 174 * per-session basis. If the user's temp hashmap contains a value in the 175 * attribute specified by the String constant SKIN_ATTRIBUTE then that is 176 * returned. Otherwise it calls getSkin to return the skin specified in 177 * TurbineResources.properties. 178 * 179 * @param user a User instance 180 */ 181 protected void setSkin(User user) 182 { 183 if (user.getTemp(SKIN_ATTRIBUTE) == null) 184 { 185 setSkin(); 186 } 187 else 188 { 189 setSkin((String) user.getTemp(SKIN_ATTRIBUTE)); 190 } 191 } 192 193 /** 194 * Set the skin name in the user's temp hashmap for the current session. 195 * 196 * @param user a User instance 197 * @param skin the skin name for the session 198 */ 199 public static void setSkin(User user, String skin) 200 { 201 user.setTemp(SKIN_ATTRIBUTE, skin); 202 } 203 204 /** 205 * Retrieve the URL for an image that is part of the skin. The images are 206 * stored in the WEBAPP/resources/ui/skins/[SKIN]/images directory. 207 * 208 * <p>Use this if for some reason your server name, server scheme, or server 209 * port change on a per request basis. I'm not sure if this would happen in 210 * a load balanced situation. I think in most cases the image(String image) 211 * method would probably be enough, but I'm not absolutely positive. 212 * 213 * @param imageId the id of the image whose URL will be generated. 214 * @param data the RunData to use as the source of the ServerData to use as 215 * the basis for the URL. 216 * @return the image URL 217 */ 218 public String image(String imageId, RunData data) 219 { 220 return image(imageId, data.getServerData()); 221 } 222 223 /** 224 * Retrieve the URL for an image that is part of the skin. The images are 225 * stored in the WEBAPP/resources/ui/skins/[SKIN]/images directory. 226 * 227 * <p>Use this if for some reason your server name, server scheme, or server 228 * port change on a per request basis. I'm not sure if this would happen in 229 * a load balanced situation. I think in most cases the image(String image) 230 * method would probably be enough, but I'm not absolutely positive. 231 * 232 * @param imageId the id of the image whose URL will be generated. 233 * @param serverData the serverData to use as the basis for the URL. 234 * @return the image URL 235 */ 236 public String image(String imageId, ServerData serverData) 237 { 238 return TurbineUI.image(getSkin(), imageId, serverData); 239 } 240 241 /** 242 * Retrieve the URL for an image that is part of the skin. The images are 243 * stored in the WEBAPP/resources/ui/skins/[SKIN]/images directory. 244 * 245 * @param imageId the id of the image whose URL will be generated. 246 * @return the image URL 247 */ 248 public String image(String imageId) 249 { 250 return TurbineUI.image(getSkin(), imageId); 251 } 252 253 /** 254 * Retrieve the URL for the style sheet that is part of the skin. The style 255 * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory with the 256 * filename skin.css 257 * 258 * <p>Use this if for some reason your server name, server scheme, or server 259 * port change on a per request basis. I'm not sure if this would happen in 260 * a load balanced situation. I think in most cases the style() method would 261 * probably be enough, but I'm not absolutely positive. 262 * 263 * @param data the RunData to use as the source of the ServerData to use as 264 * the basis for the URL. 265 * @return the CSS URL 266 */ 267 public String getStylecss(RunData data) 268 { 269 return getStylecss(data.getServerData()); 270 } 271 272 /** 273 * Retrieve the URL for the style sheet that is part of the skin. The style 274 * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory with the 275 * filename skin.css 276 * 277 * <p>Use this if for some reason your server name, server scheme, or server 278 * port change on a per request basis. I'm not sure if this would happen in 279 * a load balanced situation. I think in most cases the style() method would 280 * probably be enough, but I'm not absolutely positive. 281 * 282 * @param serverData the serverData to use as the basis for the URL. 283 * @return the CSS URL 284 */ 285 public String getStylecss(ServerData serverData) 286 { 287 return TurbineUI.getStylecss(getSkin(), serverData); 288 } 289 290 /** 291 * Retrieve the URL for the style sheet that is part of the skin. The style 292 * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory with the 293 * filename skin.css 294 * @return the CSS URL 295 */ 296 public String getStylecss() 297 { 298 return TurbineUI.getStylecss(getSkin()); 299 } 300 301 /** 302 * Retrieve the URL for a given script that is part of the skin. The script 303 * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory. 304 * 305 * <p>Use this if for some reason your server name, server scheme, or server 306 * port change on a per request basis. I'm not sure if this would happen in 307 * a load balanced situation. I think in most cases the image(String image) 308 * method would probably be enough, but I'm not absolutely positive. 309 * 310 * @param filename the name of the script file whose URL will be generated. 311 * @param data the RunDate to use as the source of the ServerData to use as 312 * the basis for the URL. 313 * @return the script URL 314 */ 315 public String getScript(String filename, RunData data) 316 { 317 return getScript(filename, data.getServerData()); 318 } 319 320 /** 321 * Retrieve the URL for a given script that is part of the skin. The script 322 * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory. 323 * 324 * <p>Use this if for some reason your server name, server scheme, or server 325 * port change on a per request basis. I'm not sure if this would happen in 326 * a load balanced situation. I think in most cases the image(String image) 327 * method would probably be enough, but I'm not absolutely positive. 328 * 329 * @param filename the name of the script file whose URL will be generated. 330 * @param serverData the serverData to use as the basis for the URL. 331 * @return the script URL 332 */ 333 public String getScript(String filename, ServerData serverData) 334 { 335 return TurbineUI.getScript(getSkin(), filename, serverData); 336 } 337 338 /** 339 * Retrieve the URL for a given script that is part of the skin. The script 340 * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory. 341 * 342 * @param filename the name of the script file whose URL will be generated. 343 * @return the script URL 344 */ 345 public String getScript(String filename) 346 { 347 return TurbineUI.getScript(getSkin(), filename); 348 } 349 350 /** 351 * Initialize the UITool object. 352 * 353 * @param data This is null, RunData or User depending upon specified tool 354 * scope. 355 */ 356 @Override 357 public void init(Object data) 358 { 359 if (data == null) 360 { 361 log.debug("UITool scope is global"); 362 setSkin(); 363 } 364 else if (data instanceof RunData) 365 { 366 log.debug("UITool scope is request"); 367 setSkin((RunData) data); 368 } 369 else if (data instanceof PipelineData) 370 { 371 PipelineData pipelineData = (PipelineData) data; 372 RunData runData = (RunData)pipelineData; 373 log.debug("UITool scope is request"); 374 setSkin(runData); 375 } 376 else if (data instanceof User) 377 { 378 log.debug("UITool scope is session"); 379 setSkin((User) data); 380 } 381 } 382 383 }