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

📄 channelifaceimpl.java

📁 这是外国一个开源推理机
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
  } //unreferenced()  /**   * a ref to the wrapped instance is stored here   */  transient Object instance;  /**   * the cookie associated with the stub. it is derived from the 'global' one and can be   * propagated to all the stubs created during a single remote method invocation.   */  transient private Object _cookie;  /**   * an array of the interfaces implemented by the <code>instance</code> is cached here   * This member is constructed within <code>buildInterfacesTable</code> method and   * it is not a subject of modification during the lifetime of the stub.   */  String[] interfaces = null;  /**   * the same kind of cache as the above one, but instead of the names, we keep   * the actual <code>Class</code> objects of the implemented interfaces   */  Class[] ifaceClasses = null;  /**   * a private method in which all the super classes are traversed up to the   * <code>Object</code> class and all implemented interfaces are collected   */  private void buildInterfacesTable() {    // an dynamic storage for the classes and ther names    Vector supers = new Vector();    Vector superClasses = new Vector();    // we start from the exact instance Class    Class current = instance.getClass();    // loop down until we reach the Object    while (!current.equals(Object.class)) {      // get all the implemented interfaces by this class      // these are usually ones found after the 'implements' clause of the class declatarion      Class[] ifaces = current.getInterfaces();      for (int i = 0; i < ifaces.length; i++) {        // keep them all        Class[] ifP = ifaces[i].getInterfaces();        if (ifP != null) {          for (int j = 0; j < ifP.length; j++) {            if (!supers.contains(ifP[j].getName())) {              supers.add(ifP[j].getName());              superClasses.add(ifP[j]);            }          }        }        if (!supers.contains(ifaces[i].getName())) {          supers.add(ifaces[i].getName());          superClasses.add(ifaces[i]);        }      }      // move down the hirarch chain      current = current.getSuperclass();    } // while (class chain)    // build the Array storages an dfill them    interfaces = new String[supers.size()];    ifaceClasses = new Class[supers.size()];    int i3=0;    for (Iterator i = supers.iterator(); i.hasNext(); i3++) {      interfaces[i3] = (String)i.next();      ifaceClasses[i3] = (Class)superClasses.get(i3);    } // for  } //buildInterfacesTable  /**   * the only constructor availible. it is <code>protected</code> and   * so the only way to obtain some instances is through the static <code>createStub()</code> method   *   * @param instance which is about to be wrapped   */  protected ChannelIfaceImpl(Object instance) {    // keep the instance    this.instance = instance;    // fint teh inmlemented interfaces    buildInterfacesTable();    // and store the current cookie fro later reference    this._cookie = getCurrentCookie();  } //ChannelIfaceImpl  /**   * <code>getInterfaces<code> is used by the client to obtain a list of the implemented,   * by the wrapped instance, interfaces . This list is used to create a dynamic   * proxy ont the client side, which is used to invoke any of the methods declared   * within these interfaces.   * @return an array of Strings with the class names of the implemented interfaces   * @throws RemoteException   */  public String[] getInterfaces() throws RemoteException {    return interfaces;  }  /**   * invoke - invokes a method of an 'instance' via reflection   * @param methodDescription a description of the method being invoked   * @param args - parameters opassed to the method during the call   * @return the result of the invocation or null if the method returns 'void'   * @throws RemoteException   */  public Object invoke(Object methodDescription, Object[]args) throws RemoteException {    // set the thread cookie      setCurrentCookie(_cookie);      // parse the chat array which holds the method description      // as you can see the buffer starts with the name of the method      // followed by all the class names of its arguments separated by '|' character      java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(new String((char[])methodDescription), "|", false);      // a class array used for the method lookup      Class[] paramTypes = null;      if (args != null)        paramTypes = new Class[args.length];      else        paramTypes = new Class[0];      //at least one token should be present in the descr. - the method name      // keep track of all arguments which are proxies itself so to flush their      // batch- job queues. see the 'batch' method description for more on 'batch' jobs      Vector batchedParams = new Vector();      final String methodName = tokenizer.nextToken();      try {      int i=0;      // loop through the tokens forun in the description      while (tokenizer.hasMoreTokens()) {        String token = tokenizer.nextToken();        try {          // try to resolve the class by the passed name          paramTypes[i] = Class.forName(token);        } catch (ClassNotFoundException e) {          // not found - probably it is a native type so try to looku in the          // 'primitiveTypes' map          Object oClass = primitiveTypes.get(token);          // in case we do not found it there we shoud rise the 'ClassNotFound' exception.          if (oClass == null)            throw e;          // keep the rsolved class into the param lookup array          paramTypes[i] = (Class)oClass;        } // catch class not found        // let chek if it is a proxy created by the server in some previous moment.        // we just lookup them into the associations kept in 'map' member        if (args[i] instanceof ChannelIface) {          ChannelIface tryAsLocal = getRef((Remote)args[i]);          if (tryAsLocal != null) {            // we found it there. how lucky we are so pass its wraped the instance directly            // instead of its remote wraper            if (tryAsLocal instanceof ChannelIfaceImpl)              args[i] = ((ChannelIfaceImpl)tryAsLocal).instance;          } else {            // hmm ... missing - at least we should wrap it in order to            args[i] = ChannelIfaceInvocation.wrapIt(args[i]);            // because the server can invoke some batchable methods we need to            // remember that particular instance so to flush the batchjob queue            // right after the server complete the method            if (args[i] instanceof Proxy)              batchedParams.add(Proxy.getInvocationHandler(args[i]));          }        }        i++;      }      // if there is an registered prolog action and we have a 'good' cookie to pass      // do that the prolog action      if (aProlog != null && _cookie != null) {          aProlog.doRoutingAction(_cookie);      }//      Method m = instance.getClass().getMethod(methodName, paramTypes);//      m.setAccessible(true);      // try to find the method description from the supportrd interfaces. This is made      // because the exact instance class can be 'inaccessible' - e.g. with non-public      // in such a case we cannot invoke its methods from here, but if we get the      // right method from an inmplemented by the instance interface, we safely can invoke it      // through reflection.      Method m = null;      for (int ifaceCount = 0; ifaceCount < ifaceClasses.length; ifaceCount++) {      	try{        	m = ifaceClasses[ifaceCount].getMethod(methodName, paramTypes);    	} catch (NoSuchMethodException _nsme){ m = null;}        if (m != null) {          break;        }      }      if (m == null) {        // let's check if at least, Object.class has such signature        m = Object.class.getMethod(methodName, paramTypes);        // if we are unlucky let's thge Exception go up so the user should know      }      // finally we can invoke it and collect its return value      Object result = null;//      try {      result = m.invoke(instance, args);//      } catch (Error e) {//        e.printStackTrace();//        throw new RuntimeException("Server's Error:"+e.getMessage());//      }      // if we have some Proxy parameters passed, ensure that their      // batched queues are flushed now      Iterator iter = batchedParams.iterator();      while (iter.hasNext()) {        ChannelIfaceInvocation obj = (ChannelIfaceInvocation)iter.next();        //flush the queue of that argument instance        obj.addJob(null);      }      batchedParams.clear();      batchedParams = null;      //  if there is an registered epilog action - invoke it with the our current cookie      if (anEpilog != null && _cookie != null) {          anEpilog.doRoutingAction(_cookie);      }      // let explore the result a bit. If it do not implement Remote or Serializable      // or it is not a natiove one - we can create a stub and return it instead      if (result != null && false == result instanceof Remote &&          false == result.getClass().isPrimitive() &&          false == result instanceof java.io.Serializable) {        result = ChannelIfaceImpl.createStub(result);      }      // if it is a wrapped proxy - e.g. it was wraped because it is not our for example      // unwrap and return the remote iinstance instead. This way we avoid the possability      // to wrap an instance multiple times      if (result instanceof Proxy) {        InvocationHandler iH = Proxy.getInvocationHandler(result);        if (iH instanceof ChannelIfaceInvocation)          result = ((ChannelIfaceInvocation)iH).remoteInstance;      }      return result;    } catch (InvocationTargetException t) {      // if the reflection do not goes smootly - wrap the 'cause' so the client to be      // able to find out what was went wrong      throw new RemoteException("While invoking "+methodName, t.getCause());    } catch (Exception t) {      // in case of any 'normal' exception - route it to client by      // wraping it into a remote one - so it can be safely unwraped at client side      throw new RemoteException("While invoking "+methodName, t);    }    // note that only the Exceptions are routed back to the client    // so eny Error - derived exception shouldn;t be catched by that code  } //invoke  /**   * <code>gotFinalized()</code> used by the client to notify this stub thet it was   * being 'garbage collected' at client side so we ca be quite sure that the   * association between this stub and the wraped instance can be safely removed from the storage map   * @throws RemoteException   */  public void gotFinalized() throws RemoteException {    unreferenced();  }  /**   * here we got the tricky part.   * The method <code>batch</code> is used to pass a bunch of methods   * that needs to be invoked by this stub with just one RMI call. In such a way we can reduce   * the network traffic and long delays because of the time needed by the RMI   * to complete a single method call.   * Not all invoked methods can be a subject of such batching. We decide to   * batch only methods that return 'void' and their arguments are either Serializable   * or just a native ones (e.g. char, byte, long, etc.)   * the client proxy can decide while it shoud commit the 'batchJob' queue. This   * usually can happen if a 'non-void' method or a method with non-Seralizable' or native   * arguments is being invoked. In such a case first the queue is flushed and the   * that method is passed to the stub here. In order to enable this functionality the wrapped   * instance should implement <code>Batchable</code> interface.   *   * @param jobs an array of Job objects that we need to process at once   * each Job object has the method description and array arguments use so wen can invoke it directly   * @throws RemoteException that can wrap any of the exception conditions found during the execution   */  public void batch(Object[] jobs) throws RemoteException {    for (int i = 0; i < jobs.length; i++) {      Job job = (Job)jobs[i];      java.io.ByteArrayInputStream buf = new java.io.ByteArrayInputStream(job.serializedArgs);//      java.io.BufferedInputStream bufinput = new java.io.BufferedInputStream(buf, 1024);      Object[] args = null;      try {      java.io.ObjectInputStream inputStream = new java.io.ObjectInputStream(buf);      args = (Object[])inputStream.readObject();      } catch (ClassNotFoundException ec) {        ec.printStackTrace();      } catch (java.io.IOException e) {        // should throw na exception here        e.printStackTrace();      }//      finally {//        try {//          bufinput.close();//          buf.close();//        } catch (java.io.IOException eee) {}//      }      invoke(job.methodDescription, args);    }  }//batch} //ChannelIfaceImpl

⌨️ 快捷键说明

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