Package org.apache.ws.util

Source Code of org.apache.ws.util.WsrfWsdlUtils$XsdElement

/*=============================================================================*
*  Copyright 2004 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*=============================================================================*/
package org.apache.ws.util;

import org.apache.ws.resource.InvalidWsrfWsdlException;
import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.PrefixResolverDefault;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.wsdl.Definition;
import javax.wsdl.Operation;
import javax.wsdl.PortType;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.UnknownExtensibilityElement;
import javax.xml.namespace.QName;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

/**
* Utility methods for working with a WSRF WSDL definition.
*
* @author Ian Springer (ian DOT springer AT hp DOT com)
*/
public abstract class WsrfWsdlUtils
{

    /**
     * DOCUMENT_ME
     *
     * @param mostDerivedPortType DOCUMENT_ME
     * @param specPortType        DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    public static boolean implementsPortType( PortType mostDerivedPortType,
                                              PortType specPortType )
    {
        List specOps = specPortType.getOperations();
        if (specOps.size() == 0 ) return false; //todo need to determine if props are present for portTypes which have no methods.
        boolean foundSome = false;
        for ( int i = 0; i < specOps.size(); i++ )
        {
            Operation specOp = (Operation) specOps.get( i );
            Operation aggregatedOp = mostDerivedPortType.getOperation( specOp.getName(),
                    null,
                    null );
            if ( !WsdlUtils.equals( specOp, aggregatedOp ) )
            {
                if ( foundSome )
                {
                    System.out.println( "WARNING: PortType " + mostDerivedPortType.getQName()
                            + " contains some, but not all, operations from portType "
                            + specPortType.getQName() );
                }

                return false;
            }

            if ( !isInheritedOperation( specOp, specPortType ) )
            {
                foundSome = true;
            }
        }

        return true;
    }

    private static boolean isInheritedOperation( Operation specOp,
                                                 PortType specPortType )
    {
        return !specOp.getInput().getMessage().getQName().getNamespaceURI().equals( specPortType.getQName()
                .getNamespaceURI() );
    }

    /**
     * @param rpDocElemName
     * @param def
     * @param baseUrl
     *
     * @return the names of the resource properties associated with the specified portType
     */
    public static QName[] getResourcePropertyNames( QName rpDocElemName,
                                                    Definition def, URL baseUrl ) throws InvalidWsrfWsdlException
    {
        if ( rpDocElemName == null )
        {
            return null;
        }
        Set propNames = new HashSet();
        Element[] schemaElems = getSchemaElements( def );
        XsdElement rpDocXsdElem = null;
        for ( int i = 0; i < schemaElems.length; i++ )
        {
            rpDocXsdElem = getXsdElementElementRecursively( schemaElems[i], rpDocElemName, baseUrl );
            if ( rpDocXsdElem != null )
            {
                break;
            }
        }
        if ( rpDocXsdElem == null )
        {
            throw new InvalidWsrfWsdlException(
                    "Unable to locate the ResourceProperties document element with QName " + rpDocElemName );
        }
        QName type = getQualifiedAttribute( rpDocXsdElem, "type" );
        Element rpDocTypeElem;
        if ( type != null )
        {
            if ( ! type.getNamespaceURI().equals( rpDocXsdElem.getSchemaElement().getAttribute( "targetNamespace" ) ) )
            {
                throw new InvalidWsrfWsdlException(
                    "This tool currently does not support referencing a ResourceProperties complexType that is not in the current schema's targetNamespace." );
            }
            rpDocTypeElem = getComplexTypeByName( rpDocXsdElem.getSchemaElement(), type.getLocalPart() );
        }
        else
        {
            rpDocTypeElem =
                    (Element) rpDocXsdElem.getElement().getElementsByTagNameNS( XmlConstants.NSURI_SCHEMA_XSD,
                            "complexType" )
                    .item( 0 );
        }
        if ( rpDocTypeElem == null )
        {
            throw new InvalidWsrfWsdlException( "Unable to determine type of the ResourceProperties document element with QName " + rpDocElemName + " - expected either a type atribute or a nested anonymous complexType element." );
        }
        Element sequenceElem = null;
        NodeList sequenceNodes = rpDocTypeElem.getElementsByTagNameNS( XmlConstants.NSURI_SCHEMA_XSD, "sequence" );
        if ( sequenceNodes != null )
        {
            sequenceElem = (Element) sequenceNodes.item( 0 );
        }
        else
        {
            sequenceNodes = rpDocTypeElem.getElementsByTagNameNS( XmlConstants.NSURI_SCHEMA_XSD, "all" );
            if ( sequenceNodes != null )
            {
                sequenceElem = (Element) sequenceNodes.item( 0 );
            }
        }
        if ( sequenceElem == null )
        {
            throw new RuntimeException(
                    "Resource property element definitions must be contained in an xsd:sequence or an xsd:all element." );
        }
        NodeList propElems = sequenceElem.getElementsByTagNameNS( XmlConstants.NSURI_SCHEMA_XSD, "element" );
        for ( int j = 0; j < propElems.getLength(); j++ )
        {
            Element propElem = (Element) propElems.item( j );
            QName propName = getQualifiedAttribute( new XsdElement( propElem, rpDocXsdElem.getSchemaElement() ), "ref" );
            if ( propName == null )
            {
                throw new InvalidWsrfWsdlException( "All element defs within the resource property document def must have a 'ref' attribute that points at a global element def." );
            }
            propNames.add( propName );
        }
        return (QName[]) propNames.toArray( new QName[0] );
    }

