Clover coverage report - Code Coverage for tapestry release 4.0-beta-6
Coverage timestamp: Wed Sep 7 2005 18:41:34 EDT
file stats: LOC: 275   Methods: 13
NCLOC: 125   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
TapestryUtils.java 100% 100% 100% 100%
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;
 16   
 17    import java.util.ArrayList;
 18    import java.util.List;
 19   
 20    import org.apache.hivemind.ApplicationRuntimeException;
 21    import org.apache.hivemind.HiveMind;
 22    import org.apache.hivemind.util.Defense;
 23   
 24    /**
 25    * Constants and static methods.
 26    *
 27    * @author Howard M. Lewis Ship
 28    * @since 4.0
 29    */
 30    public class TapestryUtils
 31    {
 32    private static final char QUOTE = '\'';
 33   
 34    private static final char BACKSLASH = '\\';
 35   
 36    /**
 37    * Stores an attribute into the request cycle, verifying that no object with that key is already
 38    * present.
 39    *
 40    * @param cycle
 41    * the cycle to store the attribute into
 42    * @param key
 43    * the key to store the attribute as
 44    * @param object
 45    * the attribute value to store
 46    * @throws IllegalStateException
 47    * if a non-null value has been stored into the cycle with the provided key.
 48    */
 49   
 50  151 public static void storeUniqueAttribute(IRequestCycle cycle, String key, Object object)
 51    {
 52  151 Defense.notNull(cycle, "cycle");
 53  151 Defense.notNull(key, "key");
 54  151 Defense.notNull(object, "object");
 55   
 56  151 Object existing = cycle.getAttribute(key);
 57  151 if (existing != null)
 58  1 throw new IllegalStateException(TapestryMessages.nonUniqueAttribute(
 59    object,
 60    key,
 61    existing));
 62   
 63  150 cycle.setAttribute(key, object);
 64    }
 65   
 66    public static final String PAGE_RENDER_SUPPORT_ATTRIBUTE = "org.apache.tapestry.PageRenderSupport";
 67   
 68    public static final String FORM_ATTRIBUTE = "org.apache.tapestry.Form";
 69   
 70    /**
 71    * Stores the support object using {@link #storeUniqueAttribute(IRequestCycle, String, Object)}.
 72    */
 73   
 74  76 public static void storePageRenderSupport(IRequestCycle cycle, PageRenderSupport support)
 75    {
 76  76 storeUniqueAttribute(cycle, PAGE_RENDER_SUPPORT_ATTRIBUTE, support);
 77    }
 78   
 79    /**
 80    * Store the IForm instance using {@link #storeUniqueAttribute(IRequestCycle, String, Object)}.
 81    */
 82   
 83  73 public static void storeForm(IRequestCycle cycle, IForm form)
 84    {
 85  73 storeUniqueAttribute(cycle, FORM_ATTRIBUTE, form);
 86    }
 87   
 88    /**
 89    * Gets the previously stored {@link org.apache.tapestry.PageRenderSupport} object.
 90    *
 91    * @param cycle
 92    * the request cycle storing the support object
 93    * @param component
 94    * the component which requires the support (used to report exceptions)
 95    * @throws ApplicationRuntimeException
 96    * if no support object has been stored
 97    */
 98   
 99  10 public static PageRenderSupport getPageRenderSupport(IRequestCycle cycle, IComponent component)
 100    {
 101  10 Defense.notNull(component, "component");
 102   
 103  10 PageRenderSupport result = getOptionalPageRenderSupport(cycle);
 104  10 if (result == null)
 105  2 throw new ApplicationRuntimeException(TapestryMessages.noPageRenderSupport(component),
 106    component.getLocation(), null);
 107   
 108  8 return result;
 109    }
 110   
 111    /**
 112    * Gets the previously stored {@link IForm} object.
 113    *
 114    * @param cycle
 115    * the request cycle storing the support object
 116    * @param component
 117    * the component which requires the form (used to report exceptions)
 118    * @throws ApplicationRuntimeException
 119    * if no form object has been stored
 120    */
 121  130 public static IForm getForm(IRequestCycle cycle, IComponent component)
 122    {
 123  130 Defense.notNull(cycle, "cycle");
 124  130 Defense.notNull(component, "component");
 125   
 126  130 IForm result = (IForm) cycle.getAttribute(FORM_ATTRIBUTE);
 127   
 128  130 if (result == null)
 129  2 throw new ApplicationRuntimeException(TapestryMessages.noForm(component), component
 130    .getLocation(), null);
 131   
 132  128 return result;
 133    }
 134   
 135  77 public static void removePageRenderSupport(IRequestCycle cycle)
 136    {
 137  77 cycle.removeAttribute(PAGE_RENDER_SUPPORT_ATTRIBUTE);
 138    }
 139   
 140  74 public static void removeForm(IRequestCycle cycle)
 141    {
 142  74 cycle.removeAttribute(FORM_ATTRIBUTE);
 143    }
 144   
 145    /**
 146    * Returns the {@link PageRenderSupport} object if previously stored, or null otherwise.
 147    * This is used in the rare case that a component wishes to adjust its behavior based on whether
 148    * the page render support services are avaiable (typically, adjust for whether enclosed by a
 149    * Body component, or not).
 150    */
 151   
 152  102 public static PageRenderSupport getOptionalPageRenderSupport(IRequestCycle cycle)
 153    {
 154  102 return (PageRenderSupport) cycle.getAttribute(PAGE_RENDER_SUPPORT_ATTRIBUTE);
 155    }
 156   
 157    /**
 158    * Splits a string using the default delimiter of ','.
 159    */
 160   
 161  367 public static String[] split(String input)
 162    {
 163  367 return split(input, ',');
 164    }
 165   
 166    /**
 167    * Splits a single string into an array of strings, using a specific delimiter character.
 168    */
 169   
 170  421 public static String[] split(String input, char delimiter)
 171    {
 172  421 if (HiveMind.isBlank(input))
 173  309 return new String[0];
 174   
 175  112 List strings = new ArrayList();
 176   
 177  112 char[] buffer = input.toCharArray();
 178   
 179  112 int start = 0;
 180  112 int length = 0;
 181   
 182  112 for (int i = 0; i < buffer.length; i++)
 183    {
 184  882 if (buffer[i] != delimiter)
 185    {
 186  814 length++;
 187  814 continue;
 188    }
 189   
 190    // Consecutive delimiters will result in a sequence
 191    // of empty strings.
 192   
 193  68 String token = new String(buffer, start, length);
 194  68 strings.add(token);
 195   
 196  68 start = i + 1;
 197  68 length = 0;
 198    }
 199   
 200    // If the string contains no delimiters, then
 201    // wrap it an an array and return it.
 202   
 203  112 if (start == 0 && length == buffer.length)
 204    {
 205  80 return new String[]
 206    { input };
 207    }
 208   
 209    // The final token.
 210  32 String token = new String(buffer, start, length);
 211  32 strings.add(token);
 212   
 213  32 return (String[]) strings.toArray(new String[strings.size()]);
 214    }
 215   
 216    /**
 217    * Enquotes a string within single quotes, ready for insertion as part of a block of JavaScript.
 218    * Single quotes and backslashes within the input string are properly escaped.
 219    */
 220   
 221  18 public static String enquote(String input)
 222    {
 223  18 Defense.notNull(input, "input");
 224   
 225  18 char[] chars = input.toCharArray();
 226   
 227    // Add room for the two quotes and a couple of escaped characters
 228   
 229  18 StringBuffer buffer = new StringBuffer(chars.length + 5);
 230   
 231  18 buffer.append(QUOTE);
 232   
 233  18 for (int i = 0; i < chars.length; i++)
 234    {
 235  308 char ch = chars[i];
 236   
 237  308 if (ch == QUOTE || ch == BACKSLASH)
 238  13 buffer.append(BACKSLASH);
 239   
 240  308 buffer.append(ch);
 241    }
 242   
 243  18 buffer.append(QUOTE);
 244   
 245  18 return buffer.toString();
 246    }
 247   
 248    /**
 249    * A Tapestry component id is a little more liberal than an XML NMTOKEN. NMTOKEN must be
 250    * [A-Za-z][A-Za-z0-9:_.-]*, but a component id might include a leading dollar sign (for an
 251    * anonymous component with a fabricated id).
 252    */
 253   
 254  171 public static String convertTapestryIdToNMToken(String baseId)
 255    {
 256  171 String result = baseId.replace('$', '_');
 257   
 258  171 while (result.startsWith("_"))
 259  78 result = result.substring(1);
 260   
 261  171 return result;
 262    }
 263   
 264    /**
 265    * Converts a clientId into a client-side DOM reference; i.e.
 266    * <code>document.getElementById('<i>id</i>')</code>.
 267    */
 268   
 269  1 public static String buildClientElementReference(String clientId)
 270    {
 271  1 Defense.notNull(clientId, "clientId");
 272   
 273  1 return "document.getElementById('" + clientId + "')";
 274    }
 275    }