Save This Page
Home » tapestry-src-5.0.19 » org.apache.tapestry5.internal » [javadoc | source]
    1   // Copyright 2006, 2007, 2008 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.tapestry5.internal;
   16   
   17   import org.apache.tapestry5.OptionModel;
   18   import org.apache.tapestry5.SelectModel;
   19   import org.apache.tapestry5.ioc.Messages;
   20   import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
   21   import org.apache.tapestry5.ioc.internal.util.Defense;
   22   import org.apache.tapestry5.ioc.internal.util.InternalUtils;
   23   
   24   import java.util.List;
   25   import java.util.Map;
   26   import java.util.regex.Pattern;
   27   
   28   /**
   29    * Shared utility methods used by various implementation classes.
   30    */
   31   public class TapestryInternalUtils
   32   {
   33       private static final String SLASH = "/";
   34   
   35       private static final Pattern SLASH_PATTERN = Pattern.compile(SLASH);
   36   
   37       private static final Pattern NON_WORD_PATTERN = Pattern.compile("[^\\w]");
   38   
   39   
   40       /**
   41        * Capitalizes the string, and inserts a space before each upper case character (or sequence of upper case
   42        * characters). Thus "userId" becomes "User Id", etc. Also, converts underscore into space (and capitalizes the
   43        * following word), thus "user_id" also becomes "User Id".
   44        */
   45       public static String toUserPresentable(String id)
   46       {
   47           StringBuilder builder = new StringBuilder(id.length() * 2);
   48   
   49           char[] chars = id.toCharArray();
   50           boolean postSpace = true;
   51           boolean upcaseNext = true;
   52   
   53           for (char ch : chars)
   54           {
   55               if (upcaseNext)
   56               {
   57                   builder.append(Character.toUpperCase(ch));
   58                   upcaseNext = false;
   59   
   60                   continue;
   61               }
   62   
   63               if (ch == '_')
   64               {
   65                   builder.append(' ');
   66                   upcaseNext = true;
   67                   continue;
   68               }
   69   
   70               boolean upperCase = Character.isUpperCase(ch);
   71   
   72               if (upperCase && !postSpace) builder.append(' ');
   73   
   74               builder.append(ch);
   75   
   76               postSpace = upperCase;
   77           }
   78   
   79           return builder.toString();
   80       }
   81   
   82       public static Map<String, String> mapFromKeysAndValues(String... keysAndValues)
   83       {
   84           Map<String, String> result = CollectionFactory.newMap();
   85   
   86           int i = 0;
   87           while (i < keysAndValues.length)
   88           {
   89               String key = keysAndValues[i++];
   90               String value = keysAndValues[i++];
   91   
   92               result.put(key, value);
   93           }
   94   
   95           return result;
   96       }
   97   
   98       /**
   99        * Converts a string to an {@link OptionModel}. The string is of the form "value=label". If the equals sign is
  100        * omitted, then the same value is used for both value and label.
  101        *
  102        * @param input
  103        * @return
  104        */
  105       public static OptionModel toOptionModel(String input)
  106       {
  107           Defense.notNull(input, "input");
  108   
  109           int equalsx = input.indexOf('=');
  110   
  111           if (equalsx < 0) return new OptionModelImpl(input);
  112   
  113           String value = input.substring(0, equalsx);
  114           String label = input.substring(equalsx + 1);
  115   
  116           return new OptionModelImpl(label, value);
  117       }
  118   
  119       /**
  120        * Parses a string input into a series of value=label pairs compatible with {@link #toOptionModel(String)}. Splits
  121        * on commas. Ignores whitespace around commas.
  122        *
  123        * @param input comma seperated list of terms
  124        * @return list of option models
  125        */
  126       public static List<OptionModel> toOptionModels(String input)
  127       {
  128           Defense.notNull(input, "input");
  129   
  130           List<OptionModel> result = CollectionFactory.newList();
  131   
  132           for (String term : input.split(","))
  133               result.add(toOptionModel(term.trim()));
  134   
  135           return result;
  136       }
  137   
  138       /**
  139        * Wraps the result of {@link #toOptionModels(String)} as a {@link SelectModel} (with no option groups).
  140        *
  141        * @param input
  142        * @return
  143        */
  144       public static SelectModel toSelectModel(String input)
  145       {
  146           List<OptionModel> options = toOptionModels(input);
  147   
  148           return new SelectModelImpl(null, options);
  149       }
  150   
  151       /**
  152        * Converts a map entry to an {@link OptionModel}.
  153        *
  154        * @param input
  155        * @return
  156        */
  157       public static OptionModel toOptionModel(Map.Entry input)
  158       {
  159           Defense.notNull(input, "input");
  160   
  161           String label = input.getValue() != null ? String.valueOf(input.getValue()) : "";
  162   
  163           return new OptionModelImpl(label, input.getKey());
  164       }
  165   
  166       /**
  167        * Processes a map input into a series of map entries compatible with {@link #toOptionModel(Map.Entry)}.
  168        *
  169        * @param input map of elements
  170        * @return list of option models
  171        */
  172       public static <K, V> List<OptionModel> toOptionModels(Map<K, V> input)
  173       {
  174           Defense.notNull(input, "input");
  175   
  176           List<OptionModel> result = CollectionFactory.newList();
  177   
  178           for (Map.Entry entry : input.entrySet())
  179               result.add(toOptionModel(entry));
  180   
  181           return result;
  182       }
  183   
  184       /**
  185        * Wraps the result of {@link #toOptionModels(Map)} as a {@link SelectModel} (with no option groups).
  186        *
  187        * @param input
  188        * @return
  189        */
  190       public static <K, V> SelectModel toSelectModel(Map<K, V> input)
  191       {
  192           List<OptionModel> options = toOptionModels(input);
  193   
  194           return new SelectModelImpl(null, options);
  195       }
  196   
  197       /**
  198        * Converts an object to an {@link OptionModel}.
  199        *
  200        * @param input
  201        * @return
  202        */
  203       public static OptionModel toOptionModel(Object input)
  204       {
  205           String label = (input != null ? String.valueOf(input) : "");
  206   
  207           return new OptionModelImpl(label, input);
  208       }
  209   
  210       /**
  211        * Processes a list input into a series of objects compatible with {@link #toOptionModel(Object)}.
  212        *
  213        * @param input list of elements
  214        * @return list of option models
  215        */
  216       public static <E> List<OptionModel> toOptionModels(List<E> input)
  217       {
  218           Defense.notNull(input, "input");
  219   
  220           List<OptionModel> result = CollectionFactory.newList();
  221   
  222           for (E element : input)
  223               result.add(toOptionModel(element));
  224   
  225           return result;
  226       }
  227   
  228       /**
  229        * Wraps the result of {@link #toOptionModels(List)} as a {@link SelectModel} (with no option groups).
  230        *
  231        * @param input
  232        * @return
  233        */
  234       public static <E> SelectModel toSelectModel(List<E> input)
  235       {
  236           List<OptionModel> options = toOptionModels(input);
  237   
  238           return new SelectModelImpl(null, options);
  239       }
  240   
  241       /**
  242        * Parses a key/value pair where the key and the value are seperated by an equals sign. The key and value are
  243        * trimmed of leading and trailing whitespace, and returned as a {@link KeyValue}.
  244        *
  245        * @param input
  246        * @return
  247        */
  248       public static KeyValue parseKeyValue(String input)
  249       {
  250           int pos = input.indexOf('=');
  251   
  252           if (pos < 1) throw new IllegalArgumentException(InternalMessages.badKeyValue(input));
  253   
  254           String key = input.substring(0, pos);
  255           String value = input.substring(pos + 1);
  256   
  257           return new KeyValue(key.trim(), value.trim());
  258       }
  259   
  260   
  261       /**
  262        * Used to convert a property expression into a key that can be used to locate various resources (Blocks, messages,
  263        * etc.). Strips out any punctuation characters, leaving just words characters (letters, number and the
  264        * underscore).
  265        *
  266        * @param expression a property expression
  267        * @return the expression with punctuation removed
  268        */
  269       public static String extractIdFromPropertyExpression(String expression)
  270       {
  271           return replace(expression, NON_WORD_PATTERN, "");
  272       }
  273   
  274       /**
  275        * Looks for a label within the messages based on the id. If found, it is used, otherwise the name is converted to a
  276        * user presentable form.
  277        */
  278       public static String defaultLabel(String id, Messages messages, String propertyExpression)
  279       {
  280           String key = id + "-label";
  281   
  282           if (messages.contains(key)) return messages.get(key);
  283   
  284           return toUserPresentable(extractIdFromPropertyExpression(lastTerm(propertyExpression)));
  285       }
  286   
  287       /**
  288        * Strips a dotted sequence (such as a property expression, or a qualified class name) down to the last term of that
  289        * expression, by locating the last period ('.') in the string.
  290        */
  291       public static String lastTerm(String input)
  292       {
  293           int dotx = input.lastIndexOf('.');
  294   
  295           return input.substring(dotx + 1);
  296       }
  297   
  298       /**
  299        * Converts an list of strings into a space-separated string combining them all, suitable for use as an HTML class
  300        * attribute value.
  301        *
  302        * @param classes classes to combine
  303        * @return the joined classes, or null if classes is empty
  304        */
  305       public static String toClassAttributeValue(List<String> classes)
  306       {
  307           if (classes.isEmpty()) return null;
  308   
  309           return InternalUtils.join(classes, " ");
  310       }
  311   
  312   
  313       /**
  314        * Converts an enum to a label string, allowing for overrides from a message catalog.
  315        * <p/>
  316        * <ul> <li>As key <em>prefix</em>.<em>name</em> if present.  Ex: "ElementType.LOCAL_VARIABLE" <li>As key
  317        * <em>name</em> if present, i.e., "LOCAL_VARIABLE". <li>As a user-presentable version of the name, i.e., "Local
  318        * Variable". </ul>
  319        *
  320        * @param messages the messages to search for the label
  321        * @param prefix
  322        * @param value    to get a label for
  323        * @return the label
  324        */
  325       public static String getLabelForEnum(Messages messages, String prefix, Enum value)
  326       {
  327           String name = value.name();
  328   
  329           String key = prefix + "." + name;
  330   
  331           if (messages.contains(key)) return messages.get(key);
  332   
  333           if (messages.contains(name)) return messages.get(name);
  334   
  335           return toUserPresentable(name.toLowerCase());
  336       }
  337   
  338       public static String getLabelForEnum(Messages messages, Enum value)
  339       {
  340           String prefix = lastTerm(value.getClass().getName());
  341   
  342           return getLabelForEnum(messages, prefix, value);
  343       }
  344   
  345       private static String replace(String input, Pattern pattern, String replacement)
  346       {
  347           return pattern.matcher(input).replaceAll(replacement);
  348       }
  349   
  350       /**
  351        * Determines if the two values are equal. They are equal if they are the exact same value (including if they are
  352        * both null). Otherwise standard equals() comparison is used.
  353        *
  354        * @param <T>
  355        * @param left  value to compare, possibly null
  356        * @param right value to compare, possibly null
  357        * @return true if same value, both null, or equal
  358        */
  359       public static <T> boolean isEqual(T left, T right)
  360       {
  361           if (left == right) return true;
  362   
  363           if (left == null) return right == null;
  364   
  365           return left.equals(right);
  366       }
  367   
  368   
  369       /**
  370        * Splits a path at each slash.
  371        */
  372       public static String[] splitPath(String path)
  373       {
  374           return SLASH_PATTERN.split(path);
  375       }
  376   }

Save This Page
Home » tapestry-src-5.0.19 » org.apache.tapestry5.internal » [javadoc | source]