Package DDEProject

Source Code of DDEProject.DDEServer

/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/
package DDEProject;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.TooManyListenersException;

import org.apache.log4j.Logger;

import Framework.Array_Of_TextData;
import Framework.ErrorMgr;
import Framework.EventManager;
import Framework.ParameterHolder;
import Framework.TextData;
import Framework.UsageException;
import Framework.remoting.parameters.Input;

import com.neva.DdeException;
import com.neva.DdeServer;
import com.neva.DdeServerConnectionEvent;
import com.neva.DdeServerTransactionEvent;
import com.neva.DdeServerTransactionRejectedException;

/**
*
* A DDEServer object is used by a Java server application to respond to requests from a DDE client application. This implementation
* currently supports only a single server (ie a single application) but with multiple topics under that server.
*
*/
public class DDEServer extends DdeServer implements DDEObject{
    private static Logger _log = Logger.getLogger(DDEServer.class);
    /** The name of the application (server) supported by this DDEServer instance */
    private String application;
    /** The topics supported by this DDEServer instance */
    private Set<String> topics;
    /** A map of client conversation ids to the actual DDEClient */
    private final Map<Integer, DDEClient> clients;
    /** A map of items to topics. Needed because Forte allowed the update of values based on the item alone */
    private final Map<String, TopicCounter> itemToTopic;
    private final Map<Integer, ItemResponse> responseData;
    private final Map<String, LinkedItem> linkedResponseData;
    private final Map<String, CommandResponse> commandResponseData;
    private int cmdID = 1;
    private int respID = 1;

    private class TopicCounter {
      String topic;
      int count;
      TopicCounter(String pTopic) {
        topic = pTopic;
      }
    }
    protected static final byte[] EMPTY = new byte[] {0x00};

    public DDEServer() {
        super();
        this.topics = new HashSet<String>();
        this.clients = new HashMap<Integer, DDEClient>();
        this.responseData = new HashMap<Integer, ItemResponse>();
        this.linkedResponseData = new HashMap<String, LinkedItem>();
        this.commandResponseData = new HashMap<String, CommandResponse>();
        this.itemToTopic = new HashMap<String, TopicCounter>();
    }
   
    public DDEServer(String application) {
        this();
        this.application = application;
        this.setService(this.application);
    }

