1 /*
2 * Copyright 2009-2010 Steve Chaloner
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package be.objectify.led;
17
18 import be.objectify.led.util.ContractUtils;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 import java.util.Arrays;
23 import java.util.Iterator;
24 import java.util.LinkedHashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29 /**
30 * Registry of {@link TypeFactory} for creating objects of the correct type based on the field.
31 *
32 * @author Steve Chaloner
33 */
34 public class TypeFactoryRegistry
35 {
36 private static final Logger LOGGER = LoggerFactory.getLogger(TypeFactoryRegistry.class);
37
38 private final Map<Class, TypeFactory> typeFactories = new LinkedHashMap<Class, TypeFactory>();
39
40 /**
41 * Registers the type factories with the registry.
42 *
43 * @param typeFactories the type factories. None of the factories can be null.
44 */
45 public void register(TypeFactory... typeFactories)
46 {
47 ContractUtils.nonNull(typeFactories,
48 "typeFactories");
49
50 register(Arrays.asList(typeFactories));
51 }
52
53 /**
54 * Registers the type factories with the registry.
55 *
56 * @param typeFactories the type factories to register. Must not be null; none of contents
57 */
58 public void register(List<TypeFactory> typeFactories)
59 {
60 ContractUtils.nonNull(typeFactories,
61 "typeFactories");
62
63 for (TypeFactory typeFactory : typeFactories)
64 {
65 this.typeFactories.put(typeFactory.getBoundClass(),
66 typeFactory);
67 }
68 }
69
70 /**
71 * Gets the type factory for the given class.
72 *
73 * @param clazz the class of the required object
74 * @return the type factory, or null if no factory is registered for the class
75 */
76 public TypeFactory getFactory(Class clazz)
77 {
78 TypeFactory factory = typeFactories.get(clazz);
79 if (factory == null)
80 {
81 Set<Class> keySet = typeFactories.keySet();
82 for (Iterator<Class> it = keySet.iterator(); factory == null && it.hasNext();)
83 {
84 Class c = it.next();
85 if (c.isAssignableFrom(clazz))
86 {
87 factory = typeFactories.get(c);
88 LOGGER.debug("Found type factory [{}] for class [{}] using supertype [{}]",
89 new Object[]{
90 factory,
91 clazz.getCanonicalName(),
92 c.getCanonicalName()
93 });
94 }
95 }
96 if (factory == null)
97 {
98 LOGGER.debug("Could not find type factory for class [{}]",
99 clazz.getCanonicalName());
100 }
101 }
102 else
103 {
104 LOGGER.debug("Found type factory [{}] for class [{}]",
105 factory,
106 clazz.getCanonicalName());
107 }
108
109 return factory;
110 }
111 }