Package com.bbn.openmap.layer.specialist

Source Code of com.bbn.openmap.layer.specialist.CSpecLayer

// **********************************************************************
//
// <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.6.2.2 $
// $Date: 2005/08/09 21:17:53 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap.layer.specialist;

/*  Java Core  */
import java.awt.Component;
import java.awt.event.MouseEvent;
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.LatLonPoint;
import com.bbn.openmap.CSpecialist.CProjection;
import com.bbn.openmap.CSpecialist.GraphicChange;
import com.bbn.openmap.CSpecialist.LLPoint;
import com.bbn.openmap.CSpecialist.Server;
import com.bbn.openmap.CSpecialist.ServerHelper;
import com.bbn.openmap.CSpecialist.UGraphic;
import com.bbn.openmap.CSpecialist.UWidget;
import com.bbn.openmap.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()");

        cproj = new CProjection((short) (p.getProjectionType()), new LLPoint(p.getCenter()
                .getLatitude(), p.getCenter().getLongitude()), (short) p.getHeight(), (short) p.getWidth(), (int) p.getScale());

        // lat-lon "box", (depends on the projection)
        LatLonPoint ul = p.getUpperLeft();
        LatLonPoint lr = p.getLowerRight();

        ll1 = new LLPoint(ul.getLatitude(), ul.getLongitude());
        ll2 = new LLPoint(lr.getLatitude(), lr.getLongitude());

        // 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.addOMGraphic(jpoly);
                break;
            case GraphicType._GT_Raster:
                JRaster jraster = new JRaster(uGraphics[i].eras());
                jraster.generate(proj);
                graphics.addOMGraphic(jraster);
                break;
            case GraphicType._GT_Bitmap:
                JBitmap jbitmap = new JBitmap(uGraphics[i].ebit());
                jbitmap.generate(proj);
                graphics.addOMGraphic(jbitmap);
                break;
            case GraphicType._GT_Text:
                JText jtext = new JText(uGraphics[i].etext());
                jtext.generate(proj);
                graphics.addOMGraphic(jtext);
                break;
            case GraphicType._GT_Line:
                JLine jline = new JLine(uGraphics[i].eline());
                jline.generate(proj);
                graphics.addOMGraphic(jline);
                break;
            case GraphicType._GT_UnitSymbol:
                JUnit junit = new JUnit(uGraphics[i].eunit());
                junit.generate(proj);
                graphics.addOMGraphic(junit);
                break;
            case GraphicType._GT_2525Symbol:
                J2525 j2525 = new J2525(uGraphics[i].e2525());
                j2525.generate(proj);
                graphics.addOMGraphic(j2525);
                break;
            case GraphicType._GT_Rectangle:
                JRect jrect = new JRect(uGraphics[i].erect());
                jrect.generate(proj);
                graphics.addOMGraphic(jrect);
                break;
            case GraphicType._GT_Circle:
                JCircle jcircle = new JCircle(uGraphics[i].ecirc());
                jcircle.generate(proj);
                graphics.addOMGraphic(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.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;
            }

            // 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.CSpecialist.UpdateRecord[]
     */
    protected void updateGraphics(
                                  com.bbn.openmap.CSpecialist.UpdateRecord[] updateRec) {

        JGraphicList jGraphics = (JGraphicList) getList();
        Projection projection = getProjection();

        com.bbn.openmap.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.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.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.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.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.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.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.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.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.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.CSpecialist.GraphicPackage.GraphicType._GT_2525Symbol:
                case com.bbn.openmap.CSpecialist.GraphicPackage.GraphicType._GT_ForceArrow:
                case com.bbn.openmap.CSpecialist.GraphicPackage.GraphicType._GT_NewGraphic:
                case com.bbn.openmap.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);
    }
}
TOP

Related Classes of com.bbn.openmap.layer.specialist.CSpecLayer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.