Clover coverage report - brownies library - 1.0-beta-1
Coverage timestamp: 月 8 16 2004 17:14:42 GMT+09:00
file stats: LOC: 386   Methods: 11
NCLOC: 172   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
ExBody.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
  * Joey and its relative products are published under the terms
 3   
  * of the Apache Software License.
 4   
  */
 5   
 /*
 6   
  * Created on 2004/01/07
 7   
  */
 8   
 package org.asyrinx.brownie.tapestry.components.html;
 9   
 
 10   
 import java.util.ArrayList;
 11   
 import java.util.HashMap;
 12   
 import java.util.List;
 13   
 import java.util.Map;
 14   
 
 15   
 import org.apache.tapestry.ApplicationRuntimeException;
 16   
 import org.apache.tapestry.IMarkupWriter;
 17   
 import org.apache.tapestry.IRequestCycle;
 18   
 import org.apache.tapestry.IResourceLocation;
 19   
 import org.apache.tapestry.Tapestry;
 20   
 import org.apache.tapestry.asset.PrivateAsset;
 21   
 import org.apache.tapestry.html.Body;
 22   
 import org.apache.tapestry.html.Rollover;
 23   
 import org.apache.tapestry.html.Script;
 24   
 import org.apache.tapestry.resource.ClasspathResourceLocation;
 25   
 import org.apache.tapestry.util.IdAllocator;
 26   
 import org.asyrinx.brownie.tapestry.script.IFinalizableScriptProcessor;
 27   
 
 28   
 /**
 29   
  * @author akima
 30   
  */
 31   
 public abstract class ExBody extends Body implements
 32   
         IFinalizableScriptProcessor {
 33   
 
 34   
     // Lines that belong inside the onLoad event handler for the <body> tag.
 35   
     private StringBuffer _initializationScript;
 36   
 
 37   
     // Lines that belong inside the onUnload event handler for the <body> tag.
 38   
     private StringBuffer _finalizationScript;
 39   
 
 40   
     // The writer initially passed to render() ... wrapped elements render
 41   
     // into a nested response writer.
 42   
 
 43   
     private IMarkupWriter _outerWriter;
 44   
 
 45   
     // Any other scripting desired
 46   
 
 47   
     private StringBuffer _bodyScript;
 48   
 
 49   
     // Contains text lines related to image initializations
 50   
 
 51   
     private StringBuffer _imageInitializations;
 52   
 
 53   
     /**
 54   
      * Map of URLs to Strings (preloaded image references).
 55   
      *  
 56   
      */
 57   
 
 58   
     private Map _imageMap;
 59   
 
 60   
     /**
 61   
      * List of included scripts. Values are Strings.
 62   
      * 
 63   
      * @since 1.0.5
 64   
      *  
 65   
      */
 66   
 
 67   
     private List _externalScripts;
 68   
 
 69   
     private IdAllocator _idAllocator;
 70   
 
 71   
     private static final String ATTRIBUTE_NAME = "org.apache.tapestry.active.Body";
 72   
 
 73   
     /**
 74   
      * Tracks a particular preloaded image.
 75   
      *  
 76   
      */
 77   
 
 78   
     /**
 79   
      * Adds to the script an initialization for the named variable as an
 80   
      * Image(), to the given URL.
 81   
      * 
 82   
      * <p>
 83   
      * Returns a reference, a string that can be used to represent the preloaded
 84   
      * image in a JavaScript function.
 85   
      * 
 86   
      * @since 1.0.2
 87   
      */
 88   
 
 89  0
     public String getPreloadedImageReference(String URL) {
 90  0
         if (_imageMap == null)
 91  0
             _imageMap = new HashMap();
 92   
 
 93  0
         String reference = (String) _imageMap.get(URL);
 94   
 
 95  0
         if (reference == null) {
 96  0
             int count = _imageMap.size();
 97  0
             String varName = "tapestry_preload[" + count + "]";
 98  0
             reference = varName + ".src";
 99   
 
 100  0
             if (_imageInitializations == null)
 101  0
                 _imageInitializations = new StringBuffer();
 102   
 
 103  0
             _imageInitializations.append("  ");
 104  0
             _imageInitializations.append(varName);
 105  0
             _imageInitializations.append(" = new Image();\n");
 106  0
             _imageInitializations.append("  ");
 107  0
             _imageInitializations.append(reference);
 108  0
             _imageInitializations.append(" = \"");
 109  0
             _imageInitializations.append(URL);
 110  0
             _imageInitializations.append("\";\n");
 111   
 
 112  0
             _imageMap.put(URL, reference);
 113   
         }
 114   
 
 115  0
         return reference;
 116   
     }
 117   
 
 118   
     /**
 119   
      * Adds other initialization, in the form of additional JavaScript code to
 120   
      * execute from the &lt;body&gt;'s <code>onLoad</code> event handler. The
 121   
      * caller is responsible for adding a semicolon (statement terminator). This
 122   
      * method will add a newline after the script.
 123   
      *  
 124   
      */
 125   
 
 126  0
     public void addInitializationScript(String script) {
 127  0
         if (_initializationScript == null)
 128  0
             _initializationScript = new StringBuffer(script.length() + 1);
 129   
 
 130  0
         _initializationScript.append(script);
 131  0
         _initializationScript.append('\n');
 132   
 
 133   
     }
 134   
 
 135   
     /**
 136   
      * Adds other finalization, in the form of additional JavaScript code to
 137   
      * execute from the &lt;body&gt;'s <code>onUnload</code> event handler.
 138   
      * The caller is responsible for adding a semicolon (statement terminator).
 139   
      * This method will add a newline after the script.
 140   
      *  
 141   
      */
 142   
 
 143  0
     public void addFinalizationScript(String script) {
 144  0
         if (_finalizationScript == null)
 145  0
             _finalizationScript = new StringBuffer(script.length() + 1);
 146   
 
 147  0
         _finalizationScript.append(script);
 148  0
         _finalizationScript.append('\n');
 149   
 
 150   
     }
 151   
 
 152   
     /**
 153   
      * Adds additional scripting code to the page. This code will be added to a
 154   
      * large block of scripting code at the top of the page (i.e., the before
 155   
      * the &lt;body&gt; tag).
 156   
      * 
 157   
      * <p>
 158   
      * This is typically used to add some form of JavaScript event handler to a
 159   
      * page. For example, the {@link Rollover}component makes use of this.
 160   
      * 
 161   
      * <p>
 162   
      * Another way this is invoked is by using the {@link Script}component.
 163   
      * 
 164   
      * <p>
 165   
      * The string will be added, as-is, within the &lt;script&gt; block
 166   
      * generated by this <code>Body</code> component. The script should
 167   
      * <em>not</em> contain HTML comments, those will be supplied by this Body
 168   
      * component.
 169   
      * 
 170   
      * <p>
 171   
      * A frequent use is to add an initialization function using this method,
 172   
      * then cause it to be executed using
 173   
      * {@link #addOtherInitialization(String)}.
 174   
      *  
 175   
      */
 176   
 
 177  0
     public void addBodyScript(String script) {
 178  0
         if (_bodyScript == null)
 179  0
             _bodyScript = new StringBuffer(script.length());
 180   
 
 181  0
         _bodyScript.append(script);
 182   
     }
 183   
 
 184   
     /**
 185   
      * Used to include a script from an outside URL (the scriptLocation is a
 186   
      * URL, probably obtained from an asset. This adds an &lt;script
 187   
      * src="..."&gt; tag before the main &lt;script&gt; tag. The Body component
 188   
      * ensures that each URL is included only once.
 189   
      * 
 190   
      * @since 1.0.5
 191   
      *  
 192   
      */
 193   
 
 194  0
     public void addExternalScript(IResourceLocation scriptLocation) {
 195  0
         if (_externalScripts == null)
 196  0
             _externalScripts = new ArrayList();
 197   
 
 198  0
         if (_externalScripts.contains(scriptLocation))
 199  0
             return;
 200   
 
 201   
         // Alas, this won't give a good ILocation for the actual problem.
 202   
 
 203  0
         if (!(scriptLocation instanceof ClasspathResourceLocation))
 204  0
             throw new ApplicationRuntimeException(
 205   
                     "Body.include-classpath-script-only", this, null, null);
 206   
 
 207   
         // Record the URL so we don't include it twice.
 208   
 
 209  0
         _externalScripts.add(scriptLocation);
 210   
     }
 211   
 
 212   
     /**
 213   
      * Writes &lt;script&gt; elements for all the external scripts.
 214   
      */
 215  0
     private void writeExternalScripts(IMarkupWriter writer) {
 216  0
         int count = Tapestry.size(_externalScripts);
 217  0
         for (int i = 0; i < count; i++) {
 218  0
             ClasspathResourceLocation scriptLocation = (ClasspathResourceLocation) _externalScripts
 219   
                     .get(i);
 220   
 
 221   
             // This is still very awkward! Should move the code inside
 222   
             // PrivateAsset somewhere
 223   
             // else, so that an asset does not have to be created to to build
 224   
             // the URL.
 225  0
             PrivateAsset asset = new PrivateAsset(scriptLocation, null);
 226  0
             String url = asset.buildURL(getPage().getRequestCycle());
 227   
 
 228   
             // Note: important to use begin(), not beginEmpty(), because browser
 229   
             // don't
 230   
             // interpret <script .../> properly.
 231   
 
 232  0
             writer.begin("script");
 233  0
             writer.attribute("language", "JavaScript");
 234  0
             writer.attribute("type", "text/javascript");
 235  0
             writer.attribute("src", url);
 236  0
             writer.end();
 237  0
             writer.println();
 238   
         }
 239   
 
 240   
     }
 241   
 
 242   
     /**
 243   
      * Retrieves the <code>Body</code> that was stored into the request cycle.
 244   
      * This allows components wrapped by the <code>Body</code> to locate it
 245   
      * and access the services it provides.
 246   
      *  
 247   
      */
 248   
 
 249  0
     public static Body get(IRequestCycle cycle) {
 250  0
         return (Body) cycle.getAttribute(ATTRIBUTE_NAME);
 251   
     }
 252   
 
 253  0
     protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
 254  0
         if (cycle.getAttribute(ATTRIBUTE_NAME) != null)
 255  0
             throw new ApplicationRuntimeException(Tapestry
 256   
                     .getMessage("Body.may-not-nest"), this, null, null);
 257   
 
 258  0
         cycle.setAttribute(ATTRIBUTE_NAME, this);
 259   
 
 260  0
         _outerWriter = writer;
 261   
 
 262  0
         IMarkupWriter nested = writer.getNestedWriter();
 263   
 
 264  0
         renderBody(nested, cycle);
 265   
 
 266   
         // Start the body tag.
 267  0
         writer.println();
 268  0
         writer.begin(getElement());
 269  0
         renderInformalParameters(writer, cycle);
 270   
 
 271  0
         writer.println();
 272   
 
 273   
         // Write the page's scripting. This is included scripts
 274   
         // and dynamic JavaScript, including initialization.
 275   
 
 276  0
         writeScript();
 277   
 
 278   
         // Close the nested writer, which dumps its buffered content
 279   
         // into its parent.
 280   
 
 281  0
         nested.close();
 282   
 
 283  0
         writer.end(); // <body>
 284   
 
 285   
     }
 286   
 
 287  0
     protected void cleanupAfterRender(IRequestCycle cycle) {
 288  0
         super.cleanupAfterRender(cycle);
 289   
 
 290  0
         if (_idAllocator != null)
 291  0
             _idAllocator.clear();
 292   
 
 293  0
         if (_imageMap != null)
 294  0
             _imageMap.clear();
 295   
 
 296  0
         if (_externalScripts != null)
 297  0
             _externalScripts.clear();
 298   
 
 299  0
         if (_initializationScript != null)
 300  0
             _initializationScript.setLength(0);
 301   
 
 302  0
         if (_finalizationScript != null)
 303  0
             _finalizationScript.setLength(0);
 304   
 
 305  0
         if (_imageInitializations != null)
 306  0
             _imageInitializations.setLength(0);
 307   
 
 308  0
         if (_bodyScript != null)
 309  0
             _bodyScript.setLength(0);
 310   
 
 311  0
         _outerWriter = null;
 312  0
         _outerWriter = null;
 313   
     }
 314   
 
 315   
     /**
 316   
      * Writes a single large JavaScript block containing:
 317   
      * <ul>
 318   
      * <li>Any image initializations
 319   
      * <li>Any scripting
 320   
      * <li>Any initializations
 321   
      * </ul>
 322   
      * 
 323   
      * <p>
 324   
      * The script is written into a nested markup writer.
 325   
      * 
 326   
      * <p>
 327   
      * If there are any other initializations (see
 328   
      * {@link #addOtherInitialization(String)}), then a function to execute
 329   
      * them is created.
 330   
      */
 331   
 
 332  0
     protected void writeScript() {
 333  0
         if (!Tapestry.isEmpty(_externalScripts))
 334  0
             writeExternalScripts(_outerWriter);
 335   
 
 336  0
         if (!(any(_initializationScript) || any(_finalizationScript)
 337   
                 || any(_bodyScript) || any(_imageInitializations)))
 338  0
             return;
 339   
 
 340  0
         _outerWriter.begin("script");
 341  0
         _outerWriter.attribute("language", "JavaScript");
 342  0
         _outerWriter.printRaw("<!--");
 343   
 
 344  0
         if (any(_imageInitializations)) {
 345  0
             _outerWriter.printRaw("\n\nvar tapestry_preload = new Array();\n");
 346  0
             _outerWriter.printRaw("if (document.images)\n");
 347  0
             _outerWriter.printRaw("{\n");
 348  0
             _outerWriter.printRaw(_imageInitializations.toString());
 349  0
             _outerWriter.printRaw("}\n");
 350   
         }
 351   
 
 352  0
         if (any(_bodyScript)) {
 353  0
             _outerWriter.printRaw("\n\n");
 354  0
             _outerWriter.printRaw(_bodyScript.toString());
 355   
         }
 356   
 
 357  0
         if (any(_initializationScript)) {
 358  0
             _outerWriter.printRaw("\n\n" + "window.onload = function ()\n"
 359   
                     + "{\n");
 360  0
             _outerWriter.printRaw(_initializationScript.toString());
 361  0
             _outerWriter.printRaw("}");
 362   
         }
 363   
 
 364  0
         if (any(_finalizationScript)) {
 365  0
             _outerWriter.printRaw("\n\n" + "window.onunload = function ()\n"
 366   
                     + "{\n");
 367  0
             _outerWriter.printRaw(_finalizationScript.toString());
 368  0
             _outerWriter.printRaw("}");
 369   
         }
 370   
 
 371  0
         _outerWriter.printRaw("\n\n// -->");
 372  0
         _outerWriter.end();
 373   
     }
 374   
 
 375  0
     private boolean any(StringBuffer buffer) {
 376  0
         if (buffer == null)
 377  0
             return false;
 378   
 
 379  0
         return buffer.length() > 0;
 380   
     }
 381   
 
 382   
     public abstract String getElement();
 383   
 
 384   
     public abstract void setElement(String element);
 385   
 
 386   
 }