001    /*
002     * JBoss, Home of Professional Open Source.
003     * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004     * as indicated by the @author tags. See the copyright.txt file in the
005     * distribution for a full listing of individual contributors.
006     *
007     * This is free software; you can redistribute it and/or modify it
008     * under the terms of the GNU Lesser General Public License as
009     * published by the Free Software Foundation; either version 2.1 of
010     * the License, or (at your option) any later version.
011     *
012     * This software is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * Lesser General Public License for more details.
016     *
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this software; if not, write to the Free
019     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021     */
022    package org.jboss.dna.graph.properties;
023    
024    import java.math.BigDecimal;
025    import java.net.URI;
026    import java.util.ArrayList;
027    import java.util.Collections;
028    import java.util.Comparator;
029    import java.util.Iterator;
030    import java.util.List;
031    import java.util.UUID;
032    import net.jcip.annotations.Immutable;
033    import org.jboss.dna.graph.GraphI18n;
034    
035    /**
036     * @author Randall Hauch
037     * @author John Verhaeg
038     */
039    @Immutable
040    public enum PropertyType {
041    
042        STRING("String", ValueComparators.STRING_COMPARATOR, String.class),
043        BINARY("Binary", ValueComparators.BINARY_COMPARATOR, Binary.class),
044        LONG("Long", ValueComparators.LONG_COMPARATOR, Long.class),
045        DOUBLE("Double", ValueComparators.DOUBLE_COMPARATOR, Double.class),
046        DECIMAL("Decimal", ValueComparators.DECIMAL_COMPARATOR, BigDecimal.class),
047        DATE("Date", ValueComparators.DATE_TIME_COMPARATOR, DateTime.class),
048        BOOLEAN("Boolean", ValueComparators.BOOLEAN_COMPARATOR, Boolean.class),
049        NAME("Name", ValueComparators.NAME_COMPARATOR, Name.class),
050        PATH("Path", ValueComparators.PATH_COMPARATOR, Path.class),
051        UUID("UUID", ValueComparators.UUID_COMPARATOR, UUID.class),
052        REFERENCE("Reference", ValueComparators.REFERENCE_COMPARATOR, Reference.class),
053        URI("URI", ValueComparators.URI_COMPARATOR, URI.class),
054        OBJECT("Object", ValueComparators.OBJECT_COMPARATOR, Object.class);
055    
056        private static final List<PropertyType> ALL_PROPERTY_TYPES;
057        static {
058            List<PropertyType> types = new ArrayList<PropertyType>();
059            for (PropertyType type : PropertyType.values()) {
060                types.add(type);
061            }
062            ALL_PROPERTY_TYPES = Collections.unmodifiableList(types);
063        }
064    
065        private final String name;
066        private final Comparator<?> comparator;
067        private final Class<?> valueClass;
068    
069        private PropertyType( String name,
070                              Comparator<?> comparator,
071                              Class<?> valueClass ) {
072            this.name = name;
073            this.comparator = comparator;
074            this.valueClass = valueClass;
075        }
076    
077        public Class<?> getValueClass() {
078            return this.valueClass;
079        }
080    
081        public String getName() {
082            return this.name;
083        }
084    
085        public Comparator<?> getComparator() {
086            return this.comparator;
087        }
088    
089        public boolean isTypeFor( Object value ) {
090            return this.valueClass.isInstance(value);
091        }
092    
093        public boolean isTypeForEach( Iterable<?> values ) {
094            for (Object value : values) {
095                if (!this.valueClass.isInstance(value)) return false;
096            }
097            return true;
098        }
099    
100        public boolean isTypeForEach( Iterator<?> values ) {
101            while (values.hasNext()) {
102                Object value = values.next();
103                if (!this.valueClass.isInstance(value)) return false;
104            }
105            return true;
106        }
107    
108        public static PropertyType discoverType( Object value ) {
109            if (value == null) {
110                throw new IllegalArgumentException(GraphI18n.unableToDiscoverPropertyTypeForNullValue.text());
111            }
112            for (PropertyType type : PropertyType.values()) {
113                if (type == OBJECT) continue;
114                if (type.isTypeFor(value)) return type;
115            }
116            return OBJECT;
117        }
118    
119        /**
120         * Return an iterator over all the property type enumeration literals.
121         * 
122         * @return an immutable iterator
123         */
124        public static Iterator<PropertyType> iterator() {
125            return ALL_PROPERTY_TYPES.iterator();
126        }
127    }