//
// This file is part of the Prose Development Tools for Eclipse 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 Development Tools for Eclipse.
//
// The Initial Developer of the Original Code is Angela Nicoara. Portions
// created by Angela Nicoara are Copyright (C) 2006 Angela Nicoara.
// All Rights Reserved.
//
// Contributor(s):
// $Id: ProseRunNode.java,v 1.1 2008/11/18 12:23:02 anicoara Exp $
// ==============================================================================
//
package ch.ethz.prose.eclipse.internal.run;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.swt.graphics.Image;
import ch.ethz.prose.eclipse.internal.core.ProsePlugin;
import ch.ethz.prose.tools.RemoteAspectManager;
/**
* Representation of a started Prose application.
*
* @author Angela Nicoara
* @author Johann Gyger
* @version $Id: ProseRunNode.java,v 1.1 2008/11/18 12:23:02 anicoara Exp $
*/
public class ProseRunNode extends AbstractRunNode implements IDebugEventSetListener {
/**
* Name of this Prose run.
*/
protected String name;
/**
* Host on which the Prose application runs.
*/
protected String host;
/**
* Port of Prose server.
*/
protected int port;
/**
* Eclipse launcher.
*/
protected ILaunch launch;
protected RemoteAspectManager[] aspectManagers;
protected AspectManagerNode[] aspectManagerNodes;
/**
* Is the Prose application reachable?
*/
protected boolean reachable = true;
/**
* Create a new Prose run.
*
* @param name Name of this Prose run
* @param host Host on which the Prose VM runs
* @param port Port of Prose server
*/
public ProseRunNode(String name, String host, int port) {
this.name = name;
this.host = host;
this.port = port;
aspectManagerNodes = new AspectManagerNode[2];
aspectManagerNodes[0] = new AspectManagerNode(this, true);
aspectManagerNodes[1] = new AspectManagerNode(this, false);
DebugPlugin.getDefault().addDebugEventListener(this);
}
/**
* Create a new Prose run.
*
* @param name Name of this Prose run
* @param host Host on which the Prose VM runs
* @param port Port of Prose server
* @param launch Eclipse launcher
*/
public ProseRunNode(String name, String host, int port, ILaunch launch) {
this(name, host, port);
this.launch = launch;
}
/**
* @return Is the Prose run reachable?
*/
public boolean isReachable() {
return reachable;
}
/**
* Prose run is not reachable.
*/
public void setUnreachable() {
reachable = false;
DebugPlugin.getDefault().removeDebugEventListener(this);
ProsePlugin.getDefault().fireRunUnreachable(this);
}
/**
* @return Name of this Prose run
*/
public String getName() {
return name;
}
/**
* @return Host on which the Prose VM runs
*/
public String getHost() {
return host;
}
/**
* @return Port of Prose server
*/
public int getPort() {
return port;
}
/**
* @return Address of Prose server (equivalent to <code>host:port</code>).
*/
public String getAddress() {
return getHost() + ":" + getPort();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer sb = new StringBuffer();
if (!reachable) sb.append("<unreachable> ");
sb.append(getName());
sb.append(" at ");
sb.append(getAddress());
return sb.toString();
}
/* (non-Javadoc)
* @see ch.ethz.prose.eclipse.internal.run.IRunNode#hasChildren()
*/
public boolean hasChildren() {
return reachable;
}
/**
* @return Nodes to the two remote aspect managers (active and testing)
*/
public IRunNode[] getChildren() {
return hasChildren()? aspectManagerNodes : null;
}
/* (non-Javadoc)
* @see ch.ethz.prose.eclipse.internal.run.IRunNode#getParent()
*/
public IRunNode getParent() {
return null;
}
/* (non-Javadoc)
* @see ch.ethz.prose.eclipse.internal.run.IRunNode#getRoot()
*/
public IRunNode getRoot() {
return this;
}
/* (non-Javadoc)
* @see ch.ethz.prose.eclipse.internal.run.IRunNode#getImage()
*/
public Image getImage() {
return PROSE_RUN_IMAGE;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
*/
public void handleDebugEvents(DebugEvent[] events) {
if (!reachable) return;
for (int i = 0; i < events.length; i++) {
Object source = events[i].getSource();
if (source instanceof IProcess) {
IProcess process = (IProcess) source;
if (process.getLaunch() == launch) setUnreachable();
}
}
}
/**
* NOTE: Should be called only by class AspectManagerNode. Use
* #getAspectManagerNodes() instead. This method is located here (and not in
* class AspectManagerNode) because the two remote aspect managers must be
* retrieved together.
*
* @return Real remote aspect managers (active and testing), or
* <code>null</code>
* @throws UnreachableException If Prose server is not reachable
*/
RemoteAspectManager[] getAspectManagers() throws UnreachableException {
if (!reachable) throw new UnreachableException();
if (aspectManagers != null) return aspectManagers;
try {
Socket s = new Socket(host, port);
s.setSoTimeout(5000);
ObjectInputStream stream = new ObjectInputStream(s.getInputStream());
RemoteAspectManager manager0 = (RemoteAspectManager) stream.readObject();
RemoteAspectManager manager1 = (RemoteAspectManager) stream.readObject();
aspectManagers = new RemoteAspectManager[] { manager0, manager1 };
} catch (ClassNotFoundException e) {
throw new Error(e);
} catch (IOException e) {
setUnreachable();
throw new UnreachableException(e);
} catch (RuntimeException e) {
setUnreachable();
throw new UnreachableException(e);
}
return aspectManagers;
}
}