View Javadoc
1   package org.andromda.cartridges.bpm4struts.metafacades;
2   
3   import java.util.ArrayList;
4   import java.util.Arrays;
5   import java.util.Collection;
6   import java.util.Collections;
7   import java.util.Iterator;
8   import java.util.LinkedHashMap;
9   import java.util.LinkedHashSet;
10  import java.util.List;
11  import java.util.Map;
12  import org.andromda.cartridges.bpm4struts.Bpm4StrutsGlobals;
13  import org.andromda.cartridges.bpm4struts.Bpm4StrutsProfile;
14  import org.andromda.cartridges.bpm4struts.Bpm4StrutsUtils;
15  import org.andromda.metafacades.uml.ClassifierFacade;
16  import org.andromda.metafacades.uml.EventFacade;
17  import org.andromda.metafacades.uml.FrontEndAction;
18  import org.andromda.metafacades.uml.FrontEndActivityGraph;
19  import org.andromda.metafacades.uml.FrontEndParameter;
20  import org.andromda.metafacades.uml.ModelElementFacade;
21  import org.andromda.metafacades.uml.TransitionFacade;
22  import org.andromda.metafacades.uml.UMLMetafacadeUtils;
23  import org.andromda.metafacades.uml.UMLProfile;
24  import org.andromda.metafacades.uml.UseCaseFacade;
25  import org.andromda.utils.StringUtilsHelper;
26  import org.apache.commons.lang.StringUtils;
27  
28  /**
29   * MetafacadeLogic implementation.
30   *
31   * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter
32   */
33  public class StrutsParameterLogicImpl
34      extends StrutsParameterLogic
35  {
36      private static final long serialVersionUID = 34L;
37      /**
38       * @param metaObject
39       * @param context
40       */
41      public StrutsParameterLogicImpl(Object metaObject,
42                                      String context)
43      {
44          super(metaObject, context);
45      }
46  
47      /**
48       * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetStrutsAction()
49       */
50      protected Object handleGetStrutsAction()
51      {
52          Object actionObject = null;
53  
54          final EventFacade event = getEvent();
55          if (event != null)
56          {
57              final TransitionFacade transition = event.getTransition();
58              if (transition instanceof StrutsAction)
59              {
60                  actionObject = transition;
61              }
62          }
63          return actionObject;
64      }
65  
66      /**
67       * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetStyleId()
68       */
69      protected String handleGetStyleId()
70      {
71          String styleId = null;
72  
73          final StrutsAction action = this.getStrutsAction();
74          if (action != null)
75          {
76              // if this parameter's action links to a table we use a specific styleId
77              if (action.isTableLink())
78              {
79                  styleId = action.getTableLinkName() + StringUtilsHelper.upperCamelCaseName(getName());
80              }
81              else
82              {
83                  final EventFacade trigger = action.getTrigger();
84                  if (trigger != null)
85                  {
86                      styleId = StringUtilsHelper.lowerCamelCaseName(trigger.getName()) +
87                          StringUtilsHelper.upperCamelCaseName(getName());
88                  }
89              }
90          }
91  
92          return styleId;
93      }
94  
95      /**
96       * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetJsp()
97       */
98      protected Object handleGetJsp()
99      {
100         Object jspObject = null;
101 
102         final EventFacade event = getEvent();
103         if (event != null)
104         {
105             final TransitionFacade transition = event.getTransition();
106             if (transition instanceof StrutsAction)
107             {
108                 final StrutsAction action = (StrutsAction)transition;
109                 jspObject = action.getInput();
110             }
111             else if (transition instanceof StrutsForward)
112             {
113                 final StrutsForward forward = (StrutsForward)transition;
114                 if (forward.isEnteringPage())
115                 {
116                     jspObject = forward.getTarget();
117                 }
118             }
119         }
120 
121         return jspObject;
122     }
123 
124     /**
125      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetFormFields()
126      */
127     protected List handleGetFormFields()
128     {
129         final List formFields;
130         if (isControllerOperationArgument() && getName() != null)
131         {
132             final String name = getName();
133             formFields = new ArrayList();
134             Collection actions = this.getControllerOperation().getDeferringActions();
135             for (final Iterator actionIterator = actions.iterator(); actionIterator.hasNext();)
136             {
137                 StrutsAction action = (StrutsAction)actionIterator.next();
138                 Collection actionFormFields = action.getActionFormFields();
139                 for (final Iterator fieldIterator = actionFormFields.iterator(); fieldIterator.hasNext();)
140                 {
141                     StrutsParameter parameter = (StrutsParameter)fieldIterator.next();
142                     if (name.equals(parameter.getName()))
143                     {
144                         formFields.add(parameter);
145                     }
146                 }
147             }
148         }
149         else
150         {
151             formFields = Collections.emptyList();
152         }
153         return formFields;
154     }
155 
156     /**
157      * @return getType().getJavaNullString()
158      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getResetValue()
159      */
160     protected String handleGetNullValue()
161     {
162         String nullValue = null;
163 
164         final ClassifierFacade type = getType();
165         if (type != null)
166         {
167             nullValue = type.getJavaNullString();
168         }
169         return nullValue;
170     }
171 
172     /**
173      * @return isSelectable() or getType()isArrayType() || type.isFileType()) ? true : this.isValidatorBoolean()
174      * @see StrutsParameter#isResetRequired()
175      */
176     protected boolean handleIsResetRequired()
177     {
178         final boolean resetRequired;
179 
180         if (isSelectable())
181         {
182             resetRequired = true;
183         }
184         else
185         {
186             final ClassifierFacade type = getType();
187             if (type == null)
188             {
189                 resetRequired = false;
190             }
191             else
192             {
193                 resetRequired = (type.isArrayType() || type.isFileType()) ? true : this.isValidatorBoolean();
194             }
195         }
196         return resetRequired;
197     }
198 
199     /**
200      * @return messageKey
201      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getMessageKey()
202      */
203     protected String handleGetMessageKey()
204     {
205         final StringBuilder messageKey = new StringBuilder();
206 
207         if (!normalizeMessages())
208         {
209             if (isActionParameter())
210             {
211                 final StrutsAction action = this.getStrutsAction();
212                 if (action != null)
213                 {
214                     messageKey.append(action.getMessageKey());
215                     messageKey.append('.');
216                 }
217             }
218             else
219             {
220                 final StrutsJsp page = getJsp();
221                 if (page != null)
222                 {
223                     messageKey.append(page.getMessageKey());
224                     messageKey.append('.');
225                 }
226             }
227             messageKey.append("param.");
228         }
229 
230         messageKey.append(StringUtilsHelper.toResourceMessageKey(super.getName()));
231         return messageKey.toString();
232     }
233 
234     /**
235      * @return StringUtilsHelper.toPhrase(super.getName())
236      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getMessageValue()
237      */
238     protected String handleGetMessageValue()
239     {
240         return StringUtilsHelper.toPhrase(super.getName()); // the actual name is used for displaying
241     }
242 
243     /**
244      * @return getMessageKey() + ".title"
245      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getTitleKey()
246      */
247     protected String handleGetTitleKey()
248     {
249         return getMessageKey() + ".title";
250     }
251 
252     /**
253      * @return documentation title value
254      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getTitleValue()
255      */
256     protected String handleGetTitleValue()
257     {
258         String requiredSuffix = "";
259         if (isRequired())
260         {
261             requiredSuffix = " is required";
262         }
263 
264         String dateSuffix = "";
265         if (isDate())
266         {
267             dateSuffix = (isStrictDateFormat())
268                 ? " (use this strict format: " + getDateFormat() + ')'
269                 : " (use this lenient format: " + getDateFormat() + ')';
270         }
271 
272         String documentation = this.getDocumentation("", 64, false);
273         return StringUtilsHelper.toResourceMessage(!this.isDocumentationPresent()
274             ? super.getName() + requiredSuffix + dateSuffix
275             : documentation.trim().replaceAll("\n", "<br/>"));
276     }
277 
278     /**
279      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetDocumentationKey()
280      */
281     protected String handleGetDocumentationKey()
282     {
283         return this.getMessageKey() + ".documentation";
284     }
285 
286     /**
287      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetDocumentationValue()
288      */
289     protected String handleGetDocumentationValue()
290     {
291         return (!this.isDocumentationPresent()) ? "" :
292             StringUtilsHelper.toResourceMessage(this.getDocumentation("", 64, false));
293     }
294 
295     /**
296      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetOnlineHelpKey()
297      */
298     protected String handleGetOnlineHelpKey()
299     {
300         return this.getMessageKey() + ".online.help";
301     }
302 
303     /**
304      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetOnlineHelpValue()
305      */
306     protected String handleGetOnlineHelpValue()
307     {
308         final String crlf = "<br/>";
309         final String format = getValidatorFormat();
310         final StringBuilder buffer = new StringBuilder();
311 
312         buffer.append(!this.isDocumentationPresent() ? "No field documentation has been specified"
313             : StringUtilsHelper.toResourceMessage(this.getDocumentation("", 64, false)));
314         buffer.append(crlf);
315         buffer.append(crlf);
316 
317         buffer.append(isRequired() ? "This field is required" : "This field is optional");
318         buffer.append(crlf);
319 
320         if ("password".equals(getWidgetType()))
321         {
322             buffer.append("This is a password field, it will not show the data you enter, ")
323                 .append("each character will be masked using an asterisk");
324             buffer.append(crlf);
325         }
326 
327         if (isCreditCardFormat(format))
328         {
329             buffer.append("The value of this field should reflect a ")
330                 .append("<a href=\"http://www.beachnet.com/~hstiles/cardtype.html\" target=\"_blank\">creditcard</a> ");
331             buffer.append(crlf);
332         }
333 
334         if (isDate())
335         {
336             String dateFormat = getDateFormat();
337             buffer.append("This field represents a date and should be formatted in the matter described here")
338                 .append("<a href=\"http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html\" ")
339                 .append("target=\"_jdk\">");
340             buffer.append(dateFormat).append("</a> ");
341 
342             if (isStrictDateFormat())
343             {
344                 buffer.append("This format is strict in the sense that the parser will not use any heuristics in ")
345                 .append("order to guess the intended date in case the input would not perfectly match the format");
346             }
347             else
348             {
349                 buffer.append("This format is lenient in the sense that the parser will attempt to use heuristics in ")
350                     .append("order to guess the intended date in case the input would not perfectly match the format");
351             }
352             buffer.append(crlf);
353             buffer.append("A calendar has been foreseen to select a date from, it will automatically convert the date ")
354                 .append("to the appropriate format.");
355             buffer.append(crlf);
356         }
357 
358         if (this.isValidatorTime())
359         {
360             String dateFormat = getDateFormat();
361             buffer
362                 .append("This field represents a time and should be formatted in the manner described here (for time) ")
363                 .append("<a href=\"http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html\" ")
364                 .append("target=\"_jdk\">");
365             buffer.append(dateFormat).append("</a> ");
366         }
367 
368         if (isEmailFormat(format))
369         {
370             buffer.append("The value of this field should reflect an email address");
371             buffer.append(crlf);
372         }
373 
374         if (isMaxLengthFormat(format))
375         {
376             buffer.append("This field should not contain more than ");
377             buffer.append(getMaxLengthValue(format));
378             buffer.append(" characters");
379             buffer.append(crlf);
380         }
381 
382         if (isMinLengthFormat(format))
383         {
384             buffer.append("This field should contain at least ");
385             buffer.append(getMinLengthValue(format));
386             buffer.append(" characters");
387             buffer.append(crlf);
388         }
389 
390         if (isPatternFormat(format))
391         {
392             buffer.append("The value should match this ");
393             buffer.append(
394                 "<a href=\"http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html\" target=\"_jdk\">");
395             buffer.append("regular expression</a>: ");
396             buffer.append(getPatternValue(format));
397             buffer.append(crlf);
398         }
399 
400         if (isRangeFormat(format))
401         {
402             buffer.append("The value of this field should be in the range of ");
403             buffer.append(getRangeStart(format));
404             buffer.append(" to ");
405             buffer.append(getRangeEnd(format));
406             buffer.append(crlf);
407         }
408 
409         final String validWhen = getValidWhen();
410         if (validWhen != null)
411         {
412             buffer.append("This field is only valid under specific conditions, more concretely the following ")
413                 .append("expression must evaluate true: ").append(validWhen);
414             buffer.append(crlf);
415         }
416 
417         if (isReadOnly())
418         {
419             buffer.append("The value of this field cannot be changed, it is read-only");
420             buffer.append(crlf);
421         }
422 
423         if (isValidatorBoolean())
424         {
425             buffer.append("The value of this field should reflect a ")
426                 .append("<a href=\"http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html\" ")
427                 .append("target=\"_jdk\">boolean</a> value");
428             buffer.append(crlf);
429         }
430         else if (isValidatorByte())
431         {
432             buffer.append("The value of this field should reflect a ")
433                 .append("<a href=\"http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html\" ")
434                 .append("target=\"_jdk\">byte</a> value");
435             buffer.append(crlf);
436         }
437         else if (isValidatorChar())
438         {
439             buffer.append("The value of this field should reflect a ")
440                 .append("<a href=\"http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html\" ")
441                 .append("target=\"_jdk\">character</a> value");
442             buffer.append(crlf);
443         }
444         else if (isValidatorDouble())
445         {
446             buffer.append("The value of this field should reflect a ")
447                 .append("<a href=\"http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html\" ")
448                 .append("target=\"_jdk\">double precision integer</a> value");
449             buffer.append(crlf);
450         }
451         else if (isValidatorFloat())
452         {
453             buffer.append("The value of this field should reflect a ")
454                 .append("<a href=\"http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html\" ")
455                 .append("target=\"_jdk\">floating point</a> value");
456             buffer.append(crlf);
457         }
458         else if (isValidatorInteger())
459         {
460             buffer.append("The value of this field should reflect a ")
461                 .append("<a href=\"http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html\" ")
462                 .append("target=\"_jdk\">integer</a> value");
463             buffer.append(crlf);
464         }
465         else if (isValidatorLong())
466         {
467             buffer.append("The value of this field should reflect a ")
468                 .append("<a href=\"http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html\" ")
469                 .append("target=\"_jdk\">long integer</a> value");
470             buffer.append(crlf);
471         }
472         else if (isValidatorShort())
473         {
474             buffer.append("The value of this field should reflect a ")
475                 .append("<a href=\"http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html\" ")
476                 .append("target=\"_jdk\">short integer</a> value");
477             buffer.append(crlf);
478         }
479         else if (isValidatorUrl())
480         {
481             buffer.append("The value of this field should reflect a ")
482                 .append("<a href=\"http://java.sun.com/j2se/1.4.2/docs/api/java/net/URL.html\" ")
483                 .append("target=\"_jdk\">URL</a> value");
484             buffer.append(crlf);
485         }
486 
487         return StringUtilsHelper.toResourceMessage(buffer.toString());
488     }
489 
490     /**
491      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsCalendarRequired()
492      */
493     protected boolean handleIsCalendarRequired()
494     {
495         return isDate() && "true".equals(String.valueOf(findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_CALENDAR)));
496     }
497 
498     /**
499      * Overridden since StrutsAction does not extend FrontEndAction.
500      *
501      * @see org.andromda.metafacades.uml.FrontEndParameter#isActionParameter()
502      */
503     public boolean isActionParameter()
504     {
505         final StrutsAction action = getStrutsAction();
506         return (action != null) && action.getActionParameters().contains(this);
507     }
508 
509     /**
510      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetCollectionImplementationType()
511      */
512     protected String handleGetCollectionImplementationType()
513     {
514         String typeName = null;
515 
516         final ClassifierFacade type = this.getType();
517         if (type != null)
518         {
519             if (type.isCollectionType() || type.isListType())
520             {
521                 typeName = "java.util.ArrayList";
522             }
523             else if (type.isSetType())
524             {
525                 typeName = "java.util.HashSet";
526             }
527             else
528             {
529                 typeName = type.getFullyQualifiedName();
530             }
531         }
532         return typeName;
533     }
534 
535     /**
536      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsTableDecoratorRequired()
537      */
538     protected boolean handleIsTableDecoratorRequired()
539     {
540         boolean required = false;
541 
542         if (isTable())
543         {
544             final Object taggedValue = findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_TABLE_DECORATOR);
545             if (taggedValue != null)
546             {
547                 final String taggedValueString = String.valueOf(taggedValue);
548                 required = Boolean.valueOf(taggedValueString).booleanValue();
549             }
550             else
551             {
552                 final Object property = getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_GENERATE_TABLE_DECORATORS);
553                 final String propertyString = String.valueOf(property);
554                 required = Boolean.valueOf(propertyString).booleanValue();
555             }
556         }
557 
558         return required;
559     }
560 
561     /**
562      * Override to not allow selectable parameters to be considered tables.
563      *
564      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#isTable()
565      */
566     public boolean isTable()
567     {
568         return super.isTable() && !this.isSelectable() && !this.isHiddenField();
569     }
570 
571     /**
572      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsAllGlobalTableActionsHaveSameParameter()
573      */
574     protected boolean handleIsAllGlobalTableActionsHaveSameParameter()
575     {
576         boolean sameParameter = true;
577 
578         String name = null;
579         String type = null;
580 
581         final Collection<StrutsAction> actions = this.getTableGlobalActions();
582         for (final Iterator<StrutsAction> actionIterator = actions.iterator(); actionIterator.hasNext() && sameParameter;)
583         {
584             final StrutsAction action = actionIterator.next();
585             final List<StrutsParameter> parameters = action.getActionParameters();
586             if (!parameters.isEmpty())
587             {
588                 final StrutsParameter parameter = parameters.iterator().next();
589                 if (name == null || type == null)
590                 {
591                     name = parameter.getName();
592                     type = parameter.getType().getFullyQualifiedName();
593                 }
594                 else
595                 {
596                     sameParameter = name.equals(parameter.getName()) &&
597                         type.equals(parameter.getType().getFullyQualifiedName());
598                 }
599             }
600         }
601 
602         return sameParameter;
603     }
604 
605     /**
606      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableFormActions()
607      */
608     protected List handleGetTableFormActions()
609     {
610         return this.internalGetTableActions(false, true, false);
611     }
612 
613     /**
614      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableHyperlinkActions()
615      */
616     protected List handleGetTableHyperlinkActions()
617     {
618         return this.internalGetTableActions(true, false, false);
619     }
620 
621     /**
622      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableGlobalActions()
623      */
624     protected Collection handleGetTableGlobalActions()
625     {
626         return this.internalGetTableActions(false, false, true);
627     }
628 
629     /**
630      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableGlobalActionParameter()
631      */
632     protected Object handleGetTableGlobalActionParameter()
633     {
634         Object parameter = null;
635 
636         final Collection<StrutsAction> actions = this.getTableGlobalActions();
637         if (!actions.isEmpty())
638         {
639             final List<StrutsParameter> actionParameters = (actions.iterator().next()).getActionParameters();
640             if (!actionParameters.isEmpty())
641             {
642                 parameter = actionParameters.iterator().next();
643             }
644         }
645 
646         return parameter;
647     }
648 
649     /**
650      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsTableFormActionSharingWidgets()
651      */
652     protected boolean handleIsTableFormActionSharingWidgets()
653     {
654         // @todo (wouter)
655         return true;
656     }
657 
658     /**
659      * If this is a table this method returns all those actions that are declared to work
660      * on this table.
661      */
662     private List internalGetTableActions(boolean hyperlink,
663                                          boolean formPost,
664                                          boolean tableAction)
665     {
666         final String name = StringUtils.trimToNull(getName());
667         if (name == null || !isTable())
668         {
669             return Collections.emptyList();
670         }
671 
672         final StrutsJsp page = this.getJsp();
673 
674         final Collection tableActions = new LinkedHashSet();
675 
676         final Collection<UseCaseFacade> allUseCases = getModel().getAllUseCases();
677         for (final Iterator<UseCaseFacade> useCaseIterator = allUseCases.iterator(); useCaseIterator.hasNext();)
678         {
679             final UseCaseFacade useCase = useCaseIterator.next();
680             if (useCase instanceof StrutsUseCase)
681             {
682                 final FrontEndActivityGraph graph = ((StrutsUseCase)useCase).getActivityGraph();
683                 if (graph != null)
684                 {
685                     final Collection<TransitionFacade> transitions = graph.getTransitions();
686                     for (final Iterator<TransitionFacade> transitionIterator = transitions.iterator(); transitionIterator.hasNext();)
687                     {
688                         final TransitionFacade transition = transitionIterator.next();
689                         if (transition.getSource().equals(page) && transition instanceof StrutsAction)
690                         {
691                             final StrutsAction action = (StrutsAction)transition;
692                             if (action.isTableLink() && name.equals(action.getTableLinkName()))
693                             {
694                                 if ((hyperlink && action.isHyperlink()) ||
695                                     (formPost && action.isFormPost()) ||
696                                     (tableAction && action.isTableAction()))
697                                 {
698                                     tableActions.add(action);
699                                 }
700                             }
701                         }
702                     }
703                 }
704             }
705         }
706         return new ArrayList(tableActions);
707     }
708 
709     /**
710      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableDecoratorFullyQualifiedName()
711      */
712     protected String handleGetTableDecoratorFullyQualifiedName()
713     {
714         String name = getTableDecoratorPackageName();
715         name = (StringUtils.trimToEmpty(name) == null) ? "" : name + '.';
716         return name + getTableDecoratorClassName();
717     }
718 
719     /**
720      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableDecoratorPackageName()
721      */
722     protected String handleGetTableDecoratorPackageName()
723     {
724         final StrutsJsp jsp = getJsp();
725         return (jsp == null) ? null : jsp.getPackageName();
726     }
727 
728     /**
729      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableDecoratorClassName()
730      */
731     protected String handleGetTableDecoratorClassName()
732     {
733         String tableDecoratorClassName = null;
734 
735         final StrutsJsp jsp = getJsp();
736         if (jsp != null)
737         {
738             String suffix = String.valueOf(getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_TABLE_DECORATOR_SUFFIX));
739             tableDecoratorClassName = StringUtilsHelper.upperCamelCaseName(getName()) + suffix;
740         }
741 
742         return tableDecoratorClassName;
743     }
744 
745     /**
746      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableDecoratorFullPath()
747      */
748     protected String handleGetTableDecoratorFullPath()
749     {
750         return getTableDecoratorFullyQualifiedName().replace('.', '/');
751     }
752 
753     /**
754      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableExportTypes()
755      */
756     protected String handleGetTableExportTypes()
757     {
758         return Bpm4StrutsUtils.getDisplayTagExportTypes(
759             this.findTaggedValues(Bpm4StrutsProfile.TAGGEDVALUE_TABLE_EXPORT),
760             (String)getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_DEFAULT_TABLE_EXPORT_TYPES) );
761     }
762 
763     /**
764      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsTableExportable()
765      */
766     protected boolean handleIsTableExportable()
767     {
768         return this.getTableExportTypes().indexOf("none") == -1;
769     }
770 
771     /**
772      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsTableSortable()
773      */
774     protected boolean handleIsTableSortable()
775     {
776         final Object taggedValue = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_TABLE_SORTABLE);
777         return (taggedValue == null)
778             ? Bpm4StrutsProfile.TAGGEDVALUE_TABLE_SORTABLE_DEFAULT_VALUE
779             : Bpm4StrutsUtils.isTrue(String.valueOf(taggedValue));
780     }
781 
782     /**
783      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsTableHyperlinkColumn()
784      */
785     protected boolean handleIsTableHyperlinkColumn()
786     {
787         boolean tableHyperlinkColumn = false;
788 
789         final String name = this.getName();
790         if (name != null)
791         {
792             // this parameter's action must be a table hyperlink
793             final StrutsAction action = this.getStrutsAction();
794             if (action.isHyperlink() && action.isTableLink())
795             {
796                 // get the table and check whether this parameter is part of that table's columns
797                 final StrutsParameter table = action.getTableLinkParameter();
798                 if (table != null)
799                 {
800                     final Collection tableColumns = table.getTableColumns();
801                     // if this parameter's name matches that targetted column name then we have found our column
802                     tableHyperlinkColumn = tableColumns.contains(this) && name.equals(action.getTableLinkColumnName());
803                 }
804             }
805         }
806 
807         return tableHyperlinkColumn;
808     }
809 
810     /**
811      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableColumnActions(String)
812      */
813     protected List<StrutsAction> handleGetTableColumnActions(final String columnName)
814     {
815         final List<StrutsAction> columnActions = new ArrayList<StrutsAction>();
816 
817         if (columnName != null)
818         {
819             // only hyperlinks can target table columns
820             final List<StrutsAction> hyperlinkActions = this.getTableHyperlinkActions();
821             for (int i = 0; i < hyperlinkActions.size(); i++)
822             {
823                 final StrutsAction action = hyperlinkActions.get(i);
824                 if (columnName.equals(action.getTableLinkColumnName()))
825                 {
826                     columnActions.add(action);
827                 }
828             }
829         }
830 
831         return columnActions;
832     }
833 
834     /**
835      * @return true if this parameter represents a table and is an array of custom types (no datatype)
836      */
837     private boolean isCustomArrayTable()
838     {
839         final ClassifierFacade type = this.getType();
840         return type != null && this.isTable() && type.isArrayType() && !type.isDataType();
841     }
842 
843     /**
844      * Overridden since StrutsAction doesn't extend FrontEndAction.
845      *
846      * @see org.andromda.metafacades.uml.FrontEndParameter#getTableColumns()
847      */
848     public Collection getTableColumns()
849     {
850         // in this method we collect the elements that represent the columns of a table
851         // if no specific element (parameter, attribute) can be found a simple String instance
852         // is used
853         // the event parameters have priority to be included in the collection because
854         // they contain additional information such as validation constraint and widget type, ...
855 
856         // try to preserve the order of the elements encountered
857         final Map tableColumnsMap = new LinkedHashMap();
858 
859         // order is important
860         final List<StrutsAction> actions = new ArrayList<StrutsAction>();
861 
862         // all table actions need the exact same parameters, just not always all of them
863         actions.addAll(this.getTableFormActions());
864         // if there are any actions that are hyperlinks then their parameters get priority
865         // the user should not have modeled it that way (constraints will warn him/her)
866         actions.addAll(this.getTableHyperlinkActions());
867 
868         for (final Iterator<StrutsAction> actionIterator = actions.iterator(); actionIterator.hasNext();)
869         {
870             final StrutsAction action = actionIterator.next();
871             final Collection<StrutsParameter>  actionParameters = action.getActionParameters();
872             for (final Iterator<StrutsParameter>  parameterIterator = actionParameters.iterator(); parameterIterator.hasNext();)
873             {
874                 final StrutsParameter parameter = parameterIterator.next();
875                 final String parameterName = parameter.getName();
876                 if (parameterName != null)
877                 {
878                     // never overwrite column specific table links
879                     // the hyperlink table links working on a real column get priority
880                     final StrutsParameter existingParameter = (StrutsParameter)tableColumnsMap.get(parameterName);
881                     if (existingParameter == null ||
882                         (action.isHyperlink() && parameterName.equals(action.getTableLinkColumnName())))
883                     {
884                         tableColumnsMap.put(parameterName, parameter);
885                     }
886                 }
887             }
888         }
889 
890         final Collection<String>  columnNames = this.getTableColumnNames();
891 
892         // in case of a custom array just add the attributes
893         if (this.isCustomArrayTable())
894         {
895             final Collection attributes = this.getType().getNonArray().getAttributes(true);
896             for (final Iterator attributeIterator = attributes.iterator(); attributeIterator.hasNext();)
897             {
898                 final ModelElementFacade attribute = (ModelElementFacade)attributeIterator.next();
899                 // don't override
900                 if (!tableColumnsMap.containsKey(attribute.getName()))
901                 {
902                     tableColumnsMap.put(attribute.getName(), attribute);
903                 }
904             }
905         }
906         else
907         {
908             for (final Iterator<String> columnNameIterator = columnNames.iterator(); columnNameIterator.hasNext();)
909             {
910                 final String columnName = columnNameIterator.next();
911                 // don't override
912                 if (!tableColumnsMap.containsKey(columnName))
913                 {
914                     tableColumnsMap.put(columnName, columnName);
915                 }
916             }
917         }
918 
919         // return everything in the same order as it has been modeled (using the table tagged value)
920         // note that only those columns mentioned in the tagged value are returned
921         final Collection tableColumns = new ArrayList();
922         for (final Iterator columnNameIterator = columnNames.iterator(); columnNameIterator.hasNext();)
923         {
924             final Object columnObject = columnNameIterator.next();
925             tableColumns.add(tableColumnsMap.get(columnObject));
926         }
927         return tableColumns;
928     }
929 
930     /**
931      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableColumnMessageKey(String)
932      */
933     protected String handleGetTableColumnMessageKey(String columnName)
934     {
935         StringBuilder messageKey = null;
936 
937         if (isTable())
938         {
939             messageKey = new StringBuilder();
940 
941             if (!normalizeMessages())
942             {
943                 final StrutsJsp page = getJsp();
944                 if (page != null)
945                 {
946                     messageKey.append(getMessageKey());
947                     messageKey.append('.');
948                 }
949             }
950 
951             messageKey.append(StringUtilsHelper.toResourceMessageKey(columnName));
952         }
953 
954         return (messageKey == null) ? null : messageKey.toString();
955     }
956 
957     /**
958      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableColumnMessageValue(String)
959      */
960     protected String handleGetTableColumnMessageValue(String columnName)
961     {
962         return (isTable()) ? StringUtilsHelper.toPhrase(columnName) : null;
963     }
964 
965     /**
966      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetTableMaxRows()
967      */
968     protected int handleGetTableMaxRows()
969     {
970         final Object taggedValue = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_TABLE_MAXROWS);
971         int pageSize;
972 
973         try
974         {
975             pageSize = Integer.parseInt(String.valueOf(taggedValue));
976         }
977         catch (Exception e)
978         {
979             pageSize = Bpm4StrutsProfile.TAGGEDVALUE_TABLE_MAXROWS_DEFAULT_COUNT;
980         }
981 
982         return pageSize;
983     }
984 
985     /**
986      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetWidgetType()
987      */
988     protected String handleGetWidgetType()
989     {
990         Object value = findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE);
991         final String fieldType = value == null ? null : value.toString();
992 
993         String widgetType = null;
994 
995         if (isActionParameter())
996         {
997             if (fieldType == null)
998             {
999                 // no widget type has been specified
1000                 final ClassifierFacade type = getType();
1001                 if (type != null)
1002                 {
1003                     if (type.isFileType()) {widgetType = Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_FILE;}
1004                     else if (isValidatorBoolean()) {widgetType = Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_CHECKBOX;}
1005                     else if (isMultiple()) {widgetType = Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_SELECT;}
1006                     else {widgetType = Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_TEXT;}
1007                 }
1008             }
1009             else if (Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_SELECT.equalsIgnoreCase(fieldType))
1010             {
1011                 widgetType = "select";
1012             }
1013             else if (Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_PASSWORD.equalsIgnoreCase(fieldType))
1014             {
1015                 widgetType = "password";
1016             }
1017             else if (Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_TEXTAREA.equalsIgnoreCase(fieldType))
1018             {
1019                 widgetType = "textarea";
1020             }
1021             else if (Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_HIDDEN.equalsIgnoreCase(fieldType))
1022             {
1023                 widgetType = HIDDEN_INPUT_TYPE;
1024             }
1025             else if (fieldType.toLowerCase().startsWith(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_RADIO))
1026             {
1027                 widgetType = "radio";
1028             }
1029             else if (Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_CHECKBOX.equalsIgnoreCase(fieldType))
1030             {
1031                 widgetType = "checkbox";
1032             }
1033             else if (Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_PLAINTEXT.equalsIgnoreCase(fieldType))
1034             {
1035                 widgetType = "plaintext";
1036             }
1037             else if (Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_TEXT.equalsIgnoreCase(fieldType))
1038             {
1039                 widgetType = "text";
1040             }
1041             else if (Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_MULTIBOX.equalsIgnoreCase(fieldType))
1042             {
1043                 if (getMultiboxPropertyName() != null)
1044                 {
1045                     widgetType = "multibox";
1046                 }
1047             }
1048             else if (Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_LINK.equalsIgnoreCase(fieldType))
1049             {
1050                 final StrutsAction action = getStrutsAction();
1051                 if (action != null)
1052                 {
1053                     if (action.isTableLink())
1054                     {
1055                         widgetType = "link";
1056                     }
1057                 }
1058             }
1059             else
1060             {
1061                 widgetType = (isMultiple()) ? "select" : "text";
1062             }
1063         }
1064         return widgetType;
1065     }
1066 
1067     /**
1068      * The input type representing a 'hidden' parameter.
1069      */
1070     static final String HIDDEN_INPUT_TYPE = "hidden";
1071 
1072     /**
1073      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsFile()
1074      */
1075     protected boolean handleIsFile()
1076     {
1077         boolean file = false;
1078 
1079         ClassifierFacade type = getType();
1080         if (type != null)
1081         {
1082             file = type.isFileType();
1083         }
1084         return file;
1085     }
1086 
1087     /**
1088      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsMultiple()
1089      */
1090     protected boolean handleIsMultiple()
1091     {
1092         boolean multiple = false;
1093 
1094         ClassifierFacade type = getType();
1095         if (type != null)
1096         {
1097             multiple = type.isCollectionType() || type.isArrayType();
1098         }
1099         return multiple;
1100     }
1101 
1102     /**
1103      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetBackingListName()
1104      */
1105     protected String handleGetBackingListName()
1106     {
1107         return getName() + "BackingList";
1108     }
1109 
1110     /**
1111      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetValueListResetValue()
1112      */
1113     protected String handleGetValueListResetValue()
1114     {
1115         return constructArray();
1116     }
1117 
1118     /**
1119      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsSelectable()
1120      */
1121     protected boolean handleIsSelectable()
1122     {
1123         boolean selectable = false;
1124 
1125         if (isActionParameter())
1126         {
1127             selectable = Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_SELECT.equals(getWidgetType());
1128             final ClassifierFacade type = getType();
1129 
1130             if (!selectable && type != null)
1131             {
1132                 final String name = getName();
1133                 final String typeName = type.getFullyQualifiedName();
1134 
1135                 /**
1136                  * if the parameter is not selectable but on a targetting page it _is_ selectable we must
1137                  * allow the user to set the backing list too
1138                  */
1139                 final Collection<StrutsJsp> pages = getStrutsAction().getTargetPages();
1140                 for (final Iterator pageIterator = pages.iterator(); pageIterator.hasNext() && !selectable;)
1141                 {
1142                     final StrutsJsp page = (StrutsJsp)pageIterator.next();
1143                     final Collection<FrontEndParameter> parameters = page.getAllActionParameters();
1144                     for (final Iterator parameterIterator = parameters.iterator();
1145                          parameterIterator.hasNext() && !selectable;)
1146                     {
1147                         final StrutsParameter parameter = (StrutsParameter)parameterIterator.next();
1148                         final String parameterName = parameter.getName();
1149                         final ClassifierFacade parameterType = parameter.getType();
1150                         if (parameterType != null)
1151                         {
1152                             final String parameterTypeName = parameterType.getFullyQualifiedName();
1153                             if (name.equals(parameterName) && typeName.equals(parameterTypeName))
1154                             {
1155                                 selectable = Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_SELECT
1156                                     .equals(parameter.getWidgetType());
1157                             }
1158                         }
1159                     }
1160                 }
1161             }
1162         }
1163         else if (isControllerOperationArgument())
1164         {
1165             final String name = this.getName();
1166             final Collection<FrontEndAction> actions = this.getControllerOperation().getDeferringActions();
1167             for (final Iterator<FrontEndAction> actionIterator = actions.iterator(); actionIterator.hasNext();)
1168             {
1169                 final StrutsAction action = (StrutsAction)actionIterator.next();
1170                 final Collection<StrutsParameter> formFields = action.getActionFormFields();
1171                 for (final Iterator fieldIterator = formFields.iterator(); fieldIterator.hasNext() && !selectable;)
1172                 {
1173                     final StrutsParameter parameter = (StrutsParameter)fieldIterator.next();
1174                     if (name.equals(parameter.getName()))
1175                     {
1176                         selectable = parameter.isSelectable();
1177                     }
1178                 }
1179             }
1180         }
1181         return selectable;
1182     }
1183 
1184     /**
1185      * @return getName() + "ValueList"
1186      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getValueListName()
1187      */
1188     protected String handleGetValueListName()
1189     {
1190         return getName() + "ValueList";
1191     }
1192 
1193     /**
1194      * @return getName() + "LabelList"
1195      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getLabelListName()
1196      */
1197     protected String handleGetLabelListName()
1198     {
1199         return getName() + "LabelList";
1200     }
1201 
1202     /**
1203      * @return A String representing Java code for the initialization of an array using 5 elements.
1204      */
1205     private String constructArray()
1206     {
1207         final String name = getName();
1208         return "new Object[] {\"" +
1209             name +
1210             "-1\", \"" +
1211             name +
1212             "-2\", \"" +
1213             name +
1214             "-3\", \"" +
1215             name +
1216             "-4\", \"" +
1217             name +
1218             "-5\"}";
1219     }
1220 
1221     /**
1222      * Override normal parameter facade required implementation.
1223      *
1224      * @see org.andromda.metafacades.uml.ParameterFacade#isRequired()
1225      */
1226     public boolean isRequired()
1227     {
1228         final Object value = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_REQUIRED);
1229         return Bpm4StrutsUtils.isTrue(value == null ? null : String.valueOf(value));
1230     }
1231 
1232     /**
1233      * @return Bpm4StrutsProfile.TAGGEDVALUE_INPUT_READONLY
1234      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#isReadOnly()
1235      */
1236     protected boolean handleIsReadOnly()
1237     {
1238         final Object value = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_READONLY);
1239         return Bpm4StrutsUtils.isTrue(value == null ? null : String.valueOf(value));
1240     }
1241 
1242     /**
1243      * @return isValidatorDate()
1244      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#isDate()
1245      */
1246     protected boolean handleIsDate()
1247     {
1248         return this.isValidatorDate();
1249     }
1250 
1251     /**
1252      * @return getDateFormat(getValidatorFormat())
1253      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getDateFormat()
1254      */
1255     protected String handleGetDateFormat()
1256     {
1257         final String format = this.getValidatorFormat();
1258         return format == null ? this.getDefaultDateFormat() : this.getDateFormat(format);
1259     }
1260 
1261     /**
1262      * @return the default date format pattern as defined using the configured property
1263      */
1264     private String getDefaultDateFormat()
1265     {
1266         return (String)getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_DEFAULT_DATEFORMAT);
1267     }
1268 
1269     /**
1270      * @return getValidatorFormat()
1271      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getTimeFormat()
1272      */
1273     protected String handleGetTimeFormat()
1274     {
1275         final String format = this.getValidatorFormat();
1276         return format == null ? this.getDefaultTimeFormat() : format;
1277     }
1278 
1279     /**
1280      * @return the default time format pattern as defined using the configured property
1281      */
1282     private String getDefaultTimeFormat()
1283     {
1284         return (String)this.getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_DEFAULT_TIMEFORMAT);
1285     }
1286 
1287     /**
1288      * @return isStrictDateFormat(getValidatorFormat())
1289      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#isStrictDateFormat()
1290      */
1291     protected boolean handleIsStrictDateFormat()
1292     {
1293         final String format = this.getValidatorFormat();
1294         return format == null
1295             ? Bpm4StrutsUtils.isTrue((String)this.getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_STRICT_DATETIMEFORMAT))
1296             : this.isStrictDateFormat(format);
1297     }
1298 
1299     /**
1300      * @return resetValue based on datatype
1301      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getResetValue()
1302      */
1303     protected String handleGetResetValue()
1304     {
1305         final ClassifierFacade type = getType();
1306         if (type != null)
1307         {
1308             final String name = getName();
1309 
1310             if (isValidatorString()) {return '\"' + name + "-test" + '\"';}
1311             if (isValidatorDate()) {return "new java.util.Date()";}
1312 
1313             if (type.isPrimitive())
1314             {
1315                 if (isValidatorInteger()) {return "(int)" + name.hashCode();}
1316                 if (isValidatorBoolean()) {return "false";}
1317                 if (isValidatorLong()) {return "(long)" + name.hashCode();}
1318                 if (isValidatorChar()) {return "(char)" + name.hashCode();}
1319                 if (isValidatorFloat()) {return "(float)" + name.hashCode();}
1320                 if (isValidatorDouble()) {return "(double)" + name.hashCode();}
1321                 if (isValidatorShort()) {return "(short)" + name.hashCode();}
1322                 if (isValidatorByte()) {return "(byte)" + name.hashCode();}
1323             }
1324             else
1325             {
1326                 if (isValidatorInteger()) {return "new Integer((int)" + name.hashCode() + ')';}
1327                 if (isValidatorBoolean()) {return "Boolean.FALSE";}
1328                 if (isValidatorLong()) {return "new Long((long)" + name.hashCode() + ')';}
1329                 if (isValidatorChar()) {return "new Character(char)" + name.hashCode() + ')';}
1330                 if (isValidatorFloat()) {return "new Float((float)" + name.hashCode() + ')';}
1331                 if (isValidatorDouble()) {return "new Double((double)" + name.hashCode() + ')';}
1332                 if (isValidatorShort()) {return "new Short((short)" + name.hashCode() + ')';}
1333                 if (isValidatorByte()) {return "new Byte((byte)" + name.hashCode() + ')';}
1334             }
1335 
1336             if (type.isArrayType()) {return constructArray();}
1337             if (type.isSetType()) {return "new java.util.HashSet(java.util.Arrays.asList(" + constructArray() + "))";}
1338             if (type.isCollectionType()) {return "java.util.Arrays.asList(" + constructArray() + ')';}
1339 
1340             // maps and others types will simply not be treated
1341         }
1342         return "null";
1343     }
1344 
1345     /**
1346      * @return validationRequired
1347      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#isValidationRequired()
1348      */
1349     protected boolean handleIsValidationRequired()
1350     {
1351         final String disableValidationForHiddenFormFields = (String)getConfiguredProperty(Bpm4StrutsGlobals.DISABLE_VALIDATION_FOR_HIDDEN_FORM_FIELDS);
1352         return !("true".equals(disableValidationForHiddenFormFields) && "hidden".equals(getWidgetType())) &&
1353             !getValidatorTypes().isEmpty();
1354     }
1355 
1356     private String getValidatorFormat()
1357     {
1358         Object value = findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_FORMAT);
1359         final String format = value == null ? null : String.valueOf(value);
1360         return (format == null) ? null : format.trim();
1361     }
1362 
1363     /**
1364      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetValidatorTypes()
1365      */
1366     protected Collection handleGetValidatorTypes()
1367     {
1368         final Collection validatorTypesList = new ArrayList();
1369 
1370         ClassifierFacade type = getType();
1371         if (type != null)
1372         {
1373             final String format = getValidatorFormat();
1374             final boolean isRangeFormat = (format != null) && isRangeFormat(format);
1375 
1376             if (isRequired()) {validatorTypesList.add("required");}
1377 
1378             if (isValidatorByte()) {validatorTypesList.add("byte");}
1379             else if (isValidatorShort()) {validatorTypesList.add("short");}
1380             else if (isValidatorInteger()) {validatorTypesList.add("integer");}
1381             else if (isValidatorLong()) {validatorTypesList.add("long");}
1382             else if (isValidatorFloat()) {validatorTypesList.add("float");}
1383             else if (isValidatorDouble()) {validatorTypesList.add("double");}
1384             else if (isValidatorDate()) {validatorTypesList.add("date");}
1385             else if (isValidatorTime()) {validatorTypesList.add("time");}
1386             else if (isValidatorUrl()) {validatorTypesList.add("url");}
1387 
1388             if (isRangeFormat)
1389             {
1390                 if (isValidatorInteger() || isValidatorShort() || isValidatorLong()) {validatorTypesList.add("intRange");}
1391                 if (isValidatorFloat()) {validatorTypesList.add("floatRange");}
1392                 if (isValidatorDouble()) {validatorTypesList.add("doubleRange");}
1393             }
1394 
1395             if (format != null)
1396             {
1397                 if (isValidatorString() && isEmailFormat(format)) {validatorTypesList.add("email");}
1398                 else if (isValidatorString() && isCreditCardFormat(format)) {validatorTypesList.add("creditCard");}
1399                 else
1400                 {
1401                     Collection formats = findTaggedValues(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_FORMAT);
1402                     for (final Iterator formatIterator = formats.iterator(); formatIterator.hasNext();)
1403                     {
1404                         String additionalFormat = String.valueOf(formatIterator.next());
1405                         if (isMinLengthFormat(additionalFormat)) {validatorTypesList.add("minlength");}
1406                         else if (isMaxLengthFormat(additionalFormat)) {validatorTypesList.add("maxlength");}
1407                         else if (isPatternFormat(additionalFormat)) {validatorTypesList.add("mask");}
1408                     }
1409                 }
1410             }
1411 
1412             if (getValidWhen() != null)
1413             {
1414                 validatorTypesList.add("validwhen");
1415             }
1416         }
1417 
1418         // custom (parameterized) validators are allowed here
1419         Collection taggedValues = findTaggedValues(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_VALIDATORS);
1420         for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();)
1421         {
1422             String validator = String.valueOf(iterator.next());
1423             validatorTypesList.add(Bpm4StrutsUtils.parseValidatorName(validator));
1424         }
1425 
1426         return validatorTypesList;
1427     }
1428 
1429     /**
1430      * @return getMessageKey()
1431      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getValidatorMsgKey()
1432      */
1433     protected String handleGetValidatorMsgKey()
1434     {
1435         return getMessageKey();
1436     }
1437 
1438     /**
1439      * @param validatorType
1440      * @return ${var: + value}
1441      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getValidatorArgs(String)
1442      */
1443     protected Collection handleGetValidatorArgs(String validatorType)
1444     {
1445         final Collection<String> args = new ArrayList<String>();
1446         if ("intRange".equals(validatorType) ||
1447             "floatRange".equals(validatorType) ||
1448             "doubleRange".equals(validatorType))
1449         {
1450             args.add("${var:min}");
1451             args.add("${var:max}");
1452         }
1453         else if ("minlength".equals(validatorType))
1454         {
1455             args.add("${var:minlength}");
1456         }
1457         else if ("maxlength".equals(validatorType))
1458         {
1459             args.add("${var:maxlength}");
1460         }
1461         else if ("date".equals(validatorType))
1462         {
1463             final String validatorFormat = getValidatorFormat();
1464             if (validatorFormat != null && isStrictDateFormat(validatorFormat))
1465             {
1466                 args.add("${var:datePatternStrict}");
1467             }
1468             else
1469             {
1470                 args.add("${var:datePattern}");
1471             }
1472         }
1473         else if ("time".equals(validatorType))
1474         {
1475             args.add("${var:timePattern}");
1476         }
1477 
1478         // custom (paramterized) validators are allowed here
1479         Collection taggedValues = findTaggedValues(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_VALIDATORS);
1480         for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();)
1481         {
1482             String validator = String.valueOf(iterator.next());
1483             if (validatorType.equals(Bpm4StrutsUtils.parseValidatorName(validator)))
1484             {
1485                 args.addAll(Bpm4StrutsUtils.parseValidatorArgs(validator));
1486             }
1487         }
1488 
1489         return args;
1490     }
1491 
1492     /**
1493      * @return mni, max, minLength, maxLength, mask
1494      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getValidatorVars()
1495      */
1496     protected Collection handleGetValidatorVars()
1497     {
1498         final Map vars = new LinkedHashMap();
1499 
1500         final ClassifierFacade type = getType();
1501         if (type != null)
1502         {
1503             final String format = getValidatorFormat();
1504             if (format != null)
1505             {
1506                 final boolean isRangeFormat = isRangeFormat(format);
1507 
1508                 if (isRangeFormat)
1509                 {
1510                     vars.put("min", Arrays.asList("min", getRangeStart(format)));
1511                     vars.put("max", Arrays.asList("max", getRangeEnd(format)));
1512                 }
1513                 else
1514                 {
1515                     final Collection formats = findTaggedValues(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_FORMAT);
1516                     for (final Iterator formatIterator = formats.iterator(); formatIterator.hasNext();)
1517                     {
1518                         final String additionalFormat = String.valueOf(formatIterator.next());
1519                         if (isMinLengthFormat(additionalFormat)) vars.put("minlength",
1520                             Arrays.asList("minlength", this.getMinLengthValue(additionalFormat)));
1521                         else if (isMaxLengthFormat(additionalFormat)) vars.put("maxlength",
1522                             Arrays.asList("maxlength", this.getMaxLengthValue(additionalFormat)));
1523                         else if (isPatternFormat(additionalFormat)) vars
1524                             .put("mask", Arrays.asList("mask", this.getPatternValue(additionalFormat)));
1525                     }
1526                 }
1527             }
1528             if (isValidatorDate())
1529             {
1530                 if (format != null && isStrictDateFormat(format))
1531                 {
1532                     vars.put("datePatternStrict",
1533                         Arrays.asList("datePatternStrict", this.getDateFormat()));
1534                 }
1535                 else
1536                 {
1537                     vars.put("datePattern", Arrays.asList("datePattern", this.getDateFormat()));
1538                 }
1539             }
1540             if (this.isValidatorTime())
1541             {
1542                 vars.put("timePattern", Arrays.asList("timePattern", this.getTimeFormat()));
1543             }
1544 
1545             final String validWhen = getValidWhen();
1546             if (validWhen != null)
1547             {
1548                 vars.put("test", Arrays.asList("test", validWhen));
1549             }
1550         }
1551 
1552         // custom (paramterized) validators are allowed here
1553         // in this case we will reuse the validator arg values
1554         Collection taggedValues = findTaggedValues(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_VALIDATORS);
1555         for (final Iterator iterator = taggedValues.iterator(); iterator.hasNext();)
1556         {
1557             String validator = String.valueOf(iterator.next());
1558 
1559             // guaranteed to be of the same length
1560             List validatorVars = Bpm4StrutsUtils.parseValidatorVars(validator);
1561             List validatorArgs = Bpm4StrutsUtils.parseValidatorArgs(validator);
1562 
1563             for (int i = 0; i < validatorVars.size(); i++)
1564             {
1565                 String validatorVar = (String)validatorVars.get(i);
1566                 String validatorArg = (String)validatorArgs.get(i);
1567 
1568                 vars.put(validatorVar, Arrays.asList(validatorVar, validatorArg));
1569             }
1570         }
1571 
1572         return vars.values();
1573     }
1574 
1575     /**
1576      * @return Bpm4StrutsProfile.TAGGEDVALUE_INPUT_VALIDWHEN
1577      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getValidWhen()
1578      */
1579     protected String handleGetValidWhen()
1580     {
1581         final Object value = findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_VALIDWHEN);
1582         return value == null ? null : '(' + value.toString() + ')';
1583     }
1584 
1585     /**
1586      * @return Bpm4StrutsProfile.TAGGEDVALUE_INPUT_MULTIBOX
1587      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getMultiboxPropertyName()
1588      */
1589     protected String handleGetMultiboxPropertyName()
1590     {
1591         Object value = findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_MULTIBOX);
1592         return (value == null) ? null : StringUtils.trimToNull(value.toString());
1593     }
1594 
1595     /**
1596      * @return optionKeys
1597      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getOptionKeys()
1598      */
1599     protected List<String> handleGetOptionKeys()
1600     {
1601         final String key = getMessageKey() + '.';
1602         final List<String> optionKeys = new ArrayList<String>();
1603         final int optionCount = getOptionCount();
1604         for (int i = 0; i < optionCount; i++)
1605             optionKeys.add(key + i);
1606         return optionKeys;
1607     }
1608 
1609     /**
1610      * @return optionValues
1611      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getOptionValues()
1612      */
1613     protected List<String> handleGetOptionValues()
1614     {
1615         final List<String> optionValues = new ArrayList<String>();
1616         final Object taggedValueObject = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_RADIO);
1617 
1618         if (taggedValueObject == null)
1619         {
1620             // we resort to the default values
1621             optionValues.add("0");
1622             optionValues.add("1");
1623             optionValues.add("2");
1624         }
1625         else
1626         {
1627             final String taggedValue = String.valueOf(taggedValueObject).trim();
1628 
1629             int optionCount;
1630             try
1631             {
1632                 optionCount = Integer.parseInt(taggedValue);
1633                 for (int i = 0; i < optionCount; i++)
1634                 {
1635                     optionValues.add(String.valueOf(i));
1636                 }
1637             }
1638             catch (Exception exception)
1639             {
1640                 // this means the value wasn't a valid integer, we'll interpret it is a comma-separated
1641                 // list of option-values
1642                 final String[] options = taggedValue.split("[,]");
1643                 for (int i = 0; i < options.length; i++)
1644                 {
1645                     optionValues.add(options[i].trim());
1646                 }
1647             }
1648         }
1649         return optionValues;
1650     }
1651 
1652     /**
1653      * @return getOptionValues().size()
1654      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getOptionCount()
1655      */
1656     protected int handleGetOptionCount()
1657     {
1658         return this.getOptionValues().size();
1659     }
1660 
1661     /**
1662      * @return Bpm4StrutsProfile.TAGGEDVALUE_INPUT_RESET
1663      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#isShouldReset()
1664      */
1665     protected boolean handleIsShouldReset()
1666     {
1667         boolean shouldReset = false;
1668         Object value = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_RESET);
1669         if (value != null)
1670         {
1671             shouldReset = Boolean.valueOf(StringUtils.trimToEmpty((String)value)).booleanValue();
1672         }
1673         return shouldReset;
1674     }
1675 
1676     /**
1677      * @return reset getName()
1678      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameter#getResetName()
1679      */
1680     protected String handleGetResetName()
1681     {
1682         return "reset" + StringUtils.capitalize(StringUtils.trimToEmpty(this.getName()));
1683     }
1684 
1685     /**
1686      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsPassword()
1687      */
1688     protected boolean handleIsPassword()
1689     {
1690         return Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_PASSWORD.equals(this.getWidgetType());
1691     }
1692 
1693     /**
1694      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsCombobox()
1695      */
1696     protected boolean handleIsCombobox()
1697     {
1698         return "select".equals(this.getWidgetType());
1699     }
1700 
1701     /**
1702      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsCheckbox()
1703      */
1704     protected boolean handleIsCheckbox()
1705     {
1706         return "checkbox".equals(this.getWidgetType());
1707     }
1708 
1709     /**
1710      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsTextField()
1711      */
1712     protected boolean handleIsTextField()
1713     {
1714         return "text".equals(this.getWidgetType());
1715     }
1716 
1717     /**
1718      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsTextArea()
1719      */
1720     protected boolean handleIsTextArea()
1721     {
1722         return "textarea".equals(this.getWidgetType());
1723     }
1724 
1725     /**
1726      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsMultibox()
1727      */
1728     protected boolean handleIsMultibox()
1729     {
1730         return "multibox".equals(this.getWidgetType());
1731     }
1732 
1733     /**
1734      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsRadioButton()
1735      */
1736     protected boolean handleIsRadioButton()
1737     {
1738         return "radio".equals(this.getWidgetType());
1739     }
1740 
1741     /**
1742      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsHiddenField()
1743      */
1744     protected boolean handleIsHiddenField()
1745     {
1746         return "hidden".equals(this.getWidgetType());
1747     }
1748 
1749     /**
1750      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsHyperlink()
1751      */
1752     protected boolean handleIsHyperlink()
1753     {
1754         return "link".equals(this.getWidgetType());
1755     }
1756 
1757     /**
1758      * @return <code>true</code> if the type of this field is a boolean, <code>false</code> otherwise
1759      */
1760     private boolean isValidatorBoolean()
1761     {
1762         return UMLMetafacadeUtils.isType(this.getType(), UMLProfile.BOOLEAN_TYPE_NAME);
1763     }
1764 
1765     /**
1766      * @return <code>true</code> if the type of this field is a character, <code>false</code> otherwise
1767      */
1768     private boolean isValidatorChar()
1769     {
1770         return UMLMetafacadeUtils.isType(this.getType(), Bpm4StrutsProfile.CHARACTER_TYPE_NAME);
1771     }
1772 
1773     /**
1774      * @return <code>true</code> if the type of this field is a byte, <code>false</code> otherwise
1775      */
1776     private boolean isValidatorByte()
1777     {
1778         return UMLMetafacadeUtils.isType(this.getType(), Bpm4StrutsProfile.BYTE_TYPE_NAME);
1779     }
1780 
1781     /**
1782      * @return <code>true</code> if the type of this field is a short, <code>false</code> otherwise
1783      */
1784     private boolean isValidatorShort()
1785     {
1786         return UMLMetafacadeUtils.isType(this.getType(), Bpm4StrutsProfile.SHORT_TYPE_NAME);
1787     }
1788 
1789     /**
1790      * @return <code>true</code> if the type of this field is an integer, <code>false</code> otherwise
1791      */
1792     private boolean isValidatorInteger()
1793     {
1794         return UMLMetafacadeUtils.isType(this.getType(), Bpm4StrutsProfile.INTEGER_TYPE_NAME);
1795     }
1796 
1797     /**
1798      * @return <code>true</code> if the type of this field is a long integer, <code>false</code> otherwise
1799      */
1800     private boolean isValidatorLong()
1801     {
1802         return UMLMetafacadeUtils.isType(this.getType(), Bpm4StrutsProfile.LONG_TYPE_NAME);
1803     }
1804 
1805     /**
1806      * @return <code>true</code> if the type of this field is a floating point, <code>false</code> otherwise
1807      */
1808     private boolean isValidatorFloat()
1809     {
1810         return UMLMetafacadeUtils.isType(this.getType(), Bpm4StrutsProfile.FLOAT_TYPE_NAME);
1811     }
1812 
1813     /**
1814      * @return <code>true</code> if the type of this field is a double precision floating point, <code>false</code> otherwise
1815      */
1816     private boolean isValidatorDouble()
1817     {
1818         return UMLMetafacadeUtils.isType(this.getType(), Bpm4StrutsProfile.DOUBLE_TYPE_NAME);
1819     }
1820 
1821     /**
1822      * @return <code>true</code> if the type of this field is a date, <code>false</code> otherwise
1823      */
1824     private boolean isValidatorDate()
1825     {
1826         return this.getType() != null && this.getType().isDateType();
1827     }
1828 
1829     /**
1830      * @return <code>true</code> if the type of this field is a time, <code>false</code> otherwise
1831      */
1832     private boolean isValidatorTime()
1833     {
1834         return UMLMetafacadeUtils.isType(this.getType(), Bpm4StrutsProfile.TIME_TYPE_NAME);
1835     }
1836 
1837     /**
1838      * @return <code>true</code> if the type of this field is a URL, <code>false</code> otherwise
1839      */
1840     private boolean isValidatorUrl()
1841     {
1842         return UMLMetafacadeUtils.isType(this.getType(), Bpm4StrutsProfile.URL_TYPE_NAME);
1843     }
1844 
1845     /**
1846      * @return <code>true</code> if the type of this field is a String, <code>false</code> otherwise
1847      */
1848     private boolean isValidatorString()
1849     {
1850         return this.getType() != null && this.getType().isStringType();
1851     }
1852 
1853     /**
1854      * @return <code>true</code> if this field is to be formatted as an email address, <code>false</code> otherwise
1855      */
1856     private boolean isEmailFormat(String format)
1857     {
1858         return "email".equalsIgnoreCase(getToken(format, 0, 2));
1859     }
1860 
1861     /**
1862      * @return <code>true</code> if this field is to be formatted as a credit card, <code>false</code> otherwise
1863      */
1864     private boolean isCreditCardFormat(String format)
1865     {
1866         return "creditcard".equalsIgnoreCase(getToken(format, 0, 2));
1867     }
1868 
1869     /**
1870      * @return <code>true</code> if this field's value needs to be in a specific range, <code>false</code> otherwise
1871      */
1872     private boolean isRangeFormat(String format)
1873     {
1874         return "range".equalsIgnoreCase(getToken(format, 0, 2)) &&
1875             (isValidatorInteger() ||
1876                 isValidatorLong() ||
1877                 isValidatorShort() ||
1878                 isValidatorFloat() ||
1879                 isValidatorDouble());
1880 
1881     }
1882 
1883     /**
1884      * @return <code>true</code> if this field's value needs to respect a certain pattern, <code>false</code> otherwise
1885      */
1886     private boolean isPatternFormat(String format)
1887     {
1888         return "pattern".equalsIgnoreCase(getToken(format, 0, 2));
1889     }
1890 
1891     /**
1892      * @return <code>true</code> if this field's value needs to conform to a strict date format, <code>false</code> otherwise
1893      */
1894     private boolean isStrictDateFormat(String format)
1895     {
1896         return "strict".equalsIgnoreCase(getToken(format, 0, 2));
1897     }
1898 
1899     /**
1900      * @return <code>true</code> if this field's value needs to consist of at least a certain number of characters, <code>false</code> otherwise
1901      */
1902     private boolean isMinLengthFormat(String format)
1903     {
1904         return "minlength".equalsIgnoreCase(getToken(format, 0, 2));
1905     }
1906 
1907     /**
1908      * @return <code>true</code> if this field's value needs to consist of at maximum a certain number of characters, <code>false</code> otherwise
1909      */
1910     private boolean isMaxLengthFormat(String format)
1911     {
1912         return "maxlength".equalsIgnoreCase(getToken(format, 0, 2));
1913     }
1914 
1915     /**
1916      * @return the lower limit for this field's value's range
1917      */
1918     private String getRangeStart(String format)
1919     {
1920         return getToken(format, 1, 3);
1921     }
1922 
1923     /**
1924      * @return the upper limit for this field's value's range
1925      */
1926     private String getRangeEnd(String format)
1927     {
1928         return getToken(format, 2, 3);
1929     }
1930 
1931     /**
1932      * @return this field's date format
1933      */
1934     private String getDateFormat(String format)
1935     {
1936         return (isStrictDateFormat(format)) ? getToken(format, 1, 2) : getToken(format, 0, 1);
1937     }
1938 
1939     /**
1940      * @return the minimum number of characters this field's value must consist of
1941      */
1942     private String getMinLengthValue(String format)
1943     {
1944         return getToken(format, 1, 2);
1945     }
1946 
1947     /**
1948      * @return the maximum number of characters this field's value must consist of
1949      */
1950     private String getMaxLengthValue(String format)
1951     {
1952         return getToken(format, 1, 2);
1953     }
1954 
1955     /**
1956      * @return the pattern this field's value must respect
1957      */
1958     private String getPatternValue(String format)
1959     {
1960         return '^' + getToken(format, 1, 2) + '$';
1961     }
1962 
1963     /**
1964      * @return the i-th space delimited token read from the argument String, where i does not exceed the specified limit
1965      */
1966     private String getToken(String string,
1967                             int index,
1968                             int limit)
1969     {
1970         if (string == null) {return null;}
1971 
1972         final String[] tokens = string.split("[\\s]+", limit);
1973         return (index >= tokens.length) ? null : tokens[index];
1974     }
1975 
1976     /**
1977      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#getValidationOwner()
1978      */
1979     public Object getValidationOwner()
1980     {
1981         return (this.isTable() && this.getJsp() != null) ? this.getJsp() : super.getValidationOwner();
1982     }
1983 
1984     /**
1985      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsSortableBy()
1986      */
1987     protected boolean handleIsSortableBy()
1988     {
1989         boolean sortableBy = true;
1990 
1991         final Object value = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE);
1992         if (value != null)
1993         {
1994             final String fieldType = value.toString();
1995             sortableBy = !(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_PASSWORD.equalsIgnoreCase(fieldType) ||
1996                 Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_HIDDEN.equalsIgnoreCase(fieldType) ||
1997                 Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_RADIO.equalsIgnoreCase(fieldType) ||
1998                 Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_CHECKBOX.equalsIgnoreCase(fieldType) ||
1999                 Bpm4StrutsProfile.TAGGEDVALUE_INPUT_TYPE_MULTIBOX.equalsIgnoreCase(fieldType));
2000         }
2001 
2002         return sortableBy;
2003     }
2004 
2005     private boolean normalizeMessages()
2006     {
2007         final String normalizeMessages = (String)getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_NORMALIZE_MESSAGES);
2008         return Boolean.valueOf(normalizeMessages).booleanValue();
2009     }
2010 
2011     /**
2012      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsTime()
2013      */
2014     protected boolean handleIsTime()
2015     {
2016         return this.isValidatorTime();
2017     }
2018 
2019     /**
2020      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetFieldColumnCount()
2021      */
2022     protected Integer handleGetFieldColumnCount()
2023     {
2024         Integer columnCount = null;
2025 
2026         Object columnCountObject = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_COLUMN_COUNT);
2027         if (columnCountObject == null)
2028         {
2029             columnCountObject = this.getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_DEFAULT_INPUT_COLUMN_COUNT);
2030         }
2031 
2032         if (columnCountObject != null)
2033         {
2034             try
2035             {
2036                 columnCount = Integer.valueOf(columnCountObject.toString());
2037             }
2038             catch (NumberFormatException e)
2039             {
2040                 // do nothing, we want columnCount to be null in case of an invalid value
2041             }
2042         }
2043 
2044         return columnCount;
2045     }
2046 
2047     /**
2048      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleGetFieldRowCount()
2049      */
2050     protected Integer handleGetFieldRowCount()
2051     {
2052         Integer rowCount = null;
2053 
2054         Object rowCountObject = this.findTaggedValue(Bpm4StrutsProfile.TAGGEDVALUE_INPUT_ROW_COUNT);
2055         if (rowCountObject == null)
2056         {
2057             rowCountObject = this.getConfiguredProperty(Bpm4StrutsGlobals.PROPERTY_DEFAULT_INPUT_ROW_COUNT);
2058         }
2059 
2060         if (rowCountObject != null)
2061         {
2062             try
2063             {
2064                 rowCount = Integer.valueOf(rowCountObject.toString());
2065             }
2066             catch (NumberFormatException e)
2067             {
2068                 // do nothing, we want rowCount to be null in case of an invalid value
2069             }
2070         }
2071 
2072         return rowCount;
2073     }
2074 
2075     /**
2076      * @see org.andromda.cartridges.bpm4struts.metafacades.StrutsParameterLogic#handleIsSafeNamePresent()
2077      */
2078     protected boolean handleIsSafeNamePresent()
2079     {
2080         return Bpm4StrutsUtils.isSafeName(this.getName());
2081     }
2082 }