001: package org.objectweb.celtix.configuration.impl;
002:
003: import java.lang.reflect.InvocationTargetException;
004: import java.lang.reflect.Method;
005: import java.util.List;
006: import java.util.ResourceBundle;
007: import java.util.Vector;
008: import java.util.logging.Level;
009: import java.util.logging.Logger;
010:
011: import javax.xml.namespace.QName;
012:
013: import org.objectweb.celtix.common.i18n.BundleUtils;
014: import org.objectweb.celtix.common.i18n.Message;
015: import org.objectweb.celtix.common.logging.LogUtils;
016: import org.objectweb.celtix.configuration.Configuration;
017: import org.objectweb.celtix.configuration.ConfigurationException;
018: import org.objectweb.celtix.configuration.ConfigurationItemMetadata;
019: import org.objectweb.celtix.configuration.ConfigurationMetadata;
020: import org.objectweb.celtix.configuration.ConfigurationProvider;
021: import org.objectweb.celtix.configuration.Configurator;
022:
023: public class AbstractConfigurationImpl implements Configuration {
024:
025: private static final Logger LOG = LogUtils
026: .getL7dLogger(AbstractConfigurationImpl.class);
027: private static final ResourceBundle BUNDLE = BundleUtils
028: .getBundle(AbstractConfigurationImpl.class);
029: private Configurator configurator;
030: private ConfigurationMetadata model;
031: private String id;
032: private List<ConfigurationProvider> providers;
033:
034: public AbstractConfigurationImpl(ConfigurationMetadata m,
035: String instanceId, Configuration parent) {
036: model = m;
037: id = instanceId;
038: configurator = new ConfiguratorImpl(
039: this ,
040: parent instanceof AbstractConfigurationImpl ? (AbstractConfigurationImpl) parent
041: : null);
042:
043: providers = new Vector<ConfigurationProvider>();
044:
045: // temporary:
046: //providers.add(new InMemoryProvider());
047:
048: DefaultConfigurationProviderFactory factory = DefaultConfigurationProviderFactory
049: .getInstance();
050: ConfigurationProvider defaultProvider = factory
051: .createDefaultProvider(this );
052:
053: if (null != defaultProvider) {
054: providers.add(defaultProvider);
055: }
056: }
057:
058: public Object getId() {
059: return id;
060: }
061:
062: public Configuration getParent() {
063: if (null != configurator.getHook()) {
064: return configurator.getHook().getConfiguration();
065: }
066: return null;
067: }
068:
069: public Configuration getChild(String namespaceURI, Object childId) {
070: for (Configurator c : configurator.getClients()) {
071: if (namespaceURI.equals(c.getConfiguration().getModel()
072: .getNamespaceURI())
073: && childId.equals(c.getConfiguration().getId())) {
074: return c.getConfiguration();
075: }
076: }
077: if (LOG.isLoggable(Level.FINE)) {
078: LOG.fine("Could not find child configuration with id: "
079: + childId);
080: }
081: return null;
082: }
083:
084: public ConfigurationMetadata getModel() {
085: return model;
086: }
087:
088: public List<ConfigurationProvider> getProviders() {
089: return providers;
090: }
091:
092: public void setProviders(List<ConfigurationProvider> p) {
093: providers = p;
094: }
095:
096: public <T> T getObject(Class<T> cls, String name) {
097: Object obj = getObject(name);
098: return cls.cast(obj);
099: }
100:
101: public Object getObject(String name) {
102:
103: ConfigurationItemMetadata definition = model
104: .getDefinition(name);
105: if (null == definition) {
106: throw new ConfigurationException(new Message(
107: "ITEM_NOT_DEFINED_EXC", BUNDLE, name));
108: }
109:
110: Configuration holder = this ;
111: while (null != holder) {
112: Object obj = getLocal(holder, name);
113: if (null != obj) {
114: return obj;
115: }
116: holder = holder.getParent();
117: }
118: return definition.getDefaultValue();
119: }
120:
121: /**
122: * Check if property is defined and validate the value.
123: * Then try all providers in turn until one is found that accepts the change.
124: */
125: public boolean setObject(String name, Object value) {
126: ConfigurationItemMetadata definition = model
127: .getDefinition(name);
128: if (null == definition) {
129: throw new ConfigurationException(new Message(
130: "ITEM_NOT_DEFINED_EXC", BUNDLE, name));
131: }
132:
133: // use model to validate value
134: Object defaultValue = definition.getDefaultValue();
135: if (defaultValue != null
136: && !defaultValue.getClass().isAssignableFrom(
137: value.getClass())) {
138: QName type = model.getDefinition(name).getType();
139: throw new ConfigurationException(new Message(
140: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
141: }
142:
143: // TODO: check if property can be modified at all:
144: // if it is static, report an error, if it is process or bus accept the change but log a
145: // warning informing the user that the change will take effect only after next bus
146: // or process restart
147:
148: // try all registered providers in turn to find one that accepts the change
149: boolean accepted = false;
150:
151: for (ConfigurationProvider provider : providers) {
152: if (provider.setObject(name, value)) {
153: accepted = true;
154: break;
155: }
156: }
157:
158: if (accepted) {
159: reconfigure(name);
160: }
161: return accepted;
162: }
163:
164: public boolean save() {
165: boolean accepted = false;
166:
167: //TODO:We need to persist all beans into one config file.
168:
169: for (ConfigurationProvider provider : providers) {
170: if (provider.save()) {
171: accepted = true;
172: break;
173: }
174: }
175: return accepted;
176: }
177:
178: public boolean getBoolean(String name) {
179: Object obj = getObject(name);
180: if (null == obj) {
181: throw new ConfigurationException(new Message(
182: "ITEM_NO_VALUE_EXC", BUNDLE, name));
183: }
184: try {
185: return ((Boolean) obj).booleanValue();
186: } catch (ClassCastException ex) {
187: QName type = model.getDefinition(name).getType();
188: throw new ConfigurationException(new Message(
189: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
190: }
191: }
192:
193: public boolean setBoolean(String name, boolean value) {
194: return setObject(name, Boolean.valueOf(value));
195: }
196:
197: public short getShort(String name) {
198: Object obj = getObject(name);
199: if (null == obj) {
200: throw new ConfigurationException(new Message(
201: "ITEM_NO_VALUE_EXC", BUNDLE, name));
202: }
203: try {
204: return ((Short) obj).shortValue();
205: } catch (ClassCastException ex) {
206: QName type = model.getDefinition(name).getType();
207: throw new ConfigurationException(new Message(
208: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
209: }
210: }
211:
212: public boolean setShort(String name, short value) {
213: return setObject(name, new Short(value));
214: }
215:
216: public int getInt(String name) {
217: Object obj = getObject(name);
218: if (null == obj) {
219: throw new ConfigurationException(new Message(
220: "ITEM_NO_VALUE_EXC", BUNDLE, name));
221: }
222: try {
223: return ((Integer) obj).intValue();
224: } catch (ClassCastException ex) {
225: QName type = model.getDefinition(name).getType();
226: throw new ConfigurationException(new Message(
227: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
228: }
229: }
230:
231: public boolean setInt(String name, int value) {
232: return setObject(name, new Integer(value));
233: }
234:
235: public float getFloat(String name) {
236: Object obj = getObject(name);
237: if (null == obj) {
238: throw new ConfigurationException(new Message(
239: "ITEM_NO_VALUE_EXC", BUNDLE, name));
240: }
241: try {
242: return ((Float) obj).floatValue();
243: } catch (ClassCastException ex) {
244: QName type = model.getDefinition(name).getType();
245: throw new ConfigurationException(new Message(
246: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
247: }
248: }
249:
250: public boolean setFloat(String name, float value) {
251: return setObject(name, new Float(value));
252: }
253:
254: public double getDouble(String name) {
255: Object obj = getObject(name);
256: if (null == obj) {
257: throw new ConfigurationException(new Message(
258: "ITEM_NO_VALUE_EXC", BUNDLE, name));
259: }
260: try {
261: return ((Double) obj).doubleValue();
262: } catch (ClassCastException ex) {
263: QName type = model.getDefinition(name).getType();
264: throw new ConfigurationException(new Message(
265: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
266: }
267: }
268:
269: public boolean setDouble(String name, double value) {
270: return setObject(name, new Double(value));
271: }
272:
273: public long getLong(String name) {
274: Object obj = getObject(name);
275: if (null == obj) {
276: throw new ConfigurationException(new Message(
277: "ITEM_NO_VALUE_EXC", BUNDLE, name));
278: }
279: try {
280: return ((Long) obj).longValue();
281: } catch (ClassCastException ex) {
282: QName type = model.getDefinition(name).getType();
283: throw new ConfigurationException(new Message(
284: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
285: }
286: }
287:
288: public boolean setLong(String name, long value) {
289: return setObject(name, new Long(value));
290: }
291:
292: public String getString(String name) {
293: Object obj = getObject(name);
294: if (null == obj) {
295: throw new ConfigurationException(new Message(
296: "ITEM_NO_VALUE_EXC", BUNDLE, name));
297: }
298: if (!(obj instanceof String)) {
299: QName type = model.getDefinition(name).getType();
300: throw new ConfigurationException(new Message(
301: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
302: }
303: return (String) obj;
304: }
305:
306: public boolean setString(String name, String value) {
307: return setObject(name, (String) value);
308: }
309:
310: @SuppressWarnings("unchecked")
311: public List<String> getStringList(String name) {
312: Object obj = getObject(name);
313: if (null == obj) {
314: throw new ConfigurationException(new Message(
315: "ITEM_NO_VALUE_EXC", BUNDLE, name));
316: }
317: try {
318: Method method = obj.getClass().getMethod("getItem",
319: new Class[0]);
320: obj = method.invoke(obj, new Object[0]);
321:
322: return (List<String>) obj;
323: } catch (ClassCastException ex) {
324: QName type = model.getDefinition(name).getType();
325: throw new ConfigurationException(new Message(
326: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
327: } catch (NoSuchMethodException e) {
328: QName type = model.getDefinition(name).getType();
329: throw new ConfigurationException(new Message(
330: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
331: } catch (IllegalAccessException e) {
332: QName type = model.getDefinition(name).getType();
333: throw new ConfigurationException(new Message(
334: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
335: } catch (InvocationTargetException e) {
336: QName type = model.getDefinition(name).getType();
337: throw new ConfigurationException(new Message(
338: "ITEM_TYPE_MISMATCH_EXC", BUNDLE, name, type));
339: }
340: }
341:
342: protected Object getLocal(Configuration c, String name) {
343: if (null == providers) {
344: return null;
345: }
346: Object obj;
347: for (ConfigurationProvider provider : providers) {
348: obj = provider.getObject(name);
349: if (null != obj) {
350: return obj;
351: }
352: }
353: return null;
354: }
355:
356: public final Configurator getConfigurator() {
357: return configurator;
358: }
359:
360: public void reconfigure(String name) {
361: //Do nothing
362: }
363: }
|