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.basic;
023    
024    import java.util.ArrayList;
025    import java.util.Collection;
026    import java.util.Iterator;
027    import java.util.List;
028    import org.jboss.dna.common.util.CheckArg;
029    import org.jboss.dna.graph.properties.Name;
030    import org.jboss.dna.graph.properties.Property;
031    import org.jboss.dna.graph.properties.PropertyFactory;
032    import org.jboss.dna.graph.properties.PropertyType;
033    import org.jboss.dna.graph.properties.ValueFactories;
034    import org.jboss.dna.graph.properties.ValueFactory;
035    
036    /**
037     * @author Randall Hauch
038     */
039    public class BasicPropertyFactory implements PropertyFactory {
040    
041        private final ValueFactories factories;
042    
043        /**
044         * @param valueFactories the value factories
045         * @throws IllegalArgumentException if the reference to the value factories is null
046         */
047        public BasicPropertyFactory( ValueFactories valueFactories ) {
048            CheckArg.isNotNull(valueFactories, "value factories");
049            this.factories = valueFactories;
050        }
051    
052        /**
053         * {@inheritDoc}
054         */
055        public Property create( Name name,
056                                Iterable<?> values ) {
057            return create(name, PropertyType.OBJECT, values);
058        }
059    
060        /**
061         * {@inheritDoc}
062         */
063        public Property create( Name name,
064                                Iterator<?> values ) {
065            return create(name, PropertyType.OBJECT, values);
066        }
067    
068        /**
069         * {@inheritDoc}
070         */
071        public Property create( Name name,
072                                Object... values ) {
073            return create(name, PropertyType.OBJECT, values);
074        }
075    
076        /**
077         * {@inheritDoc}
078         */
079        public Property create( Name name,
080                                PropertyType desiredType,
081                                Object... values ) {
082            CheckArg.isNotNull(name, "name");
083            if (values == null || values.length == 0) {
084                return new BasicEmptyProperty(name);
085            }
086            final int len = values.length;
087            if (desiredType == null) desiredType = PropertyType.OBJECT;
088            final ValueFactory<?> factory = factories.getValueFactory(desiredType);
089            if (values.length == 1) {
090                Object value = values[0];
091                // Check whether the sole value was a collection ...
092                if (value instanceof Collection) {
093                    // The single value is a collection, so create property with the collection's contents ...
094                    return create(name, (Collection<?>)value);
095                }
096                value = factory.create(values[0]);
097                return new BasicSingleValueProperty(name, value);
098            }
099            List<Object> valueList = new ArrayList<Object>(len);
100            for (int i = 0; i != len; ++i) {
101                Object value = factory.create(values[i]);
102                valueList.add(value);
103            }
104            return new BasicMultiValueProperty(name, valueList);
105        }
106    
107        /**
108         * {@inheritDoc}
109         */
110        @SuppressWarnings( "unchecked" )
111        public Property create( Name name,
112                                PropertyType desiredType,
113                                Iterable<?> values ) {
114            CheckArg.isNotNull(name, "name");
115            List<Object> valueList = null;
116            if (values instanceof Collection) {
117                Collection<Object> originalValues = (Collection<Object>)values;
118                if (originalValues.isEmpty()) {
119                    return new BasicEmptyProperty(name);
120                }
121                valueList = new ArrayList<Object>(originalValues.size());
122            } else {
123                // We don't know the size
124                valueList = new ArrayList<Object>();
125            }
126            // Copy the values, ensuring that the values are the correct type ...
127            if (desiredType == null) desiredType = PropertyType.OBJECT;
128            final ValueFactory<?> factory = factories.getValueFactory(desiredType);
129            for (Object value : values) {
130                valueList.add(factory.create(value));
131            }
132            if (valueList.isEmpty()) { // may not have been a collection earlier
133                return new BasicEmptyProperty(name);
134            }
135            if (valueList.size() == 1) {
136                return new BasicSingleValueProperty(name, valueList.get(0));
137            }
138            return new BasicMultiValueProperty(name, valueList);
139        }
140    
141        /**
142         * {@inheritDoc}
143         */
144        public Property create( Name name,
145                                PropertyType desiredType,
146                                Iterator<?> values ) {
147            CheckArg.isNotNull(name, "name");
148            final List<Object> valueList = new ArrayList<Object>();
149            if (desiredType == null) desiredType = PropertyType.OBJECT;
150            final ValueFactory<?> factory = factories.getValueFactory(desiredType);
151            while (values.hasNext()) {
152                Object value = values.next();
153                value = factory.create(value);
154                valueList.add(value);
155            }
156            if (valueList.isEmpty()) {
157                return new BasicEmptyProperty(name);
158            }
159            if (valueList.size() == 1) {
160                return new BasicSingleValueProperty(name, valueList.get(0));
161            }
162            return new BasicMultiValueProperty(name, valueList);
163        }
164    
165    }