001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.bpel.debugger.bdiclient.impl;
021:
022: import java.util.Hashtable;
023: import java.util.logging.Logger;
024: import org.netbeans.modules.bpel.debugger.BpelDebuggerImpl;
025: import org.netbeans.modules.bpel.debugger.api.DebugException;
026: import org.netbeans.modules.bpel.debuggerbdi.rmi.api.BPELDebugger;
027: import org.netbeans.modules.bpel.debuggerbdi.rmi.api.DebugListener;
028: import org.netbeans.modules.bpel.debuggerbdi.rmi.wp.ObjectAdapter;
029: import org.netbeans.modules.bpel.debuggerbdi.rmi.wp.RMIClient;
030: import org.netbeans.modules.bpel.debuggerbdi.rmi.wp.RMIServer;
031: import org.netbeans.modules.bpel.debuggerbdi.rmi.wp.RMIService;
032: import org.netbeans.modules.bpel.debuggerbdi.rmi.wp.RMIServiceFactory;
033:
034: /**
035: * Connector implementation for the Alaska BPEL debugger client.
036: * The connector opens and closes the network connection and handles
037: * creation of the controller implementation.
038: *
039: * @author Sun Microsystems
040: */
041: public class BDIDebugConnector {
042:
043: private static Logger LOGGER = Logger
044: .getLogger(BDIDebugConnector.class.getName());
045:
046: private static Hashtable<String, BDIDebugConnector> allConnectors = new Hashtable<String, BDIDebugConnector>();
047:
048: public synchronized static BDIDebugConnector getDebugConnector(
049: final String host, final int port) {
050: return allConnectors.get(host + ":" + port);
051: }
052:
053: ////////////////////////////////////////////////////////////////////////////
054: // Instance
055: private boolean mIsInitialized;
056: private boolean mIsAttached;
057: private RMIService mRmiService;
058: private ObjectAdapter mObjectAdapter;
059: private RMIServer mRmiServer;
060: private Thread mServerThread;
061: private DebugListener mListener;
062: private BDIDebugger mBDIDebugger;
063: private DebugListener mLocalListener;
064: private String mHost;
065: private int mPort;
066: private Exception mException;
067:
068: private final BpelDebuggerImpl mDebugger;
069:
070: public BDIDebugConnector(BpelDebuggerImpl debugger) {
071: mDebugger = debugger;
072: initializeConnectivity();
073: mLocalListener = new ClientDebuggerListenerStub();
074: }
075:
076: private void initializeConnectivity() {
077: try {
078: // Perform this initialization only once.
079: // Though class names include the "RMI" name,
080: // a simulated type of RMI is being used (i.e. not java.rmi).
081: mRmiService = getRMIService();
082: mRmiServer = mRmiService.createServer(0);
083: mObjectAdapter = mRmiServer.createObjectAdapter("root");
084: mRmiServer.setDefaultAdaptor(mObjectAdapter);
085: mObjectAdapter.start();
086: mServerThread = new Thread(mRmiServer);
087: mServerThread.start();
088: mIsInitialized = true;
089: } catch (Exception e) {
090: mException = e;
091: }
092: }
093:
094: public boolean isInitialized() {
095: return mIsInitialized;
096: }
097:
098: public Exception getException() {
099: return mException;
100: }
101:
102: public void attach(final String host, final int port) {
103: mHost = host;
104: mPort = port;
105: mBDIDebugger = new BDIDebugger(mDebugger);
106: final BDIDebugConnector bdiconnector = this ;
107:
108: try {
109: RMIClient cli = mRmiService.createClient(host, port);
110: cli.setObjectAdapter(mObjectAdapter);
111: LOGGER.info("Trying to connect to " + host + ":" + port);
112: mListener = (DebugListener) cli.importObject(
113: DebugListener.class, "root", "debugListener");
114:
115: BPELDebugger proxyForDebugger = (BPELDebugger) mObjectAdapter
116: .exportObject("foo", mBDIDebugger);
117: mLocalListener.setDebugger(proxyForDebugger);
118: mObjectAdapter.registerListerner(mLocalListener);
119: mListener.setDebugger(proxyForDebugger);
120:
121: mIsAttached = true;
122: synchronized (allConnectors) {
123: allConnectors.put(host + ":" + port, bdiconnector);
124: }
125:
126: } catch (Exception exc) {
127: mIsAttached = false;
128: mException = exc;
129: }
130: }
131:
132: public boolean isAttached() {
133: return mIsAttached;
134: }
135:
136: public void detach() {
137: if (!mIsAttached) {
138: return;
139: }
140:
141: mIsAttached = false;
142:
143: try {
144: mListener.setDebugger(null);
145:
146: if (mRmiServer != null) {
147: mRmiServer.closeClients();
148: }
149:
150: if (mServerThread != null) {
151: mServerThread.interrupt();
152: }
153:
154: if (mRmiServer != null) {
155: mRmiServer.destroy();
156: }
157:
158: if (mRmiService != null) {
159: mRmiService.destroy();
160: }
161:
162: if (mObjectAdapter != null) {
163: mObjectAdapter.destroy();
164: }
165:
166: synchronized (allConnectors) {
167: allConnectors.remove(mHost + ":" + mPort);
168: }
169: } catch (Exception e) {
170: mDebugger.setException(new DebugException(e));
171: }
172:
173: mServerThread = null;
174: mRmiServer = null;
175: mRmiService = null;
176: mObjectAdapter = null;
177: mBDIDebugger = null;
178: }
179:
180: public BDIDebugger getBDIDebugger() {
181: return mBDIDebugger;
182: }
183:
184: private RMIService getRMIService() {
185: try {
186: RMIServiceFactory factory = (RMIServiceFactory) getClass()
187: .getClassLoader()
188: .loadClass(
189: "org.netbeans.modules.bpel.debuggerbdi.rmi.wp.impl.DefaultRMIServiceFactory")
190: .newInstance();
191: return factory
192: .createRMIService(getClass().getClassLoader());
193: } catch (Exception e) {
194: e.printStackTrace();
195: LOGGER.warning("Exception in getRMIService:\n" + e);
196: return null;
197: }
198: }
199:
200: ////////////////////////////////////////////////////////////////////////////
201: // Inner Classes
202: class ClientDebuggerListenerStub implements DebugListener {
203: private BPELDebugger bpDebugger = null;
204:
205: public void setDebugger(BPELDebugger debugger) {
206: bpDebugger = debugger;
207: }
208:
209: public void socketClosed(Object arg0) {
210: if (bpDebugger != null) {
211: // Supposedly any kind of exception can be thrown from this
212: // invocation. Since this operation is kind of a clean-up one
213: // we should merely catch them (to avoid showing it to the
214: // user) and log.
215: try {
216: bpDebugger.detach();
217: } catch (Exception e) {
218: LOGGER
219: .warning("Exception in "
220: + "ClientDebuggerListernStub.socketClosed:\n"
221: + e);
222: }
223: }
224: }
225: }
226: }
|