FileDocCategorySizeDatePackage
MetadataClient.javaAPI DocExample14700Tue May 29 16:56:32 BST 2007com.sun.xml.ws.mex.client

MetadataClient

public class MetadataClient extends Object
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);

Fields Summary
private final String[]
suffixes
private final MetadataUtil
mexUtil
private static final JAXBContext
jaxbContext
private static final Logger
logger
Constructors Summary
public MetadataClient()
Default constructor.

    
     
        try {
            jaxbContext = JAXBContext.newInstance(
                "com.sun.xml.ws.mex.client.schema");
        } catch (JAXBException jaxbE) {
            throw new AssertionError(jaxbE);
        }
    
        mexUtil = new MetadataUtil();
    
Methods Summary
private voidcleanData(com.sun.xml.ws.mex.client.schema.Metadata mData)

        for (MetadataSection section : mData.getMetadataSection()) {
            if (section.getDialect().equals(WSDL_DIALECT) &&
                section.getAny() != null) {
                cleanWSDLNode((Node) section.getAny());
            }
            else if(section.getDialect().equals(SCHEMA_DIALECT) &&
                section.getAny() != null){
                cleanSchemaNode((Node) section.getAny());
            }
        }
    
private voidcleanImport(org.w3c.dom.Node importNode)

        final NamedNodeMap atts = importNode.getAttributes();
        Node location = atts.getNamedItem("schemaLocation");
        if (location != null &&
            location.getNodeValue().equals("")) {
            atts.removeNamedItem("schemaLocation");
            return;
        }
        location = atts.getNamedItem("location");
        if (location != null &&
            location.getNodeValue().equals("")) {
            atts.removeNamedItem("location");
        }
    
private voidcleanSchemaNode(org.w3c.dom.Node schemaNode)

        final NodeList children = schemaNode.getChildNodes();
        for (int i=0; i<children.getLength(); i++) {
            final Node importNode = children.item(i);
            if (importNode.getLocalName() != null &&
                importNode.getLocalName().equals("import")) {
                cleanImport(importNode);            }
        }
    
private voidcleanWSDLNode(org.w3c.dom.Node wsdlNode)

        final NodeList nodes = wsdlNode.getChildNodes();
        for (int i=0; i<nodes.getLength(); i++) {
            final Node node = nodes.item(i);
            if (node.getLocalName() != null) {
                if (node.getLocalName().equals("types")) {
                    final NodeList schemaNodes = node.getChildNodes();
                    for (int j=0; j<schemaNodes.getLength(); j++) {
                        final Node schemaNode = schemaNodes.item(j);
                        if (schemaNode.getLocalName() != null &&
                            schemaNode.getLocalName().equals("schema")) {
                            
                            cleanSchemaNode(schemaNode);
                        }
                    }
                } else if (node.getLocalName().equals("import")) {
                    cleanImport(node);
                }
            }
        }
    
private com.sun.xml.ws.mex.client.schema.MetadatacreateMetadata(java.io.InputStream stream)

        
        final XMLInputFactory factory = XMLInputFactory.newInstance();
        final XMLStreamReader reader =
            factory.createXMLStreamReader(stream);
        int state = 0;
        do {
            state = reader.next();
        } while (state != reader.START_ELEMENT ||
            !reader.getLocalName().equals("Metadata"));
        
        final Unmarshaller uMarhaller = jaxbContext.createUnmarshaller();
        final Metadata mData = (Metadata) uMarhaller.unmarshal(reader);
        cleanData(mData);
        return mData;
    
private java.lang.StringgetAttributeValue(org.w3c.dom.Node node, java.lang.String attName)

        return node.getAttributes().getNamedItem(attName).getNodeValue();
    
private java.lang.StringgetPortAddress(org.w3c.dom.Node portNode)

        final NodeList portDetails = portNode.getChildNodes();
        for (int i=0; i<portDetails.getLength(); i++){
            final Node addressNode = portDetails.item(i);
            if (addressNode.getLocalName() != null &&
                addressNode.getLocalName().equals("address")) {
                
                return getAttributeValue(addressNode, "location");
            }
        }
        logger.warning(
            MessagesMessages.MEX_0009_ADDRESS_NOT_FOUND_FOR_PORT(portNode));
        return null;
    
public java.util.ListgetServiceInformation(com.sun.xml.ws.mex.client.schema.Metadata data)
Used to retrieve the service and port names and port addresses from metadata. If there is more than one wsdl section in the metadata, only the first is parsed by this method.

see
com.sun.xml.ws.mex.client.PortInfo
return
A list of PortInfo objects

        for (MetadataSection section : data.getMetadataSection()) {
            if (section.getDialect().equals(WSDL_DIALECT)) {
                if (section.getAny() != null) {
                    return getServiceInformationFromNode(section.getAny());
                }
                if (section.getMetadataReference() != null) {
                    final Metadata newMetadata =
                        retrieveMetadata(section.getMetadataReference());
                    return getServiceInformation(newMetadata);
                }
                if (section.getLocation() != null) {
                    final Metadata newMetadata =
                        retrieveMetadata(section.getLocation());
                    return getServiceInformation(newMetadata);
                }
            }
        }
        return null;
    
private java.util.ListgetServiceInformationFromNode(java.lang.Object node)

        if (node == null) {
            return null;
        }
        final List<PortInfo> portInfos = new ArrayList<PortInfo>();
        final Node wsdlNode = (Node) node;
        final String namespace = getAttributeValue(wsdlNode, "targetNamespace");
        final NodeList nodes = wsdlNode.getChildNodes();
        for (int i=0; i<nodes.getLength(); i++) {
            final Node serviceNode = nodes.item(i);
            if (serviceNode.getLocalName() != null &&
                serviceNode.getLocalName().equals("service")) {
                
                final Node nameAtt = wsdlNode.getAttributes().getNamedItem("name");
                final QName serviceName = new QName(namespace,
                    nameAtt.getNodeValue());
                final NodeList portNodes = serviceNode.getChildNodes();
                for (int j=0; j<portNodes.getLength(); j++) {
                    final Node portNode = portNodes.item(j);
                    if (portNode.getLocalName() != null &&
                        portNode.getLocalName().equals("port")) {
                        
                        final QName portName = new QName(namespace,
                            getAttributeValue(portNode, "name"));
                        final String address = getPortAddress(portNode);
                        portInfos.add(new PortInfo(serviceName,
                            portName, address));
                    }
                }
            }
        }
        return portInfos;
    
public com.sun.xml.ws.mex.client.schema.MetadataretrieveMetadata(java.lang.String address)
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

        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(ERROR_LOG_LEVEL,
                        MessagesMessages.MEX_0006_RETRIEVING_MDATA_FAILURE(
                            p, newAddress));
                    continue;
                } catch (Exception e) {
                    logger.log(Level.WARNING,
                        MessagesMessages.MEX_0008_PARSING_MDATA_FAILURE(
                            p, newAddress));
                    continue;
                }
            }
        }
        logger.log(ERROR_LOG_LEVEL,
            MessagesMessages.MEX_0007_RETURNING_NULL_MDATA());
        return null;
    
public com.sun.xml.ws.mex.client.schema.MetadataretrieveMetadata(com.sun.xml.ws.mex.client.schema.MetadataReference reference)
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)

        
        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;