    001    // Copyright 2007, 2008, 2010, 2011, 2014 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    //     http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.beaneditor;
    016
    017    import org.apache.tapestry5.PropertyConduit;
    018    import org.apache.tapestry5.beaneditor.BeanModel;
    019    import org.apache.tapestry5.beaneditor.PropertyModel;
    020    import org.apache.tapestry5.beaneditor.Sortable;
    021    import org.apache.tapestry5.internal.TapestryInternalUtils;
    022    import org.apache.tapestry5.ioc.Messages;
    023    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    024    import org.apache.tapestry5.plastic.PlasticUtils;
    025
    026    import java.lang.annotation.Annotation;
    027
    028    @SuppressWarnings("all")
    029    public class PropertyModelImpl implements PropertyModel
    030    {
    031        private final BeanModel model;
    032
    033        private final String name;
    034
    035        private final PropertyConduit conduit;
    036
    037        private final String id;
    038
    039        private String label;
    040
    041        private String dataType;
    042
    043        private boolean sortable;
    044
    045        public PropertyModelImpl(BeanModel model, String name, PropertyConduit conduit, Messages messages)
    046        {
    047            this.model = model;
    048            this.name = name;
    049            this.conduit = conduit;
    050
    051            id = TapestryInternalUtils.extractIdFromPropertyExpression(name);
    052
    053            label = TapestryInternalUtils.defaultLabel(id, messages, name);
    054
    055            // TAP5-2305
    056            Sortable sortableAnnotation = conduit != null ? conduit.getAnnotation(Sortable.class) : null;
    057            if (sortableAnnotation != null)
    058            {
    059                sortable = sortableAnnotation.value();
    060            }
    061            else
    062            {
    063                // Primitive types need to be converted to wrapper types before checking to see
    064                // if they are sortable.
    065                Class wrapperType = PlasticUtils.toWrapperType(getPropertyType());
    066                sortable = Comparable.class.isAssignableFrom(wrapperType);
    067            }
    068        }
    069
    070        public String getId()
    071        {
    072            return id;
    073        }
    074
    075        public Class getPropertyType()
    076        {
    077            return conduit == null ? Object.class : conduit.getPropertyType();
    078        }
    079
    080        public PropertyConduit getConduit()
    081        {
    082            return conduit;
    083        }
    084
    085        public PropertyModel label(String label)
    086        {
    087            assert InternalUtils.isNonBlank(label);
    088            this.label = label;
    089
    090            return this;
    091        }
    092
    093        public String getLabel()
    094        {
    095            return label;
    096        }
    097
    098        public String getPropertyName()
    099        {
    100            return name;
    101        }
    102
    103        public BeanModel model()
    104        {
    105            return model;
    106        }
    107
    108        public PropertyModel dataType(String dataType)
    109        {
    110            this.dataType = dataType;
    111
    112            return this;
    113        }
    114
    115        public String getDataType()
    116        {
    117            return dataType;
    118        }
    119
    120        public boolean isSortable()
    121        {
    122            return sortable;
    123        }
    124
    125        public PropertyModel sortable(boolean sortable)
    126        {
    127            this.sortable = sortable;
    128
    129            return this;
    130        }
    131
    132        public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
    133        {
    134            return conduit == null ? null : conduit.getAnnotation(annotationClass);
    135        }
    136    }