Package com.bbn.openmap.layer.specialist

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

// **********************************************************************
//
// <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/Specialist.java,v $
// $RCSfile: Specialist.java,v $
// $Revision: 1.3.2.1 $
// $Date: 2004/10/14 18:26:32 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap.layer.specialist;

import com.bbn.openmap.CSpecialist.*;
import com.bbn.openmap.util.corba.CORBASupport;
import com.bbn.openmap.util.Debug;
import java.util.*;

/**
* The Specialist is the base class for all specialists. It assists
* the developer in creating a specialist and sending back graphics to
* OpenMap(TM) or MATT. This class performs management of the client
* graphics for multiple clients, and there are functions in the class
* specifically designed to do that. These functions have not been
* declared final in order to allow you to extend their functionality,
* depending on the behavior you want in your specialist.
*
* <P>
* To create your own specialist, you need to create a class that
* inherits from this one. Then, you need to define fillRectangle,
* which loads the list of graphics to send back to the client. For
* threading reasons, you must maintain the list of graphics yourself.
* The GraphicList class can assist you in that. signOff() should be
* overloaded to receive information about which client have stopped
* using the specialist.
*
* <P>
* If you want a palette, define a new version of makePalette(), using
* addPalette() to add widgets to the palette widget list.
*
* <P>
* If you want gesture information, overload receiveGesture().
*
* <P>
* As for running a specialist, in the specialist main() function, you
* only need to create an instance of your specialist, and then call
* the start() function that is a part of this class. start(),
* parseArgs() and printHelp() all are written here for simple
* execution. If your specialist has more complicated options and
* help, you'll need to overload these functions.
*
* @see GraphicList
*/
public abstract class Specialist extends ServerPOA {

    protected static String iorfile = null;
    protected static String naming = null;

    Dictionary clientPaletteLists;
    Dictionary clientGestureActionLists;

    protected Vector currentPaletteList;
    protected Vector currentGestureActionList;

    private short selectionDistance;
    private boolean wantAreaEvents;
    protected Vector graphicUpdates;

    /**
     * Default constructor. This is used to load specialist classes
     * directly into the OpenMap VM.
     */
    public Specialist() {
        this("Default", (short) 0, false);
    }

    /** The argument to the constructor is the name of the specialist. */
    public Specialist(String name) {
        this(name, (short) 0, false);
    }

    public Specialist(String name, short sd, boolean wae) {
        super();
        clientPaletteLists = new Hashtable();
        clientGestureActionLists = new Hashtable();
        graphicUpdates = new Vector();
        setSelectionDistance(sd);
        setWantAreaEvents(wae);
    }

    /**
     * This is the call for graphics that is made to the specialist.
     * You should never do anything with this method, because it does
     * the management of different clients for you. All of the
     * client's <b>getRectangle </b> requests are forwarded to
     * <b>fillRectangle </b>, which is the method you should override.
     * <P>
     */
    public UGraphic[] getRectangle(
                                   CProjection p,
                                   LLPoint llnw,
                                   LLPoint llse,
                                   String staticArgs,
                                   org.omg.CORBA.StringHolder dynamicArgs,
                                   org.omg.CORBA.ShortHolder graphicSelectableDistance,
                                   org.omg.CORBA.BooleanHolder areaEvents,
                                   GraphicChange notifyOnChange, String uniqueID) {

        try {
            UGraphic gl[] = fillRectangle(p,
                    llnw,
                    llse,
                    staticArgs,
                    dynamicArgs,
                    notifyOnChange,
                    uniqueID);
            graphicSelectableDistance.value = selectionDistance;
            areaEvents.value = wantAreaEvents;

            return gl;
        } catch (Throwable t) {
            Debug.error("Specialist.getRectangle(): " + t);
            t.printStackTrace();
            throw new RuntimeException();
        }
    }

    /**
     * The signoff function lets the specialist know that a client is
     * checking out. You should not override this method, because this
     * is where the specialist cleans up lists that have been used
     * internally to handle bookkeeping functions. <b>signoff </b>
     * calls <b>signOff </b> (big O) which is the specialist-specific
     * call to let a programmer clean up after a client.
     */
    public void signoff(String uniqueID) {
        signOff(uniqueID); // call to the specialist specific version
        clientPaletteLists.remove(uniqueID);
    }

