// **********************************************************************
//
// <copyright>
//
// BBN Technologies
// 10 Moulton Street
// Cambridge, MA 02138
// (617) 873-8000
//
// Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/corba/com/bbn/openmap/layer/specialist/CSpecLayer.java,v $
// $RCSfile: CSpecLayer.java,v $
// $Revision: 1.9 $
// $Date: 2005/12/09 21:08:58 $
// $Author: dietrick $
//
// **********************************************************************
package com.bbn.openmap.layer.specialist;
/* Java Core */
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.omg.CORBA.BooleanHolder;
import org.omg.CORBA.ShortHolder;
import org.omg.CORBA.StringHolder;
import com.bbn.openmap.Environment;
import com.bbn.openmap.corba.CSpecialist.CProjection;
import com.bbn.openmap.corba.CSpecialist.GraphicChange;
import com.bbn.openmap.corba.CSpecialist.LLPoint;
import com.bbn.openmap.corba.CSpecialist.Server;
import com.bbn.openmap.corba.CSpecialist.ServerHelper;
import com.bbn.openmap.corba.CSpecialist.UGraphic;
import com.bbn.openmap.corba.CSpecialist.UWidget;
import com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType;
import com.bbn.openmap.event.InfoDisplayEvent;
import com.bbn.openmap.event.MapMouseListener;
import com.bbn.openmap.event.SelectMouseMode;
import com.bbn.openmap.layer.OMGraphicHandlerLayer;
import com.bbn.openmap.omGraphics.OMGraphic;
import com.bbn.openmap.omGraphics.OMGraphicList;
import com.bbn.openmap.proj.Projection;
import com.bbn.openmap.util.Debug;
import com.bbn.openmap.util.PropUtils;
/**
* CSpecLayer is a Layer which communicates to CORBA Specialists.
* <P>
* Properties:
* <P>
*
* <pre>
*
* # If you have an ior for the server:
* cspeclayermarker.ior= URL to ior
* # If you are using the Naming Service:
* cspeclayermarker.name= SERVER NAME
* # Static Arguments for the server, to be sent on every map request:
* cspeclayermarker.staticArgs= space separated arguments
* # If the network setup allows the server to contact the client (no firewall)
* cspeclayermarker.allowServerUpdates=true/false (false is default)
*
* </pre>
*/
public class CSpecLayer
extends OMGraphicHandlerLayer
implements MapMouseListener {
// private final static String[] debugTokens = { "debug.cspec" };
/** The property specifying the IOR URL. */
public static final String iorUrlProperty = "ior";
public static final String namingProperty = "name";
/** The property specifying the static arguments. */
public static final String staticArgsProperty = "staticArgs";
/**
* The property to use for specifying whether the GraphicChange object should
* be sent to the server. The server can use the GraphicChange object to
* contact the client to notify it that updates are available. This should
* only be true if the network setup allows it to be. Running the client
* behind a firewall, taking with the server through a Gatekeeper, will not
* allow the GraphicChange object to be set. You get a BOA instantiation
* error.
*/
public static final String serverUpdateProperty = "allowServerUpdates";
/** IOR URL for the server. */
protected URL iorURL = null;
/** Name of the server. */
protected String naming = null;
/** Arguments passed in from the OverlayTable/properties file. */
protected String staticArgs = null;
/**
* Arguments modified by the Layer, or set by the Bean, at runtime.
* Historical, should use Properties instead.
*/
protected String dynamicArgs = null;
protected String clientID = Environment.generateUniqueString();
protected UWidget[] widgets = null;
protected transient CSpecPalette gui = null;
protected transient Server specialist = null;
protected ShortHolder selectDist = new ShortHolder();
protected BooleanHolder wantAreaEvents = new BooleanHolder();
protected GraphicChange notifyOnChange = null;
protected MapGesture mapGesture = new MapGesture();
/**
* Used for the MapMouseListener interface, to track whether to listen to
* mouse events, or not.
*/
protected boolean acceptingEvents = false;
/**
* Used to track if a info line was sent, so that a clearing message can be
* sent when it is no longer relevant.
*/
protected boolean sentInfoLine = false;
// all the dirty bits
protected int dirtybits = 0;
public final transient static int PALETTE_DIRTY = 0x1;
public final transient static int PREMATURE_FINISH = 0x4;
public final transient static int EXCEPTION = 0x8;
public final transient static int DIRTYMASK = 0xFFFFFFFF;
// new slots
protected boolean showDialogs = Environment.getBoolean("com.bbn.openmap.ShowLayerMessages");
/**
* Default constructor, that sets the MapMouseListener for this layer to
* itself.
*/
public CSpecLayer() {
handleGraphicChangeRequests(false);
setProjectionChangePolicy(new com.bbn.openmap.layer.policy.ListResetPCPolicy(this));
}
/**
* Sets whether the notifyOnChange object will actually be set to anything.
* This object can be used to tell the CSpecLayer to go to the specialist
* with a getRectangle. The Layer handles the creation of the object if this
* is set to true. If you are working through a firewall, this might not be
* allowed, especially if the client is behind the firewall.
*
* @param setting if the object should be created or not.
*/
public void handleGraphicChangeRequests(boolean setting) {
if (setting) {
if (notifyOnChange == null) {
notifyOnChange = new JGraphicChange(this);
}
} else {
notifyOnChange = null;
}
}
/**
*
*/
public void finalize() {
if (Debug.debugging("cspec")) {
Debug.output(getName() + "|CSpecLayer.finalize(): calling shutdown");
}
try {
if (specialist != null)
specialist.signoff(clientID);
specialist = null;
} catch (org.omg.CORBA.SystemException e) {
System.err.println(getName() + "|CSpecLayer.finalize(): " + e);
} catch (Throwable t) {
System.err.println(getName() + "|CSpecLayer.finalize(): " + t);
}
}
/**
* Set the properties for the CSpecLayer.
*/
public void setProperties(String prefix, java.util.Properties props) {
super.setProperties(prefix, props);
prefix = PropUtils.getScopedPropertyPrefix(prefix);
String url = props.getProperty(prefix + iorUrlProperty);
if (url != null) {
try {
setIorUrl(PropUtils.getResourceOrFileOrURL(null, url));
} catch (MalformedURLException e) {
throw new IllegalArgumentException("\"" + url + "\" is malformed.");
}
}
// Get the naming context to get
naming = props.getProperty(prefix + namingProperty);
String staticArgValue = props.getProperty(prefix + staticArgsProperty);
setStaticArgs(staticArgValue);
handleGraphicChangeRequests(PropUtils.booleanFromProperties(props, prefix + serverUpdateProperty, notifyOnChange != null));
}
/**
* Gets the argv for the layer from the pseudo-overlay-table. Expecting
* <URL>&rest args.
*/
public void setArgs(String argv[]) {
int argc = argv.length;
if (argc == 0) {
// Do nothing.
return;
}
String url = argv[0];
StringBuffer argBuf = new StringBuffer();
if (argc > 1) {
// More arguments, append them into one string and
// pass it off to setArgs.
argBuf.append(argv[1]);
for (int i = 2; i < argc; i++) {
argBuf.append(" ").append(argv[i]);
}
}
// dbg
// Debug.output("----------------------------------------------");
// dbg Debug.output("CSpecLayer " + getName() + ":");
// dbg Debug.output("\tURL: " + url);
// dbg Debug.output("\targs: " + argBuf);
try {
setIorUrl(new URL(url));
if (Debug.debugging("cspec")) {
Debug.output(getName() + "(CSpecLayer) using ior from " + url);
}
} catch (MalformedURLException e) {
throw new IllegalArgumentException("\"" + url + "\"" + " is not a well formed URL");
}
setStaticArgs(argBuf.toString());
}
/**
* get the specialist proxy.
*
* @return Server specialist server or null if error.
*/
public Server getSpecialist() {
if (specialist == null) {
initSpecialist();
}
return specialist;
}
/**
* Bind to the specialist server.
*/
private void initSpecialist() {
String ior = null;
org.omg.CORBA.Object object = null;
com.bbn.openmap.util.corba.CORBASupport cs = new com.bbn.openmap.util.corba.CORBASupport();
try {
object = cs.readIOR(iorURL);
specialist = ServerHelper.narrow(object);
} catch (IOException ioe) {
if (Debug.debugging("cspec")) {
Debug.output(getName() + "(CSpecLayer).initSpecialist() IO Exception with ior: " + iorURL);
}
specialist = null;
return;
}
if (specialist == null) {
object = cs.resolveName(naming);
if (object != null) {
specialist = ServerHelper.narrow(object);
if (Debug.debugging("cspec")) {
Debug.output("Have a specialist:");
Debug.output("*** Specialist Server: is a " + specialist.getClass().getName() + "\n" + specialist);
}
}
}
if (specialist == null) {
if (Debug.debugging("cspec")) {
System.err.println("CSpecLayer.initSpecialist: null specialist!\n IOR=" + ior + "\n Name = " + naming);
}
}
}
/**
* Set the server, if you've taken special steps to create on, or want to
* null out the current one to reset the connection.
*/
public void setSpecialist(Server aSpecialist) {
specialist = aSpecialist;
if (specialist == null) {
widgets = null;
gui = null;
setList(null);
}
}
/**
* Interface Layer method to get the dynamic args.
*
* @return String args
*/
public String getArgs() {
return dynamicArgs;
}
/**
* Method to set the dynamic args.
*
* @param args String
*/
public void setArgs(String args) {
dynamicArgs = args;
}
/**
* Interface Layer method to get the static args, which are usually set via
* the openmap.properties file, or setProperties().
*/
public String getStaticArgs() {
return staticArgs;
}
/**
* Interface Layer method to set the static args, which are usually set via
* the openmap.properties file.
*/
public void setStaticArgs(String args) {
staticArgs = args;
}
public URL getIorUrl() {
return iorURL;
}
public void setIorUrl(URL url) {
iorURL = url;
}
/**
* Perform the getRectangle() call on the specialist.
*
* @param p Projection
* @return UGraphic[] graphic list or null if error
*/
protected UGraphic[] getSpecGraphics(Projection p) {
CProjection cproj;
LLPoint ll1, ll2;
StringHolder dynamicArgsHolder;
UGraphic[] graphics = null;
Server spec = getSpecialist();
if (Debug.debugging("cspec"))
Debug.output(getName() + "|CSpecLayer.getSpecGraphics()");
Point2D center = p.getCenter();
cproj =
new CProjection(MakeProjection.getProjectionType(p), new LLPoint((float) center.getY(), (float) center.getX()),
(short) p.getHeight(), (short) p.getWidth(), (int) p.getScale());
// lat-lon "box", (depends on the projection)
Point2D ul = p.getUpperLeft();
Point2D lr = p.getLowerRight();
ll1 = new LLPoint((float) ul.getY(), (float) ul.getX());
ll2 = new LLPoint((float) lr.getY(), (float) lr.getX());
// check for cancellation
if (isCancelled()) {
dirtybits |= PREMATURE_FINISH;
if (Debug.debugging("cspec"))
Debug.output(getName() + "|CSpecLayer.getSpecGraphics(): aborted.");
return null;
}
// check for null specialist
if (spec == null) {
if (Debug.debugging("cspec")) {
System.err.println(getName() + "|CSpecLayer.getSpecGraphics(): null specialist!");
}
return null;
}
try {
// Keep the gestures up-to-date
mapGesture.setProjection(p);
// Static Args can't go out null....
String staticArguments = getStaticArgs();
if (staticArguments == null) {
staticArguments = "";
setStaticArgs(staticArguments);
}
// neither can dynamic args
// Layer.getArgs() was deprecated and removed
dynamicArgsHolder = new StringHolder(getArgs());
if (dynamicArgsHolder.value == null) {
dynamicArgsHolder.value = "";
}
// call getRectangle();
if (Debug.debugging("cspec")) {
Debug.output(getName() + "|CSpecLayer.getSpecGraphics():" + " calling getRectangle with projection: " + p + " ul=" + ul
+ " lr=" + lr + " staticArgs=\"" + staticArguments + "\"" + " dynamicArgs=\"" + dynamicArgsHolder.value + "\""
+ " notifyOnChange=\"" + notifyOnChange + "\"" + " clientID=" + clientID);
}
long start = System.currentTimeMillis();
if (Debug.debugging("cspecdetail")) {
Debug.output("*** Specialist Server: is a " + spec.getClass().getName() + "\n" + spec);
}
graphics =
spec.getRectangle(cproj, ll1, ll2, staticArguments, dynamicArgsHolder, selectDist, wantAreaEvents, notifyOnChange,
clientID);
long stop = System.currentTimeMillis();
if (Debug.debugging("cspec")) {
Debug.output(getName() + "|CSpecLayer.getSpecGraphics(): got " + graphics.length + " graphics in "
+ ((stop - start) / 1000d) + " seconds.");
}
} catch (org.omg.CORBA.SystemException e) {
dirtybits |= EXCEPTION;
// don't freak out if we were only interrupted...
if (e.toString().indexOf("InterruptedIOException") != -1) {
System.err.println(getName() + "|CSpecLayer.getSpecGraphics(): " + "getRectangle() call interrupted!");
} else {
System.err.println(getName() + "|CSpecLayer.getSpecGraphics(): " + "Caught CORBA exception: " + e);
System.err.println(getName() + "|CSpecLayer.getSpecGraphics(): " + "Exception class: " + e.getClass().getName());
e.printStackTrace();
}
// dontcha just love CORBA? reinit later
setSpecialist(null);
if (showDialogs)
postCORBAErrorMsg("CORBA Exception while getting graphics from\n" + getName() + " specialist:\n"
+ e.getClass().getName());
}
return graphics;
}
/**
* Prepares the graphics for the layer.
* <p>
* Occasionally it is necessary to abort a prepare call. When this happens,
* the doPrepare() call will set the cancel bit on the SwingWorker. The
* worker will get restarted after it finishes doing its cleanup.
*
* @return a JGraphicList from the server.
*/
public synchronized OMGraphicList prepare() {
JGraphicList emptyList = new JGraphicList();
if (isCancelled()) {
dirtybits |= PREMATURE_FINISH;
if (Debug.debugging("basic")) {
Debug.output(getName() + "|CSpecLayer.prepare(): aborted.");
}
return emptyList;
}
if (Debug.debugging("basic")) {
Debug.output(getName() + "|CSpecLayer.prepare(): doing it");
}
dirtybits = 0;// reset the dirty bits
// Now we're going to shut off event processing. The only
// thing that turns them on again is finishing successfully.
setAcceptingEvents(false);
Projection projection = getProjection();
// get the graphics from the specialist
UGraphic[] specGraphics = getSpecGraphics(projection);
if (isCancelled()) {
dirtybits |= PREMATURE_FINISH;
if (Debug.debugging("basic"))
Debug.output(getName() + "|CSpecLayer.prepare(): " + "aborted during/after getRectangle().");
return emptyList;
}
if (specGraphics == null) {
return emptyList;
}
// process the graphics
long start = System.currentTimeMillis();
JGraphicList graphics = createGraphicsList(specGraphics, projection);
long stop = System.currentTimeMillis();
if (Debug.debugging("cspec")) {
Debug.output(getName() + "|CSpecLayer.prepare(): generated " + specGraphics.length + " graphics in "
+ ((stop - start) / 1000d) + " seconds.");
}
if (isCancelled()) {
dirtybits |= PREMATURE_FINISH;
if (Debug.debugging("basic")) {
Debug.output(getName() + "|CSpecLayer.prepare(): " + "aborted while generating graphics.");
}
return emptyList;
}
// safe quit
if (Debug.debugging("basic")) {
Debug.output(getName() + "|CSpecLayer.prepare(): finished preparing " + graphics.size() + " graphics");
}
setAcceptingEvents(true);
return graphics;
}
/**
* Create an JGraphicList based on UGraphics and a Projection.
* <p>
* This is public static to enable out-of-package delegation.
* <p>
*
* @param uGraphics UGraphic[]
* @param proj Projection
* @return JGraphicList
*/
public static JGraphicList createGraphicsList(UGraphic[] uGraphics, Projection proj) {
int nGraphics = uGraphics.length;
JGraphicList graphics = new JGraphicList(nGraphics);
graphics.setTraverseMode(OMGraphicList.LAST_ADDED_ON_TOP);
// generate a JGraphic for each CSpecialist graphic and store
// it
for (int i = 0; i < nGraphics; i++) {
switch (uGraphics[i].discriminator().value()) {
case GraphicType._GT_Poly:
JPoly jpoly = new JPoly(uGraphics[i].epoly());
jpoly.generate(proj);
graphics.add(jpoly);
break;
case GraphicType._GT_Raster:
JRaster jraster = new JRaster(uGraphics[i].eras());
jraster.generate(proj);
graphics.add(jraster);
break;
case GraphicType._GT_Bitmap:
JBitmap jbitmap = new JBitmap(uGraphics[i].ebit());
jbitmap.generate(proj);
graphics.add(jbitmap);
break;
case GraphicType._GT_Text:
JText jtext = new JText(uGraphics[i].etext());
jtext.generate(proj);
graphics.add(jtext);
break;
case GraphicType._GT_Line:
JLine jline = new JLine(uGraphics[i].eline());
jline.generate(proj);
graphics.add(jline);
break;
case GraphicType._GT_UnitSymbol:
JUnit junit = new JUnit(uGraphics[i].eunit());
junit.generate(proj);
graphics.add(junit);
break;
case GraphicType._GT_2525Symbol:
J2525 j2525 = new J2525(uGraphics[i].e2525());
j2525.generate(proj);
graphics.add(j2525);
break;
case GraphicType._GT_Rectangle:
JRect jrect = new JRect(uGraphics[i].erect());
jrect.generate(proj);
graphics.add(jrect);
break;
case GraphicType._GT_Circle:
JCircle jcircle = new JCircle(uGraphics[i].ecirc());
jcircle.generate(proj);
graphics.add(jcircle);
break;
case GraphicType._GT_NewGraphic:
case GraphicType._GT_ReorderGraphic:
default:
System.err.println("JGraphic.generateGraphics: " + "ignoring invalid type");
break;
}
}
return graphics;
}
/**
* Gets the palette associated with the layer.
* <p>
*
* @return Component or null
*/
public Component getGUI() {
if (specialist == null)
initSpecialist();
if (specialist == null) {
if (Debug.debugging("cspec"))
Debug.output(getName() + "|CSpecLayer.getGUI(): initSpecialist() unsuccessful!");
return null;
}
try {
if (widgets == null) {
org.omg.CORBA.StringHolder paletteDynamicArgs = new org.omg.CORBA.StringHolder(getArgs());
if (paletteDynamicArgs.value == null) {
paletteDynamicArgs.value = "";
}
// Static Args can't go out null....
String staticArguments = getStaticArgs();
if (staticArguments == null) {
staticArguments = "";
setStaticArgs(staticArguments);
}
if (Debug.debugging("cspec")) {
Debug.output(getName() + "|CSpecLayer.getGUI(): calling getPaletteConfig(" + staticArguments + ","
+ paletteDynamicArgs.value + "," + clientID + ")");
}
try {
widgets = specialist.getPaletteConfig(null/* widgetChange */, staticArguments, paletteDynamicArgs, clientID);
} catch (org.omg.CORBA.SystemException e) {
System.err.println(getName() + "|CSpecLayer.getGUI(): " + e);
e.printStackTrace();
setSpecialist(null);
if (showDialogs) {
postCORBAErrorMsg("CORBA Exception while getting palette from\n" + getName() + " specialist:\n"
+ e.getClass().getName());
}
}
if (widgets == null || widgets.length == 0) {
gui = null;
} else {
gui = new CSpecPalette(widgets, clientID, this);
}
}
} catch (OutOfMemoryError e) {
setSpecialist(null);
System.err.println(getName() + "|CSpecLayer.getGUI(): " + e);
if (showDialogs) {
postMemoryErrorMsg("OutOfMemory while getting palette from\n" + getName() + " specialist.");
}
} catch (Throwable t) {
setSpecialist(null);
System.err.println(getName() + "|CSpecLayer.getGUI(): " + t);
t.printStackTrace();
if (showDialogs) {
postException("Exception while getting palette from\n" + getName() + " specialist:\n" + t.getClass().getName());
}
}
return gui;
}
/**
* A palette button has changed (we should indeed prepare when we get the
* call).
*
* @param paletteIsDirty true or false
*/
protected void setPaletteIsDirty(boolean paletteIsDirty) {
if (paletteIsDirty) {
dirtybits |= PALETTE_DIRTY;
}
}
/**
* Destroy the current palette stuff.
*/
protected void forgetPalette() {
widgets = null;
gui = null;
}
/**
* Used to set whether the MapMouseListener is listening for events or
* ignoring them.
*
* @param listening true if the listener should process mouse events.
*/
public void setAcceptingEvents(boolean listening) {
acceptingEvents = listening;
}
/**
* Used to tell if the listener is accepting mouse events for processing.
*
* @return true if the listener is processing mouse events.
*/
public boolean isAcceptingEvents() {
return acceptingEvents;
}
// Mouse Listener events
// //////////////////////
/**
* Returns the MapMouseListener object (this object) that handles the mouse
* events.
*
* @return MapMouseListener this
*/
public MapMouseListener getMapMouseListener() {
return this;
}
public String[] getMouseModeServiceList() {
String[] ret = new String[1];
ret[0] = SelectMouseMode.modeID;
return ret;
}
/**
* Handle a mouse button being pressed.
*
* @param e MouseListener MouseEvent to handle.
* @return true if the listener was able to process the event.
*/
public boolean mousePressed(MouseEvent e) {
if (acceptingEvents && specialist != null) {
return handleGesture(e, MapGesture.clickEvent, true);
}
return false;
}
/**
* Handle a mouse button being released.
*
* @param e MouseListener MouseEvent to handle.
* @return true if the listener was able to process the event.
*/
public boolean mouseReleased(MouseEvent e) {
if (acceptingEvents && specialist != null) {
return handleGesture(e, MapGesture.clickEvent, false);
}
return false;
}
/**
* Handle a mouse button being clicked - pressed and released.
*
* @param e MouseListener MouseEvent to handle.
* @return true if the listener was able to process the event.
*/
public boolean mouseClicked(MouseEvent e) {
if (acceptingEvents && specialist != null) {
return handleGesture(e, MapGesture.clickEvent, false);
}
return false;
}
/**
* Handle a mouse cursor entering a window or area.
*
* @param e MouseListener MouseEvent to handle.
*/
public void mouseEntered(MouseEvent e) {
if (acceptingEvents && specialist != null) {
handleGesture(e, MapGesture.motionEvent, false);
}
}
/**
* Handle a mouse cursor leaving a window or area.
*
* @param e MouseListener MouseEvent to handle.
*/
public void mouseExited(MouseEvent e) {
if (acceptingEvents && specialist != null) {
handleGesture(e, MapGesture.motionEvent, false);
}
}
// Mouse Motion Listener events
// /////////////////////////////
/**
* Handle a mouse button being pressed while the mouse cursor is moving.
*
* @param e MouseMotionListener MouseEvent to handle.
* @return true if the listener was able to process the event.
*/
public boolean mouseDragged(MouseEvent e) {
if (acceptingEvents && specialist != null) {
return handleGesture(e, MapGesture.motionEvent, true);
}
return false;
}
/**
* Handle a mouse cursor moving without the button being pressed.
*
* @param e MouseListener MouseEvent to handle.
* @return true if the listener was able to process the event.
*/
public boolean mouseMoved(MouseEvent e) {
if (acceptingEvents && specialist != null) {
return handleGesture(e, MapGesture.motionEvent, false);
}
return false;
}
/**
* Handle a mouse cursor moving without the button being pressed, for events
* that have been used by something else.
*/
public void mouseMoved() {
if (acceptingEvents && specialist != null) {
handleGesture(null, MapGesture.motionEvent, false);
}
}
/**
* Relays user gestures to the specialist or to the mousable objects of the
* CSpecLayer. The function finds the closest object and then its comp object
* all by itself.
* <p>
*
* @param evt MouseEvent
* @param MouseDown true if the mouse button is down
* @return true if gesture was consumed, false if not.
*/
public boolean handleGesture(MouseEvent evt, int eventType, boolean MouseDown) {
boolean got_info = false;
boolean got_the_stuff = false;
boolean updated_graphics = false;
OMGraphic moused = null;
JGraphicList jjGraphics = (JGraphicList) getList();
// Do this, so when there was a one-liner about a graphic (or
// something) sent, and now there isn't a graphic associated
// with the layer, to reset the message window to nothing, so
// stale info just doesn't hang out.
if (sentInfoLine) {
fireRequestInfoLine("");
sentInfoLine = false;
}
if (!isAcceptingEvents() || (jjGraphics == null)) {
return false;
}
// This will need to change, when we figure out who to make a
// Cspecialist capabile of handling a null event, so signify a
// reset...
if (evt == null) {
if (Debug.debugging("cspec")) {
Debug.output(getName() + "|CSpecLayer.handleGesture(): null evt!");
}
return false;// didn't consume gesture
}
try {
mapGesture.setMouseEvent(evt, eventType, MouseDown);
moused = jjGraphics.findClosest(evt.getX(), evt.getY(), selectDist.value);
com.bbn.openmap.corba.CSpecialist.ActionUnion[] action = null;
switch (mapGesture.getMode()) {
case (short) MapGesture.Raw:
// send the gesture to the comp object or the
// specialist
// if it wants area events.
if (moused != null && ((JObjectHolder) moused).getObject().comp != null) {
action = ((JObjectHolder) moused).getObject().comp.sendGesture(JGraphic.constructGesture(mapGesture), clientID);
} else if (specialist != null) {
action = wantAreaEvents.value ? specialist.sendGesture(JGraphic.constructGesture(mapGesture), clientID) : null;
if (action == null) {
if (Debug.debugging("cspec"))
Debug.output(getName() + "|CSpecLayer.handleGesture(): null action!");
return false; // didn't consume gesture
}
if (action.length == 0) {
return false; // didn't consume gesture
}
}
if (action == null) {
if (Debug.debugging("cspec")) {
System.err.println(getName() + "|CSpecLayer.handleGesture(): null action!");
}
return false; // didn't consume gesture
}
break;
case (short) MapGesture.Cooked:
default:
System.err.println("CSpecLayer|" + getName() + "|handleGesture() - cooked modes not supported");
break;
}
if (action == null) {
return false;
}
// parse the action sequence, ignore duplicate action
// directives
mapGesture.actionType = new int[action.length];
for (int i = 0; i < action.length; i++) {
switch (action[i].discriminator().value()) {
case MapGesture.NoAction:
break;
case MapGesture.UpdateGraphics:
updated_graphics = true;
// now update the specified graphics
updateGraphics(action[i].ginfo());
break;
case MapGesture.InfoText:
if (!got_info) { // can only have one instance
if (Debug.debugging("cspec")) {
Debug.output("CSpecLayer|" + getName() + "|handleGesture(): Requesting Info Text " + action[i].itext());
}
fireRequestInfoLine(action[i].itext());
sentInfoLine = true;
got_info = true;
}
break;
case MapGesture.PlainText:
if (!got_the_stuff) {
if (Debug.debugging("cspec")) {
Debug.output("CSpecLayer|" + getName() + "|handleGesture(): Requesting Plain Text " + action[i].ptext());
}
fireRequestBrowserContent(action[i].ptext());
got_the_stuff = true;
}
break;
case MapGesture.HTMLText:
if (!got_the_stuff) {
if (Debug.debugging("cspec")) {
Debug.output("CSpecLayer|" + getName() + "|handleGesture(): Requesting HTML Text " + action[i].htext());
}
fireRequestBrowserContent(action[i].htext());
got_the_stuff = true;
}
break;
case MapGesture.URL:
if (!got_the_stuff) {
if (Debug.debugging("cspec")) {
Debug.output("CSpecLayer|" + getName() + "|handleGesture(): Requesting URL " + action[i].url());
}
fireRequestURL(action[i].url());
got_the_stuff = true;
}
break;
case MapGesture.UpdatePalette:
default:
System.err.println("CSpecLayer|" + getName() + "|handleGesture(): invalid ActionSeq");
break;
}
}
} catch (org.omg.CORBA.SystemException e) {
System.err.println(getName() + "|CSpecLayer.handleGesture(): " + e);
if (showDialogs) {
postCORBAErrorMsg("CORBA Exception while gesturing on\n" + getName() + " specialist:\n" + e.getClass().getName());
}
return false;
} catch (OutOfMemoryError e) {
setSpecialist(null);
if (showDialogs) {
postMemoryErrorMsg("OutOfMemory while gesturing on\n" + getName() + " specialist.");
}
return false;
} catch (Throwable t) {
if (showDialogs) {
postException("Exception while gesturing on\n" + getName() + " specialist:\n" + t.getClass().getName());
}
t.printStackTrace();
return false;
}
if (updated_graphics) {
repaint();
}
return true;// consumed the gesture
}
/**
* Changes attributes of existing graphics, or adds new graphics, or reorders
* graphics.
* <p>
*
* @param updateRec com.bbn.openmap.corba.CSpecialist.UpdateRecord[]
*/
protected void updateGraphics(com.bbn.openmap.corba.CSpecialist.UpdateRecord[] updateRec) {
JGraphicList jGraphics = (JGraphicList) getList();
Projection projection = getProjection();
com.bbn.openmap.corba.CSpecialist.UpdateGraphic upgraphic = null;
// parse updateRec (an array of UpdateRecord)
for (int i = 0; i < updateRec.length; i++) {
String gID = updateRec[i].gID; // get the graphic ID
// parse the sequence of updates to perform on the
// graphic. You need to do this because the types of
// changes that can be made to each object can be part of
// the specific object, like _GT_Bitmap (location, bits,
// height/width), or part of the _GT_Graphic
// (color/stipple changes), or _GT_ReorderGraphic, or
// whatever.
for (int j = 0; j < updateRec[i].objectUpdates.length; j++) {
upgraphic = updateRec[i].objectUpdates[j];
// determine the type of graphic update
switch (upgraphic.discriminator().value()) {
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_Graphic:
JObjectHolder graphic = (JObjectHolder) jGraphics.getOMGraphicWithId(gID);
if (graphic != null) {
graphic.update(upgraphic.gf_update());
((OMGraphic) graphic).regenerate(projection);
}
break;
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_Bitmap:
JBitmap bitmap = (JBitmap) jGraphics.getOMGraphicWithId(gID);
if (bitmap != null) {
bitmap.update(upgraphic.bf_update());
bitmap.regenerate(projection);
}
break;
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_Text:
JText text = (JText) jGraphics.getOMGraphicWithId(gID);
if (text != null) {
text.update(upgraphic.tf_update());
text.regenerate(projection);
}
break;
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_Poly:
JPoly poly = (JPoly) jGraphics.getOMGraphicWithId(gID);
if (poly != null) {
poly.update(upgraphic.pf_update());
poly.regenerate(projection);
}
break;
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_Line:
JLine line = (JLine) jGraphics.getOMGraphicWithId(gID);
if (line != null) {
line.update(upgraphic.lf_update());
line.regenerate(projection);
}
break;
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_Rectangle:
JRect rect = (JRect) jGraphics.getOMGraphicWithId(gID);
if (rect != null) {
rect.update(upgraphic.rf_update());
rect.regenerate(projection);
}
break;
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_Raster:
JRaster raster = (JRaster) jGraphics.getOMGraphicWithId(gID);
if (raster != null) {
raster.update(upgraphic.rasf_update());
raster.regenerate(projection);
}
break;
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_Circle:
JCircle circ = (JCircle) jGraphics.getOMGraphicWithId(gID);
if (circ != null) {
circ.update(upgraphic.cf_update());
circ.regenerate(projection);
}
break;
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_UnitSymbol:
JUnit unitsymbol = (JUnit) jGraphics.getOMGraphicWithId(gID);
if (unitsymbol != null) {
unitsymbol.update(upgraphic.usf_update());
unitsymbol.regenerate(projection);
}
break;
// Uncomment when implemented!!!!
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_2525Symbol:
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_ForceArrow:
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_NewGraphic:
case com.bbn.openmap.corba.CSpecialist.GraphicPackage.GraphicType._GT_ReorderGraphic:
System.err.println("CSpecLayer|" + getName() + "|updateGraphics: Graphics Update Type not implemented.");
break;// HACK - unimplemented
// unknown update
default:
System.err.println("CSpecLayer|" + getName() + "|updateGraphics: ignoring weird update");
break;
}
}
}
}
/**
* Check if layer will show error dialogs.
*
* @return boolean
*/
public boolean getShowDialogs() {
return showDialogs;
}
/**
* Set showDialogs behavior.
*
* @param show show dialog popups?
*/
public void setShowDialogs(boolean show) {
showDialogs = show;
}
/**
*
*/
protected void postMemoryErrorMsg(String msg) {
fireRequestMessage(new InfoDisplayEvent(this, msg));
}
/**
*
*/
protected void postCORBAErrorMsg(String msg) {
fireRequestMessage(new InfoDisplayEvent(this, msg));
}
/**
*
*/
protected void postException(String msg) {
fireRequestMessage(new InfoDisplayEvent(this, msg));
}
/**
* Free up memory after being removed from the Map
*/
public void removed(java.awt.Container cont) {
if (Debug.debugging("cspec")) {
Debug.output(getName() + "CSpecLayer.removed(): Nullifying graphics");
}
if (specialist != null) {
specialist.signoff(clientID);
}
setSpecialist(null);
}
}