001package org.andromda.cartridges.jsf2.metafacades;
002
003import java.security.MessageDigest;
004import java.security.NoSuchAlgorithmException;
005import java.util.ArrayList;
006import java.util.Collection;
007import java.util.LinkedHashSet;
008import org.andromda.cartridges.jsf2.JSFGlobals;
009import org.andromda.cartridges.jsf2.JSFProfile;
010import org.andromda.cartridges.jsf2.JSFUtils;
011import org.andromda.metafacades.uml.DependencyFacade;
012import org.andromda.metafacades.uml.ManageableEntityAssociationEnd;
013import org.andromda.metafacades.uml.ManageableEntityAttribute;
014import org.andromda.metafacades.uml.Role;
015import org.andromda.metafacades.uml.UMLMetafacadeProperties;
016import org.andromda.utils.StringUtilsHelper;
017import org.apache.commons.collections.Closure;
018import org.apache.commons.collections.CollectionUtils;
019import org.apache.commons.collections.Predicate;
020import org.apache.commons.collections.Transformer;
021import org.apache.commons.lang.BooleanUtils;
022import org.apache.commons.lang.ObjectUtils;
023import org.apache.commons.lang.StringUtils;
024import org.apache.log4j.Logger;
025
026/**
027 * MetafacadeLogic implementation for org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity.
028 *
029 * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity
030 */
031public class JSFManageableEntityLogicImpl
032    extends JSFManageableEntityLogic
033{
034    private static final long serialVersionUID = 34L;
035    
036    /**
037     * The logger instance.
038     */
039    private static final Logger LOGGER = Logger.getLogger(JSFManageableEntityLogicImpl.class);    
040    
041    /**
042     * @param metaObject
043     * @param context
044     */
045    public JSFManageableEntityLogicImpl(Object metaObject, String context)
046    {
047        super(metaObject, context);
048    }
049
050    /**
051     * @return getName().toLowerCase() + "-crud"
052     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getViewName()
053     */
054    protected String handleGetViewName()
055    {
056        return this.getName().toLowerCase() + "-crud";
057    }
058
059    /**
060     * @return toResourceMessageKey(this.getName()) + ".view.title"
061     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getViewTitleKey()
062     */
063    protected String handleGetViewTitleKey()
064    {
065        return StringUtilsHelper.toResourceMessageKey(this.getName()) + ".view.title";
066    }
067
068    /**
069     * @return StringUtilsHelper.toPhrase(getName())
070     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getViewTitleValue()
071     */
072    protected String handleGetViewTitleValue()
073    {
074        return StringUtilsHelper.toPhrase(getName());
075    }
076
077    /**
078     * @return "manageableList"
079     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getListName()
080     */
081    protected String handleGetListName()
082    {
083        return "manageableList";
084    }
085
086    /**
087     * @return getManageablePackageName() + getNamespaceProperty() + this.getFormBeanClassName()
088     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getFormBeanType()
089     */
090    protected String handleGetFormBeanType()
091    {
092        return this.getManageablePackageName() + this.getNamespaceProperty() + this.getFormBeanClassName();
093    }
094
095    /**
096     * @return formBeanName
097     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getFormBeanName()
098     */
099    protected String handleGetFormBeanName()
100    {
101        final String pattern = ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.FORM_BEAN_PATTERN));
102        final String formBeanName = pattern.replaceFirst("\\{0\\}", "manage");
103        return formBeanName.replaceFirst("\\{1\\}", this.getName());
104    }
105
106    /**
107     * @return StringUtilsHelper.toResourceMessageKey(this.getName()) + ".exception"
108     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getExceptionKey()
109     */
110    protected String handleGetExceptionKey()
111    {
112        return StringUtilsHelper.toResourceMessageKey(this.getName()) + ".exception";
113    }
114
115    /**
116     * @return getManageablePackageName() + getNamespaceProperty() + getActionClassName()
117     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getActionType()
118     */
119    protected String handleGetActionType()
120    {
121        return this.getManageablePackageName() + this.getNamespaceProperty() + this.getActionClassName();
122    }
123
124    /**
125     * @return '/' + StringUtils.replace(this.getActionType(), getNamespaceProperty(), "/")
126     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getActionFullPath()
127     */
128    protected String handleGetActionFullPath()
129    {
130        return '/' + StringUtils.replace(this.getActionType(), this.getNamespaceProperty(), "/");
131    }
132
133    /**
134     * @return '/' + getName() + "/Manage"
135     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getActionPath()
136     */
137    protected String handleGetActionPath()
138    {
139        return super.getActionFullPath();
140    }
141
142    /**
143     * @return "Manage" + getName()
144     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getActionClassName()
145     */
146    protected String handleGetActionClassName()
147    {
148        return getName();
149    }
150
151    /**
152     * @return getViewFullPath()
153     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getExceptionPath()
154     */
155    protected String handleGetExceptionPath()
156    {
157        return this.getViewFullPath();
158    }
159
160    /**
161     * @return false
162     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#isPreload()
163     */
164    protected boolean handleIsPreload()
165    {
166        return false; //TODO think about...
167//        return this.isCreate() || this.isRead() || this.isUpdate() || this.isDelete();
168    }
169
170    /**
171     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntityLogic#getManageableIdentifier()
172     */
173    @Override
174    public org.andromda.metafacades.uml.ManageableEntityAttribute getManageableIdentifier()
175    {
176        return super.getManageableIdentifier();
177    }
178
179    /**
180     * @return StringUtils.capitalize(this.getFormBeanName())
181     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getFormBeanClassName()
182     */
183    protected String handleGetFormBeanClassName()
184    {
185        return StringUtils.capitalize(this.getFormBeanName());
186    }
187
188    /**
189     * @return StringUtils.replace(getFormBeanType(), getNamespaceProperty(), "/")
190     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getFormBeanFullPath()
191     */
192    protected String handleGetFormBeanFullPath()
193    {
194        return StringUtils.replace(this.getFormBeanType(), this.getNamespaceProperty(), "/");
195    }
196
197    /**
198     * @return "getManageableList"
199     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getListGetterName()
200     */
201    protected String handleGetListGetterName()
202    {
203        return "getManageableList";
204    }
205
206    /**
207     * @return "setManageableList"
208     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getListSetterName()
209     */
210    protected String handleGetListSetterName()
211    {
212        return "setManageableList";
213    }
214
215    /**
216     * @return StringUtilsHelper.toResourceMessageKey(this.getName())
217     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getMessageKey()
218     */
219    protected String handleGetMessageKey()
220    {
221        return StringUtilsHelper.toResourceMessageKey(this.getName());
222    }
223
224    /**
225     * @return StringUtilsHelper.toPhrase(this.getName())
226     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getMessageValue()
227     */
228    protected String handleGetMessageValue()
229    {
230        return StringUtilsHelper.toPhrase(this.getName());
231    }
232
233    /**
234     * @return getMessageKey() + ".online.help"
235     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getOnlineHelpKey()
236     */
237    protected String handleGetOnlineHelpKey()
238    {
239        return this.getMessageKey() + ".online.help";
240    }
241
242    /**
243     * @return onlineHelpValue
244     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getOnlineHelpValue()
245     */
246    protected String handleGetOnlineHelpValue()
247    {
248        final String value = StringUtilsHelper.toResourceMessage(this.getDocumentation("", 64, false));
249        return (value == null) ? "No entity documentation has been specified" : value;
250    }
251
252    /**
253     * @return getActionPath() + "Help"
254     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getOnlineHelpActionPath()
255     */
256    protected String handleGetOnlineHelpActionPath()
257    {
258        return this.getActionPath() + "Help";
259    }
260
261    /**
262     * @return '/' + getManageablePackagePath() + '/' + getName().toLowerCase() + "_help"
263     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getOnlineHelpPagePath()
264     */
265    protected String handleGetOnlineHelpPagePath()
266    {
267        return '/' + this.getManageablePackagePath() + '/' + this.getName().toLowerCase() + "_help";
268    }
269
270    /**
271     * @return getTableExportTypes().indexOf("none") == -1
272     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#isTableExportable()
273     */
274    protected boolean handleIsTableExportable()
275    {
276        return this.getTableExportTypes().indexOf("none") == -1;
277    }
278
279    /**
280     * @return null
281     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getTableExportTypes()
282     */
283    protected String handleGetTableExportTypes()
284    {
285        return null;
286        //TODO a resolver
287//        return JSFUtils.getDisplayTagExportTypes(
288//            this.findTaggedValues(JSFProfile.TAGGEDVALUE_TABLE_EXPORT),
289//            (String)getConfiguredProperty(JSFGlobals.PROPERTY_DEFAULT_TABLE_EXPORT_TYPES) );
290    }
291
292    /**
293     * @return tableMaxRows
294     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getTableMaxRows()
295     */
296    protected int handleGetTableMaxRows()
297    {
298        final Object taggedValue = this.findTaggedValue(JSFProfile.TAGGEDVALUE_TABLE_MAXROWS);
299        int pageSize;
300
301        try
302        {
303            pageSize = Integer.parseInt(String.valueOf(taggedValue));
304        }
305        catch (Exception e)
306        {
307            pageSize = JSFProfile.TAGGEDVALUE_TABLE_MAXROWS_DEFAULT_COUNT;
308        }
309
310        return pageSize;
311    }
312
313    /**
314     * @return tableSortable
315     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#isTableSortable()
316     */
317    protected boolean handleIsTableSortable()
318    {
319        final Object taggedValue = this.findTaggedValue(JSFProfile.TAGGEDVALUE_TABLE_SORTABLE);
320        return (taggedValue == null)
321            ? JSFProfile.TAGGEDVALUE_TABLE_SORTABLE_DEFAULT_VALUE
322            : Boolean.valueOf(String.valueOf(taggedValue)).booleanValue();
323    }
324
325    /**
326     * @return controllerType
327     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getControllerType()
328     */
329     protected String handleGetControllerType()
330     {
331         return this.getManageablePackageName() + this.getNamespaceProperty() + this.getControllerName();
332     }
333
334    /**
335     * @return StringUtils.uncapitalize(this.getName()) + "Controller"
336     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getControllerBeanName()
337     */
338    protected String handleGetControllerBeanName()
339    {
340        return StringUtils.uncapitalize(this.getName()) + "Controller";
341    }
342
343    /**
344     * @return '/' + StringUtils.replace(getControllerType(), getNamespaceProperty(), "/")
345     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getControllerFullPath()
346     */
347    protected String handleGetControllerFullPath()
348    {
349        return '/' + StringUtils.replace(this.getControllerType(), this.getNamespaceProperty(), "/");
350    }
351
352    /**
353     * @return getName() + "Controller"
354     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getControllerName()
355     */
356    protected String handleGetControllerName()
357    {
358        return this.getName() + "Controller";
359    }
360
361    /**
362     * @return getName() + this.getConfiguredProperty(JSFGlobals.CRUD_VALUE_OBJECT_SUFFIX)
363     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getValueObjectClassName()
364     */
365    protected String handleGetValueObjectClassName()
366    {
367        return getName() + this.getConfiguredProperty(JSFGlobals.CRUD_VALUE_OBJECT_SUFFIX);
368    }
369
370    /**
371     * @return formSerialVersionUID
372     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getFormSerialVersionUID()
373     */
374    protected String handleGetFormSerialVersionUID()
375    {
376        final StringBuilder buffer = new StringBuilder();
377        buffer.append(this.getFormBeanType());
378        addSerialUIDData(buffer);
379        return JSFUtils.calcSerialVersionUID(buffer);
380    }
381
382    /**
383     * @return actionSerialVersionUID
384     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getActionSerialVersionUID()
385     */
386    protected String handleGetActionSerialVersionUID()
387    {
388        final StringBuilder buffer = new StringBuilder();
389        buffer.append(this.getActionFullPath());
390        addSerialUIDData(buffer);
391        return JSFUtils.calcSerialVersionUID(buffer);
392    }
393
394    /**
395     * @return populatorName
396     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getPopulatorName()
397     */
398    protected String handleGetPopulatorName()
399    {
400        return ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.VIEW_POPULATOR_PATTERN)).replaceAll(
401            "\\{0\\}",
402            StringUtilsHelper.upperCamelCaseName(this.getFormBeanClassName()));
403    }
404
405    /**
406     * @return '/' + StringUtils.replace(getPopulatorType(), getNamespaceProperty(), "/")
407     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getPopulatorFullPath()
408     */
409    protected String handleGetPopulatorFullPath()
410    {
411        return '/' + StringUtils.replace(this.getPopulatorType(), this.getNamespaceProperty(), "/");
412    }
413
414    /**
415     * @return getManageablePackageName() + getNamespaceProperty() + getPopulatorName()
416     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getPopulatorType()
417     */
418    protected String handleGetPopulatorType()
419    {
420        return this.getManageablePackageName() + this.getNamespaceProperty() + this.getPopulatorName();
421    }
422
423    /**
424     * @return '/' + getManageablePackagePath() + '/' + getViewName()
425     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getViewFullPath()
426     */
427    protected String handleGetViewFullPath()
428    {
429        return '/' + this.getManageablePackagePath() + '/' + this.getViewName();
430    }
431
432    /**
433     * @return '/' + getManageablePackagePath() + '/' + getName().toLowerCase() + "-ods-export"
434     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getViewFullPath()
435     */
436    protected String handleGetOdsExportFullPath()
437    {
438        return '/' + this.getManageablePackagePath() + '/' + this.getName().toLowerCase()+".ods-export";
439    }
440
441    /**
442     * @return isValidationRequired
443     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#isValidationRequired()
444     */
445    protected boolean handleIsValidationRequired()
446    {
447        for (final ManageableEntityAttribute attribute : this.getManageableAttributes())
448        {
449            if(attribute instanceof JSFManageableEntityAttribute)
450            {
451                final JSFManageableEntityAttribute jsfAttribute = (JSFManageableEntityAttribute)attribute;
452                if (jsfAttribute.isValidationRequired())
453                {
454                    return true;
455                }
456            }
457        }
458        return false;
459    }
460
461    /**
462     * @return searchFormBeanName
463     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getSearchFormBeanName()
464     */
465    protected String handleGetSearchFormBeanName()
466    {
467        final String pattern = ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.FORM_BEAN_PATTERN));
468        final String formBeanName = pattern.replaceFirst("\\{0\\}", "manage");
469        return formBeanName.replaceFirst("\\{1\\}",this.getName() + "Search");
470    }
471
472    /**
473     * @return searchFormBeanType
474     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getSearchFormBeanType()
475     */
476    protected String handleGetSearchFormBeanType()
477    {
478        return this.getManageablePackageName() + this.getNamespaceProperty() + this.getSearchFormBeanClassName();
479    }
480
481    /**
482     * @return searchFormBeanFullPath
483     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getSearchFormBeanFullPath()
484     */
485    protected String handleGetSearchFormBeanFullPath()
486    {
487        return StringUtils.replace(this.getSearchFormBeanType(), this.getNamespaceProperty(), "/");
488    }
489
490    /**
491     * @return StringUtils.capitalize(this.getSearchFormBeanName())
492     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getSearchFormBeanClassName()
493     */
494    protected String handleGetSearchFormBeanClassName()
495    {
496        return StringUtils.capitalize(this.getSearchFormBeanName());
497    }
498
499    private Boolean usingManageableSearchable=null;
500    private boolean isUsingManageableSearchable()
501    {
502        if(usingManageableSearchable == null)
503        {
504            for(final ManageableEntityAttribute attr: getManageableAttributes())
505            {
506                if(BooleanUtils.toBoolean(ObjectUtils.toString(attr.findTaggedValue(JSFProfile.ANDROMDA_MANAGEABLE_ATTRIBUTE_SEARCHABLE))))
507                {
508                    usingManageableSearchable=true;
509                    break;
510                }
511            }
512            if(usingManageableSearchable == null)
513            {
514                for(final ManageableEntityAssociationEnd end: getManageableAssociationEnds())
515                {
516                    //TODO constant should go to JSFProfile of UMLPROFILE
517                    if(BooleanUtils.toBoolean(ObjectUtils.toString(end.findTaggedValue(JSFProfile.ANDROMDA_MANAGEABLE_ATTRIBUTE_SEARCHABLE))))
518                    {
519                        usingManageableSearchable=true;
520                        break;
521                    }
522                }
523            }
524            if(usingManageableSearchable == null)
525            {
526                usingManageableSearchable = false;
527            }
528        }
529        return usingManageableSearchable;
530    }
531    
532    
533    /**
534     * @return manageableSearchAttributes
535     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getManageableSearchAttributes()
536     */
537    protected Collection<JSFManageableEntityAttribute> handleGetManageableSearchAttributes()
538    {
539        final Collection<JSFManageableEntityAttribute> searchAttributes=new ArrayList<JSFManageableEntityAttribute>();
540        
541        if(isUsingManageableSearchable())
542        {
543            for(final ManageableEntityAttribute attr: getManageableAttributes())
544            {
545                if(BooleanUtils.toBoolean(ObjectUtils.toString(attr.findTaggedValue(JSFProfile.ANDROMDA_MANAGEABLE_ATTRIBUTE_SEARCHABLE))))
546                {
547                    searchAttributes.add((JSFManageableEntityAttribute)attr);
548                }
549            }
550        }
551        else
552        {
553            for(ManageableEntityAttribute attr: getManageableAttributes())
554            {
555                if(attr.isDisplay() && !attr.getType().isBlobType())
556                {
557                    searchAttributes.add((JSFManageableEntityAttribute)attr);
558                }
559            }
560        }
561
562        return searchAttributes;
563    }
564
565    /**
566     * @return getManageableAssociationEnds()
567     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getManageableSearchAssociationEnds()
568     */
569    protected Collection<ManageableEntityAssociationEnd> handleGetManageableSearchAssociationEnds()
570    {
571        final Collection<ManageableEntityAssociationEnd> searchAssociationEnds=new ArrayList<ManageableEntityAssociationEnd>();
572        
573        if(isUsingManageableSearchable())
574        {
575            for(final ManageableEntityAssociationEnd end: getManageableAssociationEnds())
576            {
577                if(BooleanUtils.toBoolean(ObjectUtils.toString(end.findTaggedValue(JSFProfile.ANDROMDA_MANAGEABLE_ATTRIBUTE_SEARCHABLE)))
578                   || end.isComposition())
579                {
580                    searchAssociationEnds.add(end);
581                }
582            }
583        }
584        else
585        {
586            for(final ManageableEntityAssociationEnd end: getManageableAssociationEnds())
587            {
588                if(end.isDisplay() || end.isComposition())
589                {
590                    searchAssociationEnds.add(end);
591                }
592            }
593        }
594
595        return searchAssociationEnds;
596    }
597
598    /**
599     * @param element
600     * @return isSearchable
601     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#isSearchable(Object)
602     */
603    protected boolean handleIsSearchable(Object element)
604    {
605       return getManageableSearchAttributes().contains(element) || getManageableSearchAssociationEnds().contains(element);
606    }
607
608    /**
609     * @return the configured property denoting the character sequence to use for the separation of namespaces
610     */
611    private String getNamespaceProperty()
612    {
613        return (String)this.getConfiguredProperty(UMLMetafacadeProperties.NAMESPACE_SEPARATOR);
614    }
615
616   private void addSerialUIDData(StringBuilder buffer)
617   {
618       for (final ManageableEntityAttribute attribute : this.getManageableAttributes())
619       {
620           buffer.append(attribute.getName());
621       }
622       for (final ManageableEntityAssociationEnd end : this.getManageableAssociationEnds())
623       {
624           buffer.append(end.getName());
625       }
626   }
627
628   /**
629    * @return allRoles
630    * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getRoles()
631    */
632   @SuppressWarnings("rawtypes")
633protected Collection handleGetRoles()
634   {
635       //copied form the Service <<Metafacade>>
636       final Collection<DependencyFacade> roles = new ArrayList<DependencyFacade>(this.getTargetDependencies());
637       CollectionUtils.filter(roles, new Predicate()
638       {
639           public boolean evaluate(final Object object)
640           {
641               DependencyFacade dependency = (DependencyFacade)object;
642               return dependency != null && dependency.getSourceElement() instanceof Role;
643           }
644       });
645       CollectionUtils.transform(roles, new Transformer()
646       {
647           public Object transform(final Object object)
648           {
649               return ((DependencyFacade)object).getSourceElement();
650           }
651       });
652       @SuppressWarnings({ "unchecked" })
653    final Collection allRoles = new LinkedHashSet(roles);
654       // add all roles which are generalizations of this one
655       CollectionUtils.forAllDo(roles, new Closure()
656       {
657           @SuppressWarnings("unchecked")
658        public void execute(final Object object)
659           {
660               allRoles.addAll(((Role)object).getAllSpecializations());
661           }
662       });
663       return allRoles;
664   }
665
666   /**
667    * @return actionRoles
668    * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getActionRoles()
669    */
670   protected String handleGetActionRoles()
671   {
672       //copied from JSFUseCaseLogicImpl
673       final StringBuilder rolesBuffer = new StringBuilder();
674       boolean first = true;
675       for (final Role role : this.getRoles())
676       {
677           if (first)
678           {
679               first = false;
680           }
681           else
682           {
683               rolesBuffer.append(',');
684           }
685           rolesBuffer.append(role.getName());
686       }
687       return rolesBuffer.toString();
688   }
689
690   /**
691    * @return needsFileUpload
692    * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#isNeedsFileUpload()
693    */
694   protected boolean handleIsNeedsFileUpload()
695   {
696       for (final ManageableEntityAttribute attribute : this.getManageableAttributes())
697       {
698           if(attribute instanceof JSFManageableEntityAttribute)
699           {
700               final JSFManageableEntityAttribute jsfAttribute = (JSFManageableEntityAttribute)attribute;
701               if(jsfAttribute.isNeedsFileUpload())
702               {
703                   return true;
704               }
705           }
706       }
707       return false;
708   }
709
710   /**
711    * @return needsUserInterface
712    * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#isNeedsUserInterface()
713    */
714   protected boolean handleIsNeedsUserInterface()
715   {
716       if(isAbstract())
717       {
718           return false;
719       }
720       for (final ManageableEntityAttribute attribute : this.getManageableAttributes())
721       {
722           if(attribute instanceof JSFManageableEntityAttribute)
723           {
724               final JSFManageableEntityAttribute jsfAttribute = (JSFManageableEntityAttribute)attribute;
725               if(!jsfAttribute.isHidden())
726               {
727                   return true;
728               }
729           }
730       }
731       for (final ManageableEntityAssociationEnd associationEnd : this.getManageableAssociationEnds())
732       {
733           if(associationEnd instanceof JSFManageableEntityAssociationEnd)
734           {
735               final JSFManageableEntityAssociationEnd jsfAssociationEnd = (JSFManageableEntityAssociationEnd)associationEnd;
736               if(!jsfAssociationEnd.isDisplay())
737               {
738                   return true;
739               }
740           }
741       }
742       return false;
743   }
744
745   /**
746    * @return converterClassName
747    * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getConverterClassName
748    */
749    public String handleGetConverterClassName()
750    {
751        return StringUtils.replace(
752            ObjectUtils.toString(this.getConfiguredProperty(JSFGlobals.CONVERTER_PATTERN)),
753            "{0}",
754            this.getName());
755    }
756
757    /**
758     * @return converterType
759     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getConverterType
760     */
761     public String handleGetConverterType()
762     {
763         return this.getManageablePackageName() + this.getNamespaceProperty() + this.getConverterClassName();
764     }
765
766    /**
767     * @return converterFullPath
768     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getConverterFullPath
769     */
770     public String handleGetConverterFullPath()
771     {
772         return StringUtils.replace(this.getConverterType(), this.getNamespaceProperty(), "/");
773     }
774
775    //TODO review
776    @Override
777    public ManageableEntityAttribute getDisplayAttribute() {
778        
779        for(final ManageableEntityAttribute attribute: getManageableAttributes())
780        {
781            if(BooleanUtils.toBoolean(ObjectUtils.toString(attribute.findTaggedValue(JSFProfile.ANDROMDA_MANAGEABLE_ATTRIBUTE_DISPLAY))))
782            {
783                return attribute;
784            }
785        }
786        
787        //associations ???
788//        for(final ManageableEntityAssociationEnd associationEnd: getManageableAssociationEnds())
789//        {
790//            if(BooleanUtils.toBoolean(ObjectUtils.toString(associationEnd.findTaggedValue("andromda_manageable_display"))))
791//            {
792//                return associationEnd;
793//            }
794//        }
795        
796        return super.getDisplayAttribute();
797    }
798
799    /**
800     * @return needsImplementation
801     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#isNeedsImplementation
802     */
803    @Override
804    protected boolean handleIsNeedsImplementation() {
805        final Object generateCrudImpls=this.getConfiguredProperty(JSFGlobals.GENERATE_CRUD_IMPLS);
806        if(generateCrudImpls != null && Boolean.parseBoolean(generateCrudImpls.toString()))
807        {
808            return true;
809        }
810        else
811        {
812            final Object taggedValue = this.findTaggedValue(JSFProfile.ANDROMDA_MANAGEABLE_IMPLEMENTATION);
813            return (taggedValue == null)
814                ? JSFProfile.TAGGEDVALUE_MANAGEABLE_IMPLEMENTATION_DEFAULT_VALUE
815                : Boolean.valueOf(String.valueOf(taggedValue)).booleanValue();
816        }
817    }
818
819    @Override
820    protected String handleGetSearchFilterFullPath() {
821        return '/' + StringUtils.replace(this.getManageablePackageName(), this.getNamespaceProperty(), "/") + '/' + getSearchFilterName();
822    }
823
824    @Override
825    protected String handleGetSearchFilterName() {
826        return this.getName() + "SearchFilter";
827    }
828
829    @Override
830    protected String handleGetSearchFilterSerialVersionUID() {
831        String serialVersionUID = String.valueOf(0L);
832        try
833        {
834            MessageDigest md = MessageDigest.getInstance("SHA");
835            byte[] hashBytes = md.digest(getSearchFilterFullPath().getBytes());
836
837            long hash = 0;
838            for (int ctr = Math.min(
839                        hashBytes.length,
840                        8) - 1; ctr >= 0; ctr--)
841            {
842                hash = (hash << 8) | (hashBytes[ctr] & 0xFF);
843            }
844            serialVersionUID = String.valueOf(hash);
845        }
846        catch (final NoSuchAlgorithmException exception)
847        {
848            final String message = "Error performing ManageableEntity.getSearchFilterSerialVersionUID";
849            LOGGER.error(
850                message,
851                exception);
852        }
853        return serialVersionUID;
854    }
855
856    /**
857     * @return manageableEditAttributes
858     * @see org.andromda.cartridges.jsf2.metafacades.JSFManageableEntity#getManageableEditAttributes()
859     */
860    @Override
861    protected Collection<JSFManageableEntityAttribute> handleGetManageableEditAttributes() {
862        final Collection<JSFManageableEntityAttribute> editAttributes=new ArrayList<JSFManageableEntityAttribute>();
863        
864        for(final ManageableEntityAttribute attr: getManageableAttributes())
865        {
866            final JSFManageableEntityAttribute jsfAttr=(JSFManageableEntityAttribute)attr;
867            if(jsfAttr.isEditable())
868            {
869                editAttributes.add(jsfAttr);
870            }
871        }
872        return editAttributes;
873    }
874}