    /**
     * getPaletteConfig is the idl call to get a palette. Palettes are
     * now managed by the specialist internally, and the specialist
     * only needs to implement <b>makePalette </b> instead. Shouldn't
     * be modified or overridden.
     */
    public UWidget[] getPaletteConfig(WidgetChange notifyOnChange,
                                      String staticArgs,
                                      org.omg.CORBA.StringHolder dynamicArgs,
                                      String uniqueID) {
        currentPaletteList = (Vector) clientPaletteLists.get(uniqueID);

        if (currentPaletteList == null) {
            currentPaletteList = new Vector();
            clientPaletteLists.put(uniqueID, currentPaletteList);
        }

        makePalette(notifyOnChange, staticArgs, dynamicArgs, uniqueID);
        return packPalette();
    }

    /*
     * packPalette is used internally, to create the UWidget[] out of
     * the Dictionary UWidgets.
     */
    protected UWidget[] packPalette() {
        int num_widgets = currentPaletteList.size();
        UWidget[] widgets = new UWidget[num_widgets];
        for (int i = 0; i < num_widgets; i++)
            widgets[i] = (UWidget) currentPaletteList.elementAt(i);
        return widgets;
    }

    /**
     * addPalette adds a palette widget to the list of palette
     * widgets. Should be called during <b>makePalette </b>.
     */
    public void addPalette(UWidget uwidget) {
        if (uwidget == null)
            return;
        currentPaletteList.addElement(uwidget);
    }

    /**
     * Sets the number of elements in the current palette widget list
     * to zero.
     */
    public void clearPalette() {
        currentPaletteList.removeAllElements();
    }

