1 package org.andromda.cartridges.bpm4struts;
2
3 import org.andromda.metafacades.uml.ManageableEntity;
4 import org.andromda.utils.StringUtilsHelper;
5 import org.apache.commons.lang.StringUtils;
6
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.Comparator;
11 import java.util.Enumeration;
12 import java.util.Iterator;
13 import java.util.List;
14 import java.util.regex.Pattern;
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.EMPTY_LIST;
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 *
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 parseValidatorArgs(String validatorTaggedValue)
53 {
54 if (validatorTaggedValue == null)
55 {
56 throw new IllegalArgumentException("Validator tagged value cannot be null");
57 }
58
59
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 validatorArgs = new ArrayList();
69
70
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
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 * @return never null, returns a list of String instances
100 * @throws IllegalArgumentException when the input string does not match the required pattern
101 */
102 public static List parseValidatorVars(String validatorTaggedValue)
103 {
104 if (validatorTaggedValue == null)
105 {
106 throw new IllegalArgumentException("Validator tagged value cannot be null");
107 }
108
109
110 if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches())
111 {
112 throw new IllegalArgumentException("Illegal validator tagged value: " + validatorTaggedValue);
113 }
114
115 final List validatorVars = new ArrayList();
116
117
118 int left = validatorTaggedValue.indexOf('(');
119 if (left > -1)
120 {
121 int right = validatorTaggedValue.indexOf(')');
122 validatorTaggedValue = validatorTaggedValue.substring(left + 1, right);
123
124 final String[] pairs = validatorTaggedValue.split(",");
125 for (int i = 0; i < pairs.length; i++)
126 {
127 final String pair = pairs[i];
128 final int equalsIndex = pair.indexOf('=');
129 validatorVars.add(pair.substring(0, equalsIndex));
130 }
131 }
132 return validatorVars;
133 }
134
135 /**
136 * Parses the validator name for a tagged value.
137 *
138 * @throws IllegalArgumentException when the input string does not match the required pattern
139 */
140 public static String parseValidatorName(String validatorTaggedValue)
141 {
142 if (validatorTaggedValue == null)
143 {
144 throw new IllegalArgumentException("Validator tagged value cannot be null");
145 }
146
147
148 if (!VALIDATOR_TAGGEDVALUE_PATTERN.matcher(validatorTaggedValue).matches())
149 {
150 throw new IllegalArgumentException("Illegal validator tagged value: " + validatorTaggedValue);
151 }
152
153 final int leftParen = validatorTaggedValue.indexOf('(');
154 return (leftParen == -1) ? validatorTaggedValue : validatorTaggedValue.substring(0, leftParen);
155 }
156
157 /**
158 * Sorts a collection of Manageable entities according to their 'manageableName' property.
159 * Returns a new collection.
160 */
161 public static Collection sortManageables(Collection collection)
162 {
163 final List sorted = new ArrayList(collection);
164 Collections.sort(sorted, new ManageableEntityComparator());
165 return sorted;
166 }
167
168 /**
169 * Converts the argument into a web file name, this means: all lowercase
170 * characters and words are separated with dashes.
171 *
172 * @param string any string
173 * @return the string converted to a value that would be well-suited for a
174 * web file name
175 */
176 public static String toWebFileName(final String string)
177 {
178 return StringUtilsHelper.toPhrase(string).replace(' ', '-').toLowerCase();
179 }
180
181 /**
182 * Returns <code>true</code> if the argument name will not cause any troubles with the Jakarta commons-beanutils
183 * library, which basically means it does not start with an lowercase characters followed by an uppercase character.
184 * This means there's a bug in that specific library that causes an incompatibility with the Java Beans
185 * specification as implemented in the JDK.
186 *
187 * @param name the name to test, may be <code>null</code>
188 * @return <code>true</code> if the name is safe to use with the Jakarta libraries, <code>false</code> otherwise
189 */
190 public static boolean isSafeName(final String name)
191 {
192 boolean safe = true;
193
194 if (name != null && name.length() > 1)
195 {
196 safe = !(Character.isLowerCase(name.charAt(0)) && Character.isUpperCase(name.charAt(1)));
197 }
198
199 return safe;
200 }
201
202 /**
203 * Returns a sequence of file formats representing the desired export types for the display tag tables
204 * used for the argument element.
205 *
206 * @param taggedValues the collection of tagged values representing the export types, should only contain
207 * <code>java.lang.String</code> instances and must never be <code>null</code>
208 * @param defaultValue the default value to use in case the tagged values are empty
209 * @return a space separated list of formats, never <code>null</code>
210 */
211 public static String getDisplayTagExportTypes(final Collection taggedValues, final String defaultValue)
212 {
213 String exportTypes;
214
215 if (taggedValues.isEmpty())
216 {
217 exportTypes = defaultValue;
218 }
219 else
220 {
221 if (taggedValues.contains("none"))
222 {
223 exportTypes = "none";
224 }
225 else
226 {
227 final StringBuffer buffer = new StringBuffer();
228 for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();)
229 {
230 final String exportType = StringUtils.trimToNull(String.valueOf(iterator.next()));
231 if ("csv".equalsIgnoreCase(exportType) ||
232 "pdf".equalsIgnoreCase(exportType) ||
233 "xml".equalsIgnoreCase(exportType) ||
234 "excel".equalsIgnoreCase(exportType))
235 {
236 buffer.append(exportType);
237 buffer.append(' ');
238 }
239 }
240 exportTypes = buffer.toString().trim();
241 }
242 }
243
244 return exportTypes;
245 }
246
247 /**
248 * Convenient method to detect whether or not a String instance represents a boolean <code>true</code> value.
249 */
250 public static boolean isTrue(String string)
251 {
252 return "yes".equalsIgnoreCase(string) ||
253 "true".equalsIgnoreCase(string) ||
254 "on".equalsIgnoreCase(string) ||
255 "1".equalsIgnoreCase(string);
256 }
257
258 final static class ManageableEntityComparator
259 implements Comparator
260 {
261 public int compare(
262 Object left,
263 Object right)
264 {
265 final ManageableEntity leftEntity = (ManageableEntity)left;
266 final ManageableEntity rightEntity = (ManageableEntity)right;
267 return StringUtils.trimToEmpty(leftEntity.getName()).compareTo(
268 StringUtils.trimToEmpty(rightEntity.getName()));
269 }
270 }
271 }