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

📄 channelifaceimpl.java

📁 这是外国一个开源推理机
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (C) 2004 OntoText Lab, Sirma AI OOD * *  Address: *  Europe            135 Tsarigradsko Shose, Sofia 1784, Bulgaria *                    (IT Center Office Express, 3rd floor) * *  North America     438 Isabey Str, Suite 103, Montreal, Canada H4T 1V3 * *  Phone: (+359 2) 9768 310 *  Fax: (+359 2) 9768 311 * * *  E-mail:                          info@ontotext.com *  Web:                             http://www.ontotext.com *  Sirma Group International Corp.  http://www.sirma.com *  Sirma AI Ltd.                    http://www.sirma.bg * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Lesser General Public *  License as published by the Free Software Foundation; either *  version 2.1 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Lesser General Public License for more details. * *  You should have received a copy of the GNU Lesser General Public *  License along with this library; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */package org.openrdf.util.rmirouting;import java.lang.reflect.InvocationHandler;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.rmi.NoSuchObjectException;import java.rmi.Remote;import java.rmi.RemoteException;import java.rmi.server.UnicastRemoteObject;import java.rmi.server.Unreferenced;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Vector;/** * <p>The implementation of a server side <code>ChannelIface</code> wraper used to handle * all the method invocation requests made by a client. It's instances can be accessed * via the standart RMI subsystem.</p> * <p>To create and support the notion of session we provide a single, inheritable server context, * into which the current session settings are stored and mantained.</p> * <p>This is necessary because, while working with Sesame remotely through some already exported * object references, you share server resources with the other users, which may work simolatenously * with Sesame either via the HTTP or RMI. So these context help so keep track of the user from * whict the cirrrent request is originated. * <p>An example of such different, per session, settings are current user id, its password, * currently selected reposiotry, etc. So to allow a smooth multiuser access trough all * the various access layers to a single running Sesame server. To identify the different * conteexts we use a cookie which is unique among the different sessinos, but its * value is inherited from the current one, automaticaly, when a stub is created at the server.</p> * <p>The usual way to export a stub, allowing remote access to an instance, is through * the static <code>createStub()</code> method of this class.</p> * <blockquote><code><pre> * ... * SesameService localSesame = Sesame.getService("system.conf"); * Remote remoteServiceStub = ChannelIfaceImpl.createStub(localSesame); * ... * </pre></code></blockquote> * <p>While transported to the client. it can wrap this Remote ref into dynamic proxy * localy with the static <code>ChannelIfaceInvocation.wrapIt()</code> method.</p> * <blockquote><code><pre> * ... * SesameService remoteSesame = (SesameService)ChannelIfaceInvocation.wrapIt(remote); * remoteSesame.login(user, pass); * ... * </pre></code></blockquote> * All this wrapping is made automaticaly becasue all the remote calls are routed * trough instances of <code>ChannelIfaceImpl</code> and <code>ChannelIfaceInvocation</code> * where such wrappig/stubbing is done for all method arguments and its return value on both sides of the channel.</p> * <p> So only the first ever instance(usualy the one retieved from the RMI Registry) should be wrapped * in that manner as it is shown in the example above. * <p> Example on how to bind a factory to the local registry:</p> * <blockquote><code><pre> *  ... *     try { *       SesameStartup.initialize(system_conf_path); *       String sFound[] = null; *       try { *         sFound = java.rmi.Naming.list("rmi://localhost:"+RMICenter.sRMIPort+"/FactoryInterface"); *       } catch (java.rmi.ConnectException e) { *       } *       if (sFound == null || sFound.length == 0) { *           SesameServer.getSystemConfig().setRMIFactory("org.openrdf.sesame.server.rmi.FactoryInterfaceImpl", Integer.parseInt(RMICenter.sRMIPort)); *           SesameServer.getSystemConfig().setRMIEnabled(true); *           FactoryInterfaceImpl.bind(new Integer(RMICenter.sRMIPort)); *           ThreadLog.log("RMI binded to "+RMICenter.sRMIPort); *         } else { *           ThreadLog.log("Probably RMI binded to "+sFound[0]); *      } *  ... * </pre></code></blockquote> * * <p>and a short example showing how you could use Sesame locally or remote:</p> * <blockquote><code><pre> *  ... *        FactoryInterface fi = null; *        SesameRepository rep = null; *        if (bRemoteOrLocal) { * //remote *          try { *            fi = (FactoryInterface)ChannelIfaceInvocation. *                 wrapIt(java.rmi.Naming.lookup("//localhost:"+sRMIPort+"/FactoryInterface")); *          } catch (Throwable t) { *            t.printStackTrace(); *            return; *          } * *          SesameService si = fi.getService(); *          si.login("testuser", "testpass"); *          rep = si.getRepository(sRepository); *        } else { * //local *          SesameStartup.initialize(sSystemConfFile); *          rep = SesameServer.getLocalService().getRepository(RMICenter.sRepository); *        } * // eval a simple SeRQL query, no matter where is Sesame *        String query = "select X from "+ *          "{X} &lt;rdf:type&gt; {&lt;rdfs:Class&gt;} "+ *          "using namespace "+ *          "rdf = &lt;!http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt; , "+ *          "rdfs = &lt;!http://www.w3.org/2000/01/rdf-schema#&gt; "; * *          LocalQueryListener sysOutQL = new LocalQueryListener(-1); *          rep.performTableQuery(QueryLanguage.SERQL, query, sysOutQL); *  ... * </pre></code></blockquote> * * @author Damyan Ognyanoff * @version 1.0 */public class ChannelIfaceImpl implements ChannelIface, Unreferenced {  // begin - static part of the definition  /**   * the cookie is used to identify the proper server context (if any) in which the stub was created   * on the server. It is used in conjuntion with <code>set|Prolog/Epilog|Action</code>.   * To aid the developer when switching to the proper server context.   */  static ThreadLocal currentCookie = new ThreadLocal();  /**   * use it to receive the value of the cookie for the current thread   * @return the thread cookie   * @todo: probably we should use <code>InheritableThreadLocal</code> instead   */  static Object getCurrentCookie() {    return currentCookie.get();  }  /**   * use it to set the thread cookie   * @param cookie to set   */  public static void setCurrentCookie(Object cookie) {    currentCookie.set(cookie);  }  /**   * A map keeping correspondence between local objects and their stubs at the server.   * Used to resolve the object by its stub when such a stub is used as argument of the method   * being invoked   */  protected static HashMap map = new HashMap();  /**   * associate a stub with its wraped object   * @param stub that is created to wrap an object   * @param inst is the wrapped object   */  protected static void putRef(Remote stub, Object inst) {    synchronized (map) {      map.put(stub, inst);    }  }  /**   * a way to retrieve an associated instance by its wraping stub   * @param stub for which the associated instance to be retrieved   * @return the associated with the stub instance or <code>null</code> if not found in the map   */  public static ChannelIfaceImpl getRef(Remote stub) {    synchronized (map) {      return (ChannelIfaceImpl)map.get(stub);    }  }  /**   * an object used to synchronize the access to the registered prolog/epilog actions   */  private static Object SYNC_PROLOG = new Object();  /**   * an <code>RoutingAction<code> object to be invoked just BEFORE to execute   * the requested method. Used to setup the proper server context, if such swithcing is necessary.   */  private static RoutingAction aProlog = null;  /**   * an <code>RoutingAction<code> object to be invoked just AFTER the execution   * of a method. Used to cleanup the server context.   */  private static RoutingAction anEpilog = null;  /**   * a way to set an aicton which can be able to setup the proper context at the server.   * It should use the current thread cookie   * @param newAction to be set   */  public static void setPrologAction(RoutingAction newAction) {    synchronized (SYNC_PROLOG) {      aProlog = newAction;    }  }  /**   * a way to set an action which can cleanup the proper context at the server.   * It should use the current thread cookie   * @param newAction to be set   */  public static void setEpilogAction(RoutingAction newAction) {    synchronized (SYNC_PROLOG) {      aProlog = newAction;    }  }  /**   * a map which keep correspondence between native classes and their names.   * It is used to speed up, in some way, the method discovery from the description   * passed as first argument of the <code>invoke</code> method.   */  private static HashMap primitiveTypes = new HashMap();  static {    primitiveTypes.put(byte.class.getName(),byte.class);    primitiveTypes.put(char.class.getName(),char.class);    primitiveTypes.put(double.class.getName(),double.class);    primitiveTypes.put(float.class.getName(),float.class);    primitiveTypes.put(int.class.getName(),int.class);    primitiveTypes.put(long.class.getName(),long.class);    primitiveTypes.put(short.class.getName(),short.class);    primitiveTypes.put(boolean.class.getName(),boolean.class);  }  /**   * Creates an instance of the <code>ChannelIfaceImpl</code> which wraps the passed object   * and register it into the RMI object table, so its methods can be invoked remotely by   * its RemoteRef. An association between the stub and wraped instance is stored into a   * <code>map</code> member and can be queried later with <code>getRef</code>.   *   * @param instance to be wraped and for which an Remote stub to be created   * @return the remote stub to the wraped instance.   *   * Note: the wraped instance should implement at least one java interface. The methods   * of the all the implemented interfaces by the instance and its ancestors, down   * to the Object class, will be exposed to the client and be visible and availible   * for invocation.   */  public static Remote createStub(Object instance) {    Remote result = new ChannelIfaceImpl(instance);    try {      Remote stub = UnicastRemoteObject.exportObject(result);      putRef(stub, result);      return stub;    } catch (RemoteException e) {      throw new RuntimeException("error while exporting the stub!", e);    }  } //createStub()  // END - static part of the definition  /**   * <code>unreferenced</code> would be invoked by the DGC when the last remote   * reference to thist stub is being 'garbage collected'. At this point we safely   * can remove the association between the stub and the wraped instance form the map.   *   * It is derived from the <code>java.rmi.server.Unreferenced</code> interface.   */  public void unreferenced() {    if (true == instance instanceof KeepAliveWhenUnreferenced )      return;    synchronized (map) {      Iterator pairs = map.entrySet().iterator();      while (pairs.hasNext()) {        Map.Entry e = (Map.Entry)pairs.next();        if (e.getValue().equals(this)) {          try {            UnicastRemoteObject.unexportObject(this,true);          } catch (NoSuchObjectException eNSO) {            // we do not need any special handling here.            // at least in my opinion :-)          }          pairs.remove();          break;        }      }    }

⌨️ 快捷键说明

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