001 /*
002 * JBoss DNA (http://www.jboss.org/dna)
003 * See the COPYRIGHT.txt file distributed with this work for information
004 * regarding copyright ownership. Some portions may be licensed
005 * to Red Hat, Inc. under one or more contributor license agreements.
006 * See the AUTHORS.txt file in the distribution for a full listing of
007 * individual contributors.
008 *
009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010 * is licensed to you under the terms of the GNU Lesser General Public License as
011 * published by the Free Software Foundation; either version 2.1 of
012 * the License, or (at your option) any later version.
013 *
014 * JBoss DNA is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 * Lesser General Public License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this software; if not, write to the Free
021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023 */
024 package org.jboss.dna.graph.property.basic;
025
026 import java.math.BigDecimal;
027 import java.net.URI;
028 import java.util.HashMap;
029 import java.util.Map;
030 import net.jcip.annotations.Immutable;
031 import org.jboss.dna.common.text.TextDecoder;
032 import org.jboss.dna.common.text.TextEncoder;
033 import org.jboss.dna.common.util.CheckArg;
034 import org.jboss.dna.graph.property.BinaryFactory;
035 import org.jboss.dna.graph.property.DateTimeFactory;
036 import org.jboss.dna.graph.property.NameFactory;
037 import org.jboss.dna.graph.property.NamespaceRegistry;
038 import org.jboss.dna.graph.property.PathFactory;
039 import org.jboss.dna.graph.property.PropertyType;
040 import org.jboss.dna.graph.property.Reference;
041 import org.jboss.dna.graph.property.UuidFactory;
042 import org.jboss.dna.graph.property.ValueFactory;
043
044 /**
045 * The standard set of {@link ValueFactory value factories}.
046 *
047 * @author Randall Hauch
048 */
049 @Immutable
050 public class StandardValueFactories extends AbstractValueFactories {
051
052 // This class is implemented with separate members for each factory so that the typical usage is optimized.
053 private final ValueFactory<String> stringFactory;
054 private final BinaryFactory binaryFactory;
055 private final ValueFactory<Boolean> booleanFactory;
056 private final DateTimeFactory dateFactory;
057 private final ValueFactory<BigDecimal> decimalFactory;
058 private final ValueFactory<Double> doubleFactory;
059 private final ValueFactory<Long> longFactory;
060 private final NameFactory nameFactory;
061 private final PathFactory pathFactory;
062 private final ValueFactory<Reference> referenceFactory;
063 private final ValueFactory<URI> uriFactory;
064 private final UuidFactory uuidFactory;
065 private final ValueFactory<Object> objectFactory;
066
067 private final NamespaceRegistry namespaceRegistry;
068 private final TextDecoder decoder;
069 private final TextEncoder encoder;
070
071 /**
072 * Create a standard set of value factories, using the {@link ValueFactory#DEFAULT_DECODER default decoder}.
073 *
074 * @param namespaceRegistry the namespace registry
075 * @throws IllegalArgumentException if the namespace registry is null
076 */
077 public StandardValueFactories( NamespaceRegistry namespaceRegistry ) {
078 this(namespaceRegistry, null, null);
079 }
080
081 /**
082 * Create a standard set of value factories, using the supplied encoder/decoder.
083 *
084 * @param namespaceRegistry the namespace registry
085 * @param decoder the decoder that should be used; if null, the {@link ValueFactory#DEFAULT_DECODER default decoder} is used.
086 * @param encoder the encoder that should be used; if null, the {@link ValueFactory#DEFAULT_ENCODER default encoder} is used.
087 * @param extraFactories any extra factories that should be used; any factory will override the standard factories based upon
088 * the {@link ValueFactory#getPropertyType() factory's property type}.
089 * @throws IllegalArgumentException if the namespace registry is null
090 */
091 public StandardValueFactories( NamespaceRegistry namespaceRegistry,
092 TextDecoder decoder,
093 TextEncoder encoder,
094 ValueFactory<?>... extraFactories ) {
095 CheckArg.isNotNull(namespaceRegistry, "namespaceRegistry");
096 this.namespaceRegistry = namespaceRegistry;
097 this.decoder = decoder != null ? decoder : ValueFactory.DEFAULT_DECODER;
098 this.encoder = encoder != null ? encoder : ValueFactory.DEFAULT_ENCODER;
099 Map<PropertyType, ValueFactory<?>> factories = new HashMap<PropertyType, ValueFactory<?>>();
100
101 // Put the extra factories into the map first ...
102 for (ValueFactory<?> factory : extraFactories) {
103 if (factory == null) continue;
104 factories.put(factory.getPropertyType(), factory);
105 }
106
107 // Now assign the members, using the factories in the map or (if null) the supplied default ...
108 this.stringFactory = getFactory(factories, new StringValueFactory(this.namespaceRegistry, this.decoder, this.encoder));
109
110 // The binary factory should NOT use the string factory that converts namespaces to prefixes ...
111 StringValueFactory stringFactoryWithoutNamespaces = new StringValueFactory(this.decoder, this.encoder);
112 this.binaryFactory = (BinaryFactory)getFactory(factories, new InMemoryBinaryValueFactory(this.decoder,
113 stringFactoryWithoutNamespaces));
114 this.booleanFactory = getFactory(factories, new BooleanValueFactory(this.decoder, this.stringFactory));
115 this.dateFactory = (DateTimeFactory)getFactory(factories, new JodaDateTimeValueFactory(this.decoder, this.stringFactory));
116 this.decimalFactory = getFactory(factories, new DecimalValueFactory(this.decoder, this.stringFactory));
117 this.doubleFactory = getFactory(factories, new DoubleValueFactory(this.decoder, this.stringFactory));
118 this.longFactory = getFactory(factories, new LongValueFactory(this.decoder, this.stringFactory));
119 this.nameFactory = (NameFactory)getFactory(factories, new NameValueFactory(this.namespaceRegistry, this.decoder,
120 this.stringFactory));
121 this.pathFactory = (PathFactory)getFactory(factories, new PathValueFactory(this.decoder, this.stringFactory,
122 this.nameFactory));
123 this.referenceFactory = getFactory(factories, new UuidReferenceValueFactory(this.decoder, this.stringFactory));
124 this.uuidFactory = (UuidFactory)getFactory(factories, new UuidValueFactory(this.decoder, this.stringFactory));
125 this.uriFactory = getFactory(factories, new UriValueFactory(this.namespaceRegistry, this.decoder, this.stringFactory));
126 this.objectFactory = getFactory(factories, new ObjectValueFactory(this.decoder, this.stringFactory, this.binaryFactory));
127 }
128
129 @SuppressWarnings( "unchecked" )
130 private static <T> ValueFactory<T> getFactory( Map<PropertyType, ValueFactory<?>> factories,
131 ValueFactory<T> defaultFactory ) {
132 PropertyType type = defaultFactory.getPropertyType();
133 ValueFactory<?> factory = factories.get(type);
134 if (factory == null) {
135 factory = defaultFactory;
136 factories.put(type, factory);
137 }
138 return (ValueFactory<T>)factory;
139 }
140
141 /**
142 * @return decoder
143 */
144 public TextDecoder getTextDecoder() {
145 return this.decoder;
146 }
147
148 /**
149 * @return namespaceRegistry
150 */
151 public NamespaceRegistry getNamespaceRegistry() {
152 return this.namespaceRegistry;
153 }
154
155 /**
156 * {@inheritDoc}
157 */
158 public BinaryFactory getBinaryFactory() {
159 return this.binaryFactory;
160 }
161
162 /**
163 * {@inheritDoc}
164 */
165 public ValueFactory<Boolean> getBooleanFactory() {
166 return this.booleanFactory;
167 }
168
169 /**
170 * {@inheritDoc}
171 */
172 public DateTimeFactory getDateFactory() {
173 return this.dateFactory;
174 }
175
176 /**
177 * {@inheritDoc}
178 */
179 public ValueFactory<BigDecimal> getDecimalFactory() {
180 return this.decimalFactory;
181 }
182
183 /**
184 * {@inheritDoc}
185 */
186 public ValueFactory<Double> getDoubleFactory() {
187 return this.doubleFactory;
188 }
189
190 /**
191 * {@inheritDoc}
192 */
193 public ValueFactory<Long> getLongFactory() {
194 return this.longFactory;
195 }
196
197 /**
198 * {@inheritDoc}
199 */
200 public NameFactory getNameFactory() {
201 return this.nameFactory;
202 }
203
204 /**
205 * {@inheritDoc}
206 */
207 public PathFactory getPathFactory() {
208 return this.pathFactory;
209 }
210
211 /**
212 * {@inheritDoc}
213 */
214 public ValueFactory<Reference> getReferenceFactory() {
215 return this.referenceFactory;
216 }
217
218 /**
219 * {@inheritDoc}
220 */
221 public ValueFactory<String> getStringFactory() {
222 return this.stringFactory;
223 }
224
225 /**
226 * {@inheritDoc}
227 */
228 public ValueFactory<URI> getUriFactory() {
229 return this.uriFactory;
230 }
231
232 /**
233 * {@inheritDoc}
234 *
235 * @see org.jboss.dna.graph.property.ValueFactories#getUuidFactory()
236 */
237 public UuidFactory getUuidFactory() {
238 return this.uuidFactory;
239 }
240
241 /**
242 * {@inheritDoc}
243 */
244 public ValueFactory<Object> getObjectFactory() {
245 return this.objectFactory;
246 }
247
248 }