/*
* JacORB - a free Java ORB
*
* Copyright (C) 1997-2004 Gerald Brose.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.jacorb.orb.rmi;
/**
* @author Gerald Brose
* @version $Id: PortableRemoteObjectDelegateImpl.java,v 1.7 2008-11-14 08:55:35 nick.cross Exp $
*/
import java.rmi.Remote;
import javax.rmi.CORBA.Stub;
import javax.rmi.CORBA.Tie;
import javax.rmi.CORBA.Util;
import org.omg.CORBA.ORB;
import org.omg.CORBA.portable.ObjectImpl;
public class PortableRemoteObjectDelegateImpl implements javax.rmi.CORBA.PortableRemoteObjectDelegate
{
private static org.jacorb.orb.ORB _orb = null;
/**
* Return the ORB to be used for RMI communications.
* @return The ORB
*/
public static synchronized ORB getORB()
{
if ( _orb == null )
{
_orb = (org.jacorb.orb.ORB)ORB.init( new String[0], null );
}
return _orb;
}
/**
* Set the ORB to be used for RMI communications.
* @param orb The ORB to use
*/
public static synchronized void setORB( ORB orb )
{
if ( _orb != null )
{
throw new IllegalStateException( "RMI orb has already been initialized" );
}
_orb = (org.jacorb.orb.ORB)orb;
}
/**
* Export an RMI object as a CORBA object
* @see javax.rmi.CORBA.PortableRemoteObjectDelegate#exportObject(java.rmi.Remote)
*/
public void exportObject( java.rmi.Remote obj ) throws java.rmi.RemoteException
{
if (obj == null)
{
throw new IllegalArgumentException();
}
if ( obj instanceof Stub )
{
throw new java.rmi.server.ExportException( "Attempted to export a stub class" );
}
Tie tie = Util.getTie( obj );
if ( tie != null )
{
throw new java.rmi.server.ExportException( "Object already exported" );
}
tie = toTie( obj );
tie.orb( getORB() );
Util.registerTarget( tie, obj );
}
/**
* Return the Stub for a RMI object.
* @param obj The RMI object
* @return The Stub object
* @see javax.rmi.CORBA.PortableRemoteObjectDelegate#toStub(java.rmi.Remote)
*/
public java.rmi.Remote toStub( java.rmi.Remote obj ) throws java.rmi.NoSuchObjectException
{
if ( obj instanceof Stub )
{
return obj;
}
Tie tie = null;
if ( obj instanceof Tie )
{
tie = ( Tie ) obj;
obj = tie.getTarget();
}
else
{
tie = Util.getTie( obj );
}
if ( tie == null )
{
throw new java.rmi.NoSuchObjectException( "Object not exported" );
}
final org.omg.CORBA.portable.ObjectImpl thisObject = (ObjectImpl) tie.thisObject();
final String[] ids = thisObject._ids();
for (int i = 0; i < ids.length; ++i)
{
final String repoID = ids[i];
final String stubClazzName = newRMIStubName(repoID);
try
{
final Stub stub = newStub(stubClazzName, obj.getClass());
stub._set_delegate(thisObject._get_delegate());
return (Remote) stub;
} catch (ClassNotFoundException e)
{
// ignored
} catch (InstantiationException e)
{
// ignored
} catch (IllegalAccessException e)
{
// ignored
}
}
throw new java.rmi.NoSuchObjectException( "Object not exported" );
}
/**
* Deactivate the exported RMI object.
* @param obj The RMI object
* @see javax.rmi.CORBA.PortableRemoteObjectDelegate#unexportObject(java.rmi.Remote)
*/
public void unexportObject( java.rmi.Remote obj ) throws java.rmi.NoSuchObjectException
{
Tie tie = Util.getTie( obj );
if ( tie == null )
{
throw new java.rmi.NoSuchObjectException( "Object not exported" );
}
Util.unexportObject( obj );
}
/**
* Narrow the remote object.
* @param obj The remote object
* @param newClass The class to narrow to
* @return the narrowed object
* @see javax.rmi.CORBA.PortableRemoteObjectDelegate#narrow(java.lang.Object, java.lang.Class)
*/
public Object narrow( Object obj, Class newClass ) throws ClassCastException
{
if (newClass == null)
{
throw new ClassCastException("Can't narrow to null class");
}
if (obj == null)
{
return null;
}
Class fromClass = obj.getClass();
try
{
if (newClass.isAssignableFrom(fromClass))
{
return obj;
}
}
catch(Exception e)
{
// ignored
}
throw new ClassCastException("Can't narrow from " + fromClass + " to " + newClass);
}
/**
* @see javax.rmi.CORBA.PortableRemoteObjectDelegate#connect(java.rmi.Remote, java.rmi.Remote)
*/
public void connect( java.rmi.Remote target, java.rmi.Remote source ) throws java.rmi.RemoteException
{
throw new UnsupportedOperationException("Not implemented for PortableRemoteObjectDelegateImpl");
}
/**
* Return the Tie object for an RMI object.
* @param obj The RMI object.
* @return The Tie object
* @throws java.rmi.server.ExportException
*/
private Tie toTie(java.rmi.Remote obj) throws java.rmi.server.ExportException
{
for (Class clz = obj.getClass(); clz != null; clz = clz.getSuperclass())
{
try
{
final String tieClzName = newRMIClassName(clz.getName(), "Tie");
return newTie(tieClzName, clz);
}
catch (ClassNotFoundException e)
{
// throw new java.rmi.server.ExportException("ClassNotFoundException: ", e );
}
catch (InstantiationException e)
{
throw new java.rmi.server.ExportException("InstantiationException: ", e);
}
catch (IllegalAccessException e)
{
throw new java.rmi.server.ExportException("IllegalAccessException: ", e);
}
}
throw new java.rmi.server.ExportException("Tie class not found ");
}
/**
* Java Language to IDL Mapping 00-01-06 1.4.6:
*
* The stub class corresponding to an RMI/IDL interface or implementation class may
* either be in the same package as its associated interface or class, or may be further
* qualified by the org.omg.stub package prefix.
*
* When loading a stub class corresponding to an interface or class
* <packagename>.<typename>, the class <packagename>._<typename>_Stub shall be
* used if it exists; otherwise, the class org.omg.stub.<packagename>._<typename>_Stub
* shall be used.
*/
private Stub newStub(String clazzName, Class source) throws InstantiationException, IllegalAccessException, ClassNotFoundException
{
try
{
return (Stub) newInstance(clazzName, source);
}
catch (ClassNotFoundException e)
{
return (Stub) newInstance("org.omg.stub." + clazzName, source);
}
}
private javax.rmi.CORBA.Tie newTie(String clazzName, Class source) throws InstantiationException, IllegalAccessException, ClassNotFoundException
{
try
{
return (Tie) newInstance(clazzName, source);
}
catch (ClassNotFoundException e)
{
return (Tie) newInstance("org.omg.stub." + clazzName, source);
}
}
private Object newInstance(String clazzName, Class source) throws InstantiationException, IllegalAccessException, ClassNotFoundException
{
return loadClass(clazzName, source).newInstance();
}
private Class loadClass(String clazzName, Class source) throws ClassNotFoundException
{
return Util.loadClass(clazzName, Util.getCodebase(source), source.getClassLoader());
}
private String newRMIStubName(final String repoID)
{
final String clazzName = repoID.substring(4, repoID.lastIndexOf(':'));
return newRMIClassName(clazzName, "Stub");
}
private String newRMIClassName(final String name, final String suffix)
{
final StringBuffer buffer = new StringBuffer(name.length() + 2 + suffix.length());
final int idx = name.lastIndexOf('.') + 1;
buffer.append(name.substring(0, idx));
buffer.append('_');
buffer.append(name.substring(idx, name.length()));
buffer.append('_');
buffer.append(suffix);
return buffer.toString();
}
}