001package org.apache.turbine.services.pull.tools; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.commons.logging.Log; 023import org.apache.commons.logging.LogFactory; 024import org.apache.turbine.om.security.User; 025import org.apache.turbine.pipeline.PipelineData; 026import org.apache.turbine.services.pull.ApplicationTool; 027import org.apache.turbine.services.ui.TurbineUI; 028import org.apache.turbine.services.ui.UIService; 029import org.apache.turbine.util.RunData; 030import org.apache.turbine.util.ServerData; 031 032/** 033 * Manages all UI elements for a Turbine Application. Any UI element can be 034 * accessed in any template using the $ui handle (assuming you use the default 035 * PullService configuration). So, for example, you could access the background 036 * color for your pages by using $ui.bgcolor 037 * <p> 038 * This implementation provides a single level of inheritance in that if a 039 * property does not exist in a non-default skin, the value from the default 040 * skin will be used. By only requiring values different to those stored in 041 * the default skin to appear in the non-default skins the amount of memory 042 * consumed in cases where the UserManager instance is used at a non-global 043 * scope will potentially be reduced due to the fact that a shared instance of 044 * the default skin properties can be used. Note that this inheritance only 045 * applies to property values - it does not apply to any images or stylesheets 046 * that may form part of your skins. 047 * <p> 048 * This is an application pull tool for the template system. You should not 049 * use it in a normal application! Within Java code you should use TurbineUI. 050 * <p> 051 * 052 * This is an application pull tool for the template system. You should 053 * <strong>only</strong> use it in a normal application to set the skin 054 * attribute for a user (setSkin(User user, String skin)) and to initialize it 055 * for the user, otherwise use TurbineUI is probably the way to go. 056 * 057 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a> 058 * @author <a href="mailto:james_coltman@majorband.co.uk">James Coltman</a> 059 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 060 * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a> 061 * @version $Id$ 062 * @see UIService 063 */ 064public class UITool implements ApplicationTool 065{ 066 /** Logging */ 067 private static Log log = LogFactory.getLog(UITool.class); 068 069 /** 070 * Attribute name of skinName value in User's temp hashmap. 071 */ 072 public static final String SKIN_ATTRIBUTE = UITool.class.getName()+ ".skin"; 073 074 /** 075 * The actual skin being used for the webapp. 076 */ 077 private String skinName; 078 079 /** 080 * Refresh the tool. 081 */ 082 @Override 083 public void refresh() 084 { 085 TurbineUI.refresh(getSkin()); 086 log.debug("UITool refreshed for skin: " + getSkin()); 087 } 088 089 /** 090 * Provide access to the list of available skin names. 091 * 092 * @return the available skin names. 093 */ 094 public String[] getSkinNames() 095 { 096 return TurbineUI.getSkinNames(); 097 } 098 099 /** 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}