001/**
002 * Copyright 2005-2018 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.datadictionary;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.data.DataType;
020import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
021import org.kuali.rice.krad.data.metadata.DataObjectAttribute;
022import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
023import org.kuali.rice.krad.datadictionary.validation.capability.ExistenceConstrainable;
024import org.kuali.rice.krad.datadictionary.validation.capability.SimpleConstrainable;
025import org.kuali.rice.krad.datadictionary.validation.constraint.SimpleConstraint;
026import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
027
028/**
029 * Common class for attribute definitions in the DataDictionary, which contains
030 * information relating to the display, validation, and general maintenance of a
031 * specific attribute of an entry. An attribute can be a simple or complex attribute
032 *
033 * @author Kuali Rice Team (rice.collab@kuali.org)
034 */
035public abstract class AttributeDefinitionBase extends DataDictionaryDefinitionBase implements ExistenceConstrainable,
036        SimpleConstrainable {
037
038    private static final long serialVersionUID = 1L;
039
040    protected String name;
041
042    protected String label;
043    protected String shortLabel;
044    protected String displayLabelAttribute;
045
046    protected String constraintText;
047    protected String summary;
048    protected String description;
049
050    protected SimpleConstraint simpleConstraint;
051
052    protected DataObjectAttribute dataObjectAttribute;
053
054    public AttributeDefinitionBase() {
055        super();
056        simpleConstraint = new SimpleConstraint();
057    }
058
059    /**
060     * Name of the attribute
061     *
062     * @return the name
063     */
064    @Override
065    @BeanTagAttribute(name="name")
066    public String getName() {
067        return name;
068    }
069
070    /**
071     * Name of the attribute
072     *
073     * @param name
074     */
075    public void setName(String name) {
076        if (StringUtils.isBlank(name)) {
077            throw new IllegalArgumentException("invalid (blank) name");
078        }
079        this.name = name;
080    }
081
082    /**
083     * The label element is the field or collection name that will be shown on
084     * inquiry and maintenance screens. This will be overridden by presence of
085     * displayLabelAttribute element.
086     *
087     * @return the label
088     */
089    @BeanTagAttribute(name="label")
090    public String getLabel() {
091        if ( label != null ) {
092            return label;
093        }
094        if ( getDataObjectAttribute() != null ) {
095            return getDataObjectAttribute().getLabel();
096        }
097        if ( GlobalResourceLoader.isInitialized() && KRADServiceLocatorWeb.getUifDefaultingService() != null ) {
098            return KRADServiceLocatorWeb.getUifDefaultingService().deriveHumanFriendlyNameFromPropertyName( getName() );
099        }
100        return getName();
101    }
102
103    /**
104     * The label element is the field or collection name that will be shown on
105     * inquiry and maintenance screens. This will be overridden by presence of
106     * displayLabelAttribute element.
107     */
108    public void setLabel(String label) {
109        if (StringUtils.isBlank(label)) {
110            throw new IllegalArgumentException("invalid (blank) label");
111        }
112        this.label = label;
113    }
114
115    /**
116     * @return the shortLabel, or the label if no shortLabel has been set
117     */
118    @BeanTagAttribute(name="shortLabel")
119    public String getShortLabel() {
120        if ( shortLabel != null ) {
121            return shortLabel;
122        }
123        if ( getDataObjectAttribute() != null ) {
124            // if the short label was not explicitly set on the metadata but the label was on the DD, default to the DD label
125            if ( StringUtils.equals(getDataObjectAttribute().getLabel(), getDataObjectAttribute().getShortLabel())
126                    && label != null ) {
127                return getLabel();
128            }
129            return getDataObjectAttribute().getShortLabel();
130        }
131        return getLabel();
132    }
133
134    /**
135     * @return the shortLabel directly, without substituting in the label
136     */
137    protected String getDirectShortLabel() {
138        if ( shortLabel != null ) {
139            return shortLabel;
140        }
141        if ( getDataObjectAttribute() != null ) {
142            return getDataObjectAttribute().getShortLabel();
143        }
144        return "";
145    }
146
147    /**
148     * The shortLabel element is the field or collection name that will be used
149     * in applications when a shorter name (than the label element) is required.
150     * This will be overridden by presence of displayLabelAttribute element.
151     */
152    public void setShortLabel(String shortLabel) {
153        if (StringUtils.isBlank(shortLabel)) {
154            throw new IllegalArgumentException("invalid (blank) shortLabel");
155        }
156        this.shortLabel = shortLabel;
157    }
158
159    /**
160     * Text that display a restriction on the value a field can hold
161     *
162     * <p>
163     * For example when the value must be a valid format (phone number, email), certain length, min/max value and
164     * so on this text can be used to indicate the constraint to the user. Generally displays with the control so
165     * it is visible when the user tabs to the field
166     * </p>
167     *
168     * @return String text to display for the constraint message
169     */
170    @BeanTagAttribute(name="constraintText")
171    public String getConstraintText() {
172        return constraintText;
173    }
174
175    /**
176     * Setter for the constraint message text
177     *
178     * @param constraintText
179     */
180    public void setConstraintText(String constraintText) {
181        this.constraintText = constraintText;
182    }
183
184    /**
185     * The summary element is used to provide a short description of the
186     * attribute or collection. This is designed to be used for help purposes.
187     *
188     * @return the summary
189     */
190    @BeanTagAttribute(name="summary")
191    public String getSummary() {
192        if ( summary != null ) {
193            return summary;
194        }
195        return "";
196    }
197
198    /**
199     * The summary element is used to provide a short description of the
200     * attribute or collection. This is designed to be used for help purposes.
201     */
202    public void setSummary(String summary) {
203        this.summary = summary;
204    }
205
206    /**
207     * The description element is used to provide a long description of the
208     * attribute or collection. This is designed to be used for help purposes.
209     *
210     * @return the description
211     */
212    @BeanTagAttribute(name="description")
213    public String getDescription() {
214        if ( description != null ) {
215            return description;
216        }
217        if ( getDataObjectAttribute() != null ) {
218            return getDataObjectAttribute().getDescription();
219        }
220        return "";
221    }
222
223    /**
224     * The description element is used to provide a long description of the
225     * attribute or collection. This is designed to be used for help purposes.
226     */
227    public void setDescription(String description) {
228        this.description = description;
229    }
230
231    public String getDisplayLabelAttribute() {
232        if ( displayLabelAttribute != null ) {
233            return displayLabelAttribute;
234        }
235        if ( getDataObjectAttribute() != null ) {
236            return getDataObjectAttribute().getDisplayAttributeName();
237        }
238        return null;
239    }
240
241    /**
242     * The displayLabelAttribute element is used to indicate that the label and
243     * short label should be obtained from another attribute.
244     *
245     * The label element and short label element defined for this attribute will
246     * be overridden. Instead, the label and short label values will be obtained
247     * by referencing the corresponding values from the attribute indicated by
248     * this element.
249     */
250    public void setDisplayLabelAttribute(String displayLabelAttribute) {
251        this.displayLabelAttribute = displayLabelAttribute;
252    }
253
254    /**
255     * Gets the SimpleConstraint which contains settings for required, min, max, minLength, and maxLength.
256     *
257     * @return SimpleConstraint object
258     */
259    @Override
260    public SimpleConstraint getSimpleConstraint() {
261        return simpleConstraint;
262    }
263
264    /**
265     * Sets the SimpleConstraint which contains settings for required, min, max, minLength, and maxLength.
266     *
267     * @param simpleConstraint
268     */
269    public void setSimpleConstraint(SimpleConstraint simpleConstraint) {
270        this.simpleConstraint = simpleConstraint;
271    }
272
273    /**
274     * Sets if this attribute is required
275     *
276     * @param required true when required, false otherwise
277     */
278    public void setRequired(Boolean required) {
279        this.simpleConstraint.setRequired(required);
280    }
281
282    /**
283     * The required element allows values of "true" or "false". A value of
284     * "true" indicates that a value must be entered for this business object
285     * when creating or editing a new business object.
286     */
287    @Override
288    @BeanTagAttribute(name="required")
289    public Boolean isRequired() {
290        if ( simpleConstraint.isRequired() != null ) {
291            return simpleConstraint.isRequired();
292        }
293        if ( getDataObjectAttribute() != null ) {
294            return getDataObjectAttribute().isRequired();
295        }
296        return Boolean.FALSE;
297    }
298
299
300    public DataObjectAttribute getDataObjectAttribute() {
301        return dataObjectAttribute;
302    }
303
304    public void setDataObjectAttribute(DataObjectAttribute dataObjectAttribute) {
305        this.dataObjectAttribute = dataObjectAttribute;
306    }
307}