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