⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlscriptaccess.java

📁 java开源的企业总线.xmlBlaster
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------Name:      XmlScriptAccess.javaProject:   xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE fileComment:   Bean to export with Windows ActiveX bridge------------------------------------------------------------------------------*/package org.xmlBlaster.client.activex;import java.io.ByteArrayOutputStream;import java.io.StringReader;import java.io.OutputStream;import java.io.Reader;import java.util.Properties;import java.beans.SimpleBeanInfo;import EDU.oswego.cs.dl.util.concurrent.Latch; // http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.htmlimport java.util.logging.Logger;import java.util.logging.Level;import org.xmlBlaster.util.Global;import org.xmlBlaster.util.XmlBlasterException;import org.xmlBlaster.util.def.ErrorCode;import org.xmlBlaster.client.script.XmlScriptClient;import org.xmlBlaster.client.script.XmlScriptInterpreter;import org.xmlBlaster.client.I_Callback;import org.xmlBlaster.client.SynchronousCache;import org.xmlBlaster.client.protocol.I_CallbackServer;import org.xmlBlaster.client.qos.ConnectQos;import org.xmlBlaster.client.qos.ConnectReturnQos;import org.xmlBlaster.client.qos.DisconnectQos;import org.xmlBlaster.client.key.UpdateKey;import org.xmlBlaster.client.qos.UpdateQos;import org.xmlBlaster.client.key.GetKey;import org.xmlBlaster.client.key.SubscribeKey;import org.xmlBlaster.client.key.UnSubscribeKey;import org.xmlBlaster.client.key.EraseKey;import org.xmlBlaster.client.qos.GetQos;import org.xmlBlaster.client.qos.PublishReturnQos;import org.xmlBlaster.client.qos.SubscribeQos;import org.xmlBlaster.client.qos.SubscribeReturnQos;import org.xmlBlaster.client.qos.EraseQos;import org.xmlBlaster.client.qos.EraseReturnQos;import org.xmlBlaster.client.qos.UnSubscribeQos;import org.xmlBlaster.client.qos.UnSubscribeReturnQos;import org.xmlBlaster.util.MsgUnit;/** * This bean can be exported to a Microsoft dll (ActiveX component) and * be accessed by C# or Visual Basic.Net  * <p> * Here we support XML scripting access as described in the <i>client.script</i> requirement * by calling <code>sendRequest()</code> or alternatively you can use the methods * like <code>publishStr()</code> or <code>subscribe()</code> directly. The latter * methods have the advantage to return a ready parsed object to the ActiveX component, * for example Visual Basic can directly call all methods of <code>SubscribeReturnQos</code> * which is returned by <code>subscribe()</code>. * </p> * <p> * Compile the ActiveX control with <code>build activex</code> and see Visual Basic * and C# samples in directory <code>xmlBlaster/demo/activex</code>. * </p> * <p> * As events into ActiveX can't have a return value and can't throw * an exception back to us we handle it here as a callback, for example * Visual Basic needs to call <code>sendUpdateReturn()</code> or <code>sendUpdateException()</code> after * processing a message received by <code>update()</code>. * Our update thread blocks until one of those two methods is called, however * the blocking times out after 10 minutes which is adjustable with * the property <code>client/activex/responseWaitTime</code> given in milli seconds. * </p> * <p> * One instance of this can hold one permanent connection to the xmlBlaster server, * multi threaded access is supported. * </p> * * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/client.script.html">client.script requirement</a> * @see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/beans/axbridge/developerguide/index.html">ActiveX Bridge Developer Guide</a> * @author <a href="mailto:xmlBlaster@marcelruff.info">Marcel Ruff</a> */public class XmlScriptAccess extends SimpleBeanInfo implements I_Callback {   private static String ME = "XmlScriptAccess";   private final Global glob;   private static Logger log = Logger.getLogger(XmlScriptAccess.class.getName());   private XmlScriptInterpreter interpreter;   private Reader reader;   private OutputStream outStream;   private UpdateListener updateListener;   // As events into ActiveX can't have a return value and can't throw   // an exception back to us we handle it here as a callback   private Latch updateReturnLatch;   private String updateReturnQos;   private XmlBlasterException updateReturnException;   private long responseWaitTime;   /**    * Create a new access bean.     * We read a xmlBlaster.properties file if one is found    */   public XmlScriptAccess() {      this.glob = new Global();  // Reads xmlBlaster.properties      // Wait max 10 minutes for update() method in C#/VB to return:      this.responseWaitTime = this.glob.getProperty().get("client/activex/responseWaitTime", 1000L * 60L * 10L);      if (log.isLoggable(Level.FINER)) log.finer("Calling ctor of XmlScriptAccess, responseWaitTime=" + this.responseWaitTime);      // Use socket protocol as default setting      String protocol = this.glob.getProperty().get("protocol", "");      if ("".equals(protocol)) {         try {            this.glob.getProperty().set("protocol", "SOCKET");         }         catch (XmlBlasterException e) {            log.severe("Failed setting SOCKET protocol, we continue nevertheless: " + e.toString());         }      }   }   /**    * Add a C# / VisualBasic listener over the ActiveX bridge.     * This method is called automatically when activating the bridge    */   public void addUpdateListener(UpdateListener updateListener) /* throws java.util.TooManyListenersException */ {      log.info("Registering update listener");      if (log.isLoggable(Level.FINEST)) Thread.dumpStack();      this.updateListener = updateListener;   }   /**    * Remove a C# / VisualBasic listener.     * This method is called automatically when deactivating the bridge    */   public void removeUpdateListener(UpdateListener updateListener) {      log.info("Removing update listener");      if (log.isLoggable(Level.FINEST)) Thread.dumpStack();      this.updateListener = null;   }   /**    * Fire an event into C# / VisualBasic containing an updated message.     * <br />    * Note: The ActiveX event can't convey a return value or an exception back    * to us. There for we block the thread and wait until the    * activeX component has delivered us a return value or an exception by    * calling setUpdateReturn() or setUpdateException()     */   protected synchronized String notifyUpdateEvent(String cbSessionId, UpdateKey key, byte[] content, UpdateQos qos) throws XmlBlasterException {      if (this.updateListener == null) {         log.warning("No updateListener is registered, ignoring " + key.toXml());         return "<qos><state id='WARNING'/></qos>";      }      UpdateEvent ev = new UpdateEvent(this, cbSessionId, key, content, qos);      if (log.isLoggable(Level.FINE)) log.fine("Notifying updateListener with new message " + key.toXml());      this.updateReturnLatch = new Latch();      this.updateListener.update(ev);      boolean awaikened = false;      while (true) {         try {            if (log.isLoggable(Level.FINE)) log.fine("notifyUpdateEvent() Entering wait ...");            awaikened = this.updateReturnLatch.attempt(this.responseWaitTime); // block max. milliseconds            break;         }         catch (InterruptedException e) {            log.warning("Waking up (waited on " + key.getOid() + " update response): " + e.toString());            // try again         }      }      try {         if (awaikened) {            if (this.updateReturnQos != null) {               if (log.isLoggable(Level.FINE)) log.fine("Notifying updateListener done: returned '" + this.updateReturnQos + "'");               return this.updateReturnQos;            }            else if (this.updateReturnException != null) {               log.warning("Update failed: " + this.updateReturnException.getMessage());               throw this.updateReturnException;            }            else {               log.severe("Update failed, no return available");               throw new XmlBlasterException(this.glob, ErrorCode.USER_UPDATE_ERROR, ME, "Update to ActiveX failed, no return available");            }         }         else {            String str = "Timeout of " + this.responseWaitTime + " milliseconds occured when waiting on " + key.getOid() + " return value";            log.warning(str);            throw new XmlBlasterException(glob, ErrorCode.USER_UPDATE_ERROR, ME, str);         }      }      finally {         this.updateReturnLatch = null;      }   }   /**    * ActiveX code needs to call this method to set the return value    * for the current update message.     * Alternatively you can call setUpdateException() to pass back    * an exception.    * <br />    * Note: You have to call setUpdateReturn() OR setUpdateException()    * for each update message to release the blocking thread!    *    * @param updateReturnQos for example "<qos><state id='OK'/></qos>"    * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.update.html">The interface.update requirement</a>    */   public void setUpdateReturn(String updateReturnQos) {      if (this.updateReturnLatch == null) {         log.warning("Ignoring setUpdateReturn(), updateReturnLatch == null, probably a timeout occurred");         return;      }      this.updateReturnQos = updateReturnQos;      this.updateReturnException = null;      this.updateReturnLatch.release();      if (log.isLoggable(Level.FINER)) log.finer("setUpdateReturn() called");   }   /**    * ActiveX code can call this method to return an exception for     * the current update message    * @param errorCode Only known ErrorCode strings of type "user.*" are allowed    * @see org.xmlBlaster.util.def.ErrorCode    */   public void setUpdateException(String errorCode, String message) {      if (this.updateReturnLatch == null) {         log.warning("Ignoring setUpdateException(), updateReturnLatch == null, probably a timeout occurred");         return;      }      this.updateReturnQos = null;      ErrorCode code = null;      try {         code = ErrorCode.toErrorCode(errorCode);      }      catch (IllegalArgumentException e) {         log.warning("Don't know error code '" + errorCode + "', changing it to " + ErrorCode.USER_UPDATE_ERROR.toString());         message += ": original errorCode=" + errorCode;         code = ErrorCode.USER_UPDATE_ERROR;      }      this.updateReturnException = new XmlBlasterException(this.glob, code, ME, message);      this.updateReturnLatch.release();      if (log.isLoggable(Level.FINER)) log.finer("setUpdateException() called");   }   /**    * Access a Properties object to be used later for initialize().     * @return We create a new instance for you    */   public Properties createPropertiesInstance() {      return new Properties();   }      /**    * Initialize the environment.     */   public void initialize(Properties properties) {      this.glob.init(properties);   }   /**    * Initialize the environment.     * If you use the initialize(Properties) variant or this method makes no difference.    * @param args Command line arguments for example { "-protocol", SOCKET, "-logging", "FINE" }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -