001: /*--
002:
003: Copyright (C) 2002-2005 Adrian Price.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The names "OBE" and "Open Business Engine" must not be used to
019: endorse or promote products derived from this software without prior
020: written permission. For written permission, please contact
021: adrianprice@sourceforge.net.
022:
023: 4. Products derived from this software may not be called "OBE" or
024: "Open Business Engine", nor may "OBE" or "Open Business Engine"
025: appear in their name, without prior written permission from
026: Adrian Price (adrianprice@users.sourceforge.net).
027:
028: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
029: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
030: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
032: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
034: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
035: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
036: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
037: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
038: POSSIBILITY OF SUCH DAMAGE.
039:
040: For more information on OBE, please see
041: <http://obe.sourceforge.net/>.
042:
043: */
044:
045: package org.obe.client.api;
046:
047: import org.obe.util.CommonConfig;
048: import org.wfmc.wapi.WMWorkflowException;
049:
050: import java.util.HashMap;
051: import java.util.Map;
052:
053: /**
054: * Factory class to support pluggable client implementations. As standard,
055: * <a href="rmi/LocalClient.html">local</a>,
056: * <a href="rmi/J2EELocalClient.html">j2ee-local</a>,
057: * <a href="rmi/J2EERemoteClient.html">rmi</a> and
058: * <a href="xmlrpc/WMXmlRpcClient.html">xml-rpc</a> are supported.
059: *
060: * @author Adrian Price
061: */
062: public final class WMClientFactory {
063: private static final String LOCAL_CLASS_NAME = "org.obe.client.api.local.LocalClient";
064: private static final String J2EE_LOCAL_CLASS_NAME = "org.obe.client.api.local.J2EELocalClient";
065: private static final String RMI_CLASS_NAME = "org.obe.client.api.rmi.J2EERemoteClient";
066: private static final String XML_RPC_CLASS_NAME = "org.obe.client.api.xmlrpc.WMXmlRpcClient";
067: /**
068: * Represents a standard, local Java interface.
069: */
070: public static final String LOCAL = "local";
071: /**
072: * Represents a standard, local J2EE interface.
073: */
074: public static final String J2EE_LOCAL = "j2ee-local";
075: /**
076: * Represents the standard RMI remote protocol.
077: */
078: public static final String RMI = "rmi";
079: /**
080: * Represents the XML-RPC protocol. The default implementation uses the
081: * Apache XML-RPC libraries.
082: */
083: public static final String XML_RPC = "xml-rpc";
084: private static final Map CLIENT_CLASSES = new HashMap();
085:
086: static {
087: registerClientClass(LOCAL, LOCAL_CLASS_NAME);
088: registerClientClass(J2EE_LOCAL, J2EE_LOCAL_CLASS_NAME);
089: registerClientClass(RMI, RMI_CLASS_NAME);
090: registerClientClass(XML_RPC, XML_RPC_CLASS_NAME);
091: }
092:
093: // Prevent instantiation.
094: private WMClientFactory() {
095: }
096:
097: /**
098: * Creates a client instance using the default protocol. The default
099: * protocol is "local", but can be overridden by setting the configuration
100: * property <code>obe.client.protocol</code>.
101: *
102: * @return A client instance.
103: * @throws WMWorkflowException if an exception occurred when instantiating
104: * the client.
105: * @throws IllegalArgumentException if the protocol name is invalid.
106: */
107: public static WMClient createClient() throws WMWorkflowException {
108: String protocol = CommonConfig.getProtocol();
109: return createClient(protocol);
110: }
111:
112: /**
113: * Creates a client instance for the specified protocol.
114: *
115: * @param protocol The protocol name, one of: {@link #LOCAL},
116: * {@link #J2EE_LOCAL}, {@link #RMI}, {@link #XML_RPC}, or some
117: * implementation that was registered by a prior call to
118: * {@link #registerClientClass}.
119: * @return A client instance.
120: * @throws WMWorkflowException if an exception occurred when instantiating
121: * the client.
122: * @throws IllegalArgumentException if the protocol name is invalid, or if
123: * the registered class is not a valid WMClient implementation.
124: */
125: public static WMClient createClient(String protocol)
126: throws WMWorkflowException {
127:
128: try {
129: // Ensure the class is registered.
130: String clientClass = (String) CLIENT_CLASSES.get(protocol);
131: if (clientClass == null)
132: throw new IllegalArgumentException(protocol);
133:
134: // Client class must implement interface WMClient.
135: Class clazz = Class.forName(clientClass);
136: if (!WMClient.class.isAssignableFrom(clazz)) {
137: throw new IllegalArgumentException("The class "
138: + clientClass
139: + " must implement the interface "
140: + WMClient.class.getName());
141: }
142:
143: // Instantiate it.
144: return (WMClient) clazz.newInstance();
145: } catch (ClassNotFoundException e) {
146: throw new IllegalArgumentException(protocol);
147: } catch (InstantiationException e) {
148: throw new WMWorkflowException(e);
149: } catch (IllegalAccessException e) {
150: throw new WMWorkflowException(e);
151: }
152: }
153:
154: /**
155: * Registers a <code>WMClient</code> implementation for the specified
156: * protocol.
157: *
158: * @param protocol The protocol name.
159: * @param clientClass The fully qualified name of the implementing class,
160: * which must implement {@link WMClient} and have a public,
161: * no-args constructor.
162: */
163: public static void registerClientClass(String protocol,
164: String clientClass) {
165:
166: if (protocol == null || clientClass == null) {
167: throw new IllegalArgumentException(
168: "protocol and clientClass must both be non-null.");
169: }
170:
171: CLIENT_CLASSES.put(protocol, clientClass);
172: }
173: }
|