001: /*
002: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License version
007: * 2 only, as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License version 2 for more details (a copy is
013: * included at /legal/license.txt).
014: *
015: * You should have received a copy of the GNU General Public License
016: * version 2 along with this work; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018: * 02110-1301 USA
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021: * Clara, CA 95054 or visit www.sun.com if you need additional
022: * information or have any questions.
023: */
024:
025: package com.sun.jumpimpl.process;
026:
027: import com.sun.jump.executive.JUMPIsolateProxy;
028: import com.sun.jump.common.JUMPWindow;
029: import com.sun.jump.common.JUMPApplication;
030: import com.sun.jump.command.JUMPResponse;
031: import com.sun.jump.command.JUMPExecutiveLifecycleRequest;
032: import com.sun.jumpimpl.process.JUMPProcessProxyImpl;
033:
034: import com.sun.jump.executive.JUMPExecutive;
035: import com.sun.jump.executive.JUMPApplicationProxy;
036: import com.sun.jump.command.JUMPIsolateLifecycleRequest;
037: import java.util.HashMap;
038: import java.util.HashSet;
039:
040: public class JUMPIsolateProxyImpl extends JUMPProcessProxyImpl
041: implements JUMPIsolateProxy {
042: // FIXME: Timeout values should be centralized somewhere
043: private static final long DEFAULT_TIMEOUT = 5000L;
044: private int isolateId;
045: private RequestSenderHelper requestSender;
046: private HashMap appIDHash = null;
047: private HashSet windows;
048: //
049: // Isolate state
050: //
051: private int state = 0;
052:
053: /**
054: * Wait for the isolate to reach a target state
055: * FIXME: This should probably return a boolean indicating
056: * whether target state was reached.
057: */
058: public synchronized void waitForState(int targetState, long timeout) {
059: long time = System.currentTimeMillis();
060:
061: while (state < targetState) {
062: try {
063: wait(timeout);
064: if (state < targetState) {
065: System.err.println("Timed out waiting for "
066: + "target state=" + targetState);
067: return;
068: }
069: } catch (Exception e) {
070: e.printStackTrace();
071: return;
072: }
073: }
074: }
075:
076: //
077: // A constructor. This instance is to be constructed after the isolate
078: // process is created. This proxy represents that isolate.
079: //
080: public JUMPIsolateProxyImpl(int pid) {
081: super (pid);
082: isolateId = pid;
083: requestSender = new RequestSenderHelper(JUMPExecutive
084: .getInstance());
085: setIsolateState(JUMPIsolateLifecycleRequest.ISOLATE_STATE_CREATED);
086: appIDHash = new HashMap();
087: }
088:
089: public static JUMPIsolateProxyImpl registerIsolate(int pid) {
090: //
091: // Synchronize on the JUMPProcessProxyImpl class which does
092: // process instance registration.
093: //
094: synchronized (JUMPProcessProxyImpl.class) {
095: JUMPIsolateProxyImpl ipi = getRegisteredIsolate(pid);
096: if (ipi == null) {
097: // The constructor registers the instance as well.
098: return new JUMPIsolateProxyImpl(pid);
099: } else {
100: return ipi;
101: }
102: }
103: }
104:
105: public static JUMPIsolateProxyImpl getRegisteredIsolate(int pid) {
106: //
107: // Synchronize on the JUMPProcessProxyImpl class which does
108: // process instance registration.
109: //
110: synchronized (JUMPProcessProxyImpl.class) {
111: JUMPProcessProxyImpl ppi = JUMPProcessProxyImpl
112: .getProcessProxyImpl(pid);
113: if ((ppi != null) && (ppi instanceof JUMPIsolateProxyImpl)) {
114: return (JUMPIsolateProxyImpl) ppi;
115: } else {
116: return null;
117: }
118: }
119: }
120:
121: /**
122: * Set isolate state to a new state, and notify all listeners
123: */
124: public synchronized void setIsolateState(int state) {
125: this .state = state;
126: notifyAll();
127: }
128:
129: /**
130: * Return last known state in isolate.
131: */
132: public synchronized int getIsolateState() {
133: return this .state;
134: }
135:
136: public JUMPApplicationProxy startApp(JUMPApplication app,
137: String[] args) {
138: if (isAlive()) {
139: int appID = requestSender.sendRequestWithIntegerResponse(
140: this , new JUMPExecutiveLifecycleRequest(
141: JUMPExecutiveLifecycleRequest.ID_START_APP,
142: app.toByteArray(), args));
143:
144: if (appID == -1) { // failure
145: return null;
146: }
147:
148: JUMPApplicationProxy appProxy = new JUMPApplicationProxyImpl(
149: app, appID, this );
150: appIDHash.put(new Integer(appID), appProxy);
151: setIsolateState(JUMPIsolateLifecycleRequest.ISOLATE_STATE_RUNNING);
152:
153: return appProxy;
154: }
155:
156: return null;
157: }
158:
159: public JUMPApplicationProxy[] getApps() {
160: Object obj[];
161: synchronized (this ) {
162: obj = appIDHash.values().toArray();
163: }
164: JUMPApplicationProxy appProxy[] = new JUMPApplicationProxy[obj.length];
165: for (int i = 0; i < obj.length; i++) {
166: appProxy[i] = (JUMPApplicationProxy) obj[i];
167: }
168: return appProxy;
169: }
170:
171: public JUMPWindow[] getWindows() {
172: synchronized (this ) {
173: if (windows == null || windows.size() == 0) {
174: return null;
175: }
176: return (JUMPWindow[]) windows.toArray(new JUMPWindow[] {});
177: }
178: }
179:
180: public int getIsolateId() {
181: return isolateId;
182: }
183:
184: public void kill(boolean force) {
185: if (isAlive()) {
186: setStateToDestroyed();
187: JUMPResponse response = requestSender
188: .sendRequest(
189: this ,
190: new JUMPExecutiveLifecycleRequest(
191: JUMPExecutiveLifecycleRequest.ID_DESTROY_ISOLATE,
192: new String[] { Boolean
193: .toString(force) }));
194: requestSender.handleBooleanResponse(response);
195: }
196: }
197:
198: RequestSenderHelper getRequestSender() {
199: return requestSender;
200: }
201:
202: /**
203: * Sets this IsolateProxy to the destroyed state and
204: * perform all the data cleanup.
205: */
206: public void setStateToDestroyed() {
207: setIsolateState(JUMPIsolateLifecycleRequest.ISOLATE_STATE_DESTROYED);
208: appIDHash.clear();
209: }
210:
211: /**
212: * Return true if this IsolateProxy represents a created and
213: * not yet destroyed Isolate.
214: */
215: public boolean isAlive() {
216: int state = getIsolateState();
217: switch (state) {
218: case JUMPIsolateLifecycleRequest.ISOLATE_STATE_CREATED:
219: case JUMPIsolateLifecycleRequest.ISOLATE_STATE_INITIALIZED:
220: case JUMPIsolateLifecycleRequest.ISOLATE_STATE_RUNNING:
221: return true;
222: }
223: return false;
224: }
225:
226: public void registerWindow(JUMPWindow w) {
227: if (w == null || w.getIsolate() != this ) {
228: throw new IllegalStateException();
229: }
230:
231: synchronized (this ) {
232: if (windows == null) {
233: windows = new HashSet();
234: }
235: windows.add(w);
236: }
237: }
238: }
|