    public DDEServer(TextData application) {
      this(application.toString());
    }
    /**
     * Use the CommandResponse method to respond to the CommandRequest event by executing the command or describing why the command failed.
     * @param client
     * @param commandID
     * @param isOkay
     * @param returnCode
     * @param isBusy
     */
    public void commandResponse(@Input DDEClient client, @Input int commandID, @Input boolean isOkay, @Input int returnCode, @Input boolean isBusy){
    CommandResponse response = new CommandResponse(client, commandID, isOkay, returnCode, isBusy);
      synchronized (this.commandResponseData){
        DDEServer.this.commandResponseData.put(client.convID+":"+commandID, response);
      }
    }
    /**
     * The EndServer method breaks the connection to the DDE client.
     */
    public void endServer( ){
        this.stop();

    }
    /**
     * Use the GetItemResponse method to respond to the GetItemRequest event by returning the specified item or describing why the request failed
     * @param client
     * @param item
     * @param isAvailable
     * @param text
     * @param returnCode
     * @param isBusy
     */
    public void getItemResponse(DDEClient client, String item, boolean isAvailable, String text, int returnCode, boolean isBusy){
        /*
         * we put the response data in storage to be picked up
         * by the transaction event listener
         */

        ItemResponse response = new ItemResponse(client, item, isAvailable, text, returnCode, isBusy);
        synchronized (this.responseData){
            this.responseData.put(client.convID, response);
        }
    }
    public void getItemResponse(DDEClient client, TextData item, boolean isAvailable, String text, int returnCode, boolean isBusy){
        this.getItemResponse(client, item.toString(), isAvailable, text, returnCode, isBusy);
    }
    public void getItemResponse(DDEClient client, TextData item, boolean isAvailable, TextData text, int returnCode, boolean isBusy){
        this.getItemResponse(client, item.toString(), isAvailable, text.toString(), returnCode, isBusy);
    }
    public void getItemResponse(DDEClient client, String item, boolean isAvailable, TextData text, int returnCode, boolean isBusy){
        this.getItemResponse(client, item, isAvailable, text.toString(), returnCode, isBusy);
    }
    /**
     * Use the LinkStartResponse method to respond to LinkStartRequest event by completing the link request.
     * @param item
     * @param isAvailable
     */
    public void linkStartResponse(String item, boolean isAvailable){

    }
    public void linkStartResponse(TextData item, boolean isAvailable){
      this.linkStartResponse(item.toString(), isAvailable);
    }
    /**
     * Use the PutItemResponse method to respond to the PutItemRequest event by accepting the new data or describing why the request failed.
     * @param client
     * @param item
     * @param isOkay
     * @param returnCode
     * @param isBusy
     * @param putItemID
     */
    public void putItemResponse(DDEClient client, int putItemID, String item, boolean isOkay, short returnCode, boolean isBusy){
        /*
         * we put the response data in storage to be picked up
         * by the transaction event listener
         */

        ItemResponse response = new ItemResponse(client, putItemID, item, isOkay, returnCode, isBusy);
        synchronized (this.responseData){
            this.responseData.put(client.convID, response);
        }

    }
    public void putItemResponse(DDEClient client, int putItemID, TextData item, boolean isOkay, short returnCode, boolean isBusy){
        this.putItemResponse(client, putItemID, item.toString(), isOkay, returnCode, isBusy);
    }
    /**
     * The StartServer method initiates the DDE server object so it is able to respond to incoming requests.
     * @param application The name of the server to listen to
     * @param topics The topics that this application supports
     */
    public void startServer(String application, Array_Of_TextData<TextData> topics){
        for (TextData topic : topics){
            this.topics.add(topic.toString());
        }
        this.application = application;
        this.setService(this.application.toString());
        this.registerEvents();
        try {
            this.start();

        } catch (DdeException e) {
            UsageException errorVar = new UsageException("Cannot start DDE server", e);
            ErrorMgr.addError(errorVar);
            _log.error("Cannot start DDE server", e);
            throw errorVar;
        }
    }
   
    /**
     * The StartServer method initiates the DDE server object so it is able to respond to incoming requests.
     * @param application The name of the server to listen to
     * @param topics The topics that this application supports
     */
    public void startServer(TextData application, Array_Of_TextData<TextData> topics){
        this.startServer(application.toString(), topics);
    }
   
    /**
     * The TerminateConnection method terminates a single connection.
     *
     * @deprecated this method is not implemented, java has no equivalent
     * @param client
     */
    public void terminateConnection(DDEClient client){

    }
    /**
     * Use the UpdateItem method to notify the DDE client when the value of a hot item has been modified and pass the client the new data.
     * This will invoke {@link #onAdvReq} on each client
     * @param item
     * @param text
     * @param client default value null
     */
    public void updateItem(String item, String text, DDEClient client){
        synchronized (this.linkedResponseData){
            LinkedItem lir = this.linkedResponseData.get(item);
            lir.value = text;
            lir.postToAllClients = (client == null);
        }
        if (client == null) {
          // Need to inform all clients about this event. Do this outside the synchronize
          // block to ensure there is no possibility of deadlock
          this.postAdvise(getTopic(item), item);
        }
    }
   
    public void updateItem(TextData item, String text, DDEClient client){
        this.updateItem(item.toString(), text, client);
    }
    public void updateItem(String item, TextData text, DDEClient client){
        this.updateItem(item, text.toString(), client);
    }
    public void updateItem(TextData item, TextData text, DDEClient client){
        this.updateItem(item.toString(), text.toString(), client);
    }
    public void updateItem(String item, String text){
        this.updateItem(item, text, null);
    }
    public void updateItem(TextData item, String text){
        this.updateItem(item == null ? null : item.toString(), text);
    }
    public void updateItem(String item, TextData text){
        this.updateItem(item, text == null ? null : text.toString());
    }
    public void updateItem(TextData item, TextData text){
        this.updateItem(item == null ? null  : item.toString(), text == null ? null : text.toString());
    }

