Package org.eclipse.wst.wsi.internal.core.util

Source Code of org.eclipse.wst.wsi.internal.core.util.TypesRegistry

/*******************************************************************************
* Copyright (c) 2002, 2009 IBM Corporation and others.
* All rights reserved.   This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*   IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.wst.wsi.internal.core.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Import;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.Types;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.schema.Schema;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPFault;
import javax.wsdl.extensions.soap.SOAPHeader;
import javax.wsdl.extensions.soap.SOAPHeaderFault;
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.xml.namespace.QName;

import org.eclipse.wst.wsi.internal.core.WSITag;
import org.eclipse.wst.wsi.internal.core.profile.validator.BaseValidator;
import org.eclipse.wst.wsi.internal.core.wsdl.traversal.WSDLTraversal;
import org.eclipse.wst.wsi.internal.core.wsdl.traversal.WSDLTraversalContext;
import org.eclipse.wst.wsi.internal.core.wsdl.traversal.WSDLVisitor;
import org.eclipse.wst.wsi.internal.core.xml.XMLUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


/**
* The class extracts XSD schema information from the given WSDL.
*
* @author Kulik
*/
public final class TypesRegistry implements WSITag, WSDLVisitor
{
  List schemaProcessedList = new ArrayList();
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(javax.wsdl.Part, java.lang.Object, org.wsi.wsdl.traversal.WSDLTraversalContext)
   */
  public void visit(Part obj, Object parent, WSDLTraversalContext ctx)
  {
  }

  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(javax.wsdl.Service, java.lang.Object, org.wsi.wsdl.traversal.WSDLTraversalContext)
   */
  public void visit(Service obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Types, Object,
   * WSDLTraversalContext)
   */
  public void visit(Types obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Operation, Object,
   * WSDLTraversalContext)
   */
  public void visit(Operation obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Input, Object,
   * WSDLTraversalContext)
   */
  public void visit(Input obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Output, Object,
   * WSDLTraversalContext)
   */
  public void visit(Output obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Fault, Object,
   * WSDLTraversalContext)
   */
  public void visit(Fault obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Binding, Object,
   * WSDLTraversalContext)
   */
  public void visit(Binding obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(BindingOperation, Object,
   * WSDLTraversalContext)
   */
  public void visit(
    BindingOperation obj,
    Object parent,
    WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(BindingInput, Object,
   * WSDLTraversalContext)
   */
  public void visit(BindingInput obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(BindingOutput, Object,
   * WSDLTraversalContext)
   */
  public void visit(BindingOutput obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(BindingFault, Object,
   * WSDLTraversalContext)
   */
  public void visit(BindingFault obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Element, Object,
   * WSDLTraversalContext)
   */
  public void visit(Element obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Message, Object,
   * WSDLTraversalContext)
   */
  public void visit(Message obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Port, Object,
   * WSDLTraversalContext)
   */
  public void visit(Port obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(PortType, Object,
   * WSDLTraversalContext)
   */
  public void visit(PortType obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(Definition, Object,
   * WSDLTraversalContext)
   */
  public void visit(Definition obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(ExtensibilityElement,
   * Object, WSDLTraversalContext)
   */
  public void visit(
    ExtensibilityElement obj,
    Object parent,
    WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(SOAPBinding, Object,
   * WSDLTraversalContext)
   */
  public void visit(SOAPBinding obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(SOAPBody, Object,
   * WSDLTraversalContext)
   */
  public void visit(SOAPBody obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(SOAPHeader, Object,
   * WSDLTraversalContext)
   */
  public void visit(SOAPHeader obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(SOAPHeaderFault, Object,
   * WSDLTraversalContext)
   */
  public void visit(
    SOAPHeaderFault obj,
    Object parent,
    WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(SOAPFault, Object,
   * WSDLTraversalContext)
   */
  public void visit(SOAPFault obj, Object parent, WSDLTraversalContext ctx)
  {
  }
 
  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(SOAPOperation, Object,
   * WSDLTraversalContext)
   */
  public void visit(SOAPOperation obj, Object parent, WSDLTraversalContext ctx)
  {
  }

  private Map element2Type = new HashMap();
  private Set extendsArray = new HashSet();
  private Set usesWsdlArrayType = new HashSet();

  protected BaseValidator baseValidator = null;
  /**
   * Constructor creates the types registry. by the given WSDL definition
   * object.
   *
   * @param def a WSDL definition.
   * @param baseValidator a base validator.
   */
  public TypesRegistry(Definition def, BaseValidator baseValidator)
  {
    this.baseValidator = baseValidator;
    if (def == null)
      throw new IllegalArgumentException("Definition can not be null");

    WSDLTraversal traversal = new WSDLTraversal();
    //VisitorAdaptor.adapt(this);
    traversal.setVisitor(this);
    traversal.visitImport(true);
   
    processTypes(def.getTypes(), def.getDocumentBaseURI());
    traversal.traverse(def);
  }

  /**
   * Constructor creates the types registry by given WSDL types object and
   * location context URI.
   * @param types WSDL types object.
   * @param context location context URI.
   * @param baseValidator a base validator.
   */
  public TypesRegistry(
    Types types,
    String context,
    BaseValidator baseValidator)
  {
    this.baseValidator = baseValidator;
    processTypes(types, context);
  }

  /**
   * The method returns type's qname by given element's qname.
   * @param elementName a qualified element name.
   * @return type's qname by given element's qname.
   */
  public QName getType(QName elementName)
  {
    return (QName) element2Type.get(elementName);
  }

  /**
   * The method returns set of types which is array attribute.
   * @return set of types which is array attribute.
   */
  public Set getArrayTypes()
  {
    Set s = new HashSet();
    s.addAll((Collection) usesWsdlArrayType);
    s.addAll((Collection) extendsArray);
    return s;
  }

  /**
   * The method returns set of elements defined in types element.
   * @return set of elements defined in types element.
   */
  public Set getElementList()
  {
    return this.element2Type.keySet();
  }

  /**
   * The method returns true if the given type declares wsdl:arrayType
   * attribute within declaration.
   * @param type a type.
   * @return true if the given type declares wsdl:arrayType
   * attribute within declaration.
   */
  public boolean isUsesWSDLArrayType(QName type)
  {
    return usesWsdlArrayType.contains(type);
  }

  /**
   * The method returns true if given type extends soapenc:Array type.
   * @param type a type.
   * @return true if given type extends soapenc:Array type.
   */
  public boolean isExtendsArray(QName type)
  {
    return extendsArray.contains(type);
  }

  /* (non-Javadoc)
   * @see org.wsi.wsdl.traversal.WSDLVisitor#visit(javax.wsdl.Import, java.lang.Object, org.wsi.wsdl.traversal.WSDLTraversalContext)
   */
  public void visit(Import im, Object parent, WSDLTraversalContext ctx)
  {
    if (im.getDefinition() != null)
      processWSDL(im.getDefinition());
  }

  /**
   * Internal method processes WSDL definition.
   * @param def a WSDL definition.
   */
  private void processWSDL(Definition def)
  {
    if (def.getTypes() != null)
      processTypes(def.getTypes(), def.getDocumentBaseURI());
  }

  /**
   * Internal method processes WSDL types.
   * @param types WSDL types.
   * @param context a context.
   */
  private void processTypes(Types types, String context)
  {
    if (types == null)
      return;
    List exts = types.getExtensibilityElements();
    if (exts != null)
    {
      Iterator it = exts.iterator();
      while (it.hasNext())
      {
        ExtensibilityElement el = (ExtensibilityElement) it.next();
        if (el instanceof Schema)
          searchForSchema(
            ((Schema) el).getElement(),
            context);
      }
    }
  }

  /**
   * Internal method searches XSD schema declaration and XSD import
   * statements.
   * @param n
   * @param context
   */
  private void searchForSchema(Node n, String context)
  {
    while (n != null)
    {
      // searches for xsd:import element
      if (Node.ELEMENT_NODE == n.getNodeType())
      {
        // if xsd:schema element is found -> process schema
        if (XMLUtils.equals(n, ELEM_XSD_SCHEMA))
          processSchema(n, context, new ArrayList());
      }
      n = n.getNextSibling();
    }
  }

  /**
   * Internal method loads XSD schema by using schema location and
   * location context.
   * @param importNode
   * @param context
   */
  private void loadSchema(Node importNode, String context, List processedSchemas)
  {
    Element im = (Element) importNode;
    Attr schemaLocation = XMLUtils.getAttribute(im, ATTR_XSD_SCHEMALOCATION);
 
    // try to parse imported XSD
    if (schemaLocation != null && schemaLocation.getValue() != null)
      try
      {
      String urlString = XMLUtils.createURLString(schemaLocation.getValue(), context);
      if (!schemaProcessedList.contains(urlString))
      {
          // if any error or root element is not XSD schema -> error
          Document schema =
            baseValidator.parseXMLDocumentURL(
              schemaLocation.getValue(),
              context,
              null);
          schemaProcessedList.add(urlString);
          if (XMLUtils.equals(schema.getDocumentElement(), ELEM_XSD_SCHEMA))
            processSchema(
              schema.getDocumentElement(),
              urlString, processedSchemas);
      }
      }
      catch (Throwable t)
      {
        //t.printStackTrace();
        // nothing. it's not a schema
      }
  }

  /**
   * Internal method processes XSD schema and retrieves types declaration from
   * it.
   * @param schema
   * @param context
   */
  private void processSchema(Node schema, String context, List processedSchemas)
  {
  if ((schema != null) && (!processedSchemas.contains(schema)))
  {
    processedSchemas.add(schema);
      Attr a = XMLUtils.getAttribute((Element) schema, ATTR_XSD_TARGETNAMESPACE);
      String targetNamespace = (a != null) ? a.getValue() : "";
      // iterate schema
      Node n = schema.getFirstChild();
      // !! we suppose that xsd:import element is occured only within xsd:schema element       
      while (n != null)
      {
        if (Node.ELEMENT_NODE == n.getNodeType())
        {
          if (XMLUtils.equals(n, ELEM_XSD_ELEMENT))
          {
            Element el = (Element) n;
            a = XMLUtils.getAttribute(el, ATTR_XSD_NAME);
            QName element =
              new QName(targetNamespace, (a != null) ? a.getValue() : "");

            a = XMLUtils.getAttribute(el, ATTR_XSD_TYPE);
            QName type = null;
            if (a != null)
            {
              String t = a.getValue();
              // if type contains ':', it means that it contains qname
              int i = t.indexOf(':');
              if (i != -1)
              {
                String prefix = t.substring(0, i);
                String nsURI = XMLUtils.findNamespaceURI(n, prefix);
                type = new QName(nsURI, t.substring(i + 1));
              }
              else
                type = new QName(targetNamespace, t);
            }
            else
            {
              // suppose that element directly contains type declaration
              type = element;
              checkType(n, type);
            }

            element2Type.put(element, type);
          }
          else if (XMLUtils.equals(n, ELEM_XSD_IMPORT))
            loadSchema(n, context, processedSchemas);
          else if (XMLUtils.equals(n, ELEM_XSD_INCLUDE))
            loadSchema(n, context, processedSchemas);
          else if (XMLUtils.equals(n, ELEM_XSD_COMPLEXTYPE))
          {
            Element el = (Element) n;
            a = XMLUtils.getAttribute(el, ATTR_XSD_NAME);
            QName type =
              new QName(targetNamespace, (a != null) ? a.getValue() : "");
            checkType(n, type);
          }

        }

        n = n.getNextSibling();
      }
  }
  }

  /**
   * Internal method checks whether specified type has WSDL array type
   * attribute in the XSD declaration.
   * @param n
   * @param name
   */
  private void checkType(Node n, QName name)
  {
    while (n != null)
    {
      if (Node.ELEMENT_NODE == n.getNodeType())
      {
        // check such sentence
        //              xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="tns:MyArray2Type[]"/>
        if (XMLUtils.equals(n, ELEM_XSD_ATTRIBUTE))
        {
          Attr a = XMLUtils.getAttribute((Element) n, ATTR_WSDL_ARRAYTYPE);
          if (a != null)
            usesWsdlArrayType.add(name);
        }

        // retrieve base attribute may be from restriction or extension
        Attr a = XMLUtils.getAttribute((Element) n, ATTR_XSD_BASE);
        if (a != null)
        {
          String base = a.getValue();
          int i = base.indexOf(":");
          if (i != -1)
          {
            String prefix = base.substring(0, i);
            String local = base.substring(i + 1);
            String namespace = XMLUtils.findNamespaceURI(n, prefix);
            if (SOAPENC_ARRAY.equals(new QName(namespace, local)))
              extendsArray.add(name);
          }
        }
        checkType(n.getFirstChild(), name);
      }
      n = n.getNextSibling();
    }
  }
}
TOP

Related Classes of org.eclipse.wst.wsi.internal.core.util.TypesRegistry

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.