View Javadoc

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 }