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.math.BigDecimal;
025 import java.net.URI;
026 import java.util.HashMap;
027 import java.util.Map;
028 import net.jcip.annotations.Immutable;
029 import org.jboss.dna.common.text.TextDecoder;
030 import org.jboss.dna.common.text.TextEncoder;
031 import org.jboss.dna.common.util.CheckArg;
032 import org.jboss.dna.graph.properties.Binary;
033 import org.jboss.dna.graph.properties.DateTimeFactory;
034 import org.jboss.dna.graph.properties.NameFactory;
035 import org.jboss.dna.graph.properties.NamespaceRegistry;
036 import org.jboss.dna.graph.properties.PathFactory;
037 import org.jboss.dna.graph.properties.PropertyType;
038 import org.jboss.dna.graph.properties.Reference;
039 import org.jboss.dna.graph.properties.UuidFactory;
040 import org.jboss.dna.graph.properties.ValueFactory;
041
042 /**
043 * The standard set of {@link ValueFactory value factories}.
044 *
045 * @author Randall Hauch
046 */
047 @Immutable
048 public class StandardValueFactories extends AbstractValueFactories {
049
050 // This class is implemented with separate members for each factory so that the typical usage is optimized.
051 private final ValueFactory<String> stringFactory;
052 private final ValueFactory<Binary> binaryFactory;
053 private final ValueFactory<Boolean> booleanFactory;
054 private final DateTimeFactory dateFactory;
055 private final ValueFactory<BigDecimal> decimalFactory;
056 private final ValueFactory<Double> doubleFactory;
057 private final ValueFactory<Long> longFactory;
058 private final NameFactory nameFactory;
059 private final PathFactory pathFactory;
060 private final ValueFactory<Reference> referenceFactory;
061 private final ValueFactory<URI> uriFactory;
062 private final UuidFactory uuidFactory;
063 private final ValueFactory<Object> objectFactory;
064
065 private final NamespaceRegistry namespaceRegistry;
066 private final TextDecoder decoder;
067 private final TextEncoder encoder;
068
069 /**
070 * Create a standard set of value factories, using the {@link ValueFactory#DEFAULT_DECODER default decoder}.
071 *
072 * @param namespaceRegistry the namespace registry
073 * @throws IllegalArgumentException if the namespace registry is null
074 */
075 public StandardValueFactories( NamespaceRegistry namespaceRegistry ) {
076 this(namespaceRegistry, null, null);
077 }
078
079 /**
080 * Create a standard set of value factories, using the supplied encoder/decoder.
081 *
082 * @param namespaceRegistry the namespace registry
083 * @param decoder the decoder that should be used; if null, the {@link ValueFactory#DEFAULT_DECODER default decoder} is used.
084 * @param encoder the encoder that should be used; if null, the {@link ValueFactory#DEFAULT_ENCODER default encoder} is used.
085 * @param extraFactories any extra factories that should be used; any factory will override the standard factories based upon
086 * the {@link ValueFactory#getPropertyType() factory's property type}.
087 * @throws IllegalArgumentException if the namespace registry is null
088 */
089 public StandardValueFactories( NamespaceRegistry namespaceRegistry,
090 TextDecoder decoder,
091 TextEncoder encoder,
092 ValueFactory<?>... extraFactories ) {
093 CheckArg.isNotNull(namespaceRegistry, "namespaceRegistry");
094 this.namespaceRegistry = namespaceRegistry;
095 this.decoder = decoder != null ? decoder : ValueFactory.DEFAULT_DECODER;
096 this.encoder = encoder != null ? encoder : ValueFactory.DEFAULT_ENCODER;
097 Map<PropertyType, ValueFactory<?>> factories = new HashMap<PropertyType, ValueFactory<?>>();
098
099 // Put the extra factories into the map first ...
100 for (ValueFactory<?> factory : extraFactories) {
101 if (factory == null) continue;
102 factories.put(factory.getPropertyType(), factory);
103 }
104
105 // Now assign the members, using the factories in the map or (if null) the supplied default ...
106 this.stringFactory = getFactory(factories, new StringValueFactory(this.decoder, this.encoder));
107 this.binaryFactory = getFactory(factories, new InMemoryBinaryValueFactory(this.decoder, this.stringFactory));
108 this.booleanFactory = getFactory(factories, new BooleanValueFactory(this.decoder, this.stringFactory));
109 this.dateFactory = (DateTimeFactory)getFactory(factories, new JodaDateTimeValueFactory(this.decoder, this.stringFactory));
110 this.decimalFactory = getFactory(factories, new DecimalValueFactory(this.decoder, this.stringFactory));
111 this.doubleFactory = getFactory(factories, new DoubleValueFactory(this.decoder, this.stringFactory));
112 this.longFactory = getFactory(factories, new LongValueFactory(this.decoder, this.stringFactory));
113 this.nameFactory = (NameFactory)getFactory(factories, new NameValueFactory(this.namespaceRegistry, this.decoder,
114 this.stringFactory));
115 this.pathFactory = (PathFactory)getFactory(factories, new PathValueFactory(this.decoder, this.stringFactory,
116 this.nameFactory));
117 this.referenceFactory = getFactory(factories, new UuidReferenceValueFactory(this.decoder, this.stringFactory));
118 this.uuidFactory = (UuidFactory)getFactory(factories, new UuidValueFactory(this.decoder, this.stringFactory));
119 this.uriFactory = getFactory(factories, new UriValueFactory(this.namespaceRegistry, this.decoder, this.stringFactory));
120 this.objectFactory = getFactory(factories, new ObjectValueFactory(this.decoder, this.stringFactory, this.binaryFactory));
121 }
122
123 @SuppressWarnings( "unchecked" )
124 private static <T> ValueFactory<T> getFactory( Map<PropertyType, ValueFactory<?>> factories,
125 ValueFactory<T> defaultFactory ) {
126 PropertyType type = defaultFactory.getPropertyType();
127 ValueFactory<?> factory = factories.get(type);
128 if (factory == null) {
129 factory = defaultFactory;
130 factories.put(type, factory);
131 }
132 return (ValueFactory<T>)factory;
133 }
134
135 /**
136 * @return decoder
137 */
138 public TextDecoder getTextDecoder() {
139 return this.decoder;
140 }
141
142 /**
143 * @return namespaceRegistry
144 */
145 public NamespaceRegistry getNamespaceRegistry() {
146 return this.namespaceRegistry;
147 }
148
149 /**
150 * {@inheritDoc}
151 */
152 public ValueFactory<Binary> getBinaryFactory() {
153 return this.binaryFactory;
154 }
155
156 /**
157 * {@inheritDoc}
158 */
159 public ValueFactory<Boolean> getBooleanFactory() {
160 return this.booleanFactory;
161 }
162
163 /**
164 * {@inheritDoc}
165 */
166 public DateTimeFactory getDateFactory() {
167 return this.dateFactory;
168 }
169
170 /**
171 * {@inheritDoc}
172 */
173 public ValueFactory<BigDecimal> getDecimalFactory() {
174 return this.decimalFactory;
175 }
176
177 /**
178 * {@inheritDoc}
179 */
180 public ValueFactory<Double> getDoubleFactory() {
181 return this.doubleFactory;
182 }
183
184 /**
185 * {@inheritDoc}
186 */
187 public ValueFactory<Long> getLongFactory() {
188 return this.longFactory;
189 }
190
191 /**
192 * {@inheritDoc}
193 */
194 public NameFactory getNameFactory() {
195 return this.nameFactory;
196 }
197
198 /**
199 * {@inheritDoc}
200 */
201 public PathFactory getPathFactory() {
202 return this.pathFactory;
203 }
204
205 /**
206 * {@inheritDoc}
207 */
208 public ValueFactory<Reference> getReferenceFactory() {
209 return this.referenceFactory;
210 }
211
212 /**
213 * {@inheritDoc}
214 */
215 public ValueFactory<String> getStringFactory() {
216 return this.stringFactory;
217 }
218
219 /**
220 * {@inheritDoc}
221 */
222 public ValueFactory<URI> getUriFactory() {
223 return this.uriFactory;
224 }
225
226 /**
227 * {@inheritDoc}
228 *
229 * @see org.jboss.dna.graph.properties.ValueFactories#getUuidFactory()
230 */
231 public UuidFactory getUuidFactory() {
232 return this.uuidFactory;
233 }
234
235 /**
236 * {@inheritDoc}
237 */
238 public ValueFactory<Object> getObjectFactory() {
239 return this.objectFactory;
240 }
241
242 }