001: /*
002: * Coefficient - facilitates project based collaboration
003: * Copyright (C) 2003, Dylan Etkin, CSIR icomtek
004: * PO Box 395
005: * Pretoria 0001, RSA
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package za.org.coefficient.util.common;
021:
022: import org.apache.commons.beanutils.MethodUtils;
023:
024: import za.org.coefficient.exception.ConfigurationException;
025: import za.org.coefficient.interfaces.Invoker;
026: import za.org.coefficient.core.Constants;
027:
028: /**
029: * This is used to get a handle on an object capable of providing us with
030: * a module invoker
031: */
032: public class InvokerFactory {
033:
034: public static boolean RUN_AS_EJB = true;
035:
036: private static String INVOKER_LOCAL_EJB_IMPLEMENTATION = "za.org.coefficient.invokers.ejb.EjbInvoker";
037: private static String INVOKER_LOCAL_WEBAPP_IMPLEMENTATION = "za.org.coefficient.invokers.webapp.WebAppInvoker";
038: private static String INVOKER_REMOTE_EJB_IMPLEMENTATION = "za.org.coefficient.invokers.ejb.interfaces.EjbInvokerFacadeHome";
039: private static String INVOKER_REMOTE_EJB_JNDI_NAME = "za/org/coefficient/util/EjbInvokerFacade";
040: private static final String CREATE = "create";
041:
042: private static Invoker local_mi = null;
043: private static Object remote_mi = null;
044: private static Object lock = new Object();
045:
046: static {
047: init();
048: }
049:
050: public static Invoker getInvoker() throws Exception {
051: Class cls = null;
052: try {
053: if (RUN_AS_EJB) {
054: cls = Class.forName(INVOKER_LOCAL_EJB_IMPLEMENTATION);
055: } else {
056: cls = Class
057: .forName(INVOKER_LOCAL_WEBAPP_IMPLEMENTATION);
058: }
059: } catch (Exception e) {
060: throw new Exception(
061: "The implementation provided to create a Module Invoker is not on the classpath");
062: }
063:
064: // don't let anyone change the reference out from under another thread
065: synchronized (lock) {
066:
067: // Check to make sure the invoker impl hasn't changed
068: // out from under us
069: if (local_mi == null || !(local_mi.getClass().equals(cls))) {
070: try {
071: Object obj = cls.newInstance();
072: if (obj instanceof Invoker) {
073: local_mi = (Invoker) obj;
074: return (Invoker) obj;
075: } else {
076: throw new Exception(
077: "The implementation provided to create a Module Invoker, "
078: + cls.getName()
079: + " is not of type Invoker");
080: }
081: } catch (Exception e) {
082: throw new Exception("Unable to instantiate: "
083: + cls.getName());
084: }
085: } else {
086: return local_mi;
087: }
088: }
089: }
090:
091: /**
092: * This should be used by objects that are separated by a remote boundary.
093: * You should also recognize that the parameters passed into a remote call
094: * will be passed by value and not by reference. In the case of a module
095: * invocation this means that the CoefficientContext that is sent across
096: * and modified will not be modified by reference. Therefore you should set
097: * your reference to the context to the returned value so that all changes
098: * will be propagated back across the remote boundary.
099: */
100: public static Invoker getRemoteInvoker() throws Exception {
101: if (RUN_AS_EJB) {
102: if (remote_mi == null) {
103: javax.naming.InitialContext initialContext = new javax.naming.InitialContext();
104: try {
105: java.lang.Object objRef = initialContext
106: .lookup(INVOKER_REMOTE_EJB_JNDI_NAME);
107: remote_mi = javax.rmi.PortableRemoteObject
108: .narrow(
109: objRef,
110: Class
111: .forName(INVOKER_REMOTE_EJB_IMPLEMENTATION));
112: } finally {
113: initialContext.close();
114: }
115: }
116: Object modInvoker = MethodUtils.invokeMethod(remote_mi,
117: CREATE, null);
118: if (modInvoker != null && modInvoker instanceof Invoker) {
119: return (Invoker) modInvoker;
120: } else {
121: throw new ConfigurationException(
122: "Unable to create a remote module invoker");
123: }
124: } else {
125: return getInvoker();
126: }
127: }
128:
129: private static void init() {
130: try {
131: Class.forName(INVOKER_LOCAL_EJB_IMPLEMENTATION);
132: } catch (ClassNotFoundException cnfe) {
133: RUN_AS_EJB = false;
134: }
135: }
136:
137: }
|