User: reverbel
Date: 01/08/28 15:19:00
Added: iiop/src/main/org/jboss/ejb/plugins/iiop/client
DynamicStub.java StubClassLoader.java
StubStrategy.java
Log:
Adding support for dynamic generation of IIOP stub classes.
Revision Changes Path
1.1
contrib/iiop/src/main/org/jboss/ejb/plugins/iiop/client/DynamicStub.java
Index: DynamicStub.java
===================================================================
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.iiop.client;
import javax.rmi.CORBA.Util;
import org.omg.CORBA_2_3.portable.ObjectImpl;
import org.omg.CORBA_2_3.portable.InputStream;
import org.omg.CORBA_2_3.portable.OutputStream;
import org.omg.CORBA.portable.ApplicationException;
import org.omg.CORBA.portable.RemarshalException;
import org.omg.CORBA.SystemException;
import org.jboss.proxy.InvocationHandler;
/**
* Dynamically generated IIOP stub classes extend this abstract superclass,
* which extends <code>org.omg.CORBA_2_3.portable.ObjectImpl</code>.
*
* A <code>DynamicStub</code> is a local proxy of a remote object. It has
* methods (<code>invoke()</code>, <code>invokeBoolean()</code>,
* <code>invokeByte()</code>, and so on) that send an IIOP request to the
* server that implements the remote object, receive the reply from the
* server, and return the results to the caller. All of these methods take
* the IDL name of the operation, a <code>StubStrategy</code> instance to be
* used for marshalling parameters and unmarshalling the result, plus an array
* of operation parameters.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Francisco Reverbel</a>
* @version $Revision: 1.1 $
*/
public abstract class DynamicStub
extends ObjectImpl
{
// Constructor -------------------------------------------------------------
/**
* Constructs a <code>DynamicStub</code>.
*/
public DynamicStub()
{
super();
}
// Protected methods used by dynamically generated IIOP stubs --------------
/**
* Sends a request message to the server, receives the reply from the
* server, and returns an <code>Object</code> result to the caller.
*/
protected Object invoke(String operationName,
StubStrategy stubStrategy, Object[] params)
throws Throwable
{
InputStream in = null;
try {
try {
OutputStream out =
(OutputStream)_request(operationName, true);
stubStrategy.writeParams(out, params);
System.err.println("sent request: " + operationName);
in = (InputStream)_invoke(out);
if (stubStrategy.isNonVoid()) {
System.err.println("received reply");
//return stubStrategy.readRetval(in);
Object retval = stubStrategy.readRetval(in);
System.err.println("retval: " + retval);
return retval;
}
else
return null;
}
catch (ApplicationException ex) {
System.err.println("got application exception");
in =(InputStream)ex.getInputStream();
throw stubStrategy.readException(in);
}
catch (RemarshalException ex) {
System.err.println("got remarshal exception");
return invoke(operationName, stubStrategy, params);
}
}
catch (SystemException ex) {
ex.printStackTrace(System.err);
throw Util.mapSystemException(ex);
}
finally {
_releaseReply(in);
}
}
/**
* Sends a request message to the server, receives the reply from the
* server, and returns a <code>boolean</code> result to the caller.
*/
protected boolean invokeBoolean(String operationName,
StubStrategy stubStrategy, Object[] params)
throws Throwable
{
return ((Boolean)invoke(operationName,
stubStrategy, params)).booleanValue();
}
/**
* Sends a request message to the server, receives the reply from the
* server, and returns a <code>byte</code> result to the caller.
*/
protected byte invokeByte(String operationName,
StubStrategy stubStrategy, Object[] params)
throws Throwable
{
return ((Number)invoke(operationName,
stubStrategy, params)).byteValue();
}
/**
* Sends a request message to the server, receives the reply from the
* server, and returns a <code>char</code> result to the caller.
*/
protected char invokeChar(String operationName,
StubStrategy stubStrategy, Object[] params)
throws Throwable
{
return ((Character)invoke(operationName,
stubStrategy, params)).charValue();
}
/**
* Sends a request message to the server, receives the reply from the
* server, and returns a <code>short</code> result to the caller.
*/
protected short invokeShort(String operationName,
StubStrategy stubStrategy, Object[] params)
throws Throwable
{
return ((Number)invoke(operationName,
stubStrategy, params)).shortValue();
}
/**
* Sends a request message to the server, receives the reply from the
* server, and returns an <code>int</code> result to the caller.
*/
protected int invokeInt(String operationName,
StubStrategy stubStrategy, Object[] params)
throws Throwable
{
return ((Number)invoke(operationName, stubStrategy, params)).intValue();
}
/**
* Sends a request message to the server, receives the reply from the
* server, and returns a <code>long</code> result to the caller.
*/
protected long invokeLong(String operationName,
StubStrategy stubStrategy, Object[] params)
throws Throwable
{
return ((Number)invoke(operationName, stubStrategy, params)).longValue();
}
/**
* Sends a request message to the server, receives the reply from the
* server, and returns a <code>float</code> result to the caller.
*/
protected float invokeFloat(String operationName,
StubStrategy stubStrategy, Object[] params)
throws Throwable
{
return ((Number)invoke(operationName,
stubStrategy, params)).floatValue();
}
/**
* Sends a request message to the server, receives the reply from the
* server, and returns a <code>double</code> result to the caller.
*/
protected double invokeDouble(String operationName,
StubStrategy stubStrategy, Object[] params)
throws Throwable
{
return ((Number)invoke(operationName,
stubStrategy, params)).doubleValue();
}
}
1.1
contrib/iiop/src/main/org/jboss/ejb/plugins/iiop/client/StubClassLoader.java
Index: StubClassLoader.java
===================================================================
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.iiop.client;
import org.jboss.proxy.IIOPStubCompiler;
/**
* This class loader dynamically generates and loads client stub classes.
* It is intended to be used by clients, as an interim solution.
* Should not be necessary when the IORs contain a JAVA_CODE_BASE tag.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Francisco Reverbel</a>
* @version $Revision: 1.1 $
*/
public class StubClassLoader
extends ClassLoader
{
// Constructor -------------------------------------------------------------
public StubClassLoader(ClassLoader parent)
{
super(parent);
}
// Protected ---------------------------------------------------------------
protected Class findClass(String name)
throws ClassNotFoundException
{
System.err.println("findClass(" + name + ") called");
if (name.endsWith("_Stub")) {
int start = name.lastIndexOf('.') + 1;
if (name.charAt(start) == '_') {
String pkg = name.substring(0, start);
String interfaceName = pkg + name.substring(start + 1,
name.length() - 5);
System.err.println("interface name " + interfaceName);
Class intf = loadClass(interfaceName);
System.err.println("loaded class " + interfaceName);
try {
byte[] code = IIOPStubCompiler.compile(intf, name);
System.err.println("compiled stub class for " + interfaceName);
Class clz = defineClass(name, code, 0, code.length);
System.err.println("defined stub class for " + interfaceName);
resolveClass(clz);
System.err.println("resolved stub class for " + interfaceName);
return clz;
}
catch (RuntimeException e) {
System.err.println("-----------------------------------------");
e.printStackTrace(System.err);
System.err.println("-----------------------------------------");
throw e;
}
}
}
throw new ClassNotFoundException(name);
}
}
1.1
contrib/iiop/src/main/org/jboss/ejb/plugins/iiop/client/StubStrategy.java
Index: StubStrategy.java
===================================================================
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.iiop.client;
import java.util.HashMap;
import java.util.Map;
import java.rmi.UnexpectedException;
import org.omg.CORBA_2_3.portable.InputStream;
import org.omg.CORBA_2_3.portable.OutputStream;
import org.jboss.ejb.plugins.iiop.CDRStream;
import org.jboss.ejb.plugins.iiop.CDRStreamReader;
import org.jboss.ejb.plugins.iiop.CDRStreamWriter;
/**
* A <code>StubStrategy</code> for a given method knows how to marshal
* the sequence of method parameters into a CDR output stream, how to unmarshal
* from a CDR input stream the return value of the method, and how to unmarshal
* from a CDR input stream an application exception thrown by the method.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Francisco Reverbel</a>
* @version $Revision: 1.1 $
*/
public class StubStrategy
{
// Fields ------------------------------------------------------------------
/**
* Each <code>CDRStreamWriter</code> in the array marshals a method
* parameter.
*/
private CDRStreamWriter[] paramWriters;
/**
* Maps exception repository ids into exception classes.
*/
private Map exceptionMap;
/**
* A <code>CDRStreamReader</code> that unmarshals the return value of the
* method.
*/
private CDRStreamReader retvalReader;
// Static ------------------------------------------------------------------
/**
* Returns a <StubStrategy> for a method, given descriptions of the
* method parameters, exceptions, and return value. Parameter and return
* value descriptions are "marshaller abbreviated names".
*
* @param paramTypes a string array with marshaller abbreviated names for
* the method parameters
* @param excepIds a string array with the CORBA repository ids of the
* exceptions thrown by the method
* @param excepTypes a string array with the Java class names of the
* exceptions thrown by the method
* @param retvalTypes marshaller abbreaviated name for the return value of
* the method
* @param cl a <code>ClassLoader</code> to load value classes
* (if null, the current thread's context class loader
* will be used)
* @return a <StubStrategy> for the operation with the parameters,
* exceptions, and return value specified.
* @see org.jboss.ejb.plugins.iiop.abbrevFor(Class clz)
*/
public static StubStrategy forMethod(String[] paramTypes,
String[] excepIds,
String[] excepTypes,
String retvalType,
ClassLoader cl)
{
// This "factory method" exists just because I have found it easier
// to invoke a static method (rather than invoking operator new)
// from a stub class dynamically assembled by an instance of
// org.jboss.proxy.ProxyAssembler.
return new StubStrategy(paramTypes, excepIds,
excepTypes, retvalType, cl);
}
// Constructor -------------------------------------------------------------
/**
* Constructs a <StubStrategy> for a method, given descriptions of the
* method parameters, exceptions, and return value. Parameter and return
* value descriptions are "marshaller abbreviated names".
*
* @param paramTypes a string array with marshaller abbreviated names for
* the method parameters
* @param excepIds a string array with the CORBA repository ids of the
* exceptions thrown by the method
* @param excepTypes a string array with the Java class names of the
* exceptions thrown by the method
* @param retvalTypes marshaller abbreaviated name for the return value of
* the method
* @param cl a <code>ClassLoader</code> to load value classes
* (if null, the current thread's context class loader
* will be used)
* @see org.jboss.ejb.plugins.iiop.abbrevFor(Class clz)
*/
private StubStrategy(String[] paramTypes, String[] excepIds,
String[] excepTypes, String retvalType,
ClassLoader cl)
{
if (cl == null) {
cl = Thread.currentThread().getContextClassLoader();
}
// Initialize paramWriters
int len = paramTypes.length;
paramWriters = new CDRStreamWriter[len];
for (int i = 0; i < len; i++) {
paramWriters[i] = CDRStream.writerFor(paramTypes[i], cl);
}
// Initialize exception map
exceptionMap = new HashMap();
len = excepIds.length;
for (int i = 0; i < len; i++) {
try {
exceptionMap.put(excepIds[i] , cl.loadClass(excepTypes[i]));
}
catch (ClassNotFoundException e) {
throw new RuntimeException("Error loading class "
+ excepTypes[i] + ": " + e);
}
}
// Initialize retvalReader
retvalReader = CDRStream.readerFor(retvalType, cl);
}
// Public -----------------------------------------------------------------
/**
* Marshals the sequence of method parameters into an output stream.
*
* @param out a CDR output stream
* @param params an object array with the parameters.
*/
public void writeParams(OutputStream out, Object[] params)
{
int len = params.length;
if (len != paramWriters.length) {
throw new RuntimeException("Cannot marshal parameters: "
+ "unexpected number of parameters");
}
for (int i = 0; i < len; i++ ) {
paramWriters[i].write(out, params[i]);
}
}
/**
* Returns true if this <code>StubStrategy</code>'s method is non void.
*/
public boolean isNonVoid()
{
return (retvalReader != null);
}
/**
* Unmarshals from an input stream the return value of the method.
*
* @param in a CDR input stream
* @return a value unmarshaled from the stream.
*/
public Object readRetval(InputStream in)
{
return retvalReader.read(in);
}
/**
* Unmarshals from an input stream an exception thrown by the method.
*
* @param in a CDR input stream
* @return an exception unmarshaled from the stream.
*/
public Exception readException(InputStream in)
{
String repositoryId = in.read_string();
Class exceptionClass = (Class)exceptionMap.get(repositoryId);
if (exceptionClass == null) {
return new UnexpectedException(repositoryId);
}
else {
return (Exception)in.read_value(exceptionClass);
}
}
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development