    private void registerEvents(){
        //Register connection event listener
        try {
            this.addDdeServerConnectionEventListener(new com.neva.DdeServerConnectionEventAdaptor() {
                @Override
                public void onConnect(com.neva.DdeServerConnectionEvent e) throws com.neva.DdeServerConnectionRejectedException {
                    // Make sure the client is asking for the right topic
                    if(DDEServer.this.topics.contains(e.getTopic()) && e.getService().equalsIgnoreCase(DDEServer.this.application.toString())) {
                        if (DDEServer.this.clients.containsKey(e.getConvHandle())) {
                            com.neva.DdeServerConnectionRejectedException errorVar = new com.neva.DdeServerConnectionRejectedException();
                            ErrorMgr.addError(errorVar);
                            throw errorVar;
                        }
                        _log.debug("New Connection established");
                        return;
                    }
                    com.neva.DdeServerConnectionRejectedException errorVar = new com.neva.DdeServerConnectionRejectedException();
                    ErrorMgr.addError(errorVar);
                    throw errorVar;
                }
                @Override
                public void onConnectConfirm(DdeServerConnectionEvent e) {
                    DDEClient client = DDEServer.this.addClient(e.getConvHandle(), e.getTopic());
                    Hashtable<String, ParameterHolder> qq_Params = new Hashtable<String, ParameterHolder>();
                    qq_Params.put( "client", new ParameterHolder(client));
                    EventManager.postEventAndWait(DDEServer.this, "Connected", qq_Params);
                    _log.debug("New Connection confirmed");
                }
                @Override
                public void onDisconnect(DdeServerConnectionEvent e) {
                    if (DDEServer.this.clients.containsKey(e.getConvHandle())){
                        DDEClient client = DDEServer.this.clients.get(e.getConvHandle());
                        synchronized (DDEServer.this.clients) {
                            DDEServer.this.clients.remove(e.getConvHandle());
                        }
                        Hashtable<String, ParameterHolder> qq_Params = new Hashtable<String, ParameterHolder>();
                        qq_Params.put( "client", new ParameterHolder(client));
                        EventManager.postEventAndWait(DDEServer.this, "Disconnected", qq_Params);
                        _log.debug("Disconnected");
                    }
                    return;
                }
            });
        } catch (TooManyListenersException e) {
            _log.error(e);
        }

        //Register transaction event listener
        try {
            this.addDdeServerTransactionEventListener(new com.neva.DdeServerTransactionEventAdaptor() {

                @Override
                public void onPoke(DdeServerTransactionEvent e)
                throws DdeServerTransactionRejectedException {
                    DDEClient client = getClient(e.getConvHandle());
                    String value = new String(e.getDdeData());
                    value = value.trim();
                    Hashtable<String, ParameterHolder> qq_Params = new Hashtable<String, ParameterHolder>();
                    qq_Params.put( "client", new ParameterHolder(client));
                    qq_Params.put( "putItemID", new ParameterHolder(getRespID()));
                    qq_Params.put( "text", new ParameterHolder(new TextData(value)));
                    qq_Params.put( "item", new ParameterHolder(new TextData(e.getItem())));
                    _log.debug("PutItemRequest: " + e.getItem() + " : " + value);
                    EventManager.postEventAndWait(DDEServer.this, "PutItemRequest", qq_Params);
                    ItemResponse response;
                    synchronized (DDEServer.this.responseData){
                        response = DDEServer.this.responseData.get(e.getConvHandle());
                        DDEServer.this.responseData.remove(e.getConvHandle());
                    }
                    if (response == null){
                        _log.debug("Processing: putItemResponse() with nothing");
                        e.setRequestedData(EMPTY);
                    } else {
                        _log.debug("Processing: putItemResponse() with " + response);
                        e.setRequestedData(new byte[] {(byte)response.getReturnCode()});
                    }
                    return;
                }

                @Override
                public void onRequest(com.neva.DdeServerTransactionEvent e)
                        throws com.neva.DdeServerTransactionRejectedException {
                    DDEClient client = getClient(e.getConvHandle());
                    Hashtable<String, ParameterHolder> qq_Params = new Hashtable<String, ParameterHolder>();
                    qq_Params.put( "client", new ParameterHolder(client));
                    qq_Params.put( "item", new ParameterHolder(new TextData(e.getItem())));
                    _log.debug("Posting: GetItemRequest for " + e.getItem());
                    EventManager.postEventAndWait(DDEServer.this, "GetItemRequest", qq_Params);

                    ItemResponse response;
                    synchronized (DDEServer.this.responseData){
                        response = DDEServer.this.responseData.get(e.getConvHandle());
                        DDEServer.this.responseData.remove(e.getConvHandle());
                    }
                    if (response == null){
                        _log.debug("Processing: getItemResponse() with nothing");
                        e.setRequestedData(EMPTY);
                    } else {
                        _log.debug("Processing: getItemResponse() with " + response);
                        e.setRequestedData(response.getTextAsCString());
                    }
                    return;
                }

                @Override
                public void onExecute(DdeServerTransactionEvent e)
                throws DdeServerTransactionRejectedException {
                    DDEClient client = getClient(e.getConvHandle());
                    int ID = getCmdID();
                    String command = new String(e.getDdeData());
                    Hashtable<String, ParameterHolder> qq_Params = new Hashtable<String, ParameterHolder>();
                    qq_Params.put( "client", new ParameterHolder(client));
                    qq_Params.put( "command", new ParameterHolder(new TextData(command)));
                    qq_Params.put( "commandID", new ParameterHolder(ID));
                    _log.debug("CommandRequest : " + command);
                    EventManager.postEventAndWait(DDEServer.this, "CommandRequest", qq_Params);
                    CommandResponse response;
                    synchronized (DDEServer.this.commandResponseData){
                        response = DDEServer.this.commandResponseData.get(e.getConvHandle()+":"+ID);
                        DDEServer.this.commandResponseData.remove(e.getConvHandle()+":"+ID);
                    }
                    if (response == null){
                        _log.debug("Processing: CommandResponse() with nothing");
                        e.setRequestedData(EMPTY);
                    } else {
                        _log.debug("Processing: CommandResponse() with " + response);
                        e.setRequestedData(new byte[] {(byte)response.getReturnCode(), 0});
                    }
                    return;
                }
                //======================================
                // linked item methods
                //======================================
                /**
                 * onAdvReq is called once for each client when postAdvise is called (from the UpdateItem method).
                 * We need to update the passed event with the data to be returned to the particular client.
                 * @throws DdeServerTransactionRejectedException
                 */
                @Override
                public void onAdvReq(DdeServerTransactionEvent e) throws DdeServerTransactionRejectedException {
                    DDEClient client = getClient(e.getConvHandle());
                    String item = e.getItem();

                    // Most of this code is obsolete. The use of the LinkedItemRequest is Forte is odd, and never
                    // seems to get posted. Hence, this method will only ever be called from the postAdvise method
                    // which should ensure that there is valid linked response data set up. So it really will just
                    // call e.setRequestedData().
                    LinkedItem response;
                  synchronized (DDEServer.this.linkedResponseData){
                    response = DDEServer.this.linkedResponseData.get( item );
                  }
                  if (response == null) {
                    Hashtable<String, ParameterHolder> qq_Params = new Hashtable<String, ParameterHolder>();
                    qq_Params.put( "client", new ParameterHolder(client));
                    qq_Params.put( "item", new ParameterHolder(new TextData(item)));
                    qq_Params.put( "isHot", new ParameterHolder(true));
                    _log.debug("LinkedItemRequest : " + item);
                    EventManager.postEventAndWait(DDEServer.this, "LinkedItemRequest", qq_Params);
                      synchronized (DDEServer.this.linkedResponseData){
                        response = DDEServer.this.linkedResponseData.get( item );
                        if (response == null){
                          _log.debug("Processing: request UpdateItem() with nothing");
                          e.setRequestedData(EMPTY);
                            } else {
                          _log.debug("Processing: request UpdateItem() with " + response);
                                e.setRequestedData(response.getTextAsCString());
                            }
                        // Clear out the linked response
                        linkedResponseData.remove(item);
                      }
                    }
                    else {
                      e.setRequestedData(response.getTextAsCString());
                    }
                    return;
               

                @Override
                public void onAdvStart(DdeServerTransactionEvent e)
                throws DdeServerTransactionRejectedException {
                    DDEClient client = getClient(e.getConvHandle());
                    String item = e.getItem();
                    String topic = e.getTopic();
                    addTopicToItemMap(item, topic);
                    synchronized (DDEServer.this.linkedResponseData){
                        LinkedItem li = DDEServer.this.linkedResponseData.get( item );
                        if ( li == null){
                            li = new LinkedItem(item, "");
                            DDEServer.this.linkedResponseData.put(item, li);
                        }
                        li.addClient(client);
                    }

                    Hashtable<String, ParameterHolder> qq_Params = new Hashtable<String, ParameterHolder>();
                    qq_Params.put( "item", new ParameterHolder(new TextData(e.getItem())));
                    _log.debug("LinkStartRequest : " + e.getItem());
                    EventManager.postEventAndWait(DDEServer.this, "LinkStartRequest", qq_Params);
                    synchronized (DDEServer.this.linkedResponseData){
                        LinkedItem lir = DDEServer.this.linkedResponseData.get(item);
                        _log.debug("Processing: start UpdateItem() with " + lir);
                        e.setRequestedData(lir.getTextAsCString());
                    }
                    return;
                }

                @Override
                public void onAdvStop(DdeServerTransactionEvent e)
                throws DdeServerTransactionRejectedException {
                    DDEClient client = getClient(e.getConvHandle());
                    String item = e.getItem();
                    String topic = e.getTopic();
                    removeTopicFromItemMap(item, topic);
                    synchronized (DDEServer.this.linkedResponseData){
                        LinkedItem lir = DDEServer.this.linkedResponseData.get(item);
                        if (lir != null){
                            lir.removeClient(client);
                        }
                    }
                    Hashtable<String, ParameterHolder> qq_Params = new Hashtable<String, ParameterHolder>();
                    qq_Params.put( "item", new ParameterHolder(new TextData(e.getItem())));
                    _log.debug("LinkEndRequest : " + e.getItem());
                    EventManager.postEventAndWait(DDEServer.this, "LinkEndRequest", qq_Params);
                    return;
                }
            });
        } catch (TooManyListenersException e) {
            _log.error(e);
        }

    }
    /**
     * Creates an new {@link DDEClient}, base on the conversation ID, and added it to the list.
     * @param convID
     */
    private DDEClient addClient(int convID, String topic){
        DDEClient client = new DDEClient();
        client.convID = convID;
        client.setTopic(new TextData(topic));
        synchronized (DDEServer.this.clients) {
            DDEServer.this.clients.put(client.convID, client);
        }
        return client;
    }
    /**
     * returns a {@link DDEClient} based on the conversation ID. If one does not exist, it is created.
     * @param convID
     */
    private DDEClient getClient(int convID){
        DDEClient client;
        if (this.clients.containsKey(convID))
            client = this.clients.get(convID);
        else {
          throw new UsageException("Shouldn't be here!");
        }
        return client;
    }
    /**
     * returns a unique command id
     */
    private synchronized int getCmdID(){
        return this.cmdID++;
    }
    private synchronized int getRespID(){
        return this.respID++;
    }
    public TextData getApplication() {
        return new TextData(this.application);
    }
    public void setApplication(TextData application) {
        this.application = application.toString();

    }
    @Override
    public String toString(){
        return "DDEServer ["+ application + "]";
    }
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        this.linkedResponseData.clear();
        this.commandResponseData.clear();
        this.topics.clear();
        this.responseData.clear();
        this.clients.clear();
        this.itemToTopic.clear();
    }

