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