001: package org.andromda.cartridges.bpm4struts;
002:
003: import org.andromda.metafacades.uml.ManageableEntity;
004: import org.andromda.utils.StringUtilsHelper;
005: import org.apache.commons.lang.StringUtils;
006:
007: import java.util.ArrayList;
008: import java.util.Collection;
009: import java.util.Collections;
010: import java.util.Comparator;
011: import java.util.Enumeration;
012: import java.util.Iterator;
013: import java.util.List;
014: import java.util.regex.Pattern;
015:
016: /**
017: * Contains utilities for bpm4struts.
018: *
019: * @author Wouter Zoons
020: */
021: public final class Bpm4StrutsUtils {
022: /**
023: * Creates and returns a List from an <code>enumeration</code>.
024: *
025: * @param enumeration the enumeration from which to create the List.
026: * @return the new List.
027: */
028: public static List listEnumeration(Enumeration enumeration) {
029: List list;
030: if (enumeration == null) {
031: list = Collections.EMPTY_LIST;
032: } else {
033: list = Collections.list(enumeration);
034: }
035: return list;
036: }
037:
038: private static final Pattern VALIDATOR_TAGGEDVALUE_PATTERN = Pattern
039: .compile("\\w+(\\(\\w+=[^,)]*(,\\w+=[^,)]*)*\\))?");
040:
041: /**
042: * Reads the validator arguments from the the given tagged value.
043: *
044: * @return never null, returns a list of String instances
045: * @throws IllegalArgumentException when the input string does not match the required pattern
046: */
047: public static List parseValidatorArgs(String validatorTaggedValue) {
048: if (validatorTaggedValue == null) {
049: throw new IllegalArgumentException(
050: "Validator tagged value cannot be null");
051: }
052:
053: // check if the input tagged value matches the required pattern
054: if (!VALIDATOR_TAGGEDVALUE_PATTERN
055: .matcher(validatorTaggedValue).matches()) {
056: throw new IllegalArgumentException(
057: "Illegal validator tagged value (this tag is used to specify custom validators "
058: + "and might look like myValidator(myVar=myArg,myVar2=myArg2), perhaps you wanted to use "
059: + "@andromda.presentation.view.field.format?): "
060: + validatorTaggedValue);
061: }
062:
063: final List validatorArgs = new ArrayList();
064:
065: // only keep what is between parentheses (if any)
066: int left = validatorTaggedValue.indexOf('(');
067: if (left > -1) {
068: final int right = validatorTaggedValue.indexOf(')');
069: validatorTaggedValue = validatorTaggedValue.substring(
070: left + 1, right);
071:
072: final String[] pairs = validatorTaggedValue.split(",");
073: for (int i = 0; i < pairs.length; i++) {
074: final String pair = pairs[i];
075: final int equalsIndex = pair.indexOf('=');
076: // it's possible the argument is the empty string
077: if (equalsIndex < pair.length() - 1) {
078: validatorArgs.add(pair.substring(equalsIndex + 1));
079: } else {
080: validatorArgs.add("");
081: }
082: }
083: }
084: return validatorArgs;
085: }
086:
087: /**
088: * Reads the validator variable names from the the given tagged value.
089: *
090: * @return never null, returns a list of String instances
091: * @throws IllegalArgumentException when the input string does not match the required pattern
092: */
093: public static List parseValidatorVars(String validatorTaggedValue) {
094: if (validatorTaggedValue == null) {
095: throw new IllegalArgumentException(
096: "Validator tagged value cannot be null");
097: }
098:
099: // check if the input tagged value matches the required pattern
100: if (!VALIDATOR_TAGGEDVALUE_PATTERN
101: .matcher(validatorTaggedValue).matches()) {
102: throw new IllegalArgumentException(
103: "Illegal validator tagged value: "
104: + validatorTaggedValue);
105: }
106:
107: final List validatorVars = new ArrayList();
108:
109: // only keep what is between parentheses (if any)
110: int left = validatorTaggedValue.indexOf('(');
111: if (left > -1) {
112: int right = validatorTaggedValue.indexOf(')');
113: validatorTaggedValue = validatorTaggedValue.substring(
114: left + 1, right);
115:
116: final String[] pairs = validatorTaggedValue.split(",");
117: for (int i = 0; i < pairs.length; i++) {
118: final String pair = pairs[i];
119: final int equalsIndex = pair.indexOf('=');
120: validatorVars.add(pair.substring(0, equalsIndex));
121: }
122: }
123: return validatorVars;
124: }
125:
126: /**
127: * Parses the validator name for a tagged value.
128: *
129: * @throws IllegalArgumentException when the input string does not match the required pattern
130: */
131: public static String parseValidatorName(String validatorTaggedValue) {
132: if (validatorTaggedValue == null) {
133: throw new IllegalArgumentException(
134: "Validator tagged value cannot be null");
135: }
136:
137: // check if the input tagged value matches the required pattern
138: if (!VALIDATOR_TAGGEDVALUE_PATTERN
139: .matcher(validatorTaggedValue).matches()) {
140: throw new IllegalArgumentException(
141: "Illegal validator tagged value: "
142: + validatorTaggedValue);
143: }
144:
145: final int leftParen = validatorTaggedValue.indexOf('(');
146: return (leftParen == -1) ? validatorTaggedValue
147: : validatorTaggedValue.substring(0, leftParen);
148: }
149:
150: /**
151: * Sorts a collection of Manageable entities according to their 'manageableName' property.
152: * Returns a new collection.
153: */
154: public static Collection sortManageables(Collection collection) {
155: final List sorted = new ArrayList(collection);
156: Collections.sort(sorted, new ManageableEntityComparator());
157: return sorted;
158: }
159:
160: /**
161: * Converts the argument into a web file name, this means: all lowercase
162: * characters and words are separated with dashes.
163: *
164: * @param string any string
165: * @return the string converted to a value that would be well-suited for a
166: * web file name
167: */
168: public static String toWebFileName(final String string) {
169: return StringUtilsHelper.toPhrase(string).replace(' ', '-')
170: .toLowerCase();
171: }
172:
173: /**
174: * Returns <code>true</code> if the argument name will not cause any troubles with the Jakarta commons-beanutils
175: * library, which basically means it does not start with an lowercase characters followed by an uppercase character.
176: * This means there's a bug in that specific library that causes an incompatibility with the Java Beans
177: * specification as implemented in the JDK.
178: *
179: * @param name the name to test, may be <code>null</code>
180: * @return <code>true</code> if the name is safe to use with the Jakarta libraries, <code>false</code> otherwise
181: */
182: public static boolean isSafeName(final String name) {
183: boolean safe = true;
184:
185: if (name != null && name.length() > 1) {
186: safe = !(Character.isLowerCase(name.charAt(0)) && Character
187: .isUpperCase(name.charAt(1)));
188: }
189:
190: return safe;
191: }
192:
193: /**
194: * Returns a sequence of file formats representing the desired export types for the display tag tables
195: * used for the argument element.
196: *
197: * @param taggedValues the collection of tagged values representing the export types, should only contain
198: * <code>java.lang.String</code> instances and must never be <code>null</code>
199: * @param defaultValue the default value to use in case the tagged values are empty
200: * @return a space separated list of formats, never <code>null</code>
201: */
202: public static String getDisplayTagExportTypes(
203: final Collection taggedValues, final String defaultValue) {
204: String exportTypes;
205:
206: if (taggedValues.isEmpty()) {
207: exportTypes = defaultValue;
208: } else {
209: if (taggedValues.contains("none")) {
210: exportTypes = "none";
211: } else {
212: final StringBuffer buffer = new StringBuffer();
213: for (final Iterator iterator = taggedValues.iterator(); iterator
214: .hasNext();) {
215: final String exportType = StringUtils
216: .trimToNull(String.valueOf(iterator.next()));
217: if ("csv".equalsIgnoreCase(exportType)
218: || "pdf".equalsIgnoreCase(exportType)
219: || "xml".equalsIgnoreCase(exportType)
220: || "excel".equalsIgnoreCase(exportType)) {
221: buffer.append(exportType);
222: buffer.append(' ');
223: }
224: }
225: exportTypes = buffer.toString().trim();
226: }
227: }
228:
229: return exportTypes;
230: }
231:
232: /**
233: * Convenient method to detect whether or not a String instance represents a boolean <code>true</code> value.
234: */
235: public static boolean isTrue(String string) {
236: return "yes".equalsIgnoreCase(string)
237: || "true".equalsIgnoreCase(string)
238: || "on".equalsIgnoreCase(string)
239: || "1".equalsIgnoreCase(string);
240: }
241:
242: final static class ManageableEntityComparator implements Comparator {
243: public int compare(Object left, Object right) {
244: final ManageableEntity leftEntity = (ManageableEntity) left;
245: final ManageableEntity rightEntity = (ManageableEntity) right;
246: return StringUtils.trimToEmpty(leftEntity.getName())
247: .compareTo(
248: StringUtils.trimToEmpty(rightEntity
249: .getName()));
250: }
251: }
252: }
|