    private void addTopicToItemMap(String pItem, String pTopic) {
      synchronized (itemToTopic) {
        TopicCounter counter = itemToTopic.get(pItem);
        if (counter == null) {
          counter = new TopicCounter(pTopic);
          itemToTopic.put(pItem, counter);
        }
        counter.count++;
      }
    }

    private void removeTopicFromItemMap(String pItem, String pTopic) {
      synchronized (itemToTopic) {
        TopicCounter counter = itemToTopic.get(pItem);
        if (counter != null) {
          if (--counter.count == 0) {
            itemToTopic.remove(counter);
          }
        }
      }
    }
   
    private String getTopic(String pItem) {
      synchronized (itemToTopic) {
      TopicCounter counter = itemToTopic.get(pItem);
      if (counter != null) {
        return counter.topic;
      }
    }
      return null;
    }

    /**
     * this class is used to store the item response for the DDEServer
     *
     */
    protected class ItemResponse {
        DDEClient client;
        String item;
        boolean isAvailable;
        String text;
        int returnCode;
        boolean isBusy;
        int putItemID;
        boolean isOKay;

        public ItemResponse(DDEClient client, String item, boolean isAvailable,
                String text, int returnCode, boolean isBusy) {
            super();
            this.client = client;
            this.item = item;
            this.isAvailable = isAvailable;
            this.text = text;
            this.returnCode = returnCode;
            this.isBusy = isBusy;

        }
        public ItemResponse(DDEClient client, int putItemID, String item,
                boolean isOkay, short returnCode, boolean isBusy) {
            super();
            this.client = client;
            this.putItemID = putItemID;
            this.item = item;
            this.isOKay = isOkay;
            this.returnCode = returnCode;
            this.isBusy = isBusy;
        }
        public DDEClient getClient() {
            return client;
        }
        public String getItem() {
            return item;
        }
        public boolean isAvailable() {
            return isAvailable;
        }
        public String getText() {
            return text;
        }
        public byte[] getTextAsCString(){
            byte[] result = new byte[text.length() + 1];
            System.arraycopy(text.getBytes(), 0, result, 0, text.length());
            result[result.length-1] = 0;
            return result;
        }
        public int getReturnCode() {
            return returnCode;
        }
        public boolean isBusy() {
            return isBusy;
        }
        public int getPutItemID() {
            return putItemID;
        }
        public boolean isOKay() {
            return isOKay;
        }
        public String toString(){
            return "["+ client.convID + ", " + item  + ", " + isAvailable  + ", " + text  + ", " + returnCode  + ", " + isBusy + ", " + putItemID + ", " + isOKay + "]";
        }

    }
    /**
     * This class holds the Command Response parameters
     * @author Peter
     *
     */
    protected class CommandResponse {
        DDEClient client;
        int commandID;
        boolean isOKay;
        int returnCode;
        boolean isBusy;
        public CommandResponse(DDEClient client, int commandID, boolean isOKay,
                int returnCode, boolean isBusy) {
            super();
            this.client = client;
            this.commandID = commandID;
            this.isOKay = isOKay;
            this.returnCode = returnCode;
            this.isBusy = isBusy;
        }
        public DDEClient getClient() {
            return client;
        }
        public int getCommandID() {
            return commandID;
        }
        public boolean isOKay() {
            return isOKay;
        }
        public int getReturnCode() {
            return returnCode;
        }
        public boolean isBusy() {
            return isBusy;
        }
        public String toString(){
            return "["+ client.convID + ", " + commandID  + ", " + isOKay  + ", " + returnCode  + ", " + isBusy  + "]";
        }

    }
    protected class LinkedItem {
        String item;
        String value;
        boolean postToAllClients;
        HashMap<Integer, DDEClient> clients = new HashMap<Integer, DDEClient>();
        public LinkedItem(String item, String value) {
            super();
            this.item = item;
            this.value = value;
        }
        public String getItem() {
            return item;
        }
        public String getValue() {
            return value;
        }
        public byte[] getTextAsCString(){
            byte[] result = new byte[value.length() + 1];
            System.arraycopy(value.getBytes(), 0, result, 0, value.length());
            result[result.length-1] = 0;
            return result;
        }
        public String toString(){
            return "[" + item  + ", " + value  + "]";
        }

        public void addClient(DDEClient client){
            this.clients.put(client.convID, client);
        }
        public void removeClient(DDEClient client){
            this.clients.remove(client.convID);
        }
    public boolean isPostToAllClients() {
      return postToAllClients;
    }
    public void setPostToAllClients(boolean postToAllClients) {
      this.postToAllClients = postToAllClients;
    }
    }
}
TOP

Related Classes of DDEProject.DDEServer

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.