View Javadoc

1   /*
2    * Copyright 2007-2008 Naoki NOSE.
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 jp.liq.container;
17  
18  import java.util.HashMap;
19  import java.util.Map;
20  
21  import jp.liq.container.ContainerException.Reason;
22  
23  /**
24   * {@link Component} を生成します。
25   * @author nose
26   */
27  public abstract class Module {
28      private final Map<Class<?>, ComponentMetadata> components;
29  
30      /**
31       * このクラスのインスタンスを構築します。
32       */
33      public Module() {
34          this.components = new HashMap<Class<?>, ComponentMetadata>();
35      }
36  
37      synchronized <T> ComponentMetadata getComponentMetadata(Class<T> type) {
38          ComponentMetadata cm = components.get(type);
39          if(cm == null) {
40              Component<?> component = createComponent(type);
41              if(component == null) {
42                  return null;
43              }
44              cm  = new ComponentMetadata(component, this);
45              components.put(type, cm);
46          }
47          return cm;
48      }
49  
50      /**
51       * 引数で指定されたコンポーネントを追加します。
52       * @param component 追加するコンポーネント
53       */
54      protected <T> void addComponent(Component<T> component) {
55          Class<T> type = component.getType();
56          if(components.containsKey(type)) {
57              throw new ContainerException(Reason.DUPLICATE_REGISTRATION, type, component,
58                      components.get(type).getComponent());
59          }
60          components.put(type, new ComponentMetadata(component, this));
61      }
62  
63      /**
64       * 引数で指定されたクラスに対応するコンポーネントを返します。
65       * @param type
66       */
67      protected <T> Component<T> createComponent(Class<T> type) {
68          return null;
69      }
70  }