    private static XsdElement getXsdElementElementRecursively( Element xsdSchemaElem, QName xsdElemName, URL baseUrl )
            throws InvalidWsrfWsdlException
    {
        XsdElement xsdElementElem = getXsdElementElement( xsdSchemaElem, xsdElemName );
        if ( xsdElementElem == null )
        {
            String[] schemaLocations = findImportsAndIncludes( xsdSchemaElem, xsdElemName.getNamespaceURI() );
            for ( int j = 0; j < schemaLocations.length; j++ )
            {
                String location = schemaLocations[j];
                URL schemaUrl = null;
                Document schemaDoc = null;
                try
                {
                    schemaUrl = new URL( baseUrl, location );
                    schemaDoc = JaxpUtils.loadDocument( schemaUrl.openStream() );
                }
                catch ( Exception e )
                {
                    throw new InvalidWsrfWsdlException( "Failed to load schema at location " + location );
                }
                xsdElementElem =
                        getXsdElementElementRecursively( schemaDoc.getDocumentElement(), xsdElemName, schemaUrl );
                if ( xsdElementElem != null )
                {
                    break;
                }
            }
        }
        return xsdElementElem;
    }

    private static QName getQualifiedAttribute( XsdElement xsdElem, String attribName )
            throws InvalidWsrfWsdlException
    {
        String value = xsdElem.getElement().getAttribute( attribName );
        if ( "".equals( value ) )
        {
            return null;
        }
        PrefixResolver prefixResolver = new PrefixResolverDefault( xsdElem.getSchemaElement() );
        QName propName = null;
        try
        {
            propName = toQName( value, prefixResolver );
        }
        catch ( PrefixResolutionException pre )
        {
            throw new InvalidWsrfWsdlException( "Unable to resolve prefix '" + pre.getPrefix() + "' in xsd:element '" + attribName + "' attribute value." );
        }
        catch ( InvalidValueException ive )
        {
            throw new InvalidWsrfWsdlException( "Value for xsd:element 'ref' attribute must be qualified via a namespace prefix." );
        }
        return propName;
    }

    private static QName toQName( String value, PrefixResolver prefixResolver ) throws InvalidValueException,
            PrefixResolutionException
    {
        StringTokenizer tokenizer = new StringTokenizer( value, ":" );
        if ( tokenizer.countTokens() != 2 )
        {
            throw new InvalidValueException();
        }
        String prefix = tokenizer.nextToken();
        String localName = tokenizer.nextToken();
        // TODO: write our own prefix resolver to eliminate dep on Xalan
        String namespace = prefixResolver.getNamespaceForPrefix( prefix );
        if ( namespace == null )
        {
           throw new PrefixResolutionException( prefix );
        }
        QName qName = new QName( namespace, localName, prefix );
        return qName;
    }

    private static String[] findImportsAndIncludes( Element schemaElem, String namespaceURI )
    {
        List elems = new ArrayList();
        NodeList imports = schemaElem.getElementsByTagNameNS( XmlConstants.NSURI_SCHEMA_XSD,
                XmlConstants.XSD_ATTRIB_IMPORT );
        for ( int i = 0; i < imports.getLength(); i++ )
        {
            Element importNode = (Element) imports.item( i );
            Attr attributeNode = importNode.getAttributeNode( "namespace" );
            if ( attributeNode != null )
            {
                if ( namespaceURI.equals( attributeNode.getValue() ) )
                {
                    elems.add( importNode );
                }
            }
        }
        NodeList includes = schemaElem.getElementsByTagNameNS( XmlConstants.NSURI_SCHEMA_XSD,
                XmlConstants.XSD_ATTRIB_INCLUDE );
        for ( int i = 0; i < includes.getLength(); i++ )
        {
            elems.add( includes.item( i ) );
        }
        String[] locations = new String[elems.size()];
        for ( int i = 0; i < elems.size(); i++ )
        {
            Element element = (Element) elems.get( i );
            Attr attributeNode = element.getAttributeNode( "schemaLocation" );
            if ( attributeNode != null )
            {
                locations[i] = attributeNode.getValue();
            }
        }
        return locations;
    }

