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