    /**
     * <b>sendGesture </b> is the arrival point for gesture
     * notifications. Again, this should not be overridden because
     * there is bookkeeping going on. All requests are sent on to
     * <b>receiveGesture </b>, which should be overridden.
     */
    public ActionUnion[] sendGesture(MouseEvent gesture, String uniqueID) {
        currentGestureActionList = (Vector) clientGestureActionLists.get(uniqueID);

        if (currentGestureActionList == null) {
            currentGestureActionList = new Vector();
            clientGestureActionLists.put(uniqueID, currentGestureActionList);
        }

        graphicUpdates.removeAllElements();
        currentGestureActionList.removeAllElements();

        try {
            receiveGesture(gesture, uniqueID);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Handle the graphics object updates as a special case,
        // because
        // the ActionUnion sequence can be made up of several objects.
        // All of the other types of gesture responses should have
        // been
        // loaded via the helper functions below.
        int num_graphicUpdates = graphicUpdates.size();
        if (num_graphicUpdates > 0) {
            UpdateRecord[] urs = new UpdateRecord[num_graphicUpdates];
            for (int i = 0; i < num_graphicUpdates; i++)
                urs[i] = (UpdateRecord) graphicUpdates.elementAt(i);
            ActionUnion au = new ActionUnion();
            au.ginfo(urs);
            currentGestureActionList.addElement(au);
        }
        return packGestures();
    }

    protected ActionUnion[] packGestures() {
        int num_actions = currentGestureActionList.size();
        ActionUnion[] actions = new ActionUnion[num_actions];
        for (int i = 0; i < num_actions; i++)
            actions[i] = (ActionUnion) currentGestureActionList.elementAt(i);
        return actions;
    }

    /**
     * Sets the number of elements in the current gesture action union
     * list to zero.
     */
    public void clearGesture() {
        currentGestureActionList.removeAllElements();
    }

    /**
     * The <b>itext </b> string will appear in the information window
     * of the client.
     */
    public void addInfoText(String itext) {
        ActionUnion ret = new ActionUnion();
        ret.itext(itext);
        currentGestureActionList.addElement(ret);
    }

    public void addPlainText(String ptext) {
        ActionUnion ret = new ActionUnion();
        ret.ptext(ptext);
        currentGestureActionList.addElement(ret);
    }

    /** The HTML string should be HTML formatted. */
    public void addHTMLText(String htext) {
        ActionUnion ret = new ActionUnion();
        ret.htext(htext);
        currentGestureActionList.addElement(ret);
    }

    /**
     * The URL string should also be formatted, as if you were passing
     * it to a browser (which you are!).
     */
    public void addURL(String url) {
        ActionUnion ret = new ActionUnion();
        ret.url(url);
        currentGestureActionList.addElement(ret);
    }

    /**
     * Get the UpdateRecord from the getGraphicUpdates method in the
     * graphic that was updated. The <b>UpdateRecord </b> can be
     * obtained by calling the <b>getGraphicUpdates </b> method of the
     * graphic object.
     */
    public void addGraphic(UpdateRecord ur) {
        graphicUpdates.addElement(ur);
    }

    /**
     * <b>fillRectangle </b> is the method that the specialist needs
     * to overridden to add the graphics to the list to be sent back.
     * The CProjection structure can provide the lat/lon center,
     * height, width, projection type and scale of the screen of the
     * client. <b>llnw </b> is the upper left coordinate of the
     * screen, and <b>llse </b> is the south east. For an OpenMap or
     * Matt client, <b>staticArgs </b> are defined in the overlay
     * table, while <b>dynamicArgs </b> are defined for the specialist
     * by the client.
     */
    public abstract UGraphic[] fillRectangle(
                                             CProjection p,
                                             LLPoint llnw,
                                             LLPoint llse,
                                             String staticArgs,
                                             org.omg.CORBA.StringHolder dynamicArgs,
                                             GraphicChange notifyOnChange,
                                             String uniqueID);

    /**
     * <b>receiveGesture </b> is the arrival point for gesture
     * notifications. Use the calls defined above to add object
     * updates, URLs, HTML text, etc, as return actions.
     *
     * @see #addInfoText
     * @see #addPlainText
     * @see #addHTMLText
     * @see #addURL
     * @see #addGraphic
     */
    public void receiveGesture(MouseEvent gesture, String uniqueID) {}

    /**
     * <b>makePalette </b> is used to create the palette for the
     * specialist. The palette widgets are: <b>SRadioButton,
     * SCheckBox, SRadioButton, SButtonBox, SSlider, SListBox </b>.
     * Add them to the palette using <b>addPalette </b>.
     *
     * @see #addPalette
     */
    public void makePalette(WidgetChange notifyOnChange, String staticArgs,
                            org.omg.CORBA.StringHolder dynamicArgs,
                            String uniqueID) {}

    protected void setWantAreaEvents(boolean setting) {
        wantAreaEvents = setting;
    }

    protected void setSelectionDistance(short value) {
        selectionDistance = value;
    }

    protected boolean getWantAreaEvents() {
        return wantAreaEvents;
    }

    protected short getSelectionDistance() {
        return selectionDistance;
    }

    /**
     * SignOff is called when a client stops. Use this to clean up
     * after a particular client.
     */
    public abstract void signOff(String uniqueID);

    /**
     * This is a default start method that initializes the specialist,
     * and handles the boa. It also handles parsing simple line
     * options (-ior and -help). If your specialist needs more
     * options, copy this function and add what you need. The args are
     * command line arguments, and the ior filename is really being
     * looked for here.
     */
    public void start(String[] args) {
        CORBASupport cs = new CORBASupport();

        if (args != null) {
            parseArgs(args);
        }

        cs.start(this, args, iorfile, naming);
    }

    /**
     * <b>parseArgs </b> should reflect the needs of your specialist.
     * It is presently defined to run with the default start() method,
     * looking for -ior and -help strings.
     */
    public void parseArgs(String[] args) {
        for (int i = 0; i < args.length; i++) {
            if (args[i].equalsIgnoreCase("-ior")) {
                iorfile = args[++i];
            } else if (args[i].equalsIgnoreCase("-name")) {
                naming = args[++i];
            } else if (args[i].equalsIgnoreCase("-help")) {
                printHelp();
            } else if (args[i].equalsIgnoreCase("-h")) {
                printHelp();
            }
        }

        // must specify an iorfile
        if (iorfile == null && naming == null) {
            Debug.error("IOR file and name service name are null!  Use `-ior' or '-name' flag!");
        }
    }

    /**
     * <b>printHelp </b> should print a usage statement which reflects
     * the command line needs of your specialist.
     */
    public void printHelp() {
        Debug.output("usage: java <specialist> [-ior <file> || -name <NAME>]");
        System.exit(1);
    }

}
TOP

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

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.