Clover coverage report - Code Coverage for tapestry release 4.0-alpha-3
Coverage timestamp: Mon May 16 2005 09:05:49 EDT
file stats: LOC: 265   Methods: 11
NCLOC: 151   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
PageRenderSupportImpl.java 96.7% 98.8% 100% 98.3%
coverage coverage
 1   
 // Copyright 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   
 
 15   
 package org.apache.tapestry.util;
 16   
 
 17   
 import java.util.ArrayList;
 18   
 import java.util.HashMap;
 19   
 import java.util.List;
 20   
 import java.util.Map;
 21   
 
 22   
 import org.apache.hivemind.ApplicationRuntimeException;
 23   
 import org.apache.hivemind.Locatable;
 24   
 import org.apache.hivemind.Location;
 25   
 import org.apache.hivemind.Resource;
 26   
 import org.apache.hivemind.util.ClasspathResource;
 27   
 import org.apache.hivemind.util.Defense;
 28   
 import org.apache.tapestry.IMarkupWriter;
 29   
 import org.apache.tapestry.IRequestCycle;
 30   
 import org.apache.tapestry.PageRenderSupport;
 31   
 import org.apache.tapestry.Tapestry;
 32   
 import org.apache.tapestry.asset.PrivateAsset;
 33   
 import org.apache.tapestry.engine.IEngineService;
 34   
 
 35   
 /**
 36   
  * Implementation of {@link org.apache.tapestry.PageRenderSupport}. The
 37   
  * {@link org.apache.tapestry.html.Body} component uses an instance of this class.
 38   
  * 
 39   
  * @author Howard M. Lewis Ship
 40   
  * @since 4.0
 41   
  */
 42   
 public class PageRenderSupportImpl implements Locatable, PageRenderSupport
 43   
 {
 44   
     private final IEngineService _assetService;
 45   
 
 46   
     private final Location _location;
 47   
 
 48   
     // Lines that belong inside the onLoad event handler for the <body> tag.
 49   
     private StringBuffer _initializationScript;
 50   
 
 51   
     // Any other scripting desired
 52   
 
 53   
     private StringBuffer _bodyScript;
 54   
 
 55   
     // Contains text lines related to image initializations
 56   
 
 57   
     private StringBuffer _imageInitializations;
 58   
 
 59   
     /**
 60   
      * Map of URLs to Strings (preloaded image references).
 61   
      */
 62   
 
 63   
     private Map _imageMap;
 64   
 
 65   
     /**
 66   
      * List of included scripts. Values are Strings.
 67   
      * 
 68   
      * @since 1.0.5
 69   
      */
 70   
 
 71   
     private List _externalScripts;
 72   
 
 73   
     private final IdAllocator _idAllocator;
 74   
 
 75   
     private final String _preloadName;
 76   
 
 77  101
     public PageRenderSupportImpl(IEngineService assetService, String namespace, Location location)
 78   
     {
 79  101
         Defense.notNull(assetService, "assetService");
 80   
 
 81  101
         _assetService = assetService;
 82  101
         _location = location;
 83  101
         _idAllocator = new IdAllocator(namespace);
 84   
 
 85  101
         _preloadName = (namespace.equals("") ? "tapestry" : namespace) + "_preload";
 86   
     }
 87   
 
 88   
     /**
 89   
      * Returns the location, which may be used in error messages. In practical terms, this is the
 90   
      * location of the {@link org.apache.tapestry.html.Body}&nbsp;component.
 91   
      */
 92   
 
 93  1
     public Location getLocation()
 94   
     {
 95  1
         return _location;
 96   
     }
 97   
 
 98  4
     public String getPreloadedImageReference(String URL)
 99   
     {
 100  4
         if (_imageMap == null)
 101  2
             _imageMap = new HashMap();
 102   
 
 103  4
         String reference = (String) _imageMap.get(URL);
 104   
 
 105  4
         if (reference == null)
 106   
         {
 107  3
             int count = _imageMap.size();
 108  3
             String varName = _preloadName + "[" + count + "]";
 109  3
             reference = varName + ".src";
 110   
 
 111  3
             if (_imageInitializations == null)
 112  2
                 _imageInitializations = new StringBuffer();
 113   
 
 114  3
             _imageInitializations.append("  ");
 115  3
             _imageInitializations.append(varName);
 116  3
             _imageInitializations.append(" = new Image();\n");
 117  3
             _imageInitializations.append("  ");
 118  3
             _imageInitializations.append(reference);
 119  3
             _imageInitializations.append(" = \"");
 120  3
             _imageInitializations.append(URL);
 121  3
             _imageInitializations.append("\";\n");
 122   
 
 123  3
             _imageMap.put(URL, reference);
 124   
         }
 125   
 
 126  4
         return reference;
 127   
     }
 128   
 
 129  7
     public void addBodyScript(String script)
 130   
     {
 131  7
         if (_bodyScript == null)
 132  5
             _bodyScript = new StringBuffer(script.length());
 133   
 
 134  7
         _bodyScript.append(script);
 135   
     }
 136   
 
 137  8
     public void addInitializationScript(String script)
 138   
     {
 139  8
         if (_initializationScript == null)
 140  3
             _initializationScript = new StringBuffer(script.length() + 1);
 141   
 
 142  8
         _initializationScript.append(script);
 143  8
         _initializationScript.append('\n');
 144   
     }
 145   
 
 146  7
     public void addExternalScript(Resource scriptLocation)
 147   
     {
 148  7
         if (_externalScripts == null)
 149  3
             _externalScripts = new ArrayList();
 150   
 
 151  7
         if (_externalScripts.contains(scriptLocation))
 152  3
             return;
 153   
 
 154   
         // Alas, this won't give a good Location for the actual problem.
 155   
 
 156  4
         if (!(scriptLocation instanceof ClasspathResource))
 157  0
             throw new ApplicationRuntimeException(Tapestry.format(
 158   
                     "Body.include-classpath-script-only",
 159   
                     scriptLocation), this, null, null);
 160   
 
 161   
         // Record the URL so we don't include it twice.
 162   
 
 163  4
         _externalScripts.add(scriptLocation);
 164   
 
 165   
     }
 166   
 
 167  13
     public String getUniqueString(String baseValue)
 168   
     {
 169  13
         return _idAllocator.allocateId(baseValue);
 170   
     }
 171   
 
 172  3
     private void writeExternalScripts(IMarkupWriter writer, IRequestCycle cycle)
 173   
     {
 174  3
         int count = Tapestry.size(_externalScripts);
 175  3
         for (int i = 0; i < count; i++)
 176   
         {
 177  4
             ClasspathResource scriptLocation = (ClasspathResource) _externalScripts.get(i);
 178   
 
 179   
             // This is still very awkward! Should move the code inside PrivateAsset somewhere
 180   
             // else, so that an asset does not have to be created to to build the URL.
 181  4
             PrivateAsset asset = new PrivateAsset(scriptLocation, _assetService, null);
 182  4
             String url = asset.buildURL(cycle);
 183   
 
 184   
             // Note: important to use begin(), not beginEmpty(), because browser don't
 185   
             // interpret <script .../> properly.
 186   
 
 187  4
             writer.begin("script");
 188  4
             writer.attribute("language", "JavaScript");
 189  4
             writer.attribute("type", "text/javascript");
 190  4
             writer.attribute("src", url);
 191  4
             writer.end();
 192  4
             writer.println();
 193   
         }
 194   
     }
 195   
 
 196   
     /**
 197   
      * Writes a single large JavaScript block containing:
 198   
      * <ul>
 199   
      * <li>Any image initializations (via {@link #getPreloadedImageReference(String)})
 200   
      * <li>Any included scripts (via {@link #addExternalScript(Resource)})
 201   
      * <li>Any contributions (via {@link #addBodyScript(String)})
 202   
      * </ul>
 203   
      * 
 204   
      * @see #writeInitializationScript(IMarkupWriter)
 205   
      */
 206   
 
 207  88
     public void writeBodyScript(IMarkupWriter writer, IRequestCycle cycle)
 208   
     {
 209  88
         if (!Tapestry.isEmpty(_externalScripts))
 210  3
             writeExternalScripts(writer, cycle);
 211   
 
 212  88
         if (!(any(_bodyScript) || any(_imageInitializations)))
 213  82
             return;
 214   
 
 215  6
         writer.begin("script");
 216  6
         writer.attribute("language", "JavaScript");
 217  6
         writer.attribute("type", "text/javascript");
 218  6
         writer.printRaw("<!--");
 219   
 
 220  6
         if (any(_imageInitializations))
 221   
         {
 222  2
             writer.printRaw("\n\nvar " + _preloadName + " = new Array();\n");
 223  2
             writer.printRaw("if (document.images)\n");
 224  2
             writer.printRaw("{\n");
 225  2
             writer.printRaw(_imageInitializations.toString());
 226  2
             writer.printRaw("}\n");
 227   
         }
 228   
 
 229  6
         if (any(_bodyScript))
 230   
         {
 231  5
             writer.printRaw("\n\n");
 232  5
             writer.printRaw(_bodyScript.toString());
 233   
         }
 234   
 
 235  6
         writer.printRaw("\n\n// -->");
 236  6
         writer.end();
 237   
     }
 238   
 
 239   
     /**
 240   
      * Writes any image initializations; this should be invoked at the end of the render, after all
 241   
      * the related HTML will have already been streamed to the client and parsed by the web browser.
 242   
      * Earlier versions of Tapestry uses a <code>window.onload</code> event handler.
 243   
      */
 244   
 
 245  85
     public void writeInitializationScript(IMarkupWriter writer)
 246   
     {
 247  85
         if (!any(_initializationScript))
 248  82
             return;
 249   
 
 250  3
         writer.begin("script");
 251  3
         writer.attribute("language", "JavaScript");
 252  3
         writer.attribute("type", "text/javascript");
 253  3
         writer.printRaw("<!--\n");
 254   
 
 255  3
         writer.printRaw(_initializationScript.toString());
 256   
 
 257  3
         writer.printRaw("\n// -->");
 258  3
         writer.end();
 259   
     }
 260   
 
 261  268
     private boolean any(StringBuffer buffer)
 262   
     {
 263  268
         return buffer != null && buffer.length() > 0;
 264   
     }
 265   
 }