1 /*
2 * Copyright (c) 2002-2006 by OpenSymphony
3 * All rights reserved.
4 */
5 package com.opensymphony.xwork2.config;
6
7 import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
8 import com.opensymphony.xwork2.config.providers.XWorkConfigurationProvider;
9 import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
10 import com.opensymphony.xwork2.util.FileManager;
11 import com.opensymphony.xwork2.util.logging.Logger;
12 import com.opensymphony.xwork2.util.logging.LoggerFactory;
13
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.concurrent.CopyOnWriteArrayList;
17 import java.util.concurrent.locks.Lock;
18 import java.util.concurrent.locks.ReentrantLock;
19
20
21 /**
22 * ConfigurationManager - central for XWork Configuration management, including
23 * its ConfigurationProvider.
24 *
25 * @author Jason Carreira
26 * @author tm_jee
27 * @version $Date: 2008-06-21 11:29:39 +0200 (Sa, 21 Jun 2008) $ $Id: ConfigurationManager.java 1833 2008-06-21 09:29:39Z rainerh $
28 */
29 public class ConfigurationManager {
30
31 protected static final Logger LOG = LoggerFactory.getLogger(ConfigurationManager.class);
32 protected Configuration configuration;
33 protected Lock providerLock = new ReentrantLock();
34 private List<ContainerProvider> containerProviders = new CopyOnWriteArrayList<ContainerProvider>();
35 private List<PackageProvider> packageProviders = new CopyOnWriteArrayList<PackageProvider>();
36 protected String defaultFrameworkBeanName;
37
38 public ConfigurationManager() {
39 this("xwork");
40 }
41
42 public ConfigurationManager(String name) {
43 this.defaultFrameworkBeanName = name;
44 }
45
46 /**
47 * Get the current XWork configuration object. By default an instance of DefaultConfiguration will be returned
48 *
49 * @see com.opensymphony.xwork2.config.impl.DefaultConfiguration
50 */
51 public synchronized Configuration getConfiguration() {
52 if (configuration == null) {
53 setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
54 try {
55 configuration.reloadContainer(getContainerProviders());
56 } catch (ConfigurationException e) {
57 setConfiguration(null);
58 throw new ConfigurationException("Unable to load configuration.", e);
59 }
60 } else {
61 conditionalReload();
62 }
63
64 return configuration;
65 }
66
67 public synchronized void setConfiguration(Configuration configuration) {
68 this.configuration = configuration;
69 }
70
71 /**
72 * Get the current list of ConfigurationProviders. If no custom ConfigurationProviders have been added, this method
73 * will return a list containing only the default ConfigurationProvider, XMLConfigurationProvider. if a custom
74 * ConfigurationProvider has been added, then the XmlConfigurationProvider must be added by hand.
75 * </p>
76 * <p/>
77 * WARNING: This returns only ContainerProviders that can be cast into ConfigurationProviders
78 *
79 * @return the list of registered ConfigurationProvider objects
80 * @see ConfigurationProvider
81 * @deprecated Since 2.1, use {@link #getContainerProviders()}
82 */
83 @Deprecated public List<ConfigurationProvider> getConfigurationProviders() {
84 List<ContainerProvider> contProviders = getContainerProviders();
85 List<ConfigurationProvider> providers = new ArrayList<ConfigurationProvider>();
86 for (ContainerProvider prov : contProviders) {
87 if (prov instanceof ConfigurationProvider) {
88 providers.add((ConfigurationProvider) prov);
89 }
90 }
91 return providers;
92 }
93
94 /**
95 * Get the current list of ConfigurationProviders. If no custom ConfigurationProviders have been added, this method
96 * will return a list containing only the default ConfigurationProvider, XMLConfigurationProvider. if a custom
97 * ConfigurationProvider has been added, then the XmlConfigurationProvider must be added by hand.
98 * </p>
99 * <p/>
100 * TODO: the lazy instantiation of XmlConfigurationProvider should be refactored to be elsewhere. the behavior described above seems unintuitive.
101 *
102 * @return the list of registered ConfigurationProvider objects
103 * @see ConfigurationProvider
104 */
105 public List<ContainerProvider> getContainerProviders() {
106 providerLock.lock();
107 try {
108 if (containerProviders.size() == 0) {
109 containerProviders.add(new XWorkConfigurationProvider());
110 containerProviders.add(new XmlConfigurationProvider("xwork.xml", false));
111 }
112
113 return containerProviders;
114 } finally {
115 providerLock.unlock();
116 }
117 }
118
119 /**
120 * Set the list of configuration providers
121 *
122 * @param configurationProviders
123 * @deprecated Since 2.1, use {@link #setContainerProvider()}
124 */
125 @Deprecated public void setConfigurationProviders(List<ConfigurationProvider> configurationProviders) {
126 // Silly copy necessary due to lack of ability to cast generic lists
127 List<ContainerProvider> contProviders = new ArrayList<ContainerProvider>();
128 contProviders.addAll(configurationProviders);
129
130 setContainerProviders(contProviders);
131 }
132
133 /**
134 * Set the list of configuration providers
135 *
136 * @param containerProviders
137 */
138 public void setContainerProviders(List<ContainerProvider> containerProviders) {
139 providerLock.lock();
140 try {
141 this.containerProviders = new CopyOnWriteArrayList<ContainerProvider>(containerProviders);
142 } finally {
143 providerLock.unlock();
144 }
145 }
146
147 /**
148 * adds a configuration provider to the List of ConfigurationProviders. a given ConfigurationProvider may be added
149 * more than once
150 *
151 * @param provider the ConfigurationProvider to register
152 * @deprecated Since 2.1, use {@link #addContainerProvider()}
153 */
154 @Deprecated public void addConfigurationProvider(ConfigurationProvider provider) {
155 addContainerProvider(provider);
156 }
157
158 /**
159 * adds a configuration provider to the List of ConfigurationProviders. a given ConfigurationProvider may be added
160 * more than once
161 *
162 * @param provider the ConfigurationProvider to register
163 */
164 public void addContainerProvider(ContainerProvider provider) {
165 if (!containerProviders.contains(provider)) {
166 containerProviders.add(provider);
167 }
168 }
169
170 /**
171 * clears the registered ConfigurationProviders. this method will call destroy() on each of the registered
172 * ConfigurationProviders
173 *
174 * @see com.opensymphony.xwork2.config.ConfigurationProvider#destroy
175 * @deprecated Since 2.1, use {@link #clearContainerProviders()}
176 */
177 @Deprecated public void clearConfigurationProviders() {
178 clearContainerProviders();
179 }
180
181 public void clearContainerProviders() {
182 for (ContainerProvider containerProvider : containerProviders) {
183 try {
184 containerProvider.destroy();
185 }
186 catch(Exception e) {
187 LOG.warn("error while destroying container provider ["+containerProvider+"]", e);
188 }
189 }
190 containerProviders.clear();
191 }
192
193 /**
194 * Destroy its managing Configuration instance
195 */
196 public synchronized void destroyConfiguration() {
197 clearConfigurationProviders(); // let's destroy the ConfigurationProvider first
198 containerProviders = new CopyOnWriteArrayList<ContainerProvider>();
199 if (configuration != null)
200 configuration.destroy(); // let's destroy it first, before nulling it.
201 configuration = null;
202 }
203
204
205 /**
206 * Reloads the Configuration files if the configuration files indicate that they need to be reloaded.
207 */
208 public synchronized void conditionalReload() {
209 if (FileManager.isReloadingConfigs()) {
210 boolean reload;
211
212 if (LOG.isDebugEnabled()) {
213 LOG.debug("Checking ConfigurationProviders for reload.");
214 }
215
216 reload = false;
217
218 List<ContainerProvider> providers = getContainerProviders();
219 for (ContainerProvider provider : providers) {
220 if (provider.needsReload()) {
221 if (LOG.isInfoEnabled()) {
222 LOG.info("Detected container provider "+provider+" needs to be reloaded. Reloading all providers.");
223 }
224 reload = true;
225
226 //break;
227 }
228 }
229
230 if (packageProviders != null && reload) {
231 for (PackageProvider provider : packageProviders) {
232 if (provider.needsReload()) {
233 if (LOG.isInfoEnabled()) {
234 LOG.info("Detected package provider "+provider+" needs to be reloaded. Reloading all providers.");
235 }
236 reload = true;
237
238 //break;
239 }
240 }
241 }
242
243 if (reload) {
244 for (ContainerProvider containerProvider : containerProviders) {
245 try {
246 containerProvider.destroy();
247 }
248 catch(Exception e) {
249 LOG.warn("error while destroying configuration provider ["+containerProvider+"]", e);
250 }
251 }
252 packageProviders = configuration.reloadContainer(providers);
253 }
254 }
255 }
256
257 public synchronized void reload() {
258 packageProviders = getConfiguration().reloadContainer(getContainerProviders());
259 }
260 }