All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.xml.ws.mex.client.ServiceDescriptorImpl Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.xml.ws.mex.client;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;

import com.sun.xml.ws.mex.MetadataConstants;
import com.sun.xml.ws.util.xml.XmlUtil;
import jakarta.xml.ws.WebServiceException;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.NamedNodeMap;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.sun.xml.ws.api.wsdl.parser.ServiceDescriptor;
import com.sun.xml.ws.mex.MessagesMessages;
import com.sun.xml.ws.mex.client.schema.Metadata;
import com.sun.xml.ws.mex.client.schema.MetadataReference;
import com.sun.xml.ws.mex.client.schema.MetadataSection;

/**
 * This class is used by the JAX-WS code when it needs to retrieve
 * metadata from an endpoint using mex. An address is passed into
 * the MetadataResolverImpl class, which creates a service
 * descriptor and returns it.
 * 

* Because wsdl and schema import@location attributes are removed * from the data when empty, this class will add them back in * for wsdl imports. The value that is used for the attribute * matches the systemId of the Source that contains the imported * wsdl (which may be different from the target namespace of the * wsdl). */ public class ServiceDescriptorImpl extends ServiceDescriptor { private final List wsdls; private final List schemas; // holds nodes that are missing location attributes private final List importsToPatch; // holds sysId for wsdls, key is wsdl targetNamespace private final Map nsToSysIdMap; private static final String LOCATION = "location"; private static final String NAMESPACE = "namespace"; private static final Logger logger = Logger.getLogger(ServiceDescriptorImpl.class.getName()); /** * The ServiceDescriptorImpl constructor does the work of * parsing the data in the Metadata object. */ public ServiceDescriptorImpl(Metadata mData) { wsdls = new ArrayList<>(); schemas = new ArrayList<>(); importsToPatch = new ArrayList<>(); nsToSysIdMap = new HashMap<>(); populateLists(mData); if (!importsToPatch.isEmpty()) { patchImports(); } } /* * This will be called recursively for metadata sections * that contain metadata references. A metadata section can * contain the xml of metadata itself (the default case), a * metadata reference that needs to be retrieved, or a * mex location which can be retrieved with http GET call. */ private void populateLists(final Metadata mData) { for (MetadataSection section : mData.getMetadataSection()) { if (section.getMetadataReference() != null) { handleReference(section); } else if (section.getLocation() != null) { handleLocation(section); } else { handleXml(section); } } } /* * This is the normal case where a metadata section contains * xml representing a wsdl, schema, etc. */ private void handleXml(final MetadataSection section) { final String dialect = section.getDialect(); final String identifier = section.getIdentifier(); if (dialect.equals(MetadataConstants.WSDL_DIALECT)) { wsdls.add(createSource(section, identifier)); } else if (dialect.equals(MetadataConstants.SCHEMA_DIALECT)) { schemas.add(createSource(section, identifier)); } else { logger.warning( MessagesMessages.MEX_0002_UNKNOWN_DIALECT_WITH_ID( dialect, identifier)); } } /* * If the metadata section contains a metadata reference, * retrieve the new metadata and add it to the lists. This * method recursively calls the the populateLists method. */ private void handleReference(final MetadataSection section) { final MetadataReference ref = section.getMetadataReference(); populateLists(new MetadataClient().retrieveMetadata(ref)); } /* * A mex location is simply the url of a document that can * be retrieved with an http GET call. */ private void handleLocation(final MetadataSection section) { final String location = section.getLocation(); final String dialect = section.getDialect(); final String identifier = section.getIdentifier(); if (dialect.equals(MetadataConstants.WSDL_DIALECT)) { wsdls.add(getSourceFromLocation(location, identifier)); } else if (dialect.equals(MetadataConstants.SCHEMA_DIALECT)) { schemas.add(getSourceFromLocation(location, identifier)); } else { logger.warning( MessagesMessages.MEX_0002_UNKNOWN_DIALECT_WITH_ID( dialect, identifier)); } } @Override public List getWSDLs() { return wsdls; } @Override public List getSchemas() { return schemas; } /* * Helper method used by handleXml() to turn the xml DOM nodes * into Sources objects. This method is also responsible for * adding data to the nsToSysIdMap map for wsdl sections in * case there are wsdl:import elements that need to be patched. */ private Source createSource(final MetadataSection section, final String identifier) { final Node node = (Node) section.getAny(); String sysId = identifier; if (section.getDialect().equals(MetadataConstants.WSDL_DIALECT)) { final String targetNamespace = getNamespaceFromNode(node); if (sysId == null) { sysId = targetNamespace; } nsToSysIdMap.put(targetNamespace, sysId); checkWsdlImports(node); } else { if (sysId == null) { sysId = getNamespaceFromNode(node); } } final Source source = new DOMSource(node); source.setSystemId(sysId); return source; } /* * Turn the address of a document into a source. The document * referred to in a mex location element must be retrievable * with an HTTP GET call. */ private Source getSourceFromLocation(final String address, final String identifier) { try { final HttpPoster poster = new HttpPoster(); final InputStream response = poster.makeGetCall(address); if (identifier != null) { final StreamSource source = new StreamSource(response); source.setSystemId(identifier); return source; } return parseAndConvertStream(address, response); } catch (IOException ioe) { final String exceptionMessage = MessagesMessages.MEX_0014_RETRIEVAL_FROM_ADDRESS_FAILURE( address); logger.log(Level.SEVERE, exceptionMessage, ioe); throw new WebServiceException(exceptionMessage, ioe); } } /* * This method used when metadata section did not include * an identifier. The node passed in must be a wsdl:definitions * or an xsd:schema node. */ private String getNamespaceFromNode(final Node node) { final Node namespace = node.getAttributes().getNamedItem("targetNamespace"); if (namespace == null) { // bug in the server? want to avoid NPE if so logger.warning( MessagesMessages.MEX_0003_UNKNOWN_WSDL_NAMESPACE( node.getNodeName())); return null; } return namespace.getNodeValue(); } /* * This method will check the wsdl for import nodes * that have no location attribute and add them to * the list to be patched. */ private void checkWsdlImports(final Node wsdl) { final NodeList kids = wsdl.getChildNodes(); for (int i=0; i





© 2015 - 2024 Weber Informatics LLC | Privacy Policy