    private static XsdElement getXsdElementElement( Element schemaElem,
                                                    QName name )
    {
        NodeList children = schemaElem.getChildNodes();
        for ( int i = 0; i < children.getLength(); i++ )
        {
            Node child = children.item( i );
            if ( child instanceof Element && child.getLocalName().equals( "element" ) )
            {
                Element elementElem = (Element) child;
                if ( String.valueOf( elementElem.getAttribute( "name" ) ).equals( name.getLocalPart() ) )
                {
                    return new XsdElement( elementElem, schemaElem );
                }
            }
        }
        return null;
    }

    private static Element getComplexTypeByName( Element schemaElem,
                                                 String name )
    {
        NodeList children = schemaElem.getChildNodes();
        for ( int i = 0; i < children.getLength(); i++ )
        {
            Node child = children.item( i );
            if ( child instanceof Element && child.getLocalName().equals( "complexType" ) )
            {
                Element elementElem = (Element) child;
                if ( String.valueOf( elementElem.getAttribute( "name" ) ).equals( name ) )
                {
                    return elementElem;
                }
            }
        }
        return null;
    }

    public static QName getResourcePropertiesDocumentName( PortType portType )
    {
        Map extAttribs = portType.getExtensionAttributes();
        QName rpDocDefQName = (QName) extAttribs.get(
                org.apache.ws.resource.properties.v2004_11.ResourcePropertiesConstants.RESOURCE_PROPERTIES_PORTTYPE_ATTRIB );
        if ( rpDocDefQName == null )
        {
            rpDocDefQName =
                    (QName) extAttribs.get(
                            org.apache.ws.resource.properties.v2004_06.ResourcePropertiesConstants.RESOURCE_PROPERTIES_PORTTYPE_ATTRIB );
        }
        return rpDocDefQName;
    }

    public static QName getMetadataDescriptorName( PortType portType )
    {
        Map extAttribs = portType.getExtensionAttributes();
        return (QName) extAttribs.get( new QName(
                "http://docs.oasis-open.org/wsrf/2004/10/wsrf-WSResourceMetadataDescriptor-1.0-draft-01.xsd",
                "metadataDescriptor", "wsrmd" ) );
    }

    public static String getMetadataDescriptorLocation( PortType portType )
            throws org.apache.ws.resource.InvalidWsrfWsdlException
    {
        Map extAttribs = portType.getExtensionAttributes();
        final QName METADATA_DESCRIPTOR_PORTTYPE_ATTRIB =
                new QName(
                        "http://docs.oasis-open.org/wsrf/2004/10/wsrf-WSResourceMetadataDescriptor-1.0-draft-01.xsd",
                        "metadataDescriptorLocation", "wsrmd" );
        QName qValue = ( (QName) extAttribs.get( METADATA_DESCRIPTOR_PORTTYPE_ATTRIB ) );
        if ( qValue == null )
        {
            return null;
        }
        String value = qValue.getLocalPart();
        StringTokenizer tokenizer = new StringTokenizer( value );
        if ( tokenizer.countTokens() != 2 )
        {
            throw new org.apache.ws.resource.InvalidWsrfWsdlException( METADATA_DESCRIPTOR_PORTTYPE_ATTRIB +
                    " attribute on portType must be of the format \"namespaceURI locationURL\"" );
        }
        tokenizer.nextToken();
        return tokenizer.nextToken();
    }

    private static Element[] getSchemaElements( Definition def )
    {
        List schemaElems = new ArrayList();
        List extElems = def.getTypes().getExtensibilityElements();
        for ( int i = 0; i < extElems.size(); i++ )
        {
            ExtensibilityElement extElem = (ExtensibilityElement) extElems.get( i );
            if ( extElem instanceof UnknownExtensibilityElement )
            {
                UnknownExtensibilityElement unknownExtElem = (UnknownExtensibilityElement) extElem;
                Element elem = unknownExtElem.getElement();
                if ( elem.getNamespaceURI().equals( XmlConstants.NSURI_SCHEMA_XSD )
                        && elem.getLocalName().equals( XmlConstants.XSD_SCHEMA.getLocalPart() ) )
                {
                    schemaElems.add( elem );
                }
            }
        }
        return (Element[]) schemaElems.toArray( new Element[0] );
    }

    private static class XsdElement
    {
        private Element m_elem;
        private Element m_schemaElem;

        public XsdElement( Element elem, Element schemaElem )
        {
            m_elem = elem;
            m_schemaElem = schemaElem;
        }

        public Element getElement()
        {
            return m_elem;
        }

        public Element getSchemaElement()
        {
            return m_schemaElem;
        }
    }

    private static class PrefixResolutionException extends Exception
    {
        private String m_prefix;

        public PrefixResolutionException( String prefix )
        {
            super();
            m_prefix = prefix;
        }

        public String getPrefix()
        {
            return m_prefix;
        }
    }

    private static class InvalidValueException extends Exception
    {
    }

}
TOP

Related Classes of org.apache.ws.util.WsrfWsdlUtils$XsdElement

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.