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 }