/** * Returns binding from a list based on it's name. * * @param bindings List of bindings. * @param name Name of desired binding. * @return Returns binding from a list based on it's name. */ private WebserviceTypeWsdlBinding getBindingByName( List<WebserviceTypeWsdlBinding> bindings, String name) { if (bindings == null || name == null) { return null; } for (WebserviceTypeWsdlBinding binding : bindings) { if (binding.getName().equals(stripOfNamespace(name))) { return binding; } } return null; }
@Override public int parseIDL(String idl, Resource resource) { //////////////////////////////////////////// // process idl and get all necessary info // //////////////////////////////////////////// // process IDL into XML DOM object DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder; Document document = null; try { builder = factory.newDocumentBuilder(); document = builder.parse(new InputSource(new StringReader(idl))); } catch (ParserConfigurationException | SAXException | IOException ex) { logger.debug("IDL is not a valid XML object", ex); } if (document == null) { return -1; } // get root WSDL element and thus detect WSDL version Element root = document.getDocumentElement(); String rootWsdlVersion; stripOfNamespaceRecursive(root); if (root.getNodeName().equalsIgnoreCase(WSDL_DESCRIPTION_V_1_1)) { rootWsdlVersion = WSDL_V_1_1; } else { if (root.getNodeName().equalsIgnoreCase(WSDL_DESCRIPTION_V_2_0)) { rootWsdlVersion = WSDL_V_2_0; } else { logger.debug( "IDL is not a valid WSDL. Does not have a root element \"{}\" or \"{}\"", WSDL_DESCRIPTION_V_1_1, WSDL_DESCRIPTION_V_2_0); return -1; } } // process all messages into list (WSDL 2.0 does not define any message elements) NodeList messages = root.getElementsByTagName(WSDL_MESSAGE); List<WebserviceTypeWsdlMessage> processedMessges = new ArrayList<>(); if (messages.getLength() > 0) { processMessages(messages, processedMessges); } // process all portTypes / interfaces into list NodeList portTypes = root.getElementsByTagName(WSDL_SERVICE_INTERFACE_V_1_1); NodeList interfaces = root.getElementsByTagName(WSDL_SERVICE_INTERFACE_V_2_0); List<WebserviceTypeWsdlInterface> processedInterfaces = new ArrayList<>(); if (portTypes.getLength() > 0 && interfaces.getLength() == 0) { // wsdlVersion = WSDL_V_1_1; processInterfaces(portTypes, processedInterfaces); } else if (portTypes.getLength() == 0 && interfaces.getLength() > 0) { // wsdlVersion = WSDL_V_2_0; processInterfaces(interfaces, processedInterfaces); } else { logger.warn( "Processed WSDL seems to use both {} and {} specification. Parsing both \"{}\" and \"{}\" elements.", WSDL_V_1_1, WSDL_V_2_0, WSDL_SERVICE_INTERFACE_V_1_1, WSDL_SERVICE_INTERFACE_V_2_0); processInterfaces(portTypes, processedInterfaces); processInterfaces(interfaces, processedInterfaces); } // process all bindings into list NodeList bindings = root.getElementsByTagName(WSDL_BINDING); List<WebserviceTypeWsdlBinding> processedBindings = new ArrayList<>(); processBindings(bindings, processedBindings); // process all services defined in this WSDL List<Webservice> processedWebservices = new ArrayList<>(); NodeList services = root.getElementsByTagName(WSDL_SERVICE); for (int i = 0; i < services.getLength(); i++) { Node service = services.item(i); NamedNodeMap serviceAttributes = service.getAttributes(); String serviceName = returnNodeValue(serviceAttributes, "name"); String serviceIdlVersion = null; // get info about service endpoints List<WebserviceEndpoint> processedEndpoints = new ArrayList<>(); NodeList endpoints = service.getChildNodes(); for (int j = 0; j < endpoints.getLength(); j++) { Node endpoint = endpoints.item(j); if (endpoint.getNodeName().equalsIgnoreCase(WSDL_SERVICE_ENDPOINT_V_1_1)) { // detected as WSDL 1.1 serviceIdlVersion = WSDL_V_1_1; } else if (endpoint.getNodeName().equalsIgnoreCase(WSDL_SERVICE_ENDPOINT_V_2_0)) { // detected as WSDL 2.0 serviceIdlVersion = WSDL_V_2_0; } else { logger.warn( "Unrecognizable element \"{}\" in WSDL \"{}\" element", endpoint.getNodeName(), WSDL_SERVICE); continue; } NamedNodeMap endpointAttributes = endpoint.getAttributes(); String endpointBinding = returnNodeValue(endpointAttributes, "binding"); // get all operations implemented by this endpoint via its's binding object and list of // operations defined in corresponding interface WebserviceTypeWsdlBinding binding = getBindingByName(processedBindings, endpointBinding); List<WebserviceTypeWsdlBindedOperation> bindedOperations = binding.getBindedOperations(); List<WebserviceTypeWsdlOperation> interfaceOperations = getInterfaceByName(processedInterfaces, binding.getInterface_()).getOperations(); // process all operation defined in binding for (WebserviceTypeWsdlBindedOperation bindedOperation : bindedOperations) { // Note: This single binded operation represent endpoint in CRCE semantics. One WSDL port // / endpoint can bind multiple particular operations // each with their parameters, datatypes, return value etc. That is why CRCE Webservice // Endpoint corresponds to WSDL Operation. WebserviceTypeWsdlOperation operation = getOperationByName(interfaceOperations, bindedOperation.getName()); // proces all input parts defined in this operation as endpoint parameters List<WebserviceEndpointParameter> processedParameters = new ArrayList<>(); if (operation.getInputMessage() != null) { List<WebserviceTypeWsdlPart> parts = getMessageByName(processedMessges, operation.getInputMessage()).getParts(); for (int k = 0; k < parts.size(); k++) { WebserviceTypeWsdlPart part = parts.get(k); String endpointParameterType = part.getType() != null ? part.getType() : part.getElement(); processedParameters.add( new WebserviceEndpointParameter( part.getName(), endpointParameterType, (long) k + 1, null, null)); } } else if (operation.getInputElement() != null) { processedParameters.add( new WebserviceEndpointParameter( operation.getName(), operation.getInputElement(), null, null, null)); } else { logger.warn( "WSDL \"input\" element of operation \"{}\" does not have \"message\" or \"element\" attributes."); } // proces all output parts defined in this operation as endpoint response // TODO In document (i.e. messaging) communication style, output message can generally // contain multiple parts - now we just grab a first one. String endpointResponseType = null; if (operation.getOutputMessage() != null) { List<WebserviceTypeWsdlPart> parts = getMessageByName(processedMessges, operation.getOutputMessage()).getParts(); if (parts.size() > 0) { endpointResponseType = parts.get(0).getType() != null ? parts.get(0).getType() : parts.get(0).getElement(); } } else if (operation.getOutputElement() != null) { endpointResponseType = operation.getOutputElement(); } else { logger.warn( "WSDL \"output\" element of operation \"{}\" does not have \"message\" or \"element\" attributes."); } WebserviceEndpointResponse processedResponse = new WebserviceEndpointResponse(endpointResponseType, null); // add info about new endpoint processedEndpoints.add( new WebserviceEndpoint( operation.getName(), bindedOperation.getSoapAction(), processedParameters, processedResponse)); } } processedWebservices.add( new Webservice( serviceName, null, serviceIdlVersion, getSpecificWebserviceType(), processedEndpoints)); } //////////////////////////////////////////////////////////////////////////// // create CRCE metadata structures and fill it by retrieved info from idl // //////////////////////////////////////////////////////////////////////////// // create new variables for holding references to current capabilities Capability capability, webservice_capability, endpoint_capability; // Capability - CRCE Identity String main_name; switch (processedWebservices.size()) { case 0: main_name = "No webservice descriptions"; break; case 1: main_name = processedWebservices.get(0).getName(); break; default: main_name = "Multiple webservice descriptions"; break; } capability = metadataService.getIdentity(resource); metadataService.setPresentationName(resource, main_name); metadataService.setSize(resource, idl.length()); setIfSet(capability, ATTRIBUTE__CRCE_IDENTITY__MIME, WSDL_MIME); setIfSet(capability, ATTRIBUTE__CRCE_IDENTITY__HASH, getIdlHash(idl)); // Capability - Webserviceschema Identity capability = metadataFactory.createCapability(NAMESPACE__WEBSERVICESCHEMA_IDENTITY); setIfSet(capability, ATTRIBUTE__WEBSERVICESCHEMA_IDENTITY__IDL_VERSION, rootWsdlVersion); resource.addCapability(capability); resource.addRootCapability(capability); // create one capability for each detected webservice representation for (Webservice processedWebservice : processedWebservices) { // Capability - Webserviceschema Webservice webservice_capability = metadataFactory.createCapability(NAMESPACE__WEBSERVICESCHEMA_WEBSERVICE); setIfSet( webservice_capability, ATTRIBUTE__WEBSERVICESCHEMA_WEBSERVICE__NAME, processedWebservice.getName()); setIfSet( webservice_capability, ATTRIBUTE__WEBSERVICESCHEMA_WEBSERVICE__TYPE, processedWebservice.getType()); setIfSet( webservice_capability, ATTRIBUTE__WEBSERVICESCHEMA_WEBSERVICE__URI, processedWebservice.getUrl()); // Capabilities - Webservice Endpoint List<WebserviceEndpoint> processedEndpoints = processedWebservice.getEndpoints(); for (int i = 0; i < processedEndpoints.size(); i++) { endpoint_capability = metadataFactory.createCapability(NAMESPACE__WEBSERVICE_ENDPOINT); setIfSet( endpoint_capability, ATTRIBUTE__WEBSERVICE_ENDPOINT__NAME, processedEndpoints.get(i).getName()); // Properties - Webservice Enpoint Parameter List<WebserviceEndpointParameter> processedParams = processedEndpoints.get(i).getParameters(); for (int j = 0; j < processedParams.size(); j++) { Property property = metadataFactory.createProperty(NAMESPACE__WEBSERVICE_ENDPOINT_PARAMETER); setIfSet( property, ATTRIBUTE__WEBSERVICE_ENDPOINT_PARAMETER__NAME, processedParams.get(j).getName()); setIfSet( property, ATTRIBUTE__WEBSERVICE_ENDPOINT_PARAMETER__TYPE, processedParams.get(j).getType()); setIfSet( property, ATTRIBUTE__WEBSERVICE_ENDPOINT_PARAMETER__ORDER, processedParams.get(j).getOrder()); endpoint_capability.addProperty(property); } // Property - Webservice Endpoint Response Property property = metadataFactory.createProperty(NAMESPACE__WEBSERVICE_ENDPOINT_RESPONSE); setIfSet( property, ATTRIBUTE__WEBSERVICE_ENDPOINT_RESPONSE__TYPE, processedEndpoints.get(i).getResponse().getType()); endpoint_capability.addProperty(property); resource.addCapability(endpoint_capability); webservice_capability.addChild(endpoint_capability); } resource.addCapability(webservice_capability); capability.addChild(webservice_capability); } return processedWebservices.size(); }