    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
    015package org.apache.tapestry5.beanmodel.internal.beanmodel;
    016
    017import java.lang.annotation.Annotation;
    018
    019import org.apache.tapestry5.beaneditor.Sortable;
    020import org.apache.tapestry5.beanmodel.BeanModel;
    021import org.apache.tapestry5.beanmodel.PropertyConduit;
    022import org.apache.tapestry5.beanmodel.PropertyModel;
    023import org.apache.tapestry5.commons.Messages;
    024import org.apache.tapestry5.commons.internal.util.InternalCommonsUtils;
    025import org.apache.tapestry5.plastic.PlasticUtils;
    026
    027@SuppressWarnings("all")
    028public class PropertyModelImpl implements PropertyModel
    029{
    030    private final BeanModel model;
    031
    032    private final String name;
    033
    034    private final PropertyConduit conduit;
    035
    036    private final String id;
    037
    038    private String label;
    039
    040    private String dataType;
    041
    042    private boolean sortable;
    043
    044    public PropertyModelImpl(BeanModel model, String name, PropertyConduit conduit, Messages messages)
    045    {
    046        this.model = model;
    047        this.name = name;
    048        this.conduit = conduit;
    049
    050        id = InternalCommonsUtils.extractIdFromPropertyExpression(name);
    051
    052        label = InternalCommonsUtils.defaultLabel(id, messages, name);
    053
    054        // TAP5-2305
    055        if (conduit != null)
    056        {
    057            Sortable sortableAnnotation = conduit.getAnnotation(Sortable.class);
    058            if (sortableAnnotation != null)
    059            {
    060                sortable = sortableAnnotation.value();
    061            }
    062            else
    063            {
    064                // Primitive types need to be converted to wrapper types before checking to see
    065                // if they are sortable.
    066                Class wrapperType = PlasticUtils.toWrapperType(getPropertyType());
    067                sortable = Comparable.class.isAssignableFrom(wrapperType);
    068            }
    069        }
    070    }
    071
    072    public String getId()
    073    {
    074        return id;
    075    }
    076
    077    public Class getPropertyType()
    078    {
    079        return conduit == null ? Object.class : conduit.getPropertyType();
    080    }
    081
    082    public PropertyConduit getConduit()
    083    {
    084        return conduit;
    085    }
    086
    087    public PropertyModel label(String label)
    088    {
    089        assert InternalCommonsUtils.isNonBlank(label);
    090        this.label = label;
    091
    092        return this;
    093    }
    094
    095    public String getLabel()
    096    {
    097        return label;
    098    }
    099
    100    public String getPropertyName()
    101    {
    102        return name;
    103    }
    104
    105    public BeanModel model()
    106    {
    107        return model;
    108    }
    109
    110    public PropertyModel dataType(String dataType)
    111    {
    112        this.dataType = dataType;
    113
    114        return this;
    115    }
    116
    117    public String getDataType()
    118    {
    119        return dataType;
    120    }
    121
    122    public boolean isSortable()
    123    {
    124        return sortable;
    125    }
    126
    127    public PropertyModel sortable(boolean sortable)
    128    {
    129        this.sortable = sortable;
    130
    131        return this;
    132    }
    133
    134    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
    135    {
    136        return conduit == null ? null : conduit.getAnnotation(annotationClass);
    137    }
    138}