User: andreas
Date: 00/08/31 10:46:18
Added: src/main/org/jboss/jmx/server ObjectHandler.java
RMIConnectorImpl.java RMIConnectorService.java
RMIConnectorServiceMBean.java
Log:
Server-side Connector implementation which runs within
jBoss.
Revision Changes Path
1.1 jboss/src/main/org/jboss/jmx/server/ObjectHandler.java
Index: ObjectHandler.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.jmx.server;
import java.io.Serializable;
/**
* Object returned to the client to use it as an handler to an object created
* and stored on the server side. The server side implementation has to look
* for instances of these class and then to replace them by the objec thez
* refer to.
*
* @author <A href="mailto:[EMAIL PROTECTED]">Andreas "Mad"
Schaefer</A>
**/
public class ObjectHandler
implements Serializable
{
// Constants -----------------------------------------------------
// Static --------------------------------------------------------
/** Unique number generator **/
private int
sNextUniqueNumber = 0;
// Members -------------------------------------------------------
/**
* Server reference to ensure that this object is handled on this
* server
**/
private String mServerReference;
/** Object index used within the server to reference the effectiv object **/
private int
mObjectReference;
// Constructors --------------------------------------------------
/**
* Creates an Object Handler
*
* @param pServerReference Server Reference which should
be unique
* within
the network
*
* @return Object handler
which can be used to
*
reference a object on the server side
*/
public ObjectHandler(
String pServerReference
) {
if( pServerReference == null ) {
throw new IllegalArgumentException( "Server Reference must not
be null" );
}
mServerReference = pServerReference;
mObjectReference = sNextUniqueNumber++;
}
// Public --------------------------------------------------------
/**
* @return Server
Reference
**/
public String getServerReference() {
return mServerReference;
}
/**
* @return Unique object
reference
*/
public int getObjectReference() {
return mObjectReference;
}
/**
* Checks if two Object Handler are equal even when the went over the net
*
* @pTest Object to test
against
*
* @return True the given
object is instance
* of
Object Handler and have the same
* Server
and Object Reference
**/
public boolean equals( Object pTest ) {
if( pTest instanceof ObjectHandler ) {
ObjectHandler lTest = (ObjectHandler) pTest;
return
getServerReference().equals(
lTest.getServerReference() ) &&
getObjectReference() == lTest.getObjectReference();
}
return false;
}
/**
* @return Hash code for
this Object Handler which
* is
just the sum of Server and Object
*
reference
*/
public int hashCode() {
return
getServerReference().hashCode() +
getObjectReference();
}
}
1.1 jboss/src/main/org/jboss/jmx/server/RMIConnectorImpl.java
Index: RMIConnectorImpl.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.jmx.server;
import java.io.ObjectInputStream;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.ObjectInstance;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.MBeanServer;
import javax.management.MBeanInfo;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanRegistrationException;
import javax.management.NotCompliantMBeanException;
import javax.management.OperationsException;
import javax.management.ReflectionException;
import javax.naming.InitialContext;
import org.jboss.logging.Log;
import org.jboss.util.ServiceMBeanSupport;
import org.jboss.jmx.interfaces.RMIConnector;
import org.jboss.jmx.interfaces.RMINotificationListener;
/**
* RMI Interface for the server side Connector which
* is nearly the same as the MBeanServer Interface but
* has an additional RemoteException.
* <BR>
* AS 8/18/00
* <BR>
* Add the ObjectHandler to enable this server-side implementation to instantiate
* objects locally but enable the client to use them as parameter from the
* client side transparently (except that the user cannot invoke a method on this
* instance).
*
* @author Rickard �berg ([EMAIL PROTECTED])
* @author <A href="mailto:[EMAIL PROTECTED]">Andreas "Mad"
Schaefer</A>
**/
public class RMIConnectorImpl
extends UnicastRemoteObject
implements RMIConnector
{
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
/**
* Reference to the MBeanServer all the methods of this Connector are
* forwarded to
**/
private MBeanServer mServer;
/** Pool of object referenced by an object handler **/
private Hashtable mObjectPool = new
Hashtable();
/** Pool of registered listeners **/
private Vector mListeners = new
Vector();
// Static --------------------------------------------------------
// Public --------------------------------------------------------
// Constructors --------------------------------------------------
public RMIConnectorImpl(
MBeanServer pServer
) throws RemoteException {
super();
mServer = pServer;
}
// RMIConnector implementation -------------------------------------
public Object instantiate(
String pClassName
) throws
ReflectionException,
MBeanException,
RemoteException
{
return assignObjectHandler(
mServer.instantiate( pClassName )
);
}
public Object instantiate(
String pClassName,
ObjectName pLoaderName
) throws
ReflectionException,
MBeanException,
InstanceNotFoundException,
RemoteException
{
return assignObjectHandler(
mServer.instantiate( pClassName, pLoaderName )
);
}
public Object instantiate(
String pClassName,
String[] pParams,
String[] pSignature
) throws
ReflectionException,
MBeanException,
RemoteException
{
// First check the given parameters to see if there is an ObjectHandler
// to be replaced
checkForObjectHandlers(
pParams,
pSignature
);
return assignObjectHandler(
mServer.instantiate(
pClassName,
pParams,
pSignature
)
);
}
public Object instantiate(
String pClassName,
ObjectName pLoaderName,
String[] pParams,
String[] pSignature
) throws
ReflectionException,
MBeanException,
InstanceNotFoundException,
RemoteException
{
// First check the given parameters to see if there is an ObjectHandler
// to be replaced
checkForObjectHandlers(
pParams,
pSignature
);
return assignObjectHandler(
mServer.instantiate(
pClassName,
pLoaderName,
pParams,
pSignature
)
);
}
public ObjectInstance createMBean(
String pClassName,
ObjectName pName
) throws
ReflectionException,
InstanceAlreadyExistsException,
MBeanRegistrationException,
MBeanException,
NotCompliantMBeanException,
RemoteException
{
return mServer.createMBean( pClassName, pName );
}
public ObjectInstance createMBean(
String pClassName,
ObjectName pName,
ObjectName pLoaderName
) throws
ReflectionException,
InstanceAlreadyExistsException,
MBeanRegistrationException,
MBeanException,
NotCompliantMBeanException,
InstanceNotFoundException,
RemoteException
{
return mServer.createMBean( pClassName, pName, pLoaderName );
}
public ObjectInstance createMBean(
String pClassName,
ObjectName pName,
String[] pParams,
String[] pSignature
) throws
ReflectionException,
InstanceAlreadyExistsException,
MBeanRegistrationException,
MBeanException,
NotCompliantMBeanException,
RemoteException
{
// First check the given parameters to see if there is an ObjectHandler
// to be replaced
checkForObjectHandlers(
pParams,
pSignature
);
return mServer.createMBean( pClassName, pName, pParams, pSignature );
}
public ObjectInstance createMBean(
String pClassName,
ObjectName pName,
ObjectName pLoaderName,
String[] pParams,
String[] pSignature
) throws
ReflectionException,
InstanceAlreadyExistsException,
MBeanRegistrationException,
MBeanException,
NotCompliantMBeanException,
InstanceNotFoundException,
RemoteException
{
// First check the given parameters to see if there is an ObjectHandler
// to be replaced
checkForObjectHandlers(
pParams,
pSignature
);
return mServer.createMBean( pClassName, pName, pLoaderName, pParams,
pSignature );
}
public ObjectInstance registerMBean(
Object pObjectHandler,
ObjectName pNameToAssign
) throws
InstanceAlreadyExistsException,
MBeanRegistrationException,
NotCompliantMBeanException,
RemoteException
{
if( !( pObjectHandler instanceof ObjectHandler ) ) {
throw new IllegalArgumentException(
"You can only register local objects referenced by
ObjectHandler"
);
}
return mServer.registerMBean(
checkForObjectHandler( pObjectHandler ),
pNameToAssign
);
}
public void unregisterMBean(
ObjectName pName
) throws
InstanceNotFoundException,
MBeanRegistrationException,
RemoteException
{
mServer.unregisterMBean( pName );
}
public ObjectInstance getObjectInstance(
ObjectName pName
) throws
InstanceNotFoundException,
RemoteException
{
return mServer.getObjectInstance( pName );
}
public Set queryMBeans(
ObjectName pName,
QueryExp pQuery
) throws
RemoteException
{
return mServer.queryMBeans( pName, pQuery );
}
public Set queryNames(
ObjectName pName,
QueryExp pQuery
) throws
RemoteException
{
return mServer.queryNames( pName, pQuery );
}
public boolean isRegistered(
ObjectName pName
) throws
RemoteException
{
return mServer.isRegistered( pName );
}
public Integer getMBeanCount(
) throws
RemoteException
{
return mServer.getMBeanCount();
}
public Object getAttribute(
ObjectName pName,
String pAttribute
) throws
MBeanException,
AttributeNotFoundException,
InstanceNotFoundException,
ReflectionException,
RemoteException
{
return mServer.getAttribute( pName, pAttribute );
}
public AttributeList getAttributes(
ObjectName pName,
String[] pAttributes
) throws
InstanceNotFoundException,
ReflectionException,
RemoteException
{
return mServer.getAttributes( pName, pAttributes );
}
public void setAttribute(
ObjectName pName,
Attribute pAttribute
) throws
InstanceNotFoundException,
AttributeNotFoundException,
InvalidAttributeValueException,
MBeanException,
ReflectionException,
RemoteException
{
mServer.setAttribute( pName, pAttribute );
}
public void setAttributes(
ObjectName pName,
AttributeList pAttributes
) throws
InstanceNotFoundException,
ReflectionException,
RemoteException
{
mServer.setAttributes( pName, pAttributes );
}
public Object invoke(
ObjectName pName,
String pActionName,
Object[] pParams,
String[] pSignature
) throws
InstanceNotFoundException,
MBeanException,
ReflectionException,
RemoteException
{
// First check the given parameters to see if there is an ObjectHandler
// to be replaced
checkForObjectHandlers(
pParams,
pSignature
);
return mServer.invoke( pName, pActionName, pParams, pSignature );
}
public String getDefaultDomain(
) throws
RemoteException
{
return mServer.getDefaultDomain();
}
/**
* Adds a given remote notification listeners to the given
* Broadcaster.
* Please note that this is not the same as within the
* MBeanServer because it is protocol specific.
*/
public void addNotificationListener(
ObjectName pName,
RMINotificationListener pListener,
NotificationFilter pFilter,
Object pHandback
) throws
InstanceNotFoundException,
RemoteException
{
NotificationListener lRemoteListener = new Listener( pListener );
mServer.addNotificationListener(
pName,
lRemoteListener,
pFilter,
pHandback
);
mListeners.addElement( lRemoteListener );
}
public void removeNotificationListener(
ObjectName pName,
RMINotificationListener pListener
) throws
InstanceNotFoundException,
ListenerNotFoundException,
RemoteException
{
int lIndex = mListeners.indexOf(
new Listener(
pListener
)
);
if( lIndex >= 0 ) {
mServer.removeNotificationListener(
pName,
(Listener) mListeners.elementAt( lIndex )
);
}
}
public MBeanInfo getMBeanInfo(
ObjectName pName
) throws
InstanceNotFoundException,
IntrospectionException,
ReflectionException,
RemoteException
{
return mServer.getMBeanInfo( pName );
}
/**
* Checks in the given list of object if there is one of type ObjectHandler
* and if it will replaced by the referenced object. In addition it checks
* if the given signature is of type ObjectHandler and if then it replace
* it by the type of the referenced object.
* <BR>
* Please note that this method works directly on the given arrays!
*
* @param pListOfObjects Array of object to be
checked
* @param pSignature Array of class
names (full paht)
*
beeing the signature for the object
*
on the according object (list above)
*/
private void checkForObjectHandlers(
Object[] pListOfObjects,
String[] pSignature
) {
for( int i = 0; i < pListOfObjects.length; i++ ) {
Object lEffective = checkForObjectHandler( pListOfObjects[ i ]
);
if( pListOfObjects[ i ] != lEffective ) {
// Replace the Object Handler by the effective object
pListOfObjects[ i ] = lEffective;
if( i < pSignature.length ) {
if( pSignature[ i ].equals(
ObjectHandler.class.getName() ) ) {
pSignature[ i ] =
lEffective.getClass().getName();
}
}
}
}
}
/**
* Checks if the given object is of type ObjectHandler and if then
* it replaces by the object referenced by the ObjectHandler
*
* @param pObjectToCheck Object to be checked
*
* @return The
given object if not a reference or
*
or the referenced object
*/
private Object checkForObjectHandler( Object pObjectToCheck ) {
if( pObjectToCheck instanceof ObjectHandler ) {
return mObjectPool.get(
pObjectToCheck
);
}
else {
return pObjectToCheck;
}
}
/**
* Creates an ObjectHandler for the given object and store it on
* this side
*
* @param pNewObject New object to
be referenced by an
*
ObjectHandler
*
* @return Object
Handler which stands for a
*
remote reference to an object created
*
and only usable on this side
*/
private ObjectHandler assignObjectHandler( Object pNewObject ) {
ObjectHandler lObjectHandler = new ObjectHandler(
this.toString()
);
mObjectPool.put(
lObjectHandler,
pNewObject
);
return lObjectHandler;
}
/**
* Listener wrapper around the remote RMI Notification Listener
*/
private class Listener implements NotificationListener {
private RMINotificationListener mRemoteListener;
public Listener( RMINotificationListener pRemoteListener ) {
mRemoteListener = pRemoteListener;
}
/**
* Handles the given notification by sending this to the remote
* client listener
*
* @param pNotification Notification to be send
* @param pHandback Handback object
*/
public void handleNotification(
Notification pNotification,
Object pHandback
) {
try {
mRemoteListener.handleNotification( pNotification,
pHandback );
}
catch( RemoteException re ) {
re.printStackTrace();
}
}
/**
* Test if this and the given Object are equal. This is true if the
given
* object both refer to the same local listener
*
* @param pTest Other object
to test if equal
*
* @return True
if both are of same type and
*
refer to the same local listener
**/
public boolean equals( Object pTest ) {
if( pTest instanceof Listener ) {
return mRemoteListener.equals(
( (Listener) pTest).mRemoteListener
);
}
return false;
}
/**
* @return
Hashcode of the remote listener
**/
public int hashCode() {
return mRemoteListener.hashCode();
}
}
}
1.1 jboss/src/main/org/jboss/jmx/server/RMIConnectorService.java
Index: RMIConnectorService.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.jmx.server;
import java.io.File;
import java.net.URL;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.util.ArrayList;
import java.util.Iterator;
import javax.management.Attribute;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.ObjectInstance;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.ReflectionException;
import javax.management.MBeanServer;
import javax.naming.InitialContext;
import org.jboss.logging.Log;
import org.jboss.util.ServiceMBeanSupport;
/**
* <description>
*
* @author Rickard �berg ([EMAIL PROTECTED])
* @author <A href="mailto:[EMAIL PROTECTED]">Andreas "Mad"
Schaefer</A>
**/
public class RMIConnectorService
extends ServiceMBeanSupport
implements RMIConnectorServiceMBean
{
// Constants -----------------------------------------------------
//AS I am not quite sure if this works but somehow the protocol should become
//AS part of the JNDI name because there could be more than one protcol
public static String JNDI_NAME = "jmx:rmi";
// Attributes ----------------------------------------------------
MBeanServer server;
RMIConnectorImpl adaptor;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
// Public --------------------------------------------------------
public ObjectName getObjectName(
MBeanServer server,
ObjectName name
) throws javax.management.MalformedObjectNameException {
this.server = server;
return new ObjectName( OBJECT_NAME );
}
public String getName() {
return "JMX RMI Connector";
}
// Protected -----------------------------------------------------
protected void initService() throws Exception {
adaptor = new RMIConnectorImpl( server );
}
protected void startService() throws Exception {
new InitialContext().bind( JNDI_NAME, adaptor );
}
protected void stopService() {
try {
new InitialContext().unbind(JNDI_NAME);
}
catch( Exception e ) {
log.exception( e );
}
}
}
1.1
jboss/src/main/org/jboss/jmx/server/RMIConnectorServiceMBean.java
Index: RMIConnectorServiceMBean.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.jmx.server;
/**
* Server side MBean for the RMI connector
*
* @author Rickard �berg ([EMAIL PROTECTED])
* @author <A href="mailto:[EMAIL PROTECTED]">Andreas "Mad"
Schaefer</A>
**/
public interface RMIConnectorServiceMBean
extends org.jboss.util.ServiceMBean
{
// Constants -----------------------------------------------------
public static final String OBJECT_NAME = "Connector:name=RMI";
// Public --------------------------------------------------------
}