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}