package gov.nist.registry.ws.wsbypass; import gov.nist.registry.common2.exception.ExceptionUtil; import gov.nist.registry.common2.exception.XdsInternalException; import gov.nist.registry.common2.registry.MetadataSupport; import gov.nist.registry.common2.xml.Util; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Iterator; import javax.xml.namespace.QName; import javax.xml.parsers.FactoryConfigurationError; import org.apache.axiom.om.OMElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class ServiceFinder { private static final Log log = LogFactory.getLog(ServiceFinder.class); File serviceFile = new File("/Users/bill/exp/xds/services-testng.xml"); OMElement services; static QName nameQName = new QName("name"); String methodName; Method meth; Class<?> clas; public ServiceFinder(String endpoint, String action) throws FactoryConfigurationError, Exception { services = Util.parse_xml(serviceFile); Class<?>[] parmTypes = { Class.forName("org.apache.axiom.om.OMElement") }; clas = getClass(endpoint, action); String serviceName = getServiceName(endpoint); OMElement serviceEle = getServiceDef(serviceName); methodName = getMethodName(serviceEle, action); try { meth = clas.getMethod(methodName, parmTypes); } catch (NoSuchMethodException e) { log.error(ExceptionUtil.exception_details(e)); throw new Exception("ServiceFinder: endpoint=" + endpoint + " action=" + action + " class=" + clas.getName() + " method=" + methodName, e); } //System.out.println("ServiceFinder: launching " + clas.getName() + "#" + meth.getName()); } Class<?> getClass(String endpoint, String action) throws Exception { String endpointService = getServiceName(endpoint); OMElement serviceDefEle = getServiceDef(endpointService); String className = getServiceClassName(serviceDefEle); return Class.forName(className); } String getServiceName(String endpoint) throws Exception { String[] endpointParts = endpoint.split("/"); if (endpointParts.length == 0) throw new Exception("Cannot extract service name from endpoint " + endpoint); String endpointService = endpointParts[endpointParts.length-1]; return endpointService; } public OMElement invoke(OMElement in ) throws XdsInternalException { Object[] args = { in }; Object obj = null; try { obj = clas.newInstance(); } catch (InstantiationException e1) { throw new XdsInternalException("Error creating instance of " + clas, e1); } catch (IllegalAccessException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } //System.out.println("obj is of class " + obj.getClass().getName()); try { return (OMElement) meth.invoke(obj, args); } catch (IllegalArgumentException e) { throw new XdsInternalException("Error invoking " + meth + " on " + obj, e); } catch (IllegalAccessException e) { throw new XdsInternalException("Error invoking " + meth + " on " + obj, e); } catch (InvocationTargetException e) { throw new XdsInternalException("Error invoking " + meth + " on " + obj, e); } catch (Exception e) { throw new XdsInternalException("Error from invocation ", e); } } @SuppressWarnings("unchecked") OMElement getServiceDef(String serviceName) throws Exception { for (Iterator<OMElement> it=services.getChildElements(); it.hasNext(); ) { OMElement serviceEle = it.next(); String name = serviceEle.getAttributeValue(nameQName); if (serviceName.equals(name)) return serviceEle; } throw new Exception("No service defined for " + serviceName); } @SuppressWarnings("unchecked") String getServiceClassName(OMElement serviceEle) throws Exception { for (Iterator<OMElement> it=serviceEle.getChildElements(); it.hasNext(); ) { OMElement ele = it.next(); if ( ! "parameter".equals(ele.getLocalName())) continue; String name = ele.getAttributeValue(nameQName); if ("ServiceClass".equals(name)) return ele.getText(); } throw new Exception("No ServiceClass defined for " + serviceEle.getAttributeValue(new QName("name"))); } @SuppressWarnings("unchecked") String getMethodName(OMElement serviceEle, String action) throws Exception { for (Iterator<OMElement> it=serviceEle.getChildElements(); it.hasNext(); ) { OMElement ele = it.next(); if ( !"operation".equals(ele.getLocalName())) continue; OMElement actionMappingEle = MetadataSupport.firstChildWithLocalName(ele, "actionMapping"); if (actionMappingEle == null) continue; String actionMapping = actionMappingEle.getText(); if (action.equals(actionMapping)) return ele.getAttributeValue(nameQName); } throw new Exception("Cannot find method name for service = " + serviceEle.getAttributeValue(nameQName) + " action = " + action); } }