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 }