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

com.sun.xml.ws.mex.client.MetadataClient 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.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.sun.xml.ws.mex.MetadataConstants;
import com.sun.xml.ws.util.xml.XmlUtil;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import com.sun.istack.NotNull;
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;

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

/**
 * Class used for retrieving metadata at runtime. The intended usage is:
 * 

* MetadataClient mClient = new MetadataClient();
* Metadata mData = mClient.retrieveMetadata(someAddress);
*

* Utility methods will be added for common usages of the metadata. For * instance, the service and port QNames from the endpoint can be * retrieved from the metadata with: *

* Map<QName, List<PortInfo>> names = mClient.getServiceAndPortNames(mData); */ public class MetadataClient { enum Protocol { SOAP_1_2, SOAP_1_1 } private final String [] suffixes = { "" , "/mex" }; private final MetadataUtil mexUtil; private static final JAXBContext jaxbContext; private static final Logger logger = Logger.getLogger(MetadataClient.class.getName()); static { try { jaxbContext = JAXBContext.newInstance( "com.sun.xml.ws.mex.client.schema"); } catch (JAXBException jaxbE) { throw new AssertionError(jaxbE); } } /** * Default constructor. */ public MetadataClient() { mexUtil = new MetadataUtil(); } /** * Method used to load the metadata from the endpoint. First * soap 1.2 is used, then 1.1. If both attempts fail, the * client will try again adding "/mex" to the address. *

* If any wsdl or schema import elements are found with * empty location attributes, these attributes are removed. * In the case of data returned to JAX-WS through * ServiceDescriptorImpl, these attributes are added back * in with appropriate location information. * * @see com.sun.xml.ws.mex.client.ServiceDescriptorImpl * @param address The address used to query for Metadata * @return The metadata object, or null if no metadata could * be obtained from the service */ public Metadata retrieveMetadata(@NotNull final String address) { for (String suffix : suffixes) { final String newAddress = address.concat(suffix); for (Protocol p : Protocol.values()) { InputStream responseStream = null; try { responseStream = mexUtil.getMetadata(newAddress, p); return createMetadata(responseStream); } catch (IOException e) { logger.log(MetadataConstants.ERROR_LOG_LEVEL, MessagesMessages.MEX_0006_RETRIEVING_MDATA_FAILURE( p, newAddress)); } catch (Exception e) { logger.log(Level.WARNING, MessagesMessages.MEX_0008_PARSING_MDATA_FAILURE( p, newAddress)); } } } logger.log(MetadataConstants.ERROR_LOG_LEVEL, MessagesMessages.MEX_0007_RETURNING_NULL_MDATA()); return null; } /** * Currently only supports Get requests (not Get Metadata), * so we only need the reference's address. Any metadata * about the request is ignored. * * @see #retrieveMetadata(String) */ public Metadata retrieveMetadata( @NotNull final MetadataReference reference) { final List nodes = reference.getAny(); for (Object o : nodes) { final Node node = (Node) o; if (node.getLocalName().equals("Address")) { final String address = node.getFirstChild().getNodeValue(); return retrieveMetadata(address); } } return null; } /** * Used to retrieve the service and port names and port addresses * from metadata. * * @see com.sun.xml.ws.mex.client.PortInfo * @return A list of PortInfo objects */ public List getServiceInformation(@NotNull final Metadata data) { List portInfos = new ArrayList<>(); for (MetadataSection section : data.getMetadataSection()) { if (section.getDialect().equals(MetadataConstants.WSDL_DIALECT)) { if (section.getAny() != null) { getServiceInformationFromNode(portInfos, section.getAny()); } if (section.getMetadataReference() != null) { final Metadata newMetadata = retrieveMetadata(section.getMetadataReference()); List newPortInfos = getServiceInformation(newMetadata); portInfos.addAll(newPortInfos); } if (section.getLocation() != null) { final Metadata newMetadata = retrieveMetadata(section.getLocation()); List newPortInfos = getServiceInformation(newMetadata); portInfos.addAll(newPortInfos); } } } return portInfos; } private void getServiceInformationFromNode(List portInfos, final Object node) { final Node wsdlNode = (Node) node; final String namespace = getAttributeValue(wsdlNode, "targetNamespace"); final NodeList nodes = wsdlNode.getChildNodes(); for (int i=0; i