Package org.openquark.util.attributes

Source Code of org.openquark.util.attributes.Attribute$AttributeComparator

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Business Objects nor the names of its contributors
*       may be used to endorse or promote products derived from this software
*       without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/


/*
* Attribute.java
* Created: 5-Feb-2003
* By: Rick Cameron
*/
package org.openquark.util.attributes;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.openquark.util.CaseInsensitiveMap;
import org.openquark.util.time.Time;
import org.openquark.util.xml.XMLSerializationManager;
import org.w3c.dom.Element;


/**
* An Attribute is an association of a String (the name) and an Object (the
* value, or list of values).
* This class is immutable.
*/
public final class Attribute {

    private static final AttributeComparator attributeComparator = new AttributeComparator();
   
    /** Attribute type constants */
    public enum Type {
        UNKNOWN,
        COLOR,
        BOOLEAN,
        INTEGER,
        DOUBLE,
        STRING,
        ATTRIBUTE_SET,
        TIME
    }
   
    /** The name of the attribute. */
    private final String name;

    /** The attribute value (or list of values). */
    private final Object value;

    /** A method to correctly compare 2 attribute names. */
    public static boolean equalNames (String s1, String s2) {
        return CaseInsensitiveMap.equalsCaseInsensitive(s1, s2);
    }

    /**
     * Attribute constructor.
     * @param name    the attribute name
     * @param colour  the attribute value
     */
    public Attribute(String name, Color colour) {
        this(name, (Object) colour);
    }

    /**
     * Attribute constructor.
     * @param name     the attribute name
     * @param boolVal  the attribute value
     */
    public Attribute(String name, boolean boolVal) {
        this(name, Boolean.valueOf(boolVal));
    }

    /**
     * Attribute constructor.
     * @param name    the attribute name
     * @param intVal  the attribute value
     */
    public Attribute(String name, int intVal) {
        this(name, Integer.valueOf(intVal));
    }

    /**
     * Attribute constructor.
     * @param name       the attribute name
     * @param doubleVal  the attribute value
     */
    public Attribute(String name, double doubleVal) {
        this(name, Double.valueOf(doubleVal));
    }

    /**
     * Attribute constructor.
     * @param name       the attribute name
     * @param stringVal  the attribute value
     */
    public Attribute(String name, String stringVal) {
        this(name, (Object) stringVal);
    }

    /**
     * Attribute constructor.
     * @param name     the attribute name
     * @param timeVal  the attribute value
     */
    public Attribute(String name, Time timeVal) {
        this(name, (Object) timeVal);
    }

    /**
     * Attribute constructor.
     * @param name     the attribute name
     * @param attrSet  the attribute value
     */
    public Attribute(String name, AttributeSet attrSet) {
        this(name, (Object) attrSet);
    }

    /**
     * Attribute constructor.
     * @param name    the attribute name
     * @param values  the attribute values
     */
    public Attribute(String name, Collection<?> values) {
        this(name, (Object) values);
    }

    /**
     * Attribute constructor.
     * @param name   the attribute name
     * @param value  the attribute value
     */
    public Attribute (String name, Object value) {
        this.name = name;

        if (value instanceof Collection) {
            // Check that all items in the collection are the same type.
            // and of a type supported by this class.
            Collection<?> collection = (Collection<?>) value;
            if (collection.isEmpty()) {
                this.value = Collections.EMPTY_LIST;
            } else {
                List<Object> valueList = new ArrayList<Object>();
                Class<?> firstValueType = null;

                // Leave out any null values or values of types not supported by this class.
                // Also, only add values which are of the same type as the first value added.
                for (Object val : collection) {
                    if (val != null) {
                        if (firstValueType == null && isSupportedAttributeType(val.getClass())) {
                            firstValueType = val.getClass();
                            valueList.add(val);
                        }
                        else if (val.getClass().equals(firstValueType)){
                            valueList.add(val);
                        }
                    }
                }
               
                this.value = valueList;
            }
        }
        else {
            this.value = value;
        }
    }

    /**
     * Returns whether the specified value type can be stored as an attribute value.
     * <p>
     * Subclasses can override this method to change the supported attribute type set.
     * @param valueClass  the class of a value
     * @return boolean <code>true</code> if the value type can be stored as an attribute value
     */
    protected boolean isSupportedAttributeType(Class<?> valueClass) {
        // The supported attribute type is primarily determined by the serializer
        XMLSerializationManager serializer = XMLSerializationManager.getDefaultInstance();
        return serializer.getSupportedValueClasses().contains(valueClass);
    }

    /**
     * @see java.lang.Object#toString()
     * @return a string to assist in debugging
     */
    public String toString () {
        return getName () + "=" + valueToString(value); //$NON-NLS-1$
    }

    /**
     * A helper function for converting values to strings.
     * The string is intended for debugging purposes only.
     * @param value  an attribute value (or list of values)
     * @return a human readable string representing the value
     */
    private static String valueToString (Object value) {
        if (value == null) {
            return "<null>"; //$NON-NLS-1$
        }
        else if (value instanceof Color) {
            Color colour = (Color) value;
            int red = colour.getRed();
            int green = colour.getGreen();
            int blue = colour.getBlue();
            return "R:" + red + " G:" + green + " B:" + blue; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }
        else if (value instanceof List) {
            List<?> list = (List<?>) value;
            StringBuilder sb = new StringBuilder("["); //$NON-NLS-1$

            for (int valueN = 0, nValues = list.size(); valueN < nValues; ++valueN) {
                sb.append (valueToString (list.get (valueN)));
                if (valueN < nValues - 1)
                    sb.append(", "); //$NON-NLS-1$
            }

            sb.append(']');
            return sb.toString();
        }
        else if (value instanceof Boolean) {
            return (((Boolean) value).booleanValue()) ? "True" : "False"; //$NON-NLS-1$ //$NON-NLS-2$
        }
        else {
            return value.toString();
        }
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object obj) {
        if (obj == null || getClass() != obj.getClass())
            return false;

        Attribute other = (Attribute) obj;

        if ((value == null) != (other.value == null))
            return false;

        if (value != null && !value.equals(other.value))
            return false;

        if (!equalNames(getName(), other.getName()))
            return false;

        return true;
    }

    /** Cache the hash code for the attribute, as it is relatively expensive to calculate. */
    private int hash = 0;
   
    /**
     * @see java.lang.Object#hashCode()
     */
    public int hashCode() {
        // Note: ensure any modifications are thread safe.  See java.lang.String for an example.
       
        int h = hash;
        if (h == 0) {
            h = 37 + CaseInsensitiveMap.caseInsensitiveHashCode(getName());

            if (value != null) {
                h = h * 17 + value.hashCode();
            }

            hash = h;
        }
       
        return h;
    }

    /**
     * Returns the attribute name.
     * @return the attribute name
     */
    public String getName () {
        return name;
    }

    /**
     * Returns a single value for the attribute.
     * If there are multiple values, then the last one in the list (if any) will be returned.
     * @return a single value of the attribute
     */
    public Object getSingleValue () {
        if (value instanceof List) {
            List<?> l  = (List<?>) value;
            if (l.isEmpty ())
                return null;

            return l.get (l.size () - 1);
        } else {
            return value;
        }
    }

    /**
     * Returns the list of values for the attribute.
     * If there is only one value, then it will be put into a list.
     * @return the list of the attribute values
     */
    public List<?> getValues () {
        if (value instanceof List) {
            return Collections.unmodifiableList((List<?>)value);
        }
        else if (value instanceof Collection) {
            return new ArrayList<Object> ((Collection<?>)value);
        }
        else {
            return Collections.singletonList (value);
        }
    }

    /**
     * Load the attribute from the specified XML element.
     * @param attrElement  the root element for the attribute XML data
     * @return the new attribute created by loading it from the XML element
     */
    public static Attribute Load (Element attrElement) {
        XMLSerializationManager serializer = XMLSerializationManager.getDefaultInstance();
        return (Attribute) serializer.loadFromElement(attrElement,
                XMLSerializationManager.getAttributeSerializer());
    }

    /**
     * Store the attribute in the specified XML element.
     * @param parentElem  the parent XML element under which the attribute data will be stored
     */
    public void store (Element parentElem) {
        XMLSerializationManager serializer = XMLSerializationManager.getDefaultInstance();
        serializer.storeToElement(parentElem, this,
                XMLSerializationManager.getAttributeSerializer());
    }

    /**
     * Returns the {@link Attribute.Type} enum
     */
    public Type getAttributeType() {
        Object val = getSingleValue();

        if (val instanceof Color)
            return Type.COLOR;
        else if (val instanceof Boolean)
            return Type.BOOLEAN;
        else if (val instanceof Integer)
            return Type.INTEGER;
        else if (val instanceof Double)
            return Type.DOUBLE;
        else if (val instanceof String)
            return Type.STRING;
        else if (val instanceof AttributeSet)
            return Type.ATTRIBUTE_SET;
        else if (val instanceof Time)
            return Type.TIME;

        return Type.UNKNOWN;
    }
   
    /**
     * This is a helper for CAL - as CAL still needs to deal with ordinals
     * @return
     *  0 - Unknown
     *  1 - Colour
     *  2 - Boolean
     *  3 - Integer
     *  4 - Double
     *  5 - String
     *  6 - AttributeSet
     *  7 - Time
     * @deprecated
     */
    public int getAttributeTypeOrdinal() {
        return getAttributeType().ordinal();
    }
   
    /**
     * Creates a new attribute with the specified name and value list.
     * @param name    the attribute name
     * @param values  the value list for the attribute
     * @return a new attribute
     */
    public static Attribute makeAttribute(String name, List<?> values) {
        return new Attribute(name, values);
    }

    /**
     * Returns a <code>Comparator</code> that compares two attributes by their names.
     * @return Comparator
     */
    public static Comparator<Attribute> getNameComparator() {
        return attributeComparator;
    }
      
    /**
     * A <code>Comparator</code> that compares two attributes by their names.
     */
    private static final class AttributeComparator implements Comparator<Attribute> {
        public int compare(Attribute attr1, Attribute attr2) {
            return attr1.getName().compareToIgnoreCase(attr2.getName());
        }
    }
}
TOP

Related Classes of org.openquark.util.attributes.Attribute$AttributeComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.