View Javadoc
1   package org.andromda.cartridges.bpm4struts;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.Collection;
6   import java.util.Collections;
7   import java.util.Comparator;
8   import java.util.Enumeration;
9   import java.util.Iterator;
10  import java.util.List;
11  import java.util.regex.Pattern;
12  import org.andromda.metafacades.uml.ManageableEntity;
13  import org.andromda.utils.StringUtilsHelper;
14  import org.apache.commons.lang.StringUtils;
15  
16  /**
17   * Contains utilities for bpm4struts.
18   *
19   * @author Wouter Zoons
20   */
21  public final class Bpm4StrutsUtils
22  {
23      /**
24       * Creates and returns a List from an <code>enumeration</code>.
25       *
26       * @param enumeration the enumeration from which to create the List.
27       * @return the new List.
28       */
29      public static List listEnumeration(Enumeration enumeration)
30      {
31          List list;
32          if (enumeration == null)
33          {
34              list = Collections.emptyList();
35          }
36          else
37          {
38              list = Collections.list(enumeration);
39          }
40          return list;
41      }
42  
43      private static final Pattern VALIDATOR_TAGGEDVALUE_PATTERN = Pattern.compile(
44          "\\w+(\\(\\w+=[^,)]*(,\\w+=[^,)]*)*\\))?");
45  
46      /**
47       * Reads the validator arguments from the the given tagged value.
48       * @param validatorTaggedValue
49       * @return never null, returns a list of String instances
50       * @throws IllegalArgumentException when the input string does not match the required pattern
51       */
52      public static List<String> parseValidatorArgs(String validatorTaggedValue)
53      {
54          if (validatorTaggedValue == null)
55          {
56              throw new IllegalArgumentException("Validator tagged value cannot be null");
57          }
58  
59          // check if the input tagged value matches the required pattern
60          if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches())
61          {
62              throw new IllegalArgumentException(
63                  "Illegal validator tagged value (this tag is used to specify custom validators " +
64                      "and might look like myValidator(myVar=myArg,myVar2=myArg2), perhaps you wanted to use " +
65                      "andromda_presentation_view_field_format?): " + validatorTaggedValue);
66          }
67  
68          final List<String> validatorArgs = new ArrayList<String>();
69  
70          // only keep what is between parentheses (if any)
71          int left = validatorTaggedValue.indexOf('(');
72          if (left > -1)
73          {
74              final int right = validatorTaggedValue.indexOf(')');
75              validatorTaggedValue = validatorTaggedValue.substring(left + 1, right);
76  
77              final String[] pairs = validatorTaggedValue.split(",");
78              for (int i = 0; i < pairs.length; i++)
79              {
80                  final String pair = pairs[i];
81                  final int equalsIndex = pair.indexOf('=');
82                  // it's possible the argument is the empty string
83                  if (equalsIndex < pair.length() - 1)
84                  {
85                      validatorArgs.add(pair.substring(equalsIndex + 1));
86                  }
87                  else
88                  {
89                      validatorArgs.add("");
90                  }
91              }
92          }
93          return validatorArgs;
94      }
95  
96      /**
97       * Reads the validator variable names from the the given tagged value.
98       *
99       * @param validatorTaggedValue
100      * @return never null, returns a list of String instances
101      * @throws IllegalArgumentException when the input string does not match the required pattern
102      */
103     public static List<String> parseValidatorVars(String validatorTaggedValue)
104     {
105         if (validatorTaggedValue == null)
106         {
107             throw new IllegalArgumentException("Validator tagged value cannot be null");
108         }
109 
110         // check if the input tagged value matches the required pattern
111         if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches())
112         {
113             throw new IllegalArgumentException("Illegal validator tagged value: " + validatorTaggedValue);
114         }
115 
116         final List<String> validatorVars = new ArrayList<String>();
117 
118         // only keep what is between parentheses (if any)
119         int left = validatorTaggedValue.indexOf('(');
120         if (left > -1)
121         {
122             int right = validatorTaggedValue.indexOf(')');
123             validatorTaggedValue = validatorTaggedValue.substring(left + 1, right);
124 
125             final String[] pairs = validatorTaggedValue.split(",");
126             for (int i = 0; i < pairs.length; i++)
127             {
128                 final String pair = pairs[i];
129                 final int equalsIndex = pair.indexOf('=');
130                 validatorVars.add(pair.substring(0, equalsIndex));
131             }
132         }
133         return validatorVars;
134     }
135 
136     /**
137      * Parses the validator name for a tagged value.
138      *
139      * @param validatorTaggedValue
140      * @return validatorTaggedValue.substring(0, leftParen
141      * @throws IllegalArgumentException when the input string does not match the required pattern
142      */
143     public static String parseValidatorName(String validatorTaggedValue)
144     {
145         if (validatorTaggedValue == null)
146         {
147             throw new IllegalArgumentException("Validator tagged value cannot be null");
148         }
149 
150         // check if the input tagged value matches the required pattern
151         if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches())
152         {
153             throw new IllegalArgumentException("Illegal validator tagged value: " + validatorTaggedValue);
154         }
155 
156         final int leftParen = validatorTaggedValue.indexOf('(');
157         return (leftParen == -1) ? validatorTaggedValue : validatorTaggedValue.substring(0, leftParen);
158     }
159 
160     /**
161      * Sorts a collection of Manageable entities according to their 'manageableName' property.
162      * Returns a new collection.
163      * @param collection
164      * @return Collections.sort(sorted, new ManageableEntityComparator())
165      */
166     public static Collection sortManageables(Collection collection)
167     {
168         final List sorted = new ArrayList(collection);
169         Collections.sort(sorted, new ManageableEntityComparator());
170         return sorted;
171     }
172 
173     /**
174      * Converts the argument into a web file name, this means: all lowercase
175      * characters and words are separated with dashes.
176      *
177      * @param string any string
178      * @return the string converted to a value that would be well-suited for a
179      *         web file name
180      */
181     public static String toWebFileName(final String string)
182     {
183         return StringUtilsHelper.toPhrase(string).replace(' ', '-').toLowerCase();
184     }
185 
186     /**
187      * Returns <code>true</code> if the argument name will not cause any troubles with the Jakarta commons-beanutils
188      * library, which basically means it does not start with an lowercase characters followed by an uppercase character.
189      * This means there's a bug in that specific library that causes an incompatibility with the Java Beans
190      * specification as implemented in the JDK.
191      *
192      * @param name the name to test, may be <code>null</code>
193      * @return <code>true</code> if the name is safe to use with the Jakarta libraries, <code>false</code> otherwise
194      */
195     public static boolean isSafeName(final String name)
196     {
197         boolean safe = true;
198 
199         if (name != null && name.length() > 1)
200         {
201             safe = !(Character.isLowerCase(name.charAt(0)) && Character.isUpperCase(name.charAt(1)));
202         }
203 
204         return safe;
205     }
206 
207     /**
208      * Returns a sequence of file formats representing the desired export types for the display tag tables
209      * used for the argument element.
210      *
211      * @param taggedValues the collection of tagged values representing the export types, should only contain
212      *  <code>String</code> instances and must never be <code>null</code>
213      * @param defaultValue the default value to use in case the tagged values are empty
214      * @return a space separated list of formats, never <code>null</code>
215      */
216     public static String getDisplayTagExportTypes(final Collection taggedValues, final String defaultValue)
217     {
218         String exportTypes;
219 
220         if (taggedValues.isEmpty())
221         {
222             exportTypes = defaultValue;
223         }
224         else
225         {
226             if (taggedValues.contains("none"))
227             {
228                 exportTypes = "none";
229             }
230             else
231             {
232                 final StringBuilder buffer = new StringBuilder();
233                 for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();)
234                 {
235                     final String exportType = StringUtils.trimToNull(String.valueOf(iterator.next()));
236                     if ("csv".equalsIgnoreCase(exportType) ||
237                         "pdf".equalsIgnoreCase(exportType) ||
238                         "xml".equalsIgnoreCase(exportType) ||
239                         "excel".equalsIgnoreCase(exportType))
240                     {
241                         buffer.append(exportType);
242                         buffer.append(' ');
243                     }
244                 }
245                 exportTypes = buffer.toString().trim();
246             }
247         }
248 
249         return exportTypes;
250     }
251 
252     /**
253      * Convenient method to detect whether or not a String instance represents a boolean <code>true</code> value.
254      * @param string
255      * @return true if yes, true, on, 1
256      */
257     public static boolean isTrue(String string)
258     {
259         return "yes".equalsIgnoreCase(string) ||
260             "true".equalsIgnoreCase(string) ||
261             "on".equalsIgnoreCase(string) ||
262             "1".equalsIgnoreCase(string);
263     }
264 
265     /**
266      *
267      */
268     static final class ManageableEntityComparator
269         implements Comparator, Serializable
270     {
271         private static final long serialVersionUID = 1L;
272         /**
273          * @see java.util.Comparator#compare(Object, Object)
274          */
275         public int compare(
276             Object left,
277             Object right)
278         {
279             final ManageableEntity leftEntity = (ManageableEntity)left;
280             final ManageableEntity rightEntity = (ManageableEntity)right;
281             return StringUtils.trimToEmpty(leftEntity.getName()).compareTo(
282                 StringUtils.trimToEmpty(rightEntity.getName()));
283         }
284     }
285 }