//
// This file is part of the prose package.
//
// The contents of this file are subject to the Mozilla Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is prose.
//
// The Initial Developer of the Original Code is Andrei Popovici. Portions
// created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
// All Rights Reserved.
//
// Contributor(s):
// $Id: RemoteProseComponent.java,v 1.4 2008/11/18 11:43:39 anicoara Exp $
// =====================================================================
//
package ch.ethz.prose.tools;
// used packages
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import ch.ethz.prose.SystemStartupException;
import ch.ethz.prose.SystemTeardownException;
/**
* Class RemoteExtensionSystem starts up a remote service (a
* <code>RemoteExtensionManager</code>) for the insertion of
* extensions.
*
* <p>
* The current implementation uses a <code>RemoteExtensionManagerImpl</code>.
* <p>
*
* Note that for starting the remote extension system you will have to add
* a property like:
* <code>ch.ethz.prose.ESSystem.X=ch.ethz.prose.tools.RemoteExtensionSystem</code>
* to the System's properties.
*
* The property <code>prose.port</code> defines the port to start prose on.
*
* @version $Revision: 1.4 $
* @author Andrei Popovici
*/
public class RemoteProseComponent {
protected static String ACTIVE_INSTANCE = "activeInstance";
protected static String TEST_INSTANCE = "testInstance";
private static boolean systemUp = false;
private static RemoteAspectManager activeInstance = null;
private static RemoteAspectManager testInstance = null;
private static Remote activeInstanceRef = null;
private static Remote testInstanceRef = null;
private static ServerSocket listener = null;
/**
* Create and export an instance of <code>RemoteExtnesionManager</code>
* <p>
* <em>Note: this method is idempotent. Successive calls have the same
* effect as just one.</em>
*
* @exception SystemStartupException could not successfully start the
* remote extension manager.
*/
public synchronized static void startup() throws SystemStartupException {
if (systemUp)
return;
systemUp = true;
System.setSecurityManager(new java.rmi.RMISecurityManager());
// ATENTION!
// Comment because the JVM 1.4.1. blocks. To avoid this deadlock, now first starts "RemoteProseComponent" and then "ProseSystem".
// make sure that prose runs
// ProseSystem.startup();
int portNumber = -1;
try {
portNumber = Integer.parseInt(System.getProperty("prose.port","UNDEFINED"));
}
catch (NumberFormatException noPortWasSpecified) {
throw new SystemStartupException("To use prose Remotely please specify the 'prose.port' property");
}
try {
// create, and export the objects.
activeInstance = new RemoteAspectManagerImpl(true);
activeInstanceRef = UnicastRemoteObject.exportObject(activeInstance);
testInstance = new RemoteAspectManagerImpl(false);
testInstanceRef = UnicastRemoteObject.exportObject(testInstance);
listener = new ServerSocket(portNumber);
Thread worker = new Thread() {
public void run() {
while (systemUp) {
try {
Socket s = listener.accept();
ObjectOutputStream objOut = new ObjectOutputStream(s.getOutputStream());
objOut.writeObject(activeInstanceRef);
objOut.writeObject(testInstanceRef);
}
catch (Exception e) { e.printStackTrace(); }
}
}
};
worker.start();
}
catch (RemoteException e) {
e.printStackTrace();
throw new SystemStartupException("Cannot export RemoteAspectManager");
}
catch (java.io.IOException e) {
e.printStackTrace();
throw new SystemStartupException("Cannot start a listener socket on the given port");
}
}
/**
* Unexport (without forcing)
* the current instance of <code>RemoteExtensionManager</code> server.
* <p>
* <em>Note: this method is idempotent. Successive calls have the same
* effect as just one.</em>
*/
public synchronized static void teardown() throws SystemTeardownException {
if (!systemUp)
return;
try {
UnicastRemoteObject.unexportObject(activeInstance,true);
UnicastRemoteObject.unexportObject(testInstance,true);
}
catch (NoSuchObjectException noChance) {
// object HAS to be there
throw new Error("FIXME FOR PROSE DEVELOPER: why is the object not there?");
}
systemUp = false;
}
protected static RemoteAspectManager[] doGetRemoteAspectManagers(String host, int connectTo)
throws java.net.UnknownHostException,java.io.IOException {
RemoteAspectManager[] result = new RemoteAspectManager[2];
Socket s = new Socket(host,connectTo);
ObjectInputStream objIn = new ObjectInputStream(s.getInputStream());
try {
result[0]= (RemoteAspectManager)objIn.readObject();
result[1]= (RemoteAspectManager)objIn.readObject();
}
catch (java.lang.ClassNotFoundException e) {
throw new Error(e.toString());
}
return result;
}
}