View Javadoc

1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
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,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.plugin;
17  
18  import static org.seasar.cubby.internal.util.LogMessages.format;
19  
20  import java.util.HashMap;
21  import java.util.HashSet;
22  import java.util.Map;
23  import java.util.Set;
24  
25  import javax.servlet.ServletContextEvent;
26  
27  import org.seasar.cubby.spi.Provider;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  /**
32   * プラグインのレジストリです。
33   * 
34   * @author baba
35   */
36  public class PluginRegistry {
37  
38  	/** ロガー。 */
39  	private static final Logger logger = LoggerFactory
40  			.getLogger(PluginRegistry.class);
41  
42  	/** シングルトンインスタンス。 */
43  	private static final PluginRegistry INSTANCE = new PluginRegistry();
44  
45  	/** プラグインのセット。 */
46  	private Set<Plugin> plugins = new HashSet<Plugin>();
47  
48  	/** サービスとそのサービスを提供するプラグインとのマッピング。 */
49  	private Map<Class<? extends Provider>, Plugin> serviceToPlugins = new HashMap<Class<? extends Provider>, Plugin>();
50  
51  	/**
52  	 * インスタンス化を禁止するためのコンストラクタ。
53  	 */
54  	private PluginRegistry() {
55  	}
56  
57  	/**
58  	 * {@link Plugins} のシングルトンを取得します。
59  	 * 
60  	 * @return {@link Plugins} のシングルトン
61  	 */
62  	public static PluginRegistry getInstance() {
63  		return INSTANCE;
64  	}
65  
66  	/**
67  	 * 登録されたプラグインをクリアします。
68  	 */
69  	public synchronized void clear() {
70  		this.plugins.clear();
71  		this.serviceToPlugins.clear();
72  	}
73  
74  	/**
75  	 * 指定されたプラグインを登録します。
76  	 * 
77  	 * @param plugin
78  	 *            プラグイン
79  	 */
80  	public synchronized void register(final Plugin plugin) {
81  		this.plugins.add(plugin);
82  		for (final Class<? extends Provider> service : plugin
83  				.getSupportedServices()) {
84  			this.serviceToPlugins.put(service, plugin);
85  			if (logger.isInfoEnabled()) {
86  				logger.info(format("ICUB0001", plugin, service));
87  			}
88  		}
89  	}
90  
91  	/**
92  	 * 指定されたサービスのプロバイダを取得します。
93  	 * 
94  	 * @param <S>
95  	 *            サービスの型
96  	 * @param service
97  	 *            サービス
98  	 * @return プロバイダ
99  	 * @throws IllegalStateException
100 	 *             {@link #initialize(ServletContextEvent)} で初期化される前に呼び出された場合
101 	 */
102 	public <S extends Provider> S getProvider(final Class<S> service) {
103 		if (this.serviceToPlugins == null) {
104 			throw new IllegalStateException(format("ECUB0053"));
105 		}
106 		final Plugin plugin = this.serviceToPlugins.get(service);
107 		if (plugin == null) {
108 			throw new IllegalArgumentException(format("ECUB0054", service));
109 		}
110 		final S provider = service.cast(plugin.getProvider(service));
111 		if (provider == null) {
112 			throw new NullPointerException("provider");
113 		}
114 		return provider;
115 	}
116 
117 	/**
118 	 * 登録されているプラグインのセットを取得します。
119 	 * 
120 	 * @return 登録されているプラグインのセット
121 	 */
122 	public Set<Plugin> getPlugins() {
123 		return plugins;
124 	}
125 
126 	/**
127 	 * 登録されたプラグインから指定された型のプラグインを取得します。
128 	 * <p>
129 	 * 該当するプラグインが登録されていない場合は <code>null</code> を返します。
130 	 * </p>
131 	 * 
132 	 * @param <T>
133 	 *            プラグインの型
134 	 * @param pluginType
135 	 *            プラグインの型
136 	 * @return 指定された型のプラグイン
137 	 */
138 	public <T extends Plugin> T getPlugin(final Class<T> pluginType) {
139 		for (final Plugin plugin : plugins) {
140 			if (plugin.getClass().equals(pluginType)) {
141 				return pluginType.cast(plugin);
142 			}
143 		}
144 		return null;
145 	}
146 
147 }