View Javadoc
1   package org.andromda.cartridges.jsf2.metafacades;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.HashMap;
6   import java.util.HashSet;
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 java.util.Set;
13  import org.andromda.cartridges.jsf2.JSFGlobals;
14  import org.andromda.cartridges.jsf2.JSFProfile;
15  import org.andromda.cartridges.jsf2.JSFUtils;
16  import org.andromda.metafacades.uml.AssociationEndFacade;
17  import org.andromda.metafacades.uml.AttributeFacade;
18  import org.andromda.metafacades.uml.ClassifierFacade;
19  import org.andromda.metafacades.uml.EventFacade;
20  import org.andromda.metafacades.uml.FrontEndAction;
21  import org.andromda.metafacades.uml.FrontEndActivityGraph;
22  import org.andromda.metafacades.uml.FrontEndForward;
23  import org.andromda.metafacades.uml.FrontEndParameter;
24  import org.andromda.metafacades.uml.FrontEndView;
25  import org.andromda.metafacades.uml.ModelElementFacade;
26  import org.andromda.metafacades.uml.TransitionFacade;
27  import org.andromda.metafacades.uml.UseCaseFacade;
28  import org.andromda.utils.StringUtilsHelper;
29  import org.apache.commons.collections.CollectionUtils;
30  import org.apache.commons.collections.Predicate;
31  import org.apache.commons.lang.ObjectUtils;
32  import org.apache.commons.lang.StringUtils;
33  
34  /**
35   * MetafacadeLogic implementation for org.andromda.cartridges.jsf2.metafacades.JSFParameter.
36   *
37   * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter
38   */
39  public class JSFParameterLogicImpl
40      extends JSFParameterLogic
41  {
42      private static final long serialVersionUID = 34L;
43      /**
44       * @param metaObject
45       * @param context
46       */
47      public JSFParameterLogicImpl(
48          Object metaObject,
49          String context)
50      {
51          super(metaObject, context);
52      }
53  
54      /**
55       * Overridden to make sure it's not an inputTable.
56       *
57       * @see org.andromda.metafacades.uml.FrontEndParameter#isTable()
58       */
59      public boolean isTable()
60      {
61          return (super.isTable() || this.isPageableTable()) && !this.isSelectable()
62              && !this.isInputTable() && !this.isInputHidden();
63      }
64  
65      /**
66       * @return isPageableTable
67       * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isPageableTable()
68       */
69      protected boolean handleIsPageableTable()
70      {
71          final Object value = this.findTaggedValue(JSFProfile.TAGGEDVALUE_TABLE_PAGEABLE);
72          return Boolean.valueOf(ObjectUtils.toString(value)).booleanValue();
73      }
74  
75      /**
76       * @return messageKey
77       * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getMessageKey()
78       */
79      protected String handleGetMessageKey()
80      {
81          final StringBuilder messageKey = new StringBuilder();
82  
83          if (!this.isNormalizeMessages())
84          {
85              if (this.isActionParameter())
86              {
87                  final JSFAction action = (JSFAction)this.getAction();
88                  if (action != null)
89                  {
90                      messageKey.append(action.getMessageKey());
91                      messageKey.append('.');
92                  }
93              }
94              else
95              {
96                  final JSFView view = (JSFView)this.getView();
97                  if (view != null)
98                  {
99                      messageKey.append(view.getMessageKey());
100                     messageKey.append('.');
101                 }
102             }
103             messageKey.append("param.");
104         }
105 
106         messageKey.append(StringUtilsHelper.toResourceMessageKey(super.getName()));
107         return messageKey.toString();
108     }
109 
110     /**
111      * @return getMessageKey() + '.' + JSFGlobals.DOCUMENTATION_MESSAGE_KEY_SUFFIX
112      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getDocumentationKey()
113      */
114     protected String handleGetDocumentationKey()
115     {
116         return getMessageKey() + '.' + JSFGlobals.DOCUMENTATION_MESSAGE_KEY_SUFFIX;
117     }
118 
119     /**
120      * @return documentationValue
121      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getDocumentationValue()
122      */
123     protected String handleGetDocumentationValue()
124     {
125         final String value = StringUtilsHelper.toResourceMessage(this.getDocumentation(
126                     "",
127                     64,
128                     false));
129         return value == null ? "" : value;
130     }
131 
132     /**
133      * Indicates whether or not we should normalize messages.
134      *
135      * @return true/false
136      */
137     private boolean isNormalizeMessages()
138     {
139         final String normalizeMessages = (String)getConfiguredProperty(JSFGlobals.NORMALIZE_MESSAGES);
140         return Boolean.valueOf(normalizeMessages).booleanValue();
141     }
142 
143     /**
144      * @return messageValue
145      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getMessageValue()
146      */
147     protected String handleGetMessageValue()
148     {
149         return StringUtilsHelper.toPhrase(super.getName()); // the actual name is used for displaying
150     }
151 
152     /**
153      * @param columnName
154      * @return tableColumnMessageKey
155      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getTableColumnMessageKey(String)
156      */
157     protected String handleGetTableColumnMessageKey(final String columnName)
158     {
159         StringBuilder messageKey = new StringBuilder();
160         if (!this.isNormalizeMessages())
161         {
162             final JSFView view = (JSFView)this.getView();
163             if (view != null)
164             {
165                 messageKey.append(this.getMessageKey());
166                 messageKey.append('.');
167             }
168         }
169         messageKey.append(StringUtilsHelper.toResourceMessageKey(columnName));
170         return messageKey.toString();
171     }
172 
173     /**
174      * @param columnName
175      * @return StringUtilsHelper.toPhrase(columnName)
176      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getTableColumnMessageValue(String)
177      */
178     protected String handleGetTableColumnMessageValue(final String columnName)
179     {
180         return StringUtilsHelper.toPhrase(columnName);
181     }
182 
183     /**
184      * @return getTableActions(true)
185      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getTableHyperlinkActions()
186      */
187     protected List<JSFAction> handleGetTableHyperlinkActions()
188     {
189         return this.getTableActions(true);
190     }
191 
192     private class ActionFilter implements Predicate
193     {
194         final private boolean hyperlink;
195         public ActionFilter(boolean hyperlink)
196         {
197             this.hyperlink = hyperlink;
198         }
199         
200         @Override
201         public boolean evaluate(Object action) 
202         {
203             return ((JSFAction)action).isHyperlink() == this.hyperlink;
204         }
205     }
206     
207     /**
208      * If this is a table this method returns all those actions that are declared to work
209      * on this table.
210      *
211      * @param hyperlink denotes on which type of actions to filter
212      */
213     private List<JSFAction> getTableActions(boolean hyperlink)
214     {
215         final List<JSFAction> actions = new ArrayList<JSFAction>(super.getTableActions());
216         CollectionUtils.filter(actions, new ActionFilter(hyperlink));
217         return actions;
218     }
219 
220     /**
221      * @return getTableActions(false)
222      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getTableFormActions()
223      */
224     protected List<JSFAction> handleGetTableFormActions()
225     {
226         return this.getTableActions(false);
227     }
228 
229     /**
230      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getTableActions()
231      */
232     protected List<JSFAction> handleGetTableActions() {
233         final Set<JSFAction> actions = new LinkedHashSet<JSFAction>();
234         final String name = StringUtils.trimToNull(getName());
235         if (name != null && isTable())
236         {
237             final JSFView view = (JSFView)this.getView();
238 
239             final Collection<UseCaseFacade> allUseCases = getModel().getAllUseCases();
240             for (final UseCaseFacade useCase : allUseCases)
241             {
242                 if (useCase instanceof JSFUseCase)
243                 {
244                     final FrontEndActivityGraph graph = ((JSFUseCase)useCase).getActivityGraph();
245                     if (graph != null)
246                     {
247                         final Collection<TransitionFacade> transitions = graph.getTransitions();
248                         for (final TransitionFacade transition : transitions)
249                         {
250                             if (transition.getSource().equals(view) && transition instanceof JSFAction)
251                             {
252                                 final JSFAction action = (JSFAction)transition;
253                                 if (action.isTableLink() && name.equals(action.getTableLinkName()))
254                                 {
255                                     actions.add(action);
256                                 }
257                             }
258                         }
259                     }
260                 }
261             }
262         }
263         return new ArrayList<JSFAction>(actions);
264     }
265 
266     /**
267      * @see org.andromda.metafacades.uml.FrontEndParameter#getTableColumns()
268      */
269     // TODO tableColumns can be either String or JSFParameter. Should use a single return type in Collection.
270     public Collection getTableColumns()
271     {
272         final Collection tableColumns = super.getTableColumns();
273         if (tableColumns.isEmpty())
274         {
275             // try to preserve the order of the elements encountered
276             //final Map<String, JSFParameter> tableColumnsMap = new LinkedHashMap<String, JSFParameter>();
277             final Map tableColumnsMap = new LinkedHashMap();
278 
279             // order is important
280             final List<JSFAction> actions = new ArrayList<JSFAction>();
281 
282             // all table actions need the exact same parameters, just not always all of them
283             actions.addAll(this.getTableFormActions());
284 
285             // if there are any actions that are hyperlinks then their parameters get priority
286             // the user should not have modeled it that way (constraints will warn him/her)
287             actions.addAll(this.getTableHyperlinkActions());
288 
289             for (final JSFAction action : actions)
290             {
291                 for (final FrontEndParameter actionParameter : action.getParameters())
292                 {
293                     if (actionParameter instanceof JSFParameter)
294                     {
295                         final JSFParameter parameter = (JSFParameter)actionParameter;
296                         final String parameterName = parameter.getName();
297                         if (parameterName != null)
298                         {
299                             // never overwrite column specific table links
300                             // the hyperlink table links working on a real column get priority
301                             final Object existingObject = tableColumnsMap.get(parameterName);
302                             if (existingObject instanceof JSFParameter)
303                             {
304                                 if (action.isHyperlink() && parameterName.equals(action.getTableLinkColumnName()))
305                                 {
306                                     tableColumnsMap.put(
307                                         parameterName,
308                                         parameter);
309                                 }
310                             }
311                         }
312                     }
313                 }
314             }
315 
316             // for any missing parameters we just add the name of the column
317             for (final String columnName : this.getTableColumnNames())
318             {
319                 if (!tableColumnsMap.containsKey(columnName))
320                 {
321                     tableColumnsMap.put(
322                         columnName,
323                         columnName);
324                 }
325             }
326 
327             // return everything in the same order as it has been modeled (using the table tagged value)
328             for (final String columnObject : this.getTableColumnNames())
329             {
330                 tableColumns.add(tableColumnsMap.get(columnObject));
331             }
332         }
333         return tableColumns;
334     }
335 
336     /**
337      * @return the default date format pattern as defined using the configured property
338      */
339     private String getDefaultDateFormat()
340     {
341         return (String)this.getConfiguredProperty(JSFGlobals.PROPERTY_DEFAULT_DATEFORMAT);
342     }
343 
344     /**
345      * @return format
346      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getFormat()
347      */
348     protected String handleGetFormat()
349     {
350         return JSFUtils.getFormat(
351             (ModelElementFacade)this.THIS(),
352             this.getType(),
353             this.getDefaultDateFormat(),
354             this.getDefaultTimeFormat());
355     }
356 
357     /**
358      * @return the default time format pattern as defined using the configured property
359      */
360     private String getDefaultTimeFormat()
361     {
362         return (String)this.getConfiguredProperty(JSFGlobals.PROPERTY_DEFAULT_TIMEFORMAT);
363     }
364 
365     /**
366      * @return JSFUtils.isStrictDateFormat((ModelElementFacade)this.THIS())
367      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isStrictDateFormat()
368      */
369     protected boolean handleIsStrictDateFormat()
370     {
371         return JSFUtils.isStrictDateFormat((ModelElementFacade)this.THIS());
372     }
373 
374     /**
375      * @return dateFormatter
376      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getDateFormatter()
377      */
378     protected String handleGetDateFormatter()
379     {
380         final ClassifierFacade type = this.getType();
381         return type != null && type.isDateType() ? this.getName() + "DateFormatter" : null;
382     }
383 
384     /**
385      * @return timeFormatter
386      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getTimeFormatter()
387      */
388     protected String handleGetTimeFormatter()
389     {
390         final ClassifierFacade type = this.getType();
391         return type != null && type.isTimeType() ? this.getName() + "TimeFormatter" : null;
392     }
393 
394     /**
395      * Gets the current value of the specified input type (or an empty string
396      * if one isn't specified).
397      *
398      * @return the input type name.
399      */
400     private String getInputType()
401     {
402         return ObjectUtils.toString(this.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_TYPE)).trim();
403     }
404 
405     /**
406      * Indicates whether or not this parameter is of the given input type.
407      *
408      * @param inputType the name of the input type to check for.
409      * @return true/false
410      */
411     private boolean isInputType(final String inputType)
412     {
413         return inputType.equalsIgnoreCase(this.getInputType());
414     }
415 
416     /**
417      * @return isInputType(JSFGlobals.INPUT_TEXTAREA)
418      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputTextarea()
419      */
420     protected boolean handleIsInputTextarea()
421     {
422         return this.isInputType(JSFGlobals.INPUT_TEXTAREA);
423     }
424 
425     /**
426      * @return isInputType(JSFGlobals.INPUT_SELECT)
427      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputSelect()
428      */
429     protected boolean handleIsInputSelect()
430     {
431         return this.isInputType(JSFGlobals.INPUT_SELECT);
432     }
433 
434     /**
435      * @return isInputType(JSFGlobals.INPUT_PASSWORD)
436      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputSecret()
437      */
438     protected boolean handleIsInputSecret()
439     {
440         return this.isInputType(JSFGlobals.INPUT_PASSWORD);
441     }
442 
443     /**
444      * @return isInputType(JSFGlobals.INPUT_HIDDEN)
445      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputHidden()
446      */
447     protected boolean handleIsInputHidden()
448     {
449         return this.isInputType(JSFGlobals.INPUT_HIDDEN);
450     }
451 
452     /**
453      * @return isInputType(JSFGlobals.PLAIN_TEXT)
454      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isPlaintext()
455      */
456     protected boolean handleIsPlaintext()
457     {
458         return this.isInputType(JSFGlobals.PLAIN_TEXT);
459     }
460 
461     /**
462      * @return isInputTable
463      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputTable()
464      */
465     protected boolean handleIsInputTable()
466     {
467         return this.getInputTableIdentifierColumns().length() > 0 || this.isInputType(JSFGlobals.INPUT_TABLE);
468     }
469 
470     /**
471      * @return isInputType(JSFGlobals.INPUT_RADIO)
472      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputRadio()
473      */
474     protected boolean handleIsInputRadio()
475     {
476         return this.isInputType(JSFGlobals.INPUT_RADIO);
477     }
478 
479     /**
480      * @return isInputType(JSFGlobals.INPUT_TEXT)
481      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputText()
482      */
483     protected boolean handleIsInputText()
484     {
485         return this.isInputType(JSFGlobals.INPUT_TEXT);
486     }
487 
488     /**
489      * @return isInputType(JSFGlobals.INPUT_MULTIBOX)
490      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputMultibox()
491      */
492     protected boolean handleIsInputMultibox()
493     {
494         return this.isInputType(JSFGlobals.INPUT_MULTIBOX);
495     }
496 
497     /**
498      * @return isInputCheckbox
499      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputCheckbox()
500      */
501     protected boolean handleIsInputCheckbox()
502     {
503         boolean checkbox = this.isInputType(JSFGlobals.INPUT_CHECKBOX);
504         if (!checkbox && this.getInputType().length() == 0)
505         {
506             final ClassifierFacade type = this.getType();
507             checkbox = type != null ? type.isBooleanType() : false;
508         }
509         return checkbox;
510     }
511 
512     /**
513      * @return isInputFile
514      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isInputFile()
515      */
516     protected boolean handleIsInputFile()
517     {
518         boolean file = false;
519         ClassifierFacade type = getType();
520         if (type != null)
521         {
522             file = type.isFileType();
523         }
524         return file;
525     }
526 
527     /**
528      * @return backingListName
529      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getBackingListName()
530      */
531     protected String handleGetBackingListName()
532     {
533         return ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.BACKING_LIST_PATTERN)).replaceAll(
534             "\\{0\\}",
535             this.getName());
536     }
537 
538     /**
539      * @return backingValueName
540      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getBackingValueName()
541      */
542     protected String handleGetBackingValueName()
543     {
544         return ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.BACKING_VALUE_PATTERN)).replaceAll(
545             "\\{0\\}",
546             this.getName());
547     }
548 
549     /**
550      * @return valueListName
551      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getValueListName()
552      */
553     protected String handleGetValueListName()
554     {
555         return ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.VALUE_LIST_PATTERN)).replaceAll(
556             "\\{0\\}",
557             this.getName());
558     }
559 
560     /**
561      * @return labelListName
562      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getLabelListName()
563      */
564     protected String handleGetLabelListName()
565     {
566         return ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.LABEL_LIST_PATTERN)).replaceAll(
567             "\\{0\\}",
568             this.getName());
569     }
570 
571     /**
572      * @return isSelectable
573      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isSelectable()
574      */
575     protected boolean handleIsSelectable()
576     {
577         boolean selectable = false;
578         if (this.isActionParameter())
579         {
580             selectable = this.isInputMultibox() || this.isInputSelect() || this.isInputRadio();
581             final ClassifierFacade type = this.getType();
582 
583             if (!selectable && type != null)
584             {
585                 final String name = this.getName();
586                 final String typeName = type.getFullyQualifiedName();
587 
588                 // - if the parameter is not selectable but on a targetting page it IS selectable we must
589                 //   allow the user to set the backing list too
590                 final Collection<FrontEndView> views = this.getAction().getTargetViews();
591                 for (final Iterator<FrontEndView> iterator = views.iterator(); iterator.hasNext() && !selectable;)
592                 {
593                     final Collection<FrontEndParameter> parameters = iterator.next().getAllActionParameters();
594                     for (final Iterator<FrontEndParameter> parameterIterator = parameters.iterator();
595                         parameterIterator.hasNext() && !selectable;)
596                     {
597                         final Object object = parameterIterator.next();
598                         if (object instanceof JSFParameter)
599                         {
600                             final JSFParameter parameter = (JSFParameter)object;
601                             final String parameterName = parameter.getName();
602                             final ClassifierFacade parameterType = parameter.getType();
603                             if (parameterType != null)
604                             {
605                                 final String parameterTypeName = parameterType.getFullyQualifiedName();
606                                 if (name.equals(parameterName) && typeName.equals(parameterTypeName))
607                                 {
608                                     selectable =
609                                         parameter.isInputMultibox() || parameter.isInputSelect() ||
610                                         parameter.isInputRadio();
611                                 }
612                             }
613                         }
614                     }
615                 }
616             }
617         }
618         else if (this.isControllerOperationArgument())
619         {
620             final String name = this.getName();
621             final Collection actions = this.getControllerOperation().getDeferringActions();
622             for (final Iterator actionIterator = actions.iterator(); actionIterator.hasNext();)
623             {
624                 final JSFAction action = (JSFAction)actionIterator.next();
625                 final Collection<FrontEndParameter>  formFields = action.getFormFields();
626                 for (final Iterator<FrontEndParameter>  fieldIterator = formFields.iterator();
627                     fieldIterator.hasNext() && !selectable;)
628                 {
629                     final Object object = fieldIterator.next();
630                     if (object instanceof JSFParameter)
631                     {
632                         final JSFParameter parameter = (JSFParameter)object;
633                         if (!parameter.equals(this))
634                         {
635                             if (name.equals(parameter.getName()))
636                             {
637                                 selectable = parameter.isSelectable();
638                             }
639                         }
640                     }
641                 }
642             }
643         }
644         return selectable;
645     }
646 
647     /**
648      * Stores the initial value of each type.
649      */
650     private final Map<String, String> initialValues = new HashMap<String, String>();
651 
652     /**
653      * @return constructDummyArray()
654      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getValueListDummyValue()
655      */
656     protected String handleGetValueListDummyValue()
657     {
658         return this.constructDummyArray();
659     }
660 
661     /**
662      * @return dummyValue
663      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getDummyValue()
664      */
665     protected String handleGetDummyValue()
666     {
667         final ClassifierFacade type = this.getType();
668         final String typeName = type != null ? type.getFullyQualifiedName() : "";
669         String initialValue = null;
670         if (type != null)
671         {
672             if (type.isSetType())
673             {
674                 initialValue =
675                     "new java.util.LinkedHashSet(java.util.Arrays.asList(" + this.constructDummyArray() + "))";
676             }
677             else if (type.isCollectionType())
678             {
679                 initialValue = "java.util.Arrays.asList(" + this.constructDummyArray() + ")";
680             }
681             else if (type.isArrayType())
682             {
683                 initialValue = this.constructDummyArray();
684             }
685             final String name = this.getName() != null ? this.getName() : "";
686             if (this.initialValues.isEmpty())
687             {
688                 initialValues.put(
689                     boolean.class.getName(),
690                     "false");
691                 initialValues.put(
692                     int.class.getName(),
693                     "(int)" + name.hashCode());
694                 initialValues.put(
695                     long.class.getName(),
696                     "(long)" + name.hashCode());
697                 initialValues.put(
698                     short.class.getName(),
699                     "(short)" + name.hashCode());
700                 initialValues.put(
701                     byte.class.getName(),
702                     "(byte)" + name.hashCode());
703                 initialValues.put(
704                     float.class.getName(),
705                     "(float)" + name.hashCode());
706                 initialValues.put(
707                     double.class.getName(),
708                     "(double)" + name.hashCode());
709                 initialValues.put(
710                     char.class.getName(),
711                     "(char)" + name.hashCode());
712 
713                 initialValues.put(
714                     String.class.getName(),
715                     "\"" + name + "-test" + "\"");
716                 initialValues.put(
717                     java.util.Date.class.getName(),
718                     "new java.util.Date()");
719                 initialValues.put(
720                     java.sql.Date.class.getName(),
721                     "new java.util.Date()");
722                 initialValues.put(
723                     java.sql.Timestamp.class.getName(),
724                     "new java.util.Date()");
725 
726                 initialValues.put(
727                     Integer.class.getName(),
728                     "new Integer((int)" + name.hashCode() + ")");
729                 initialValues.put(
730                     Boolean.class.getName(),
731                     "Boolean.FALSE");
732                 initialValues.put(
733                     Long.class.getName(),
734                     "new Long((long)" + name.hashCode() + ")");
735                 initialValues.put(
736                     Character.class.getName(),
737                     "new Character(char)" + name.hashCode() + ")");
738                 initialValues.put(
739                     Float.class.getName(),
740                     "new Float((float)" + name.hashCode() / hashCode() + ")");
741                 initialValues.put(
742                     Double.class.getName(),
743                     "new Double((double)" + name.hashCode() / hashCode() + ")");
744                 initialValues.put(
745                     Short.class.getName(),
746                     "new Short((short)" + name.hashCode() + ")");
747                 initialValues.put(
748                     Byte.class.getName(),
749                     "new Byte((byte)" + name.hashCode() + ")");
750             }
751             if (initialValue == null)
752             {
753                 initialValue = this.initialValues.get(typeName);
754             }
755         }
756         if (initialValue == null)
757         {
758             initialValue = "null";
759         }
760         return initialValue;
761     }
762 
763     /**
764      * Constructs a string representing an array initialization in Java.
765      *
766      * @return A String representing Java code for the initialization of an array.
767      */
768     private String constructDummyArray()
769     {
770         return JSFUtils.constructDummyArrayDeclaration(
771             this.getName(),
772             JSFGlobals.DUMMY_ARRAY_COUNT);
773     }
774 
775     /**
776      * @return getName() + "SortColumn"
777      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getTableSortColumnProperty()
778      */
779     protected String handleGetTableSortColumnProperty()
780     {
781         return this.getName() + "SortColumn";
782     }
783 
784     /**
785      * @return getName() + "SortAscending"
786      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getTableSortAscendingProperty()
787      */
788     protected String handleGetTableSortAscendingProperty()
789     {
790         return this.getName() + "SortAscending";
791     }
792 
793     /**
794      * @return getName() + "Set"
795      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getFormAttributeSetProperty()
796      */
797     protected String handleGetFormAttributeSetProperty()
798     {
799         return this.getName() + "Set";
800     }
801 
802     //TODO remove after 3.4 release
803     /**
804      * Hack to keep the compatibility with Andromda 3.4-SNAPSHOT
805      */
806     /**
807      * @see org.andromda.metafacades.uml.FrontEndParameter#getView()
808      */
809     public FrontEndView getView()
810     {
811         Object view = null;
812         final EventFacade event = this.getEvent();
813         if (event != null)
814         {
815             final TransitionFacade transition = event.getTransition();
816             if (transition instanceof JSFActionLogicImpl)
817             {
818                 final JSFActionLogicImpl action = (JSFActionLogicImpl)transition;
819                 view = action.getInput();
820             }
821             else if (transition instanceof FrontEndForward)
822             {
823                 final FrontEndForward forward = (FrontEndForward)transition;
824                 if (forward.isEnteringView())
825                 {
826                     view = forward.getTarget();
827                 }
828             }
829         }
830         return (FrontEndView)view;
831     }
832 
833     /**
834      * @return validationRequired
835      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isValidationRequired()
836      */
837     protected boolean handleIsValidationRequired()
838     {
839         boolean required = !this.getValidatorTypes().isEmpty();
840         if (!required)
841         {
842             // - look for any attributes
843             for (final Iterator<JSFAttribute> iterator = this.getAttributes().iterator(); iterator.hasNext();)
844             {
845                 required = !iterator.next().getValidatorTypes().isEmpty();
846                 if (required)
847                 {
848                     break;
849                 }
850             }
851 
852             // - look for any table columns
853             if (!required)
854             {
855                 for (final Iterator iterator = this.getTableColumns().iterator(); iterator.hasNext();)
856                 {
857                     final Object object = iterator.next();
858                     if (object instanceof JSFAttribute)
859                     {
860                         final JSFAttribute attribute = (JSFAttribute)object;
861                         required = !attribute.getValidatorTypes().isEmpty();
862                         if (required)
863                         {
864                             break;
865                         }
866                     }
867                 }
868             }
869         }
870         return required;
871     }
872 
873     /**
874      * @return validatorTypes
875      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getValidatorTypes()
876      */
877     protected Collection handleGetValidatorTypes()
878     {
879         return JSFUtils.getValidatorTypes(
880             (ModelElementFacade)this.THIS(),
881             this.getType());
882     }
883 
884     /**
885      * @return JSFUtils.getValidWhen(this)
886      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getValidWhen()
887      */
888     protected String handleGetValidWhen()
889     {
890         return JSFUtils.getValidWhen(this);
891     }
892 
893     /**
894      * Overridden to have the same behavior as bpm4struts.
895      *
896      * @see org.andromda.metafacades.uml.ParameterFacade#isRequired()
897      */
898     public boolean isRequired()
899     {
900         if("org.omg.uml.foundation.core".equals(metaObject.getClass().getPackage().getName()))
901         {
902             //if uml 1.4, keep the old behavior (like bpm4struts)
903             final Object value = this.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_REQUIRED);
904             return Boolean.valueOf(ObjectUtils.toString(value)).booleanValue();
905         }
906         else
907         {
908             //if >= uml 2, default behavior
909             return super.isRequired();
910         }
911     }
912 
913     /**
914      * @return JSFUtils.isReadOnly(this)
915      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isReadOnly()
916      */
917     protected boolean handleIsReadOnly()
918     {
919         return JSFUtils.isReadOnly(this);
920     }
921 
922     /**
923      * @param validatorType
924      * @return validatorArgs
925      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getValidatorArgs(String)
926      */
927     protected Collection handleGetValidatorArgs(final String validatorType)
928     {
929         return JSFUtils.getValidatorArgs(
930             (ModelElementFacade)this.THIS(),
931             validatorType);
932     }
933 
934     /**
935      * @return validatorVars
936      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getValidatorVars()
937      */
938     protected Collection handleGetValidatorVars()
939     {
940         return JSFUtils.getValidatorVars(
941             (ModelElementFacade)this.THIS(),
942             this.getType(),
943             null);
944     }
945 
946     /**
947      * @return reset
948      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isReset()
949      */
950     protected boolean handleIsReset()
951     {
952         boolean reset =
953             Boolean.valueOf(ObjectUtils.toString(this.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_RESET)))
954                    .booleanValue();
955         if (!reset)
956         {
957             final JSFAction action = (JSFAction)this.getAction();
958             reset = action != null && action.isFormReset();
959         }
960         return reset;
961     }
962 
963     /**
964      * @return complex
965      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isComplex()
966      */
967     protected boolean handleIsComplex()
968     {
969         boolean complex = false;
970         final ClassifierFacade type = this.getType();
971         if (type != null)
972         {
973             complex = !type.getAttributes().isEmpty();
974             if (!complex)
975             {
976                 complex = !type.getAssociationEnds().isEmpty();
977             }
978         }
979         return complex;
980     }
981 
982     /**
983      * @return attributes
984      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getAttributes()
985      */
986     protected Collection<AttributeFacade> handleGetAttributes()
987     {
988         Collection<AttributeFacade> attributes = null;
989         ClassifierFacade type = this.getType();
990         if (type != null)
991         {
992             if (type.isArrayType())
993             {
994                 type = type.getNonArray();
995             }
996             if (type != null)
997             {
998                 attributes = type.getAttributes(true);
999             }
1000         }
1001         return attributes == null ? new ArrayList<AttributeFacade>() : attributes;
1002     }
1003 
1004     /**
1005      * @return navigableAssociationEnds
1006      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getNavigableAssociationEnds()
1007      */
1008     @Override
1009     protected Collection<AssociationEndFacade> handleGetNavigableAssociationEnds()
1010     {
1011         Collection<AssociationEndFacade> associationEnds = null;
1012         ClassifierFacade type = this.getType();
1013         if (type != null)
1014         {
1015             if (type.isArrayType())
1016             {
1017                 type = type.getNonArray();
1018             }
1019             if (type != null)
1020             {
1021                 associationEnds = type.getNavigableConnectingEnds();
1022             }
1023         }
1024         return associationEnds == null ? new ArrayList<AssociationEndFacade>() : associationEnds;
1025     }
1026 
1027     /**
1028      * @return isEqualValidator
1029      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isEqualValidator()
1030      */
1031     protected boolean handleIsEqualValidator()
1032     {
1033         final String equal = JSFUtils.getEqual((ModelElementFacade)this.THIS());
1034         return equal != null && equal.trim().length() > 0;
1035     }
1036 
1037     /**
1038      * @return isBackingValueRequired
1039      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#isEqualValidator()
1040      */
1041     protected boolean handleIsBackingValueRequired()
1042     {
1043         boolean required = false;
1044         if (this.isActionParameter())
1045         {
1046             required = this.isInputTable();
1047             final ClassifierFacade type = this.getType();
1048 
1049             if (!required && type != null)
1050             {
1051                 final String name = this.getName();
1052                 final String typeName = type.getFullyQualifiedName();
1053 
1054                 // - if the backing value is not required for this parameter but on
1055                 //   a targeting page it IS selectable we must allow the user to set the backing value as well
1056                 final Collection<FrontEndView> views = this.getAction().getTargetViews();
1057                 for (final Iterator<FrontEndView> iterator = views.iterator(); iterator.hasNext() && !required;)
1058                 {
1059                     final Collection<FrontEndParameter> parameters = iterator.next().getAllActionParameters();
1060                     for (final Iterator<FrontEndParameter> parameterIterator = parameters.iterator();
1061                         parameterIterator.hasNext() && !required;)
1062                     {
1063                         final FrontEndParameter object = parameterIterator.next();
1064                         if (object instanceof JSFParameter)
1065                         {
1066                             final JSFParameter parameter = (JSFParameter)object;
1067                             final String parameterName = parameter.getName();
1068                             final ClassifierFacade parameterType = parameter.getType();
1069                             if (parameterType != null)
1070                             {
1071                                 final String parameterTypeName = parameterType.getFullyQualifiedName();
1072                                 if (name.equals(parameterName) && typeName.equals(parameterTypeName))
1073                                 {
1074                                     required = parameter.isInputTable();
1075                                 }
1076                             }
1077                         }
1078                     }
1079                 }
1080             }
1081         }
1082         else if (this.isControllerOperationArgument())
1083         {
1084             final String name = this.getName();
1085             final Collection<FrontEndAction> actions = this.getControllerOperation().getDeferringActions();
1086             for (final Iterator<FrontEndAction> actionIterator = actions.iterator(); actionIterator.hasNext();)
1087             {
1088                 final JSFAction action = (JSFAction)actionIterator.next();
1089                 final Collection<FrontEndParameter> formFields = action.getFormFields();
1090                 for (final Iterator<FrontEndParameter> fieldIterator = formFields.iterator();
1091                     fieldIterator.hasNext() && !required;)
1092                 {
1093                     final Object object = fieldIterator.next();
1094                     if (object instanceof JSFParameter)
1095                     {
1096                         final JSFParameter parameter = (JSFParameter)object;
1097                         if (!parameter.equals(this))
1098                         {
1099                             if (name.equals(parameter.getName()))
1100                             {
1101                                 required = parameter.isBackingValueRequired();
1102                             }
1103                         }
1104                     }
1105                 }
1106             }
1107         }
1108         return required;
1109     }
1110 
1111     /**
1112      * @return findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_TABLE_IDENTIFIER_COLUMNS)
1113      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getInputTableIdentifierColumns()
1114      */
1115     protected String handleGetInputTableIdentifierColumns()
1116     {
1117         return ObjectUtils.toString(this.findTaggedValue(JSFProfile.TAGGEDVALUE_INPUT_TABLE_IDENTIFIER_COLUMNS)).trim();
1118     }
1119 
1120     /**
1121      * @param columnName
1122      * @return tableColumnActions
1123      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getTableColumnActions(String)
1124      */
1125     protected List<JSFAction> handleGetTableColumnActions(final String columnName)
1126     {
1127         final List<JSFAction> columnActions = new ArrayList<JSFAction>();
1128 
1129         if (columnName != null)
1130         {
1131             final Set<JSFAction> actions = new LinkedHashSet<JSFAction>(this.getTableHyperlinkActions());
1132             actions.addAll(this.getTableFormActions());
1133             for (final JSFAction action : actions)
1134             {
1135                 if (columnName.equals(action.getTableLinkColumnName()))
1136                 {
1137                     columnActions.add(action);
1138                 }
1139             }
1140         }
1141 
1142         return columnActions;
1143     }
1144 
1145     /**
1146      * @return maxLength
1147      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getMaxLength()
1148      */
1149     protected String handleGetMaxLength()
1150     {
1151         final Collection<Collection> vars=getValidatorVars();
1152         if(vars == null)
1153         {
1154             return null;
1155         }
1156         for(Iterator<Collection> it=vars.iterator(); it.hasNext();)
1157         {
1158             final Object[] values=(it.next()).toArray();
1159             if("maxlength".equals(values[0]))
1160             {
1161                 return values[1].toString();
1162             }
1163         }
1164         return null;
1165     }
1166 
1167     //to be used in the range validator: "range - 1000" or "range 20 -".
1168     /** - */
1169     static final String UNDEFINED_BOUND="-";
1170     /** javax.validation.constraints.NotNull */
1171     static final String AN_REQUIRED = "@javax.validation.constraints.NotNull";
1172     /** org.hibernate.validator.constraints.URL */
1173     static final String AN_URL = "@org.hibernate.validator.constraints.URL";
1174     /** org.apache.myfaces.extensions.validator.baseval.annotation.LongRange */
1175     static final String AN_LONG_RANGE = "@org.apache.myfaces.extensions.validator.baseval.annotation.LongRange";
1176     /** org.apache.myfaces.extensions.validator.baseval.annotation.DoubleRange */
1177     static final String AN_DOUBLE_RANGE = "@org.apache.myfaces.extensions.validator.baseval.annotation.DoubleRange";
1178     /** org.hibernate.validator.constraints.Email */
1179     static final String AN_EMAIL = "@org.hibernate.validator.constraints.Email";
1180     /** org.hibernate.validator.constraints.CreditCardNumber */
1181     static final String AN_CREDIT_CARD = "@org.hibernate.validator.constraints.CreditCardNumber";
1182     /** javax.validation.constraints.Size */
1183     static final String AN_LENGTH = "@javax.validation.constraints.Size";
1184     /** org.apache.myfaces.extensions.validator.baseval.annotation.Pattern */
1185     static final String AN_PATTERN = "@org.apache.myfaces.extensions.validator.baseval.annotation.Pattern";
1186     /** org.apache.myfaces.extensions.validator.crossval.annotation.Equals */
1187     static final String AN_EQUALS = "@org.apache.myfaces.extensions.validator.crossval.annotation.Equals";
1188 
1189     /**
1190      * @return the annotations
1191      * @see org.andromda.cartridges.jsf2.metafacades.JSFParameter#getMaxLength()
1192      */
1193     @Override
1194     protected Collection<String> handleGetAnnotations()
1195     {
1196         final Collection<String> result=new HashSet<String>();
1197         boolean requiredAdded=false;
1198         for(String vt: (Collection<String>)getValidatorTypes())
1199         {
1200             if(vt.startsWith("@")) //add the annotation
1201             {
1202                 result.add(vt);
1203             }
1204             if(JSFUtils.VT_REQUIRED.equals(vt))
1205             {
1206                 requiredAdded=true;
1207                 result.add(AN_REQUIRED);
1208             }
1209             else if(JSFUtils.VT_URL.equals(vt))
1210             {
1211                 result.add(AN_URL);
1212             }
1213             else if(JSFUtils.VT_INT_RANGE.equals(vt))
1214             {
1215                 final StringBuilder sb=new StringBuilder(AN_LONG_RANGE+"(");
1216                 final String format = JSFUtils.getInputFormat((ModelElementFacade)this.THIS());
1217                 final String rangeStart = JSFUtils.getRangeStart(format);
1218                 boolean addComma=false;
1219                 if(StringUtils.isNotBlank(rangeStart) && !rangeStart.equals(UNDEFINED_BOUND))
1220                 {
1221                     sb.append("minimum="+rangeStart);
1222                     addComma=true;
1223                 }
1224                 final String rangeEnd = JSFUtils.getRangeEnd(format);
1225                 if(StringUtils.isNotBlank(rangeEnd) && !rangeEnd.equals(UNDEFINED_BOUND))
1226                 {
1227                     if(addComma)
1228                     {
1229                         sb.append(",");
1230                     }
1231                     sb.append("maximum="+rangeEnd);
1232                 }
1233                 sb.append(")");
1234                 result.add(sb.toString());
1235             }
1236             else if(JSFUtils.VT_FLOAT_RANGE.equals(vt) || JSFUtils.VT_DOUBLE_RANGE.equals(vt))
1237             {
1238                 final StringBuilder sb=new StringBuilder(AN_DOUBLE_RANGE+"(");
1239                 final String format = JSFUtils.getInputFormat(((ModelElementFacade)this.THIS()));
1240                 final String rangeStart = JSFUtils.getRangeStart(format);
1241                 boolean addComma=false;
1242                 if(StringUtils.isNotBlank(rangeStart) && !rangeStart.equals(UNDEFINED_BOUND))
1243                 {
1244                     sb.append("minimum="+rangeStart);
1245                     addComma=true;
1246                 }
1247                 final String rangeEnd = JSFUtils.getRangeEnd(format);
1248                 if(StringUtils.isNotBlank(rangeEnd) && !rangeEnd.equals(UNDEFINED_BOUND))
1249                 {
1250                     if(addComma)
1251                     {
1252                         sb.append(",");
1253                     }
1254                     sb.append("maximum="+rangeEnd);
1255                 }
1256                 sb.append(")");
1257                 result.add(sb.toString());
1258             }
1259             else if(JSFUtils.VT_EMAIL.equals(vt))
1260             {
1261                 result.add(AN_EMAIL);
1262             }
1263             else if(JSFUtils.VT_CREDIT_CARD.equals(vt))
1264             {
1265                 result.add(AN_CREDIT_CARD);
1266             }
1267             else if(JSFUtils.VT_MIN_LENGTH.equals(vt) || JSFUtils.VT_MAX_LENGTH.equals(vt))
1268             {
1269                 final StringBuilder sb=new StringBuilder(AN_LENGTH+"(");
1270                 final Collection formats = this.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_FORMAT);
1271                 boolean addComma=false;
1272                 for (final Iterator formatIterator = formats.iterator(); formatIterator.hasNext();)
1273                 {
1274                     final String additionalFormat = String.valueOf(formatIterator.next());
1275                     if (JSFUtils.isMinLengthFormat(additionalFormat))
1276                     {
1277                         if(addComma)
1278                         {
1279                             sb.append(",");
1280                         }
1281                         sb.append("min=");
1282                         sb.append(JSFUtils.getMinLengthValue(additionalFormat));
1283                         addComma=true;
1284                     }
1285                     else if (JSFUtils.isMaxLengthFormat(additionalFormat))
1286                     {
1287                         if(addComma)
1288                         {
1289                             sb.append(",");
1290                         }
1291                         sb.append("max=");
1292                         sb.append(JSFUtils.getMinLengthValue(additionalFormat));
1293                         addComma=true;
1294                     }
1295                 }
1296                 sb.append(")");
1297                 result.add(sb.toString());
1298             }
1299             else if(JSFUtils.VT_MASK.equals(vt))
1300             {
1301                 final Collection formats = this.findTaggedValues(JSFProfile.TAGGEDVALUE_INPUT_FORMAT);
1302                 for (final Iterator formatIterator = formats.iterator(); formatIterator.hasNext();)
1303                 {
1304                     final String additionalFormat = String.valueOf(formatIterator.next());
1305                     if (JSFUtils.isPatternFormat(additionalFormat))
1306                     {
1307                         result.add(AN_PATTERN+"(\""+JSFUtils.getPatternValue(additionalFormat)+"\")");
1308                     }
1309                 }
1310             }
1311             else if(JSFUtils.VT_VALID_WHEN.equals(vt))
1312             {
1313                 result.add("");
1314             }
1315             else if(JSFUtils.VT_EQUAL.equals(vt))
1316             {
1317                 result.add(AN_EQUALS+"(\""+JSFUtils.getEqual((ModelElementFacade)this.THIS())+"\")");
1318             }
1319         }
1320         if(!requiredAdded && getLower() > 0)
1321         {
1322             result.add(AN_REQUIRED);
1323         }
1324         return result;
1325     }
1326 }