Package javaclients.graphical

Source Code of javaclients.graphical.XmlBlasterDrawing

/*------------------------------------------------------------------------------
Name:      GraphicChat.java
Project:   xmlBlaster.org
Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
------------------------------------------------------------------------------*/

package javaclients.graphical;

import CH.ifa.draw.framework.FigureChangeEvent;
import CH.ifa.draw.framework.Figure;
import CH.ifa.draw.standard.StandardDrawing;

import java.util.logging.Logger;
import java.util.logging.Level;
import org.xmlBlaster.util.def.Constants;
import org.xmlBlaster.util.Global;
import org.xmlBlaster.util.Timestamp;
import org.xmlBlaster.util.XmlBlasterException;
import org.xmlBlaster.util.I_Timeout;
import org.xmlBlaster.util.Timeout;
import org.xmlBlaster.client.I_XmlBlasterAccess;
import org.xmlBlaster.client.qos.*;
import org.xmlBlaster.client.key.*;
import org.xmlBlaster.util.qos.HistoryQos;
import org.xmlBlaster.util.MsgUnit;

import org.xmlBlaster.client.I_Callback;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.io.IOException;
import CH.ifa.draw.framework.Drawing;


/**
* @author <a href="mailto:michele@laghi.eu">Michele Laghi</a>
*/
public  class XmlBlasterDrawing extends StandardDrawing implements I_Timeout, I_Callback {

   private static final String ME = "XmlBlasterDrawing";
   private Global global;
   private static Logger log = Logger.getLogger(XmlBlasterDrawing.class.getName());
   /** inhibit events to avoid loops when events are generated in update method */
   private boolean doPublishEvent;
   /** key = timestamp, value = object reference (Figure) */
   private HashMap timestampFigureTable;
   /** key = object reference (Figure), value = timestamp */
   private HashMap figureTimestampTable;
   private HashSet[] newChanged;
   private int currentIndex = 0;
   private int publishIndex = 1;
   private Timeout timeout;
   private long publishDelay = 5000L;
   private I_XmlBlasterAccess access;
   private SubscribeReturnQos subRetQos;
   private String drawingName = "GraphicChat";
   private SubscribeReturnQos subscribeReturnQos;
   private boolean isBurstPublish; // if true publish are collected and sent on bulk

   public XmlBlasterDrawing() {
      super();
      init(Global.instance());
      if (log.isLoggable(Level.FINER)) this.log.finer("default contructor");
   }

   public XmlBlasterDrawing(Global global) {
      super();
      init(global);
      if (log.isLoggable(Level.FINER)) this.log.finer("global contructor");
   }

   public void init(Global global) {
      this.global = global.getClone(null);

      if (log.isLoggable(Level.FINER)) this.log.finer("init");
      this.doPublishEvent = true;
      this.timestampFigureTable = new HashMap();
      this.figureTimestampTable = new HashMap();
      this.newChanged = new HashSet[2];
      for (int i=0; i < 2; i++) {
         this.newChanged[i] = new HashSet();
      }
      this.publishDelay = this.global.getProperty().get("publishDelay", 200L);
      if (this.publishDelay > 0L) this.isBurstPublish = true;
      else isBurstPublish = false;
      if (this.isBurstPublish) {
         this.timeout = new Timeout("PublishTimer");
         this.timeout.addTimeoutListener(this, this.publishDelay, this);
     
      if (this.getTitle() != null) this.drawingName = this.getTitle();
      initConnection();
   }

   public void initConnection() {
      try {
         if (log.isLoggable(Level.FINER)) this.log.finer("initConnection");
         this.access = this.global.getXmlBlasterAccess();
         ConnectQos qos = new ConnectQos(this.global);
         this.access.connect(qos, this)// Login to xmlBlaster, register for updates

         SubscribeKey sk = new SubscribeKey(this.global, "/xmlBlaster/key[drawingName='" + this.drawingName + "']", Constants.XPATH);
         SubscribeQos sq = new SubscribeQos(this.global);
         sq.setWantLocal(false);
         sq.setWantInitialUpdate(true);
         HistoryQos historyQos = new HistoryQos(this.global);
         historyQos.setNumEntries(1);
         sq.setHistoryQos(historyQos);
        
         // this.publishMetaInfo(this.drawingName);
         this.subscribeReturnQos = this.access.subscribe(sk, sq);
      }
      catch (XmlBlasterException ex) {
         log.severe("initConnection. Exception : " + ex.getMessage());
         ex.printStackTrace();
      }
   }

   synchronized public void shutdown() {
      if (log.isLoggable(Level.FINER)) this.log.finer("shutdown");
      try {
         if (this.subscribeReturnQos != null) {
            this.access.unSubscribe(new UnSubscribeKey(this.global, this.subscribeReturnQos.getSubscriptionId()), new UnSubscribeQos(this.global));
         }
         this.access.disconnect(new DisconnectQos(this.global));
         log.info("successfully shutdown drawing (unsubscribed and disconnected");
      }
      catch (XmlBlasterException ex) {
         log.severe("shutdown. Exception : " + ex.getMessage());
      }
   }


   synchronized private void swapIndex() {
      if (this.currentIndex == 0) {
         this.currentIndex = 1;
         this.publishIndex = 0;
      }
      else {
         this.currentIndex = 0;
         this.publishIndex = 1;
      }
   }

   synchronized public void figureChanged(FigureChangeEvent e) {
      if (log.isLoggable(Level.FINER)) this.log.finer("figureChanged event='" + e.toString() + "'");
      if (e.getFigure() instanceof Drawing) {
         if (log.isLoggable(Level.FINE)) this.log.fine("figureChanged for a Drawing instance " + e.getFigure());
         return;
      }
      super.figureChanged(e);
      if (this.doPublishEvent) {
         StorableFigureHolder figureHolder = getFigureHolder(e.getFigure());
         if (this.isBurstPublish) this.newChanged[this.currentIndex].add(figureHolder);
         else publish(figureHolder);
      }
      if (log.isLoggable(Level.FINER)) this.log.finer("figureChanged " + e.getFigure());
   }

   protected void addToTable(StorableFigureHolder figureHolder) {
      String figureId = figureHolder.getFigureId();
      Figure figure = figureHolder.getFigure();
      synchronized (this.timestampFigureTable) {
         this.figureTimestampTable.put(figure, figureHolder);
         this.timestampFigureTable.put(figureId, figureHolder);
      }
   }  

   protected void removeFromTable(StorableFigureHolder figureHolder) {
      if (log.isLoggable(Level.FINER)) this.log.finer("remove");
      String figureId = figureHolder.getFigureId();
      Figure figure = figureHolder.getFigure();
      synchronized (this.timestampFigureTable) {
         if (figure != null) {
            this.figureTimestampTable.remove(figure);
         }
         if (figureId != null) {
            this.timestampFigureTable.remove(figureId);
         }
      }
   }

   private StorableFigureHolder getFigureHolder(Figure figure) {
      // MEMO: getAttribute does not work when using 'group or lines'
      StorableFigureHolder figureHolder = (StorableFigureHolder)this.figureTimestampTable.get(figure);
      if (figureHolder == null) {
         String timestamp = "" + (new Timestamp()).getTimestampLong();
         String figureId = this.drawingName + "-" + timestamp;
         figureHolder = new StorableFigureHolder(figure, figureId, null);
         addToTable(figureHolder);
      }
      return figureHolder;
   }

   synchronized public Figure add(Figure figure) {
      if (log.isLoggable(Level.FINER)) this.log.finer("add");
      if (figure instanceof Drawing) return figure;
      if (this.doPublishEvent) {
         StorableFigureHolder figureHolder = getFigureHolder(figure);
         if (this.isBurstPublish) this.newChanged[this.currentIndex].add(figureHolder);
         else publish(figureHolder);
         if (log.isLoggable(Level.FINE)) this.log.fine("add: adding '" + figureHolder.getFigureId() + "'");
      }
      return super.add(figure);
   }

   synchronized public void bringToFront(Figure figure) {
      if (log.isLoggable(Level.FINER)) this.log.finer("bringToFront");
      if (this.doPublishEvent) {
         ((StorableFigureHolder)this.figureTimestampTable.get(figure)).setToFront("true");
      }
      super.bringToFront(figure);
   }

   synchronized public Figure orphan(Figure figure) {
      if (log.isLoggable(Level.FINER)) this.log.finer("orphan");
      if (figure instanceof Drawing) return figure;
      if (this.doPublishEvent) {
         try {
            erase(figure);
         }
         catch (XmlBlasterException ex) {
            String figureId = ((StorableFigureHolder)this.figureTimestampTable.get(figure)).getFigureId();
            log.severe("orphan '" + figureId + "' exception : " + ex.getMessage());
            ex.printStackTrace();
         }
      }
      return super.orphan(figure); // clean from my drawing area
   }

   public synchronized void sendToBack(Figure figure) {
      if (log.isLoggable(Level.FINER)) this.log.finer("sendToBack");
      if (this.doPublishEvent) {
         ((StorableFigureHolder)this.figureTimestampTable.get(figure)).setToFront("false");
      }
      super.sendToBack(figure);
   }

   public synchronized void sendToLayer(Figure figure, int layerNr) {
      if (log.isLoggable(Level.FINER)) this.log.finer("sendToLayer");
      super.sendToLayer(figure, layerNr);
   }

   public synchronized void setTitle(java.lang.String name) {
      if (log.isLoggable(Level.FINER)) this.log.finer("");
      super.setTitle(name);
   }


   /**
    * Invoked by the timer
    */
   public synchronized void timeout(Object userData) {
      try {
         swapIndex();
         if (this.newChanged[this.publishIndex].size() == 0) return;
         Iterator iter = this.newChanged[this.publishIndex].iterator();
         while (iter.hasNext()) {
            StorableFigureHolder figureHolder = (StorableFigureHolder)iter.next();
            if (figureHolder.getFigure() instanceof Drawing) continue;
            publish(figureHolder);
         }
         this.newChanged[this.publishIndex].clear();
      }
      catch (Throwable ex) {
         log.warning("timeout: exception occured in timeout: " + ex.getMessage());
         ex.printStackTrace();
      }
      finally {
         this.timeout.addTimeoutListener(this, this.publishDelay, this);
      }
   }

   // publish -----------------------------------------------------------

   private void publish(StorableFigureHolder figureHolder) {
      if (log.isLoggable(Level.FINER)) this.log.finer("publish");
      // publish the message here ...
      if (figureHolder == null || figureHolder.getFigure() instanceof Drawing) return;
      try {
         String figureId = figureHolder.getFigureId();
         if (log.isLoggable(Level.FINE)) this.log.fine("publish '" + figureId + "'");
         PublishKey pk = new PublishKey(this.global, figureId, "application/draw", "1.0");
         pk.setClientTags("<drawingName>"+this.drawingName+"</drawingName>");
         PublishQos pq = new PublishQos(this.global);

         MsgUnit msgUnit = new MsgUnit(pk, figureHolder.toBytes(), pq);
         this.access.publish(msgUnit);
      }
      catch (IOException ex) {
         log.severe("exception occured when publishing: " + ex.toString());
      }
      catch (XmlBlasterException ex) {
         log.severe("exception occured when publishing: " + ex.getMessage());
      }
   }

   private void publishMetaInfo(String data) {
      if (log.isLoggable(Level.FINER)) this.log.finer("publishMetaInfo");
      // publish the message here ...
      try {
         PublishKey pk = new PublishKey(this.global, null, "text/plain", "1.0");
         pk.setClientTags("<drawingMetadata>"+this.drawingName+"</drawingMetadata>");
         PublishQos pq = new PublishQos(this.global);

         MsgUnit msgUnit = new MsgUnit(pk, data.getBytes(), pq);
         this.access.publish(msgUnit);
      }
      catch (XmlBlasterException ex) {
              log.severe("exception occured when publishing: " + ex.getMessage());
      }
   }

   // erase ---------------------------------------------------------------

   private void erase(Figure figure) throws XmlBlasterException {
      if (log.isLoggable(Level.FINER)) this.log.finer("erase");
      if (figure == null) return;
      StorableFigureHolder figureHolder = (StorableFigureHolder)this.figureTimestampTable.get(figure);
      if (figureHolder == null) return;
      String figureId = figureHolder.getFigureId();
      if (log.isLoggable(Level.FINE)) this.log.fine("erase '" + figureId + "'");
      EraseKey ek = new EraseKey(this.global, figureId);
      EraseQos eq = new EraseQos(this.global);
      EraseReturnQos[] eraseArr = this.access.erase(ek, eq);
      removeFromTable(figureHolder);
   }

   // update ---------------------------------------------------------------

   private void currentFigureUpdate(StorableFigureHolder figureHolder) {
      if (log.isLoggable(Level.FINER)) this.log.finer("currentFigureUpdate");
      boolean sendToBack = false;
      boolean sendToFront = false;
      String toFront = figureHolder.getToFront();
      if (toFront != null) {
         boolean val = "true".equalsIgnoreCase(toFront);
         log.info("update: the attribute 'TO_FRONT' is set to '" + val + "'");
         if (val == true) sendToFront = true;
         else sendToBack = true;                        
         // setFigureAttribute(fig, TO_FRONT, null);
      }
      String figureId = figureHolder.getFigureId();
      if (log.isLoggable(Level.FINE)) this.log.fine("currentFigureUpdate figureId='" + figureId + "'");
      if (figureId == null) return;
      // String figureId = msgContent.getFigureId();
      log.info("update figure: '" + figureId  + "' changed or added");
      StorableFigureHolder oldFigureHolder = (StorableFigureHolder)this.timestampFigureTable.get(figureId);

      Figure fig = figureHolder.getFigure();
      if (oldFigureHolder == null) {
         addToTable(figureHolder);
         super.add(fig);
      }
      else {
         Figure oldFigure = oldFigureHolder.getFigure();
         super.replace(oldFigure, fig);
         removeFromTable(oldFigureHolder);
         addToTable(figureHolder);
         FigureChangeEvent ev = new FigureChangeEvent(oldFigure);
         figureRequestUpdate(ev);
         if (sendToFront) {
            if (log.isLoggable(Level.FINE)) this.log.fine("update: send to front");
            bringToFront(fig);
         }
         else if (sendToBack) {
            if (log.isLoggable(Level.FINE)) this.log.fine("update: send to back");
            sendToBack(fig);
         }
      }
      FigureChangeEvent ev1 = new FigureChangeEvent(fig);
      figureRequestUpdate(ev1);
   }

   public synchronized String update(String cbSessionId, UpdateKey updateKey, byte[] content, UpdateQos updateQos) {
      log.info("update for '" + cbSessionId + "', '" + updateKey.getOid() + "' length of msg is '" + content.length + "'");
      try {
         lock();
         this.doPublishEvent = false;
             
         if (updateQos.isErased()) {
            log.info("Message '" + updateKey.getOid() + "' is erased");
            String figureId = updateKey.getOid();
            StorableFigureHolder figHolder = (StorableFigureHolder)this.timestampFigureTable.get(figureId);
            if (figHolder != null) {
               removeFromTable(figHolder);
               Figure fig = figHolder.getFigure();
               Figure figToRelease = super.orphan(fig);
               FigureChangeEvent ev = new FigureChangeEvent(fig);
               figureRequestUpdate(ev);
               figToRelease.release();
            }
            return "OK";
         }

         StorableFigureHolder figureHolder = StorableFigureHolder.fromBytes(content);
         currentFigureUpdate(figureHolder);
      }
      catch (IOException ex) {
         log.severe("update: an IOException occured when reconstructing the content: " + ex.getMessage());
      }
      catch (Throwable ex) {
         log.severe("update: a Throwable occured when reconstructing the content (acknowledge anyway): " + ex.getMessage());
         ex.printStackTrace();
      }
      finally {
         this.doPublishEvent = true;
         unlock();
      }
      return "OK";
   }

   public void release() {
      if (log.isLoggable(Level.FINER)) this.log.finer("release");
      shutdown();
      super.release();
   }



   /*
      public void figureInvalidated(FigureChangeEvent e) {
         super.figureInvalidated(e);
         if (log.isLoggable(Level.FINER)) this.log.finer("figureInvalidated " + e.getFigure());
      }

      public void figureRemoved(FigureChangeEvent e) {
         super.figureRemoved(e);
         if (log.isLoggable(Level.FINER)) this.log.finer("figureRemoved " + e.getFigure());
      }

      public void figureRequestRemove(FigureChangeEvent e) {
         super.figureRequestRemove(e);
         if (log.isLoggable(Level.FINER)) this.log.finer("figureRequestRemove " + e.getFigure());
      }

      public void figureRequestUpdate(FigureChangeEvent e) {
         super.figureRequestUpdate(e);
         if (log.isLoggable(Level.FINER)) this.log.finer("figureRequestUpdate");
      }

      public void addAll(FigureEnumeration fe) {
         if (log.isLoggable(Level.FINER)) this.log.finer("addAll");
         super.addAll(fe);
      }

      public void init(java.awt.Rectangle viewRectangle) {
         if (log.isLoggable(Level.FINER)) this.log.finer("init");
         super.init(viewRectangle);
      }

      public void orphanAll(FigureEnumeration fe) {
         if (log.isLoggable(Level.FINER)) this.log.finer("orphanAll");
         super.orphanAll(fe);
      }

      public Figure remove(Figure figure) {
         if (log.isLoggable(Level.FINER)) this.log.finer("remove");
         return super.remove(figure);
      }

      public void removeAll(FigureEnumeration fe) {
         if (log.isLoggable(Level.FINER)) this.log.finer("removeAll");
         super.removeAll(fe);
      }

      public Figure replace(Figure figure, Figure replacement) {
         if (log.isLoggable(Level.FINER)) this.log.finer("replace");
         return super.replace(figure, replacement);
      }
   */
}
 
TOP

Related Classes of javaclients.graphical.XmlBlasterDrawing

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.