001    /**
002     * Copyright 2005-2013 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     */
016    package org.kuali.rice.kns.web.comparator;
017    
018    import org.apache.commons.collections.comparators.ComparableComparator;
019    import org.apache.commons.lang.StringUtils;
020    import org.displaytag.model.Cell;
021    import org.kuali.rice.core.api.util.type.TypeUtils;
022    import org.kuali.rice.krad.comparator.NumericValueComparator;
023    import org.kuali.rice.krad.comparator.StringValueComparator;
024    import org.kuali.rice.krad.comparator.TemporalValueComparator;
025    
026    import java.util.Comparator;
027    import java.util.regex.Matcher;
028    import java.util.regex.Pattern;
029    
030    /**
031     * This class...
032     */
033    public class CellComparatorHelper {
034    
035        static private Pattern HREF_ENCLOSURE = Pattern.compile("<a [^>]+>([^<]*)</a>.*", Pattern.MULTILINE);
036    
037        /**
038         * This method is intended to be used in conjunction with displaytag.
039         * 
040         * @see #getSanitizedStaticValue(String)
041         * 
042         * @param cell
043         * @return a sanitized version of cell.getStaticValue().toString().
044         */
045        static public String getSanitizedStaticValue(Cell cell) {
046            if (null == cell) {
047                return null;
048            }
049    
050            return null == cell.getStaticValue() ? null : getSanitizedStaticValue(cell.getStaticValue().toString());
051        }
052    
053        /**
054         * Remove all end-of-line and tab characters (\r, \n, \t). If the value is enclosed in an html anchor tag, strip the html anchor
055         * tag. If the value ends in one or many "&nbsp;"s, strip them off. Return the modified String.
056         * 
057         * @param staticValue
058         * @return a sanitized version of staticValue
059         */
060        static public String getSanitizedStaticValue(String staticValue) {
061    
062            if (null == staticValue) {
063                return null;
064            }
065    
066            staticValue = StringUtils.replace(staticValue, "\r", "");
067            staticValue = StringUtils.replace(staticValue, "\n", "");
068            staticValue = StringUtils.replace(staticValue, "\t", "");
069    
070            String sanitizedValue = staticValue;
071    
072            // Extract the value if it's wrapped in an href.
073            Matcher matcher = HREF_ENCLOSURE.matcher(staticValue);
074            if (matcher.matches()) {
075    
076                sanitizedValue = matcher.group(1).trim();
077    
078            }
079    
080            // Strip off any "&nbsp;"s if they come at the end of the value.
081            while (sanitizedValue.endsWith("&nbsp;")) {
082    
083                sanitizedValue = sanitizedValue.substring(0, sanitizedValue.length() - 6).trim();
084    
085            }
086    
087            return sanitizedValue;
088    
089        }
090    
091        /**
092         * This method returns a comparator to be used for comparing the contents of cells, that is
093         * the compareTo method will be invoked w/ displaytag Cell objects
094         * @param propClass
095         * @return
096         */
097        public static Comparator getAppropriateComparatorForPropertyClass(Class propClass) {
098            // TODO, do we really need to create so many comparators (1 per each cell)?
099            if (propClass == null) {
100                return new NullCellComparator();
101            }
102            else if (TypeUtils.isDecimalClass(propClass) || TypeUtils.isIntegralClass(propClass)) {
103                return new NumericCellComparator();
104            }
105            else if (TypeUtils.isTemporalClass(propClass)) {
106                return new TemporalCellComparator();
107            }
108            else if (String.class.equals(propClass)) {
109                // StringCellComparator is smarter about nulls than String.CASE_INSENSITIVE_ORDER
110                return new StringCellComparator();
111            }
112            else {
113                return ComparableComparator.getInstance();
114            }
115        }
116        
117        /**
118         * This method returns a comparator to be used for comparing propertyValues (in String form)
119         * @param propClass
120         * @return
121         */
122        public static Comparator getAppropriateValueComparatorForPropertyClass(Class propClass) {
123            if (propClass == null) {
124                return NullValueComparator.getInstance();
125            }
126            else if (TypeUtils.isDecimalClass(propClass) || TypeUtils.isIntegralClass(propClass)) {
127                return NumericValueComparator.getInstance();
128            }
129            else if (TypeUtils.isTemporalClass(propClass)) {
130                return TemporalValueComparator.getInstance();
131            }
132            else if (String.class.equals(propClass)) {
133                // StringCellComparator is smarter about nulls than String.CASE_INSENSITIVE_ORDER
134                return StringValueComparator.getInstance();
135            }
136            else {
137                return ComparableComparator.getInstance();
138            }
139        }
140    }