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 java.util.ArrayList;
019import java.util.Iterator;
020import java.util.List;
021
022import org.apache.commons.lang.StringUtils;
023import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
024
025/**
026 * The defaultSort element specifies the sequence in which the lookup search results should be displayed
027 *
028 * <p>It contains an ascending/descending indicator and a list of attribute names.
029 * JSTL: defaultSort is a Map with the following keys:
030 * sortAscending (boolean String) and sortAttributes (Map).
031 * By the time JSTL export occurs, the optional attributeName from the defaultSort
032 * tag will have been converted into the first contained sortAttribute.
033 * </p>
034 *
035 * @author Kuali Rice Team (rice.collab@kuali.org)
036 */
037public class SortDefinition extends DataDictionaryDefinitionBase {
038    private static final long serialVersionUID = -1092811342186612461L;
039
040    protected boolean sortAscending = true;
041    protected List<String> attributeNames = new ArrayList<String>();
042
043    public SortDefinition() {
044
045    }
046
047    /**
048     * The sortAttribute element defines one part of the sort key.
049     * The full sort key is comprised of the sortAttribute's in the
050     * order in which they have been defined.
051     *
052     * DD: See SortAttributesDefinition.java.
053     *
054     * JSTL: sortAttribute is a Map which is accessed using a
055     * key of the attributeName of the sortAttribute.
056     * It contains a single entry with the following key:
057     * "attributeName"
058     *
059     * The associated value is the attributeName of the sortAttribute.
060     * See LookupMapBuilder.java
061     *
062     * @throws IllegalArgumentException if the given attributeName is blank
063     */
064    public void setAttributeName(String attributeName) {
065        if (StringUtils.isBlank(attributeName)) {
066            throw new IllegalArgumentException("invalid (blank) attributeName");
067        }
068        if (!attributeNames.isEmpty()) {
069            throw new IllegalStateException(
070                    "unable to set sort attributeName when sortAttributes have already been added");
071        }
072
073        attributeNames.add(attributeName);
074    }
075
076    /**
077     * @return the List of associated attribute names as Strings
078     */
079    public List<String> getAttributeNames() {
080        return this.attributeNames;
081    }
082
083    /**
084     * Indicates that the items must be sorted in ascending order
085     *
086     * @return true if items should sort in ascending order
087     */
088    public boolean getSortAscending() {
089        return sortAscending;
090    }
091
092    /**
093     * Setter for the flag to indicate ascending sorting of items
094     *
095     * @param sortAscending
096     */
097    public void setSortAscending(boolean sortAscending) {
098        this.sortAscending = sortAscending;
099    }
100
101    @Override
102    public void completeValidation(Class rootBusinessObjectClass, Class otherBusinessObjectClass, ValidationTrace tracer) {
103
104        if ( attributeNames == null || attributeNames.isEmpty() ) {
105            String currentValues[] = {"attributeNames = " + attributeNames, "rootBusinessObjectClass = " + rootBusinessObjectClass};
106            tracer.createError("SortDefinition may not have an empty attribute list", currentValues);
107        }
108
109        for (String attributeName : attributeNames) {
110            if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, attributeName)) {
111                String currentValues[] = {"attributeName = " + attributeName, "rootBusinessObjectClass = " + rootBusinessObjectClass};
112                tracer.createError("attribute in SortDefinition not found on business object", currentValues);
113            }
114        }
115    }
116
117    @Override
118    public String toString() {
119        StringBuilder attrList = new StringBuilder("[");
120        for (Iterator<String> i = attributeNames.iterator(); i.hasNext(); ) {
121            attrList.append(i.next());
122            if (i.hasNext()) {
123                attrList.append(",");
124            }
125        }
126        attrList.append("]");
127
128        return "SortDefinition :  " + attrList;
129    }
130
131    /**
132     * The sortAttributes element allows a multiple-part sort key to be defined
133     *
134     * JSTL: sortAttributes is a Map which is accessed using a key of "sortAttributes". This map contains an entry for
135     * sort attribute.  The key is: attributeName of a sort field. The associated value is a sortAttribute ExportMap.
136     */
137    public void setAttributeNames(List<String> attributeNames) {
138        this.attributeNames = attributeNames;
139    }
140
141}