/*=============================================================================*
* 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.properties.v1_2.ResourceProperties1_2Constants;
import org.apache.ws.resource.properties.v1_3.ResourceProperties1_3Constants;
import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.PrefixResolverDefault;
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.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();
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 propsDocName
* @param def
*
* @return the names of the resource properties associated with the specified portType
*/
public static QName[] getResourcePropertyNames( QName propsDocName,
Definition def )
{
if ( propsDocName == null )
{
return null;
}
Element schemaElem = getSchemaElement( def );
Element rpDocElementElem = getElementByName( schemaElem, propsDocName );
String type = rpDocElementElem.getAttribute( "type" );
Element rpDocTypeElem;
if ( !"".equals( type ) )
{
rpDocTypeElem = getComplexTypeByName( schemaElem, type );
}
else
{
rpDocTypeElem = (Element) rpDocElementElem.getElementsByTagNameNS( XmlConstants.NSURI_SCHEMA_XSD, "complexType" ).item( 0 );
}
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" );
Set propNames = new HashSet();
for ( int i = 0; i < propElems.getLength(); i++ )
{
Element propElem = (Element) propElems.item( i );
String ref = propElem.getAttribute( "ref" );
StringTokenizer tokenizer = new StringTokenizer( ref, ":" );
String propPrefix = tokenizer.nextToken();
String propLocalName = tokenizer.nextToken();
// TODO: write our own prefix resolver to eliminate dep on Xalan
PrefixResolver prefixResolver = new PrefixResolverDefault( schemaElem );
String propNamespace = prefixResolver.getNamespaceForPrefix( propPrefix );
propNames.add( new QName( propNamespace, propLocalName, propPrefix ) );
}
return (QName[]) propNames.toArray( new QName[0] );
}
private static Element getElementByName( 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 elementElem;
}
}
}
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( ResourceProperties1_3Constants.RESOURCE_PROPERTIES_PORTTYPE_ATTRIB );
if ( rpDocDefQName == null )
{
rpDocDefQName = (QName) extAttribs.get( ResourceProperties1_2Constants.RESOURCE_PROPERTIES_PORTTYPE_ATTRIB );
}
return rpDocDefQName;
}
private static Element getSchemaElement( Definition def )
{
Element schemaElem = null;
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() ) )
{
schemaElem = elem;
break;
}
}
}
return schemaElem;
}
}