001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019:
020: package de.schlund.pfixcore.workflow;
021:
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.Map;
027:
028: import org.apache.log4j.Logger;
029:
030: import de.schlund.pfixcore.exception.PustefixApplicationException;
031: import de.schlund.pfixcore.exception.PustefixCoreException;
032: import de.schlund.pfixcore.exception.PustefixRuntimeException;
033: import de.schlund.pfixxml.config.ContextConfig;
034: import de.schlund.pfixxml.config.ContextResourceConfig;
035:
036: /**
037: * Implements the ability to store objects implementing a number of interfaces extending
038: * the ContextResource interface
039: *
040: * @author jtl, thomas
041: *
042: */
043:
044: public class ContextResourceManagerImpl implements
045: ContextResourceManager {
046: private final static Logger LOG = Logger
047: .getLogger(ContextResourceManagerImpl.class);
048: private HashMap<String, ContextResource> resources = new HashMap<String, ContextResource>();
049:
050: /**
051: * Instanciates the objects and registers the interfaces which
052: * should be used from each.
053: *
054: * In general such an object implements a number of interfaces extending
055: * the ContextResource interface. You are able to specify the classes
056: * you want to instanciate and to specify which interfaces you want to
057: * use from such an object.
058: *
059: * The configuration is done by passing properties, each object you want
060: * to use must be specified in a single property.
061: * <br>
062: * The name of this property consists of the prefix
063: * <code>context.resource.[A_NUMBER].</code> followed by the
064: * full qualified classname of the class.
065: * <br>
066: * The value of the property specifies the interfaces you want to use
067: * from this object. All interfaces are declared by the full qualified
068: * classname of the interface and separated by a comma.
069: * <br>
070: * An wrong example:<br>
071: * <code>context.rescoure.1.de.foo.FooImpl = Foo</code><br>
072: * <code>context.rescoure.2.de.foo.FooAndBarAndBazImpl = Foo,Bar,Baz</code>
073: *
074: * This example, written as above, would be invalid as no two ContextRessources
075: * are allowed to act as an implementation for the same interface(Foo in this case).
076: * Note that the classes may implement the same interface, they are just not allowed to act as
077: * an implementation for the same interface in a ContextRessource declaration.
078: *
079: * The correct example could be:<br>
080: * <code>context.rescoure.1.de.foo.FooImpl = Foo</code><br>
081: * <code>context.rescoure.2.de.foo.FooAndBarAndBazImpl = Bar,Baz</code>
082: *
083: * which is correct without any change in the code of the implementing classes.
084: * @throws PustefixApplicationException
085: * @throws PustefixCoreException
086: *
087: */
088:
089: public void init(Context context, ContextConfig config)
090: throws PustefixApplicationException, PustefixCoreException {
091: LOG.debug("initialize ContextResources...");
092:
093: Collection<ContextResource> resourcesToInitialize = new ArrayList<ContextResource>();
094: Map<String, ContextResource> resourceClassToInstance = new HashMap<String, ContextResource>();
095:
096: for (ContextResourceConfig resourceConfig : config
097: .getContextResourceConfigs()) {
098: ContextResource cr = null;
099: String classname = resourceConfig.getContextResourceClass()
100: .getName();
101: try {
102: LOG.debug("Creating object with name [" + classname
103: + "]");
104: cr = (ContextResource) resourceConfig
105: .getContextResourceClass().newInstance();
106: } catch (InstantiationException e) {
107: throw new PustefixRuntimeException(
108: "Exception while creating object " + classname
109: + ":" + e);
110: } catch (IllegalAccessException e) {
111: throw new PustefixRuntimeException(
112: "Exception while creating object " + classname
113: + ":" + e);
114: }
115:
116: resourcesToInitialize.add(cr);
117: resourceClassToInstance.put(cr.getClass().getName(), cr);
118: }
119:
120: Map<Class<? extends ContextResource>, ? extends ContextResourceConfig> interfaces = config
121: .getInterfaceToContextResourceMap();
122: for (Class<? extends ContextResource> clazz : interfaces
123: .keySet()) {
124: String interfacename = clazz.getName();
125: String resourceclass = interfaces.get(clazz)
126: .getContextResourceClass().getName();
127: ContextResource cr = resourceClassToInstance
128: .get(resourceclass);
129: checkInterface(cr, interfacename);
130: LOG.debug("* Registering [" + cr.getClass().getName()
131: + "] for interface [" + interfacename + "]");
132: resources.put(interfacename, cr);
133: }
134:
135: for (Iterator<ContextResource> i = resourcesToInitialize
136: .iterator(); i.hasNext();) {
137: ContextResource resource = i.next();
138: try {
139: resource.init(context);
140: } catch (Exception e) {
141: throw new PustefixApplicationException(
142: "Exception while initializing context resource "
143: + resource.getClass(), e);
144: }
145: }
146:
147: }
148:
149: /* (non-Javadoc)
150: * @see de.schlund.pfixcore.workflow.ContextResourceManager#getResource(java.lang.String)
151: */
152: public ContextResource getResource(String name) {
153: return (ContextResource) resources.get(name);
154: }
155:
156: /* (non-Javadoc)
157: * @see de.schlund.pfixcore.workflow.ContextResourceManager#getResource(java.lang.Class)
158: */
159: @SuppressWarnings("unchecked")
160: public <T extends ContextResource> T getResource(Class<T> clazz) {
161: return (T) resources.get(clazz.getName());
162: }
163:
164: private void checkInterface(Object obj, String interfacename)
165: throws PustefixCoreException {
166: Class<?> wantedinterface = null;
167:
168: // Get the class of the requested interface and get all
169: // implemented interfaces of the object
170: try {
171: wantedinterface = Class.forName(interfacename);
172: } catch (ClassNotFoundException e) {
173: throw new PustefixRuntimeException(
174: "Got ClassNotFoundException for classname "
175: + interfacename
176: + "while checking for interface");
177: }
178:
179: LOG.debug("Check if requested interface [" + interfacename
180: + "] is implemented by [" + obj.getClass().getName()
181: + "]");
182:
183: // Check for all implemented interfaces, if it equals the interface that
184: // we want, than break.
185:
186: if (wantedinterface.isInstance(obj)) {
187: LOG.debug("Got requested interface " + interfacename);
188: } else {
189: // Uh, the requested interface is not implemented by the
190: // object, that's not nice!
191: throw new PustefixCoreException("The class ["
192: + obj.getClass().getName()
193: + "] doesn't implemented requested interface "
194: + interfacename);
195: }
196:
197: // Now check if the interface is already registered...
198: if (resources.containsKey(interfacename)) {
199: throw new PustefixCoreException("Interface ["
200: + interfacename
201: + "] already registered for instance of ["
202: + resources.get(interfacename).getClass().getName()
203: + "]");
204: }
205: }
206:
207: /* (non-Javadoc)
208: * @see de.schlund.pfixcore.workflow.ContextResourceManager#getResourceIterator()
209: */
210: public Iterator<ContextResource> getResourceIterator() {
211: return resources.values().iterator();
212: }
213:
214: }
|