Coverage Report - org.apache.tapestry.dojo.AjaxShellDelegate
 
Classes in this File Line Coverage Branch Coverage Complexity
AjaxShellDelegate
0%
0/83
0%
0/44
2.5
 
 1  
 // Copyright 2004, 2005 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 package org.apache.tapestry.dojo;
 15  
 
 16  
 import java.util.Locale;
 17  
 
 18  
 import org.apache.hivemind.util.Defense;
 19  
 import org.apache.tapestry.IAsset;
 20  
 import org.apache.tapestry.IMarkupWriter;
 21  
 import org.apache.tapestry.IPage;
 22  
 import org.apache.tapestry.IRender;
 23  
 import org.apache.tapestry.IRequestCycle;
 24  
 import org.apache.tapestry.json.JSONLiteral;
 25  
 import org.apache.tapestry.json.JSONObject;
 26  
 
 27  
 
 28  
 /**
 29  
  * The default rendering delegate responsible for include the dojo sources in
 30  
  * to the {@link org.apache.tapestry.html.Shell} component.
 31  
  */
 32  0
 public class AjaxShellDelegate implements IRender {
 33  
 
 34  
     /** Client side debug log level. */
 35  
     public static final String BROWSER_LOG_DEBUG="DEBUG";
 36  
     /** Client side info log level. */
 37  
     public static final String BROWSER_LOG_INFO="INFO";
 38  
     /** Client side warning log level. */
 39  
     public static final String BROWSER_LOG_WARNING="WARNING";
 40  
     /** Client side error log level. */
 41  
     public static final String BROWSER_LOG_ERROR="ERROR";
 42  
     /** Client side critical log level. */
 43  
     public static final String BROWSER_LOG_CRITICAL="CRITICAL";
 44  
 
 45  0
     private static final String SYSTEM_NEWLINE= (String)java.security.AccessController.doPrivileged(
 46  
       new sun.security.action.GetPropertyAction("line.separator"));    
 47  
 
 48  
     /** Default list of pre-bundled dojo supported locales. */
 49  0
     protected String[] SUPPORTED_LOCALES = { "en-us", "de-de", "de", "en-gb",
 50  
                                              "es-es", "es", "fr-fr", "fr", "zh-cn",
 51  
                                              "zh-tw", "zh" , "it-it", "it", "ja-jp",
 52  
                                              "ja", "ko-kr", "ko", "pt-br", "pt", "en", "xx"};
 53  
 
 54  
     private IAsset _dojoSource;
 55  
 
 56  
     private IAsset _dojoFormSource;
 57  
 
 58  
     private IAsset _dojoWidgetSource;
 59  
 
 60  
     private IAsset _dojoPath;
 61  
 
 62  
     private IAsset _tapestrySource;
 63  
 
 64  
     private IAsset _tapestryPath;
 65  
 
 66  
     private boolean _parseWidgets;
 67  
 
 68  0
     private String _browserLogLevel = BROWSER_LOG_WARNING;
 69  
 
 70  
     private boolean _debug;
 71  
 
 72  
     private String _debugContainerId;
 73  
 
 74  
     private boolean _consoleEnabled;
 75  
 
 76  
     private boolean _preventBackButtonFix;
 77  
 
 78  
     private boolean _debugAtAllCosts;
 79  
     
 80  
     private String _searchIds;
 81  
 
 82  
     /**
 83  
      * {@inheritDoc}
 84  
      */
 85  
     public void render(IMarkupWriter writer, IRequestCycle cycle)
 86  
     {
 87  
         // first configure dojo, has to happen before package include
 88  
 
 89  0
         JSONObject dojoConfig = new JSONObject();
 90  
 
 91  
         // Debugging configuration , debugAtAlCosts causes the individual 
 92  
         // .js files to included in the document head so that javascript errors
 93  
         // are able to resolve to the context of the file instead of just "dojo.js"
 94  
 
 95  0
         if (_debug)
 96  
         {
 97  0
             dojoConfig.put("isDebug", _debug);
 98  
         }
 99  
 
 100  0
         if (_debugAtAllCosts)
 101  0
             dojoConfig.put("debugAtAllCosts", _debugAtAllCosts);
 102  0
         if (_debugContainerId != null)
 103  0
             dojoConfig.put("debugContainerId", _debugContainerId);
 104  
 
 105  0
         IPage page = cycle.getPage();
 106  
 
 107  
         // The key to resolving everything out of the asset service
 108  
 
 109  0
         if (_dojoPath!=null)
 110  
         {
 111  0
             dojoConfig.put("baseRelativePath", _dojoPath.buildURL());
 112  
         }
 113  
 
 114  0
         if (page.hasFormComponents())
 115  
         {
 116  0
             dojoConfig.put("preventBackButtonFix", _preventBackButtonFix);
 117  
         }
 118  
         
 119  0
         dojoConfig.put("parseWidgets", _parseWidgets);
 120  0
         if (_searchIds != null)
 121  0
             dojoConfig.put("searchIds", new JSONLiteral(_searchIds));
 122  
 
 123  
         // Supports setting up locale in dojo environment to match the requested page locale.
 124  
         // (for things that use these settings, like DropdownDatePicker / date parsing / etc..
 125  
 
 126  0
         Locale locale = cycle.getPage().getLocale();
 127  
 
 128  0
         String localeStr = locale.getLanguage().toLowerCase()
 129  
                            + ((locale.getCountry() != null && locale.getCountry().trim().length() > 0)
 130  
                               ? "-" + locale.getCountry().toLowerCase()
 131  
                               : "");
 132  
 
 133  0
         if (isLocaleSupported(localeStr))
 134  
         {
 135  0
             dojoConfig.put("locale", localeStr);
 136  
         }
 137  
 
 138  
         // Write the required script includes and dojo.requires
 139  
 
 140  0
         StringBuffer str = new StringBuffer("<script type=\"text/javascript\">");
 141  0
         str.append("djConfig = ").append(dojoConfig.toString())
 142  
           .append(" </script>")
 143  
           .append(SYSTEM_NEWLINE).append(SYSTEM_NEWLINE);
 144  
 
 145  
         // include the core dojo.js package
 146  
 
 147  0
         if (_dojoSource!=null)
 148  
         {
 149  0
             str.append("<script type=\"text/javascript\" src=\"")
 150  
               .append(_dojoSource.buildURL()).append("\"></script>");
 151  
         }
 152  
 
 153  0
         if (page.hasFormComponents() && _dojoFormSource!=null)
 154  
         {
 155  0
             str.append("<script type=\"text/javascript\" src=\"")
 156  
               .append(_dojoFormSource.buildURL()).append("\"></script>");
 157  
         }
 158  
 
 159  0
         if (page.hasWidgets() && _dojoWidgetSource!=null)
 160  
         {
 161  0
             str.append("<script type=\"text/javascript\" src=\"")
 162  
               .append(_dojoWidgetSource.buildURL()).append("\"></script>");
 163  
         }
 164  
 
 165  
         // configure basic dojo properties , logging includes
 166  
 
 167  0
         if (_debug)
 168  
         {
 169  0
             String logRequire = _consoleEnabled ? "dojo.require(\"dojo.debug.console\");" + SYSTEM_NEWLINE
 170  
                                 : "dojo.require(\"dojo.logging.Logger\");" + SYSTEM_NEWLINE;
 171  
 
 172  0
             str.append(SYSTEM_NEWLINE).append("<script type=\"text/javascript\">").append(SYSTEM_NEWLINE);
 173  0
             str.append(logRequire)
 174  
               .append("dojo.log.setLevel(dojo.log.getLevel(\"").append(_browserLogLevel)
 175  
               .append("\"));").append(SYSTEM_NEWLINE)
 176  
               .append("</script>");
 177  
         }
 178  
 
 179  
         // module path registration to tapestry javascript sources
 180  
 
 181  0
         if (_tapestryPath!=null)
 182  
         {
 183  0
             String tapestryUrl = _tapestryPath.buildURL();
 184  0
             if (tapestryUrl.endsWith("/"))
 185  
             {
 186  0
                 tapestryUrl = tapestryUrl.substring(0, tapestryUrl.length() - 1);
 187  
             }
 188  
 
 189  0
             str.append(SYSTEM_NEWLINE).append("<script type=\"text/javascript\">").append(SYSTEM_NEWLINE)
 190  
               .append("dojo.registerModulePath(\"tapestry\", \"")
 191  
               .append(tapestryUrl).append("\");").append(SYSTEM_NEWLINE);
 192  0
             str.append("</script>").append(SYSTEM_NEWLINE);
 193  
         }
 194  
 
 195  
         // include core tapestry.js package
 196  
 
 197  0
         if (_tapestrySource!=null)
 198  
         {
 199  0
             str.append("<script type=\"text/javascript\" src=\"")
 200  
               .append(_tapestrySource.buildURL()).append("\"></script>");
 201  
         }
 202  
 
 203  
         // namespace registration
 204  
 
 205  0
         str.append(SYSTEM_NEWLINE).append("<script type=\"text/javascript\">").append(SYSTEM_NEWLINE);
 206  0
         str.append("dojo.require(\"tapestry.namespace\");").append(SYSTEM_NEWLINE)
 207  
           .append("tapestry.requestEncoding='")
 208  
           .append(cycle.getEngine().getOutputEncoding()).append("';")
 209  
           .append(SYSTEM_NEWLINE).append("</script>");
 210  
 
 211  0
         writer.printRaw(str.toString());
 212  0
         writer.println();
 213  0
     }
 214  
 
 215  
     /**
 216  
      * Checks if the provided locale string matches one of the predefined {@link #SUPPORTED_LOCALES}
 217  
      * in the dojo javascript library.
 218  
      *
 219  
      * @param locale
 220  
      *          The Dojo formatted locale string to check.
 221  
      *
 222  
      * @return True if locale is supported and ok to define in dojoConfig - false otherwise.
 223  
      */
 224  
     protected boolean isLocaleSupported(String locale)
 225  
     {
 226  0
         if (locale == null)
 227  0
             return false;
 228  
 
 229  0
         for (int i=0; i < SUPPORTED_LOCALES.length; i++)
 230  
         {
 231  0
             if (locale.equals(SUPPORTED_LOCALES[i]))
 232  0
                 return true;
 233  
         }
 234  
 
 235  0
         return false;
 236  
     }
 237  
 
 238  
     /**
 239  
      * Sets the dojo logging level. Similar to log4j style
 240  
      * log levels. 
 241  
      * @param level The string constant for the level, valid values
 242  
      *              are:
 243  
      *              <p>
 244  
      *              <ul>
 245  
      *              <li>{@link #BROWSER_LOG_DEBUG}</li>
 246  
      *              <li>{@link #BROWSER_LOG_INFO}</li>
 247  
      *              <li>{@link #BROWSER_LOG_WARNING}</li>
 248  
      *              <li>{@link #BROWSER_LOG_ERROR}</li>
 249  
      *              <li>{@link #BROWSER_LOG_CRITICAL}</li>
 250  
      *              </ul>
 251  
      *              </p>
 252  
      */
 253  
     public void setLogLevel(String level)
 254  
     {
 255  0
         Defense.notNull("level", level);
 256  
 
 257  0
         _browserLogLevel = level;
 258  0
     }
 259  
 
 260  
     /**
 261  
      * Allows for turning browser debugging on/off.
 262  
      *
 263  
      * @param debug If false, no logging output will be written.
 264  
      */
 265  
     public void setDebug(boolean debug)
 266  
     {
 267  0
         _debug = debug;
 268  0
     }
 269  
 
 270  
     /**
 271  
      * Turns off deep context level javascript debugging mode for dojo. This means
 272  
      * that exceptions/debug statements will show you line numbers from the actual 
 273  
      * javascript file that generated them instead of the normal default which is 
 274  
      * usually bootstrap.js .
 275  
      *
 276  
      * <p>The default value is false if not set.</p>
 277  
      *
 278  
      * <p>
 279  
      *  People should be wary of turning this on as it may cause problems
 280  
      *  under certain conditions, and you definitely don't ever want this 
 281  
      *  on in production. 
 282  
      * </p>
 283  
      *
 284  
      * @param value If true deep debugging will be turned on.
 285  
      */
 286  
     public void setDebugAtAllCosts(boolean value)
 287  
     {
 288  0
         _debugAtAllCosts = value;
 289  0
     }
 290  
 
 291  
     /**
 292  
      * Sets the html element node id of the element you would like all browser
 293  
      * debug content to go to.
 294  
      *
 295  
      * @param debugContainerId the debugContainerId to set
 296  
      */
 297  
     public void setDebugContainerId(String debugContainerId)
 298  
     {
 299  0
         _debugContainerId = debugContainerId;
 300  0
     }
 301  
 
 302  
     /**
 303  
      * Enables/disables the dojo.debug.console functionality which should redirect
 304  
      * most logging messages to your browsers javascript console. (if it supports 
 305  
      * one).
 306  
      *
 307  
      * <p>
 308  
      *  The debug console is disabled by default. Currently known supported 
 309  
      *  browsers are FireFox(having FireBug extension helps a great deal)/Opera/Safari.
 310  
      * </p>
 311  
      *
 312  
      * @param enabled Whether or not the enable debug console.
 313  
      */
 314  
     public void setConsoleEnabled(boolean enabled)
 315  
     {
 316  0
         _consoleEnabled = enabled;
 317  0
     }
 318  
 
 319  
     /**
 320  
      * Sets the dojo preventBackButtonFix djConfig configuration. This should
 321  
      * typically be avoided but is provided for flexibility.
 322  
      *
 323  
      * @param prevent
 324  
      *          Whether or not to prevent back button fix.
 325  
      */
 326  
     public void setPreventBackButtonFix(boolean prevent)
 327  
     {
 328  0
         _preventBackButtonFix = prevent;
 329  0
     }
 330  
 
 331  
     /**
 332  
      * Tells dojo whether or not to parse widgets by traversing the entire 
 333  
      * dom node of your document. It is highly reccomended that you keep this
 334  
      * at its default value of false.
 335  
      *
 336  
      * @param parseWidgets the parseWidgets to set
 337  
      */
 338  
     public void setParseWidgets(boolean parseWidgets)
 339  
     {
 340  0
         _parseWidgets = parseWidgets;
 341  0
     }
 342  
     
 343  
     /**
 344  
      * Provides a way to have dojo automatically parse a known set of page 
 345  
      * widgets without enabling full automatic parsing.
 346  
      * 
 347  
      * @param searchIds the html ids within which to search for widgets
 348  
      */ 
 349  
     public void setSearchIds(String searchIds) 
 350  
     {
 351  0
         _searchIds = searchIds;
 352  0
     }
 353  
 
 354  
     /**
 355  
      * Sets a valid path to the base dojo javascript installation
 356  
      * directory.
 357  
      *
 358  
      * @param dojoSource
 359  
      *          Path to dojo source directory core "dojo.js" file.
 360  
      */
 361  
     public void setDojoSource(IAsset dojoSource)
 362  
     {
 363  0
         _dojoSource = dojoSource;
 364  0
     }
 365  
 
 366  
     public void setDojoFormSource(IAsset formSource)
 367  
     {
 368  0
         _dojoFormSource = formSource;
 369  0
     }
 370  
 
 371  
     public void setDojoWidgetSource(IAsset widgetSource)
 372  
     {
 373  0
         _dojoWidgetSource = widgetSource;
 374  0
     }
 375  
 
 376  
     /**
 377  
      * Sets the dojo baseRelativePath value.
 378  
      *
 379  
      * @param dojoPath
 380  
      *          The base path to dojo directory.
 381  
      */
 382  
     public void setDojoPath(IAsset dojoPath)
 383  
     {
 384  0
         _dojoPath = dojoPath;
 385  0
     }
 386  
 
 387  
     /**
 388  
      * Sets a valid base path to resolve tapestry core.js.
 389  
      *
 390  
      * @param tapestrySource
 391  
      *          Main tapestry core.js file.
 392  
      */
 393  
     public void setTapestrySource(IAsset tapestrySource)
 394  
     {
 395  0
         _tapestrySource = tapestrySource;
 396  0
     }
 397  
 
 398  
     /**
 399  
      * Sets the path to the tapestry javascript modules. (Needed for dojo to resolve the 
 400  
      * path to tapestry javascript, esp when overriding the default bundled dojo.)
 401  
      *
 402  
      * @param tapestryPath The path to tapestry.
 403  
      */
 404  
     public void setTapestryPath(IAsset tapestryPath)
 405  
     {
 406  0
         _tapestryPath = tapestryPath;
 407  0
     }
 408  
 }