View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.graph.property.basic;
25  
26  import java.util.ArrayList;
27  import java.util.Collection;
28  import java.util.Iterator;
29  import java.util.List;
30  import net.jcip.annotations.Immutable;
31  import org.modeshape.common.util.CheckArg;
32  import org.modeshape.graph.property.Name;
33  import org.modeshape.graph.property.Path;
34  import org.modeshape.graph.property.Property;
35  import org.modeshape.graph.property.PropertyFactory;
36  import org.modeshape.graph.property.PropertyType;
37  import org.modeshape.graph.property.ValueFactories;
38  import org.modeshape.graph.property.ValueFactory;
39  
40  /**
41   * A basic {@link PropertyFactory} implementation.
42   */
43  @Immutable
44  public class BasicPropertyFactory implements PropertyFactory {
45  
46      private final ValueFactories factories;
47  
48      /**
49       * @param valueFactories the value factories
50       * @throws IllegalArgumentException if the reference to the value factories is null
51       */
52      public BasicPropertyFactory( ValueFactories valueFactories ) {
53          CheckArg.isNotNull(valueFactories, "value factories");
54          this.factories = valueFactories;
55      }
56  
57      /**
58       * {@inheritDoc}
59       * 
60       * @see org.modeshape.graph.property.PropertyFactory#create(org.modeshape.graph.property.Name,
61       *      org.modeshape.graph.property.Path)
62       */
63      public Property create( Name name,
64                              Path value ) {
65          return new BasicSingleValueProperty(name, value);
66      }
67  
68      /**
69       * {@inheritDoc}
70       */
71      public Property create( Name name,
72                              Iterable<?> values ) {
73          return create(name, PropertyType.OBJECT, values);
74      }
75  
76      /**
77       * {@inheritDoc}
78       */
79      public Property create( Name name,
80                              Iterator<?> values ) {
81          return create(name, PropertyType.OBJECT, values);
82      }
83  
84      /**
85       * {@inheritDoc}
86       */
87      public Property create( Name name,
88                              Object... values ) {
89          return create(name, PropertyType.OBJECT, values);
90      }
91  
92      /**
93       * {@inheritDoc}
94       */
95      public Property create( Name name,
96                              PropertyType desiredType,
97                              Object... values ) {
98          CheckArg.isNotNull(name, "name");
99          if (values == null || values.length == 0) {
100             return new BasicEmptyProperty(name);
101         }
102         final int len = values.length;
103         if (desiredType == null) desiredType = PropertyType.OBJECT;
104         final ValueFactory<?> factory = factories.getValueFactory(desiredType);
105         if (values.length == 1) {
106             Object value = values[0];
107             // Check whether the sole value was a collection ...
108             if (value instanceof Path) {
109                 value = factory.create(value);
110                 return new BasicSingleValueProperty(name, value);
111             }
112             if (value instanceof Collection<?>) {
113                 // The single value is a collection, so create property with the collection's contents ...
114                 return create(name, desiredType, (Iterable<?>)value);
115             }
116             if (value instanceof Iterator<?>) {
117                 // The single value is an iterator over a collection, so create property with the iterator's contents ...
118                 return create(name, desiredType, (Iterator<?>)value);
119             }
120             if (value instanceof Object[]) {
121                 // The single value is an object array, so create the property with the array as the value(s)...
122                 return create(name, desiredType, (Object[])value);
123             }
124             value = factory.create(value);
125             return new BasicSingleValueProperty(name, value);
126         }
127         List<Object> valueList = new ArrayList<Object>(len);
128         for (int i = 0; i != len; ++i) {
129             Object value = factory.create(values[i]);
130             valueList.add(value);
131         }
132         return new BasicMultiValueProperty(name, valueList);
133     }
134 
135     /**
136      * {@inheritDoc}
137      */
138     @SuppressWarnings( "unchecked" )
139     public Property create( Name name,
140                             PropertyType desiredType,
141                             Iterable<?> values ) {
142         CheckArg.isNotNull(name, "name");
143         List<Object> valueList = null;
144         if (values instanceof Collection) {
145             Collection<Object> originalValues = (Collection<Object>)values;
146             if (originalValues.isEmpty()) {
147                 return new BasicEmptyProperty(name);
148             }
149             valueList = new ArrayList<Object>(originalValues.size());
150         } else {
151             // We don't know the size
152             valueList = new ArrayList<Object>();
153         }
154         // Copy the values, ensuring that the values are the correct type ...
155         if (desiredType == null) desiredType = PropertyType.OBJECT;
156         final ValueFactory<?> factory = factories.getValueFactory(desiredType);
157         for (Object value : values) {
158             valueList.add(factory.create(value));
159         }
160         if (valueList.isEmpty()) { // may not have been a collection earlier
161             return new BasicEmptyProperty(name);
162         }
163         if (valueList.size() == 1) {
164             return new BasicSingleValueProperty(name, valueList.get(0));
165         }
166         return new BasicMultiValueProperty(name, valueList);
167     }
168 
169     /**
170      * {@inheritDoc}
171      */
172     public Property create( Name name,
173                             PropertyType desiredType,
174                             Iterator<?> values ) {
175         CheckArg.isNotNull(name, "name");
176         final List<Object> valueList = new ArrayList<Object>();
177         if (desiredType == null) desiredType = PropertyType.OBJECT;
178         final ValueFactory<?> factory = factories.getValueFactory(desiredType);
179         while (values.hasNext()) {
180             Object value = values.next();
181             value = factory.create(value);
182             valueList.add(value);
183         }
184         if (valueList.isEmpty()) {
185             return new BasicEmptyProperty(name);
186         }
187         if (valueList.size() == 1) {
188             return new BasicSingleValueProperty(name, valueList.get(0));
189         }
190         return new BasicMultiValueProperty(name, valueList);
191     }
192 
193 }