package org.jboss.net.jmx.server;
import org.jboss.axis.AxisFault;
import org.jboss.axis.Message;
import org.jboss.axis.MessageContext;
import org.jboss.axis.description.OperationDesc;
import org.jboss.axis.description.ParameterDesc;
import org.jboss.axis.description.ServiceDesc;
import org.jboss.axis.encoding.TypeMapping;
import org.jboss.axis.handlers.soap.SOAPService;
import org.jboss.axis.message.RPCElement;
import org.jboss.axis.message.RPCParam;
import org.jboss.axis.message.SOAPEnvelopeAxisImpl;
import org.jboss.axis.providers.BasicProvider;
import org.jboss.axis.providers.java.JavaProvider;
import org.jboss.axis.utils.JavaUtils;
import org.jboss.axis.utils.Messages;
import org.jboss.axis.wsdl.fromJava.Emitter;
import org.jboss.axis.wsdl.fromJava.Types;
import org.jboss.logging.Logger;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.util.Classes;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.wsdl.Definition;
import javax.wsdl.factory.WSDLFactory;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class MBeanProvider extends BasicProvider
{
private static Logger log = Logger.getLogger(MBeanProvider.class);
protected MBeanServer server;
protected ObjectName name;
protected Map attributeData = new java.util.HashMap();
protected Map methodData = new java.util.HashMap();
protected String allowedMethodsOption = "allowedMethods";
protected String allowedReadAttributesOption = "allowedReadAttributes";
protected String allowedWriteAttributesOption = "allowedWriteAttributes";
public MBeanProvider()
{
}
public void initServiceDesc(SOAPService service, MessageContext msgCtx)
throws AxisFault
{
try
{
String allowedMethods =
(String)service.getOption(allowedMethodsOption);
String allowedReadAttributes =
(String)service.getOption(allowedReadAttributesOption);
String allowedWriteAttributes =
(String)service.getOption(allowedWriteAttributesOption);
String objectName =
(String)service.getOption(Constants.OBJECTNAME_PROPERTY);
String serverId =
(String)service.getOption(Constants.MBEAN_SERVER_ID_PROPERTY);
try
{
server = MBeanServerLocator.locateJBoss();
}
catch (IllegalStateException e)
{
throw new AxisFault(Constants.NO_MBEAN_SERVER_FOUND);
}
name = new ObjectName(objectName);
MBeanInfo info = server.getMBeanInfo(name);
ServiceDesc serviceDesc = service.getServiceDescription();
java.lang.reflect.Field completeField =
ServiceDesc.class.getDeclaredField("introspectionComplete");
completeField.setAccessible(true);
completeField.set(serviceDesc, Boolean.TRUE);
Class implClass = Classes.loadClass(info.getClassName(), msgCtx.getClassLoader());
serviceDesc.setImplClass(implClass);
serviceDesc.setTypeMapping((TypeMapping)service.getTypeMappingRegistry().getTypeMapping(org.jboss.axis.Constants.URI_DEFAULT_SOAP_ENC));
MBeanOperationInfo[] operations = info.getOperations();
for (int count = 0; count < operations.length; count++)
{
String operationName = operations[count].getName();
if (allowedMethods != null
&& allowedMethods.equals("*")
|| allowedMethods.indexOf(operationName + " ") != -1
|| allowedMethods.indexOf(" " + operationName) != -1
|| allowedMethods.equals(operationName))
{
OperationDesc opDesc = new OperationDesc();
if (methodData.containsKey(operationName))
{
operationName = operationName + count;
}
opDesc.setName(operationName);
opDesc.setElementQName(new QName("", operationName));
methodData.put(operationName, operations[count]);
MBeanParameterInfo[] parameters =
operations[count].getSignature();
Class[] parameterTypes = new Class[parameters.length];
for (int count2 = 0; count2 < parameters.length; count2++)
{
ParameterDesc param = new ParameterDesc();
param.setName("arg" + count2);
parameterTypes[count2] =
forName(parameters[count2].getType(), msgCtx.getClassLoader());
param.setJavaType(parameterTypes[count2]);
param.setTypeQName(forName(parameterTypes[count2],
serviceDesc.getTypeMapping()));
opDesc.addParameter(param);
}
opDesc.setReturnClass(forName(operations[count].getReturnType(), msgCtx.getClassLoader()));
opDesc.setReturnType(forName(opDesc.getReturnClass(),
serviceDesc.getTypeMapping()));
serviceDesc.addOperationDesc(opDesc);
} } MBeanAttributeInfo[] attributes = info.getAttributes();
for (int count = 0; count < attributes.length; count++)
{
String attributeName = attributes[count].getName();
if (attributes[count].isReadable()
&& allowedReadAttributes != null
&& (allowedReadAttributes.equals("*")
|| allowedReadAttributes.indexOf(attributeName + " ") != -1
|| allowedReadAttributes.indexOf(" " + attributeName) != -1
|| allowedReadAttributes.equals(attributeName)))
{
OperationDesc opDesc = new OperationDesc();
if (attributes[count].getType().equals("boolean"))
{
opDesc.setName("is" + attributeName);
}
else
{
opDesc.setName("get" + attributeName);
}
if (methodData.containsKey(opDesc.getName()))
{
opDesc.setName(opDesc.getName() + count + "A");
}
opDesc.setElementQName(new QName("", opDesc.getName()));
attributeData.put(opDesc.getName(), attributes[count]);
opDesc.setReturnClass(forName(attributes[count].getType(), msgCtx.getClassLoader()));
opDesc.setReturnType(forName(opDesc.getReturnClass(),
serviceDesc.getTypeMapping()));
serviceDesc.addOperationDesc(opDesc);
} if (attributes[count].isWritable()
&& allowedWriteAttributes != null
&& (allowedWriteAttributes.equals("*")
|| allowedWriteAttributes.indexOf(attributeName + " ") != -1
|| allowedWriteAttributes.indexOf(" " + attributeName) != -1
|| allowedWriteAttributes.equals(attributeName)))
{
OperationDesc opDesc = new OperationDesc();
opDesc.setName("set" + attributeName);
if (methodData.containsKey(opDesc.getName()))
{
opDesc.setName(opDesc.getName() + count + "A");
}
opDesc.setElementQName(new QName("", opDesc.getName()));
attributeData.put(opDesc.getName(), attributes[count]);
ParameterDesc p = new ParameterDesc();
p.setName("arg0");
p.setJavaType(forName(attributes[count].getType(), msgCtx.getClassLoader()));
p.setTypeQName(forName(p.getJavaType(), serviceDesc.getTypeMapping()));
opDesc.addParameter(p);
opDesc.setReturnType(null);
serviceDesc.addOperationDesc(opDesc);
} } }
catch (InstanceNotFoundException e)
{
throw new AxisFault(Constants.NO_MBEAN_INSTANCE, e);
}
catch (IntrospectionException e)
{
throw new AxisFault(Constants.INTROSPECTION_EXCEPTION, e);
}
catch (ReflectionException e)
{
throw new AxisFault(Constants.INTROSPECTION_EXCEPTION, e);
}
catch (ClassNotFoundException e)
{
throw new AxisFault(Constants.INTROSPECTION_EXCEPTION, e);
}
catch (MalformedObjectNameException e)
{
throw new AxisFault(Constants.WRONG_OBJECT_NAME, e);
}
catch (IllegalAccessException e)
{
throw new AxisFault(Constants.INTROSPECTION_EXCEPTION, e);
}
catch (NoSuchFieldException e)
{
throw new AxisFault(Constants.INTROSPECTION_EXCEPTION, e);
}
}
protected Class forName(String string, ClassLoader loader) throws ClassNotFoundException
{
if ("void".equals(string))
{
return void.class;
}
else if ("boolean".equals(string))
{
return boolean.class;
}
else if ("float".equals(string))
{
return float.class;
}
else if ("double".equals(string))
{
return double.class;
}
else if ("int".equals(string))
{
return int.class;
}
else if ("long".equals(string))
{
return long.class;
}
else if ("short".equals(string))
{
return short.class;
}
else if ("byte".equals(string))
{
return byte.class;
}
else if ("char".equals(string))
{
return char.class;
}
else
{
return org.jboss.util.Classes.loadClass(string, loader);
}
}
protected QName forName(Class clazz, TypeMapping tm)
throws ClassNotFoundException
{
if (void.class.equals(clazz))
{
return null;
}
else
{
return tm.getTypeQName(clazz);
}
}
public void invoke(MessageContext msgContext) throws AxisFault
{
String serviceName = msgContext.getTargetService();
Message reqMsg = msgContext.getRequestMessage();
SOAPEnvelopeAxisImpl reqEnv = (SOAPEnvelopeAxisImpl)reqMsg.getSOAPEnvelope();
Message resMsg = msgContext.getResponseMessage();
SOAPEnvelopeAxisImpl resEnv =
(resMsg == null)
? new SOAPEnvelopeAxisImpl()
: (SOAPEnvelopeAxisImpl)resMsg.getSOAPEnvelope();
if (msgContext.getResponseMessage() == null)
{
resMsg = new Message(resEnv);
msgContext.setResponseMessage(resMsg);
}
Iterator allBodies = reqEnv.getBodyElements().iterator();
while (allBodies.hasNext())
{
Object nextBody = allBodies.next();
if (nextBody instanceof RPCElement)
{
RPCElement body = (RPCElement)nextBody;
String mName = body.getMethodName();
List args = null;
try
{
args = body.getParams();
}
catch (SAXException e)
{
throw new AxisFault(Constants.EXCEPTION_OCCURED, e);
}
Object result = null;
try
{
MBeanAttributeInfo attr =
(MBeanAttributeInfo)attributeData.get(mName);
if (attr != null)
{
if (mName.startsWith("get") || mName.startsWith("is"))
{
result = server.getAttribute(name, attr.getName());
}
else
{
RPCParam p = (RPCParam)args.get(0);
Object arg =
JavaUtils.convert(p.getValue(),
forName(attr.getType(), msgContext.getClassLoader()));
server.setAttribute(name,
new Attribute(attr.getName(), arg));
result = null;
}
}
else
{
MBeanOperationInfo meth =
(MBeanOperationInfo)methodData.get(mName);
MBeanParameterInfo[] params = meth.getSignature();
Object[] arguments = new Object[params.length];
String[] classNames = new String[params.length];
for (int count2 = 0; count2 < params.length; count2++)
{
classNames[count2] = params[count2].getType();
if (args.size() > count2)
{
RPCParam param = (RPCParam)args.get(count2);
arguments[count2] =
JavaUtils.convert(param.getValue(),
forName(classNames[count2], msgContext.getClassLoader()));
}
else
{
arguments[count2] = null;
}
}
result =
server.invoke(name, meth.getName(), arguments, classNames);
}
RPCElement resBody = new RPCElement(mName + "Response");
resBody.setPrefix(body.getPrefix());
resBody.setNamespaceURI(body.getNamespaceURI());
RPCParam param = new RPCParam(mName + "Result", result);
resBody.addParam(param);
resEnv.addBodyElement(resBody);
resEnv.setEncodingStyle(org.jboss.axis.Constants.URI_DEFAULT_SOAP_ENC);
}
catch (InstanceNotFoundException e)
{
throw new AxisFault(Constants.NO_MBEAN_INSTANCE, e);
}
catch (AttributeNotFoundException e)
{
throw new AxisFault(Constants.NO_SUCH_ATTRIBUTE, e);
}
catch (InvalidAttributeValueException e)
{
throw new AxisFault(Constants.INVALID_ARGUMENT, e);
}
catch (MBeanException e)
{
throw new AxisFault(Constants.MBEAN_EXCEPTION, e);
}
catch (ClassNotFoundException e)
{
throw new AxisFault(Constants.CLASS_NOT_FOUND, e);
}
catch (ReflectionException e)
{
throw new AxisFault(Constants.EXCEPTION_OCCURED,
e.getTargetException());
}
catch (SOAPException e)
{
throw new AxisFault(Constants.EXCEPTION_OCCURED, e);
}
} } }
public void generateWSDL(MessageContext msgCtx) throws AxisFault
{
SOAPService service = msgCtx.getService();
ServiceDesc serviceDesc = service.getInitializedServiceDesc(msgCtx);
if (msgCtx != null)
{
boolean isSoapAction =
msgCtx.getProperty(Constants.ACTION_HANDLER_PRESENT_PROPERTY)
== Boolean.TRUE;
for (Iterator alloperations = serviceDesc.getOperations().iterator();
alloperations.hasNext();
)
{
OperationDesc opDesc = (OperationDesc)alloperations.next();
opDesc.setSoapAction(isSoapAction ? service.getName() : null);
}
}
try
{
String locationUrl =
msgCtx.getStrProp(MessageContext.WSDLGEN_SERV_LOC_URL);
if (locationUrl == null)
{
locationUrl = serviceDesc.getEndpointURL();
}
if (locationUrl == null)
{
locationUrl = msgCtx.getStrProp(MessageContext.TRANS_URL);
}
String interfaceNamespace =
msgCtx.getStrProp(MessageContext.WSDLGEN_INTFNAMESPACE);
if (interfaceNamespace == null)
{
interfaceNamespace = serviceDesc.getDefaultNamespace();
}
if (interfaceNamespace == null)
{
interfaceNamespace = locationUrl;
}
Emitter emitter = new Emitter();
String alias = (String)service.getOption("alias");
if (alias != null)
emitter.setServiceElementName(alias);
emitter.setCls(serviceDesc.getImplClass());
String targetNamespace =
(String)service.getOption(JavaProvider.OPTION_WSDL_TARGETNAMESPACE);
if (targetNamespace == null || targetNamespace.length() == 0)
{
targetNamespace = interfaceNamespace;
}
emitter.setIntfNamespace(targetNamespace);
emitter.setLocationUrl(locationUrl);
emitter.setServiceDesc(serviceDesc);
emitter.setTypeMapping((TypeMapping)service.getTypeMappingRegistry().getTypeMapping(org.jboss.axis.Constants.URI_DEFAULT_SOAP_ENC));
emitter.setDefaultTypeMapping((TypeMapping)msgCtx
.getTypeMappingRegistry()
.getDefaultTypeMapping());
String wsdlPortType =
(String)service.getOption(JavaProvider.OPTION_WSDL_PORTTYPE);
String wsdlServiceElement =
(String)service.getOption(JavaProvider.OPTION_WSDL_SERVICEELEMENT);
String wsdlServicePort =
(String)service.getOption(JavaProvider.OPTION_WSDL_SERVICEPORT);
if (wsdlPortType != null && wsdlPortType.length() > 0)
{
emitter.setPortTypeName(wsdlPortType);
}
if (wsdlServiceElement != null && wsdlServiceElement.length() > 0)
{
emitter.setServiceElementName(wsdlServiceElement);
}
if (wsdlServicePort != null && wsdlServicePort.length() > 0)
{
emitter.setServicePortName(wsdlServicePort);
}
Definition def = emitter.getWSDL();
def.addNamespace("xsd99",
org.jboss.axis.Constants.URI_1999_SCHEMA_XSD);
def.addNamespace("xsd00",
org.jboss.axis.Constants.URI_2000_SCHEMA_XSD);
def.addNamespace("axis",
org.jboss.axis.Constants.NS_URI_AXIS);
Document doc =
WSDLFactory.newInstance().newWSDLWriter().getDocument(def);
java.lang.reflect.Field field =
Emitter.class.getDeclaredField("types");
field.setAccessible(true);
((Types)field.get(emitter)).insertTypesFragment(doc);
msgCtx.setProperty("WSDL", doc);
}
catch (NoClassDefFoundError e)
{
log.info(Messages.getMessage("toAxisFault00"), e);
throw new AxisFault(e.toString(), e);
}
catch (Exception e)
{
log.info(Messages.getMessage("toAxisFault00"), e);
throw AxisFault.makeFault(e);
}
}
public void undo(MessageContext msgContext)
{
}
}