Coverage report

  %line %branch
org.apache.turbine.services.pull.util.UIManager
62% 
92% 

 1  
 package org.apache.turbine.services.pull.util;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2005 The Apache Software Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License")
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import java.io.InputStream;
 20  
 import java.util.Properties;
 21  
 
 22  
 import org.apache.commons.configuration.Configuration;
 23  
 import org.apache.commons.lang.StringUtils;
 24  
 import org.apache.commons.logging.Log;
 25  
 import org.apache.commons.logging.LogFactory;
 26  
 import org.apache.turbine.Turbine;
 27  
 import org.apache.turbine.om.security.User;
 28  
 import org.apache.turbine.services.pull.ApplicationTool;
 29  
 import org.apache.turbine.services.pull.TurbinePull;
 30  
 import org.apache.turbine.services.servlet.TurbineServlet;
 31  
 import org.apache.turbine.util.RunData;
 32  
 import org.apache.turbine.util.ServerData;
 33  
 import org.apache.turbine.util.uri.DataURI;
 34  
 
 35  
 /**
 36  
  * UIManager.java
 37  
  * <br>
 38  
  * Manages all UI elements for a Turbine Application. Any
 39  
  * UI element can be accessed in any template using the
 40  
  * $ui handle (assuming you use the default PullService
 41  
  * configuration). So, for example, you could access
 42  
  * the background colour for your pages by using
 43  
  * $ui.bgcolor
 44  
  * <p>
 45  
  * <h3>Questions:</h3>
 46  
  * What is the best way to allow an application
 47  
  * to be skinned. And how to allow the flexible
 48  
  * altering of a particular UI element in certain
 49  
  * parts of the template hierarchy. For example
 50  
  * on one section of your site you might like
 51  
  * a certain bgcolor, on another part of your
 52  
  * site you might want another. How can be let
 53  
  * the designer specify these properties and
 54  
  * still use the single $app.ui.bgcolor in
 55  
  * all the templates.
 56  
  * <p>
 57  
  * It would also be very cool to use some form
 58  
  * of inheritence for UI elements. Say a $ui.bgcolor
 59  
  * is used in a template where the bgcolor is not
 60  
  * set for that part of hierarch, it would be cool
 61  
  * if it could find the setting for the bgcolor
 62  
  * in the parent directory. So you could override
 63  
  * a UI element where you wanted and the system
 64  
  * would fall back to the parent when necessary.
 65  
  * <p>
 66  
  * How to specify skins, how to deal with images,
 67  
  * how could this be handled with a web app.
 68  
  * <p>
 69  
  *
 70  
  * This is an application pull tool for the template system. You should <b>not</b>
 71  
  * use it in a normal application!
 72  
  *
 73  
  *
 74  
  * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
 75  
  * @author <a href="mailto:james_coltman@majorband.co.uk">James Coltman</a>
 76  
  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 77  
  * @author <a href="thomas.vandahl@tewisoft.de">Thomas Vandahl</a>
 78  
  * @version $Id: UIManager.java 290076 2005-09-19 07:13:51Z henning $
 79  
  */
 80  52
 public class UIManager implements ApplicationTool
 81  
 {
 82  
     /** Logging */
 83  52
     private static Log log = LogFactory.getLog(UIManager.class);
 84  
 
 85  
     /**
 86  
      * The location of the skins within the application
 87  
      * resources directory.
 88  
      */
 89  
     private static final String SKINS_DIRECTORY = "/ui/skins";
 90  
 
 91  
     /**
 92  
      * The name of the directory where images are
 93  
      * stored for this skin.
 94  
      */
 95  
     private static final String IMAGES_DIRECTORY = "/images";
 96  
 
 97  
     /**
 98  
      * Property tag for the default skin that is to be
 99  
      * used for the web application.
 100  
      */
 101  
     private static final String SKIN_PROPERTY = "tool.ui.skin";
 102  
 
 103  
     /**
 104  
      * Property tag for the image directory inside the skin that is to be
 105  
      * used for the web application.
 106  
      */
 107  
     private static final String IMAGEDIR_PROPERTY = "tool.ui.dir.image";
 108  
 
 109  
     /**
 110  
      * Property tag for the skin directory that is to be
 111  
      * used for the web application.
 112  
      */
 113  
     private static final String SKINDIR_PROPERTY = "tool.ui.dir.skin";
 114  
 
 115  
     /**
 116  
      * Property tag for the css file that is to be
 117  
      * used for the web application.
 118  
      */
 119  
     private static final String CSS_PROPERTY = "tool.ui.css";
 120  
 
 121  
     /**
 122  
      * Property tag for the css file that is to be
 123  
      * used for the web application.
 124  
      */
 125  
     private static final String RELATIVE_PROPERTY = "tool.ui.want.relative";
 126  
 
 127  
     /**
 128  
      * Default skin name. This name actually represents
 129  
      * a directory in the WEBAPP/resources/ui/skins
 130  
      * directory. There is a file called skin.props
 131  
      * which actually contains the name/value pairs.
 132  
      */
 133  
     private static final String SKIN_PROPERTY_DEFAULT = "default";
 134  
 
 135  
     /**
 136  
      * Attribute name of skinName value in User's temp hashmap.
 137  
      */
 138  26
     private static final String SKIN_ATTRIBUTE =
 139  
             UIManager.class.getName()+ ".skin";
 140  
 
 141  
     /**
 142  
      * The actual skin being used for the webapp.
 143  
      */
 144  
     private String skinName;
 145  
 
 146  
     /**
 147  
      * The skins directory.
 148  
      */
 149  
     private String skinsDirectory;
 150  
 
 151  
     /**
 152  
      * The file within the skin directory that actually
 153  
      * contains the name/value pairs for the skin.
 154  
      */
 155  
     private static final String SKIN_PROPS_FILE = "skin.props";
 156  
 
 157  
     /**
 158  
      * The file name for the skin style sheet.
 159  
      */
 160  
     private static final String DEFAULT_SKIN_CSS_FILE = "skin.css";
 161  
 
 162  
     /**
 163  
      * This the resources directory relative to the
 164  
      * webapp context. Used for constructing correct
 165  
      * URIs for retrieving images in image().
 166  
      */
 167  
     private String resourcesDirectory;
 168  
     private String imagesDirectory;
 169  
     private String cssFile;
 170  
 
 171  26
     private boolean wantRelative = false;
 172  
 
 173  
     /**
 174  
      * Properties to hold the name/value pairs
 175  
      * for the skin.
 176  
      */
 177  
     private Properties skinProperties;
 178  
 
 179  
     /**
 180  
      * Initialize the UIManager object.
 181  
      *
 182  
      * @param data This is null, RunData or User depending upon specified tool scope.
 183  
      */
 184  
     public void init(Object data)
 185  
     {
 186  
         /**
 187  
          * Store the resources directory for use in image().
 188  
          */
 189  26
         Configuration cfg = Turbine.getConfiguration();
 190  
 
 191  26
         resourcesDirectory = stripSlashes(TurbinePull.getResourcesDirectory());
 192  
 
 193  26
         if (data == null)
 194  
         {
 195  26
             log.debug("UI Manager scope is global");
 196  26
             setSkin();
 197  
         }
 198  0
         else if (data instanceof RunData)
 199  
         {
 200  0
             log.debug("UI Manager scope is request");
 201  0
             setSkin((RunData) data);
 202  
         }
 203  0
         else if (data instanceof User)
 204  
         {
 205  0
             log.debug("UI Manager scope is session");
 206  0
             setSkin((User) data);
 207  
         }
 208  
 
 209  26
         skinsDirectory = stripSlashes(cfg.getString(SKINDIR_PROPERTY, SKINS_DIRECTORY));
 210  
 
 211  26
         imagesDirectory = stripSlashes(cfg.getString(IMAGEDIR_PROPERTY, IMAGES_DIRECTORY));
 212  
 
 213  26
         cssFile = cfg.getString(CSS_PROPERTY, DEFAULT_SKIN_CSS_FILE);
 214  
 
 215  26
         wantRelative = cfg.getBoolean(RELATIVE_PROPERTY, false);
 216  
 
 217  26
         loadSkin();
 218  26
     }
 219  
 
 220  
     private String stripSlashes(final String path)
 221  
     {
 222  92
         if (StringUtils.isEmpty(path))
 223  
         {
 224  2
             return "";
 225  
         }
 226  
 
 227  90
         String ret = path;
 228  90
         int len = ret.length() - 1;
 229  
 
 230  90
         if (ret.charAt(len) == '/')
 231  
         {
 232  82
             ret = ret.substring(0, len);
 233  
         }
 234  
 
 235  90
         if (len > 0 && ret.charAt(0) == '/')
 236  
         {
 237  82
             ret = ret.substring(1);
 238  
         }
 239  
 
 240  90
         return ret;
 241  
     }
 242  
 
 243  
     /**
 244  
      * This lets the tool know that it should be
 245  
      * refreshed. The tool can perform whatever actions
 246  
      * are necessary to refresh itself. This is necessary
 247  
      * for sane development where you probably want the
 248  
      * tools to refresh themselves on every request.
 249  
      */
 250  
     public void refresh()
 251  
     {
 252  8
         log.debug("Refreshing UI manager");
 253  
 
 254  8
         loadSkin();
 255  8
     }
 256  
 
 257  
     /**
 258  
      * Retrieve a property from the properties held
 259  
      * within the properties file for this skin.
 260  
      */
 261  
     public String get(String key)
 262  
     {
 263  0
         return skinProperties.getProperty(key);
 264  
     }
 265  
 
 266  
     /**
 267  
      * Retrieve the skin name.
 268  
      */
 269  
     public String getSkin()
 270  
     {
 271  48
         return skinName;
 272  
     }
 273  
 
 274  
     /**
 275  
      * Retrieve the URL for an image that is part
 276  
      * of a skin. The images are stored in the
 277  
      * WEBAPP/resources/ui/skins/&lt;SKIN&gt;/images
 278  
      * directory.
 279  
      *
 280  
      * Use this if for some reason your server name,
 281  
      * server scheme, or server port change on a
 282  
      * per request basis. I'm not sure if this
 283  
      * would happend in a load balanced situation.
 284  
      * I think in most cases the image(String image)
 285  
      * method would probably be enough, but I'm not
 286  
      * absolutely positive.
 287  
      */
 288  
     public String image(String imageId, RunData data)
 289  
     {
 290  0
         DataURI du = new DataURI(data);
 291  
 
 292  0
         StringBuffer sb = new StringBuffer();
 293  
 
 294  0
         sb.append(resourcesDirectory).
 295  
                 append('/').
 296  
                 append(skinsDirectory).
 297  
                 append('/').
 298  
                 append(getSkin()).
 299  
                 append('/').
 300  
                 append(imagesDirectory).
 301  
                 append('/').
 302  
                 append(stripSlashes(imageId));
 303  
 
 304  0
         du.setScriptName(sb.toString());
 305  
 
 306  0
         return wantRelative ? du.getRelativeLink() : du.getAbsoluteLink();
 307  
     }
 308  
 
 309  
     /**
 310  
      * Retrieve the URL for an image that is part
 311  
      * of a skin. The images are stored in the
 312  
      * WEBAPP/resources/ui/skins/&lt;SKIN&gt;/images
 313  
      * directory.
 314  
      */
 315  
     public String image(String imageId)
 316  
     {
 317  12
         ServerData sd = Turbine.getDefaultServerData();
 318  12
         DataURI du = new DataURI(sd);
 319  
 
 320  12
         StringBuffer sb = new StringBuffer();
 321  
 
 322  12
         sb.append(resourcesDirectory).
 323  
                 append('/').
 324  
                 append(skinsDirectory).
 325  
                 append('/').
 326  
                 append(getSkin()).
 327  
                 append('/').
 328  
                 append(imagesDirectory).
 329  
                 append('/').
 330  
                 append(stripSlashes(imageId));
 331  
 
 332  12
         du.setScriptName(sb.toString());
 333  12
         return wantRelative ? du.getRelativeLink() : du.getAbsoluteLink();
 334  
     }
 335  
 
 336  
     /**
 337  
      * Retrieve the URL for the style sheet that is part
 338  
      * of a skin. The style is stored in the
 339  
      * WEBAPP/resources/ui/skins/&lt;SKIN&gt; directory with the
 340  
      * filename skin.css
 341  
      *
 342  
      * Use this if for some reason your server name,
 343  
      * server scheme, or server port change on a
 344  
      * per request basis. I'm not sure if this
 345  
      * would happend in a load balanced situation.
 346  
      * I think in most cases the style()
 347  
      * method would probably be enough, but I'm not
 348  
      * absolutely positive.
 349  
      */
 350  
     public String getStylecss(RunData data)
 351  
     {
 352  0
         return getScript(cssFile, data);
 353  
     }
 354  
 
 355  
     /**
 356  
      * Retrieve the URL for the style sheet that is part
 357  
      * of a skin. The style is stored in the
 358  
      * WEBAPP/resources/ui/skins/&lt;SKIN&gt; directory with the
 359  
      * filename skin.css
 360  
      */
 361  
     public String getStylecss()
 362  
     {
 363  2
         return getScript(cssFile);
 364  
     }
 365  
 
 366  
     /**
 367  
      * Retrieve the URL for a given script that is part
 368  
      * of a skin. The script is stored in the
 369  
      * WEBAPP/resources/ui/skins/<SKIN> directory
 370  
      */
 371  
     public String getScript(String filename, RunData data)
 372  
     {
 373  0
         DataURI du = new DataURI(data);
 374  
 
 375  0
         StringBuffer sb = new StringBuffer();
 376  
 
 377  0
         sb.append(resourcesDirectory).
 378  
                 append('/').
 379  
                 append(skinsDirectory).
 380  
                 append('/').
 381  
                 append(getSkin()).
 382  
                 append('/').
 383  
                 append(stripSlashes(filename));
 384  
 
 385  0
         du.setScriptName(sb.toString());
 386  0
         return wantRelative ? du.getRelativeLink() : du.getAbsoluteLink();
 387  
     }
 388  
 
 389  
     /**
 390  
      * Retrieve the URL for a given script that is part
 391  
      * of a skin. The script is stored in the
 392  
      * WEBAPP/resources/ui/skins/<SKIN> directory
 393  
      */
 394  
     public String getScript(String filename)
 395  
     {
 396  2
         ServerData sd = Turbine.getDefaultServerData();
 397  2
         DataURI du = new DataURI(sd);
 398  
 
 399  2
         StringBuffer sb = new StringBuffer();
 400  
 
 401  2
         sb.append(resourcesDirectory).
 402  
                 append('/').
 403  
                 append(skinsDirectory).
 404  
                 append('/').
 405  
                 append(getSkin()).
 406  
                 append('/').
 407  
                 append(stripSlashes(filename));
 408  
 
 409  2
         du.setScriptName(sb.toString());
 410  2
         return wantRelative ? du.getRelativeLink() : du.getAbsoluteLink();
 411  
     }
 412  
 
 413  
     /**
 414  
      * Load the specified skin. In development mode
 415  
      * this may occur frequently as the skin properties
 416  
      * are being changed.
 417  
      */
 418  
     private void loadSkin()
 419  
     {
 420  34
         skinProperties = new Properties();
 421  
 
 422  
         try
 423  
         {
 424  34
             StringBuffer sb = new StringBuffer();
 425  
 
 426  34
             sb.append(resourcesDirectory).
 427  
                     append('/').
 428  
                     append(skinsDirectory).
 429  
                     append('/').
 430  
                     append(getSkin()).
 431  
                     append('/').
 432  
                     append(SKIN_PROPS_FILE);
 433  
 
 434  34
             InputStream is = TurbineServlet.getResourceAsStream(sb.toString());
 435  
 
 436  0
             skinProperties.load(is);
 437  
         }
 438  17
         catch (Exception e)
 439  
         {
 440  34
             log.error("Cannot load skin: " + skinName);
 441  0
         }
 442  34
     }
 443  
 
 444  
     /**
 445  
      * Set the skin name to the skin from the TR.props
 446  
      * file. If the property is not present use the
 447  
      * default skin.
 448  
      */
 449  
     public void setSkin()
 450  
     {
 451  26
         this.skinName = Turbine.getConfiguration()
 452  
                 .getString(SKIN_PROPERTY,
 453  
                         SKIN_PROPERTY_DEFAULT);
 454  26
     }
 455  
 
 456  
     /**
 457  
      * Set the skin name to the specified skin.
 458  
      *
 459  
      * @param skinName the skin name to use.
 460  
      */
 461  
     public void setSkin(String skinName)
 462  
     {
 463  0
         this.skinName = skinName;
 464  0
     }
 465  
 
 466  
     /**
 467  
      * Set the skin name when the tool is configured to be
 468  
      * loaded on a per-request basis. By default it calls getSkin
 469  
      * to return the skin specified in TR.properties. Developers can
 470  
      * write a subclass of UIManager that overrides this method to
 471  
      * determine the skin to use based on information held in the request.
 472  
      *
 473  
      * @param data a RunData instance
 474  
      */
 475  
     protected void setSkin(RunData data)
 476  
     {
 477  0
         setSkin();
 478  0
     }
 479  
 
 480  
     /**
 481  
      * Set the skin name when the tool is configured to be
 482  
      * loaded on a per-session basis. It the user's temp hashmap contains
 483  
      * a value in the attribute specified by the String constant SKIN_ATTRIBUTE
 484  
      * then that is returned. Otherwise it calls getSkin to return the skin
 485  
      * specified in TR.properties.
 486  
      *
 487  
      * @param user a User instance
 488  
      */
 489  
     protected void setSkin(User user)
 490  
     {
 491  0
         if (user.getTemp(SKIN_ATTRIBUTE) == null)
 492  
         {
 493  0
             setSkin();
 494  
         }
 495  
         else
 496  
         {
 497  0
             setSkin((String) user.getTemp(SKIN_ATTRIBUTE));
 498  
         }
 499  0
     }
 500  
 
 501  
     /**
 502  
      * Set the skin name user's temp hashmap for the current session.
 503  
      *
 504  
      * @param user a User instance
 505  
      * @param skin the skin name for the session
 506  
      */
 507  
     public static void setSkin(User user, String skin)
 508  
     {
 509  0
         user.setTemp(SKIN_ATTRIBUTE, skin);
 510  0
     }
 511  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.