You are viewing a plain text version of this content. The canonical link for it is here.
Posted to muse-commits@ws.apache.org by da...@apache.org on 2006/08/23 06:02:35 UTC

svn commit: r433870 [3/3] - in /webservices/muse/trunk/modules/muse-core/src/org/apache/muse: core/ core/descriptor/ core/platform/ core/proxy/ core/routing/ core/serializer/ ws/wsdl/

Modified: webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/routing/SimpleResourceRouter.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/routing/SimpleResourceRouter.java?rev=433870&r1=433869&r2=433870&view=diff
==============================================================================
--- webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/routing/SimpleResourceRouter.java (original)
+++ webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/routing/SimpleResourceRouter.java Tue Aug 22 21:02:32 2006
@@ -31,12 +31,15 @@
 import org.apache.muse.util.messages.Messages;
 import org.apache.muse.util.messages.MessagesFactory;
 import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.MessageHeaders;
 import org.apache.muse.ws.addressing.soap.SoapFault;
 
 /**
  *
- * SimpleResourceRouter is Muse's default implementation of the implied 
- * resource pattern (as defined by {@linkplain ResourceRouter ResourceRouter}).
+ * SimpleResourceRouter is Muse's default implementation of a router that uses 
+ * the implied resource pattern to delegate requests to resources. It uses 
+ * the WS-A header data to map the request to a particular resource in its 
+ * {@linkplain ResourceManager ResourceManager}.
  *
  * @author Dan Jemiolo (danj)
  *
@@ -49,23 +52,23 @@
     //
     private static Messages _MESSAGES = MessagesFactory.get(SimpleResourceRouter.class);
     
-    //
-    // The portal to the outside world - this allows us to retrieve system 
-    // and deployment info in a platform-independent way
-    //
     private Environment _environment = null;
     
     private boolean _hasBeenInitialized = false;
     
     private boolean _hasBeenShutdown = false;
     
+    private Logger _log = null;
+
     //
-    // Used to log all messages
+    // optional persistence mechanism for saving/re-loading router entries
     //
-    private Logger _log = null;
-    
     private RouterPersistence _persistence = null;
     
+    //
+    // all of the ResourceDefinition objects for the resource types that 
+    // are controlled by this router
+    //
     private Collection _resourceDefinitions = null;
     
     //
@@ -73,6 +76,14 @@
     //
     private ResourceManager _resourceManager = null;
     
+    /**
+     * 
+     * This method can be overridden to provide an alternate implementation 
+     * of the ResourceManager component to the router.
+     *
+     * @return An instance of SimpleResourceManager.
+     *
+     */
     protected ResourceManager createResourceManager()
     {
         return new SimpleResourceManager();
@@ -88,6 +99,11 @@
         return _log;
     }
     
+    public RouterPersistence getPersistence()
+    {
+        return _persistence;
+    }
+    
     public Collection getResourceDefinitions()
     {
         return _resourceDefinitions;
@@ -115,7 +131,7 @@
      *         not associated with any resource instance.</li>
      *         </ul>
      * 
-     * @see Environment#getTargetEPR()
+     * @see MessageHeaders#getToAddress()
      * @see ResourceManager#getResource(EndpointReference)
      *
      */
@@ -124,7 +140,12 @@
     {
         ResourceManager manager = getResourceManager();
         Environment env = getEnvironment();
-        EndpointReference epr = env.getTargetEPR();
+        MessageHeaders wsa = env.getAddressingContext();
+        
+        if (wsa == null)
+            throw new RuntimeException(_MESSAGES.get("NoAddressingContext"));
+        
+        EndpointReference epr = wsa.getToAddress();
         
         Resource resource = manager.getResource(epr);
         
@@ -205,6 +226,9 @@
             next.setLog(log);
         }
         
+        //
+        // tell the resource manager about all our resource types
+        //
         _resourceManager = createResourceManager();
         _resourceManager.setEnvironment(env);
         _resourceManager.addResourceDefinitions(definitions);
@@ -270,16 +294,27 @@
         _log = log;
     }
     
+    public void setPersistence(RouterPersistence persistence)
+    {
+        _persistence = persistence;
+    }
+    
     public void setResourceDefinitions(Collection resourceDefinitions)
     {
+        if (resourceDefinitions == null)
+            throw new NullPointerException(_MESSAGES.get("NullResourceDefinitions"));
+        
         _resourceDefinitions = resourceDefinitions;
     }
-    
+
     public void setResourceManager(ResourceManager resourceManager)
     {
+        if (resourceManager == null)
+            throw new NullPointerException(_MESSAGES.get("NullResourceManager"));
+        
         _resourceManager = resourceManager;
     }
-    
+
     /**
      * 
      * {@inheritDoc}
@@ -304,15 +339,5 @@
         }
         
         _hasBeenShutdown = true;
-    }
-
-    public RouterPersistence getPersistence()
-    {
-        return _persistence;
-    }
-
-    public void setPersistence(RouterPersistence persistence)
-    {
-        _persistence = persistence;
     }
 }

Modified: webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/ArraySerializer.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/ArraySerializer.java?rev=433870&r1=433869&r2=433870&view=diff
==============================================================================
--- webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/ArraySerializer.java (original)
+++ webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/ArraySerializer.java Tue Aug 22 21:02:32 2006
@@ -91,21 +91,6 @@
         _classSerializer = classSerializer;
     }
     
-    public Class getArrayClass()
-    {
-        return _arrayClass;
-    }
-    
-    public Serializer getClassSerializer()
-    {
-        return _classSerializer;
-    }
-    
-    public Class getSerializableType()
-    {
-        return getArrayClass();
-    }
-    
     /**
      * 
      * {@inheritDoc}
@@ -140,6 +125,21 @@
         }
         
         return array;
+    }
+    
+    public Class getArrayClass()
+    {
+        return _arrayClass;
+    }
+    
+    public Serializer getClassSerializer()
+    {
+        return _classSerializer;
+    }
+    
+    public Class getSerializableType()
+    {
+        return getArrayClass();
     }
     
     /**

Modified: webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/Messages.properties
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/Messages.properties?rev=433870&r1=433869&r2=433870&view=diff
==============================================================================
--- webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/Messages.properties (original)
+++ webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/Messages.properties Tue Aug 22 21:02:32 2006
@@ -4,3 +4,4 @@
 NullArrayClass=The Class representing the array type is null.
 NotArrayClass=The type 'XXX' is not an array type. The value of this parameter must be equal to YourType[].class, not YourType.class.
 NoSerializer=The type XXX has no Serializer class specified - you must include a custom-serializer element for this type in the deployment descriptor. The types that currently have serializers are\: XXX
+NoFromXML=The XmlSerializableSerializer does not have an implementation of fromXML() - it only knows how to convert objects that implement XmlSerialiable to XML (using XmlSerializable.toXML()). If you want to deserialize objects of this type from XML, you should extend the XmlSerializableSerializer and override toXML() and getSerializableType().

Modified: webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/Serializer.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/Serializer.java?rev=433870&r1=433869&r2=433870&view=diff
==============================================================================
--- webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/Serializer.java (original)
+++ webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/Serializer.java Tue Aug 22 21:02:32 2006
@@ -33,7 +33,7 @@
  * or return types.
  * <br><br>
  * New Serializers can be introduced to Muse by adding the following XML 
- * to the Muse deployment descriptor:
+ * to the Muse deployment descriptor (muse.xml):
  * <br><br>
  * <code>
  * &lt;custom-serializer&gt;<br>
@@ -42,11 +42,9 @@
  * &lt;/custom-serializer&gt;<br><br>
  * </code>
  * This package contains many Serializers for built-in types, including 
- * primitives, simple types, and a few common complex types. These built-in 
- * types have their Serializers loaded at startup by Muse.
+ * primitives and simple types. These built-in types have their Serializers 
+ * loaded at startup by Muse.
  * 
- * @see org.apache.muse.core.descriptor.DescriptorConstants
- *
  * @author Dan Jemiolo (danj)
  *
  */

Modified: webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/SerializerRegistry.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/SerializerRegistry.java?rev=433870&r1=433869&r2=433870&view=diff
==============================================================================
--- webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/SerializerRegistry.java (original)
+++ webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/SerializerRegistry.java Tue Aug 22 21:02:32 2006
@@ -50,7 +50,7 @@
  */
 
 public class SerializerRegistry
-{
+{    
     //
     // Used to lookup all exception messages
     //
@@ -58,17 +58,22 @@
     
     private static final SerializerRegistry _SINGLETON = new SerializerRegistry();
     
-    public static SerializerRegistry getInstance()
-    {
-        return _SINGLETON;
-    }
-    
     //
     // keep instance map as a tree so that we can show a sorted list 
     // of available serializers if an error occurs (no serializer found)
     //
     private Map _serializers = new TreeMap(new ClassComparator());
     
+    /**
+     * 
+     * @return The singleton instance of this class.
+     *
+     */
+    public static SerializerRegistry getInstance()
+    {
+        return _SINGLETON;
+    }
+    
     private SerializerRegistry()
     {
         //
@@ -95,7 +100,7 @@
         registerSerializer(Element.class, new ElementSerializer());
         registerSerializer(XmlSerializable.class, new XmlSerializableSerializer());
     }
-        
+    
     /**
      * 
      * @param type
@@ -111,9 +116,16 @@
         
         Serializer ser = searchClassHierarchy(type);
         
+        //
+        // found a match - return it
+        //
         if (ser != null)
             return ser;
         
+        //
+        // otherwise, construct an error message the has all of the 
+        // available types in it
+        //
         Iterator i = _serializers.keySet().iterator();
         
         StringBuffer availableTypes = new StringBuffer(1024);
@@ -129,6 +141,15 @@
         throw new RuntimeException(_MESSAGES.get("NoSerializer", filler));
     }
     
+    /**
+     * 
+     * Associates the given serializer with the type and any of its sub-types. 
+     * An ArraySerializer is also created for arrays of the type.
+     * 
+     * @param type
+     * @param ser
+     *
+     */
     public void registerSerializer(Class type, Serializer ser)
     {
         if (type == null)
@@ -137,6 +158,9 @@
         if (ser == null)
             throw new NullPointerException(_MESSAGES.get("NullSerializer"));
         
+        //
+        // make an array version of the serializer
+        //
         Class arrayType = ReflectUtils.getArrayClassFromClass(type);
         Serializer array = new ArraySerializer(arrayType, ser);
         
@@ -144,6 +168,19 @@
         _serializers.put(arrayType, array);
     }
     
+    /**
+     * 
+     * Looks through the parent class and interfaces of the given type to 
+     * see if one of them has a registered serializer that could be used 
+     * on the sub-type. The paren classes are considered first, then the 
+     * interfaces of the type, then the interfaces of each parent class.
+     * 
+     * @param type
+     * 
+     * @return A serializer for one of the type's parent classes or interfaces, 
+     *         or null if no possible serializer is found.
+     *
+     */
     protected Serializer searchClassHierarchy(Class type)
     {
         Serializer ser = (Serializer)_serializers.get(type);
@@ -151,6 +188,10 @@
         if (ser != null)
             return ser;
         
+        //
+        // if there's a parent class (not java.lang.Object), recurse 
+        // up the hierarchy for our search
+        //        
         Class parent = type.getSuperclass();
         
         if (parent != null && parent != Object.class)
@@ -161,6 +202,9 @@
                 return ser;
         }
         
+        //
+        // start the recursion again - this time with interfaces
+        //
         Class[] interfaces = type.getInterfaces();
         
         for (int n = 0; n < interfaces.length; ++n)
@@ -173,7 +217,14 @@
         
         return null;
     }
-
+    
+    /**
+     * 
+     * ClassComparator sorts java.lang.Class objects by name (ABC order).
+     *
+     * @author Dan Jemiolo (danj)
+     *
+     */
     private class ClassComparator implements Comparator
     {
         public int compare(Object obj1, Object obj2)

Modified: webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/XmlSerializableSerializer.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/XmlSerializableSerializer.java?rev=433870&r1=433869&r2=433870&view=diff
==============================================================================
--- webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/XmlSerializableSerializer.java (original)
+++ webservices/muse/trunk/modules/muse-core/src/org/apache/muse/core/serializer/XmlSerializableSerializer.java Tue Aug 22 21:02:32 2006
@@ -20,6 +20,8 @@
 
 import org.w3c.dom.Element;
 
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
 import org.apache.muse.util.xml.XmlSerializable;
 import org.apache.muse.util.xml.XmlUtils;
 
@@ -39,9 +41,14 @@
 
 public class XmlSerializableSerializer implements Serializer
 {
+    //
+    // Used to lookup all exception messages
+    //
+    private static Messages _MESSAGES = MessagesFactory.get(XmlSerializableSerializer.class);
+    
     public Object fromXML(Element xml)
     {
-        throw new UnsupportedOperationException();
+        throw new UnsupportedOperationException(_MESSAGES.get("NoFromXML"));
     }
     
     public Class getSerializableType()

Modified: webservices/muse/trunk/modules/muse-core/src/org/apache/muse/ws/wsdl/WsdlUtils.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-core/src/org/apache/muse/ws/wsdl/WsdlUtils.java?rev=433870&r1=433869&r2=433870&view=diff
==============================================================================
--- webservices/muse/trunk/modules/muse-core/src/org/apache/muse/ws/wsdl/WsdlUtils.java (original)
+++ webservices/muse/trunk/modules/muse-core/src/org/apache/muse/ws/wsdl/WsdlUtils.java Tue Aug 22 21:02:32 2006
@@ -1,18 +1,20 @@
-/*=============================================================================*
- *  Copyright 2006 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.
- *=============================================================================*/
+/*******************************************************************************
+ * =============================================================================
+ * Copyright 2006 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.muse.ws.wsdl;
 
@@ -47,11 +49,11 @@
 import org.apache.muse.ws.addressing.WsaConstants;
 
 /**
- *
+ * 
  * WsdlUtils is a collection of utility methods related to WSDL 1.1.
- *
+ * 
  * @author Dan Jemiolo (danj)
- *
+ * 
  */
 
 public class WsdlUtils
@@ -69,7 +71,7 @@
     public static final String NAMESPACE_URI = "http://schemas.xmlsoap.org/wsdl/";
     
     public static final String PREFIX = "wsdl";
-    
+
     /**
      * 
      * The "WSDL-SOAP" namespace used for SOAP bindings.
@@ -79,104 +81,246 @@
     
     public static final String SOAP_PREFIX = "wsdl-soap";
     
-    public static final String WSDL4J_VERBOSE_FLAG = "javax.wsdl.verbose";
-    
+    public static final QName ADDRESS_QNAME = new QName(SOAP_URI, "address", SOAP_PREFIX);
+
+    public static final QName BINDING_QNAME = new QName(NAMESPACE_URI, "binding", PREFIX);
+
+    public static final QName DEFINITIONS_QNAME = new QName(NAMESPACE_URI, "definitions", PREFIX);
+
+    public static final QName IMPORT_QNAME = new QName(NAMESPACE_URI, "import", PREFIX);
+
+    public static final QName INPUT_QNAME = new QName(NAMESPACE_URI, "input", PREFIX);
+
     //
     // below are the names of common WSDL tags
     //
-    
-    public static final QName ADDRESS_QNAME = 
-        new QName(SOAP_URI, "address", SOAP_PREFIX);
-    
-    public static final QName BINDING_QNAME = 
-        new QName(NAMESPACE_URI, "binding", PREFIX);
-    
-    public static final QName DEFINITIONS_QNAME = 
-        new QName(NAMESPACE_URI, "definitions", PREFIX);
 
-    public static final QName IMPORT_QNAME = 
-        new QName(NAMESPACE_URI, "import", PREFIX);
-    
     public static final String LOCATION = "location";
-    
-    public static final QName MESSAGE_QNAME = 
-        new QName(NAMESPACE_URI, "message", PREFIX);
+
+    public static final QName MESSAGE_QNAME = new QName(NAMESPACE_URI, "message", PREFIX);
 
     public static final String NAME = "name";
 
-    public static final QName PORT_QNAME = 
-        new QName(NAMESPACE_URI, "port", PREFIX);
-    
-    public static final QName PORT_TYPE_QNAME = 
-        new QName(NAMESPACE_URI, "portType", PREFIX);
-    
-    public static final QName OPERATION_QNAME = 
-        new QName(NAMESPACE_URI, "operation", PREFIX);
-    
-    public static final QName INPUT_QNAME = 
-        new QName(NAMESPACE_URI, "input", PREFIX);
-    
-    public static final QName OUTPUT_QNAME = 
-        new QName(NAMESPACE_URI, "output", PREFIX);
-    
-    public static final QName SERVICE_QNAME = 
-        new QName(NAMESPACE_URI, "service", PREFIX);
-    
-    public static final QName TYPES_QNAME = 
-        new QName(NAMESPACE_URI, "types", PREFIX);
-    
+    public static final QName OPERATION_QNAME = new QName(NAMESPACE_URI, "operation", PREFIX);
+
+    public static final QName OUTPUT_QNAME = new QName(NAMESPACE_URI, "output", PREFIX);
+
+    public static final QName PORT_QNAME = new QName(NAMESPACE_URI, "port", PREFIX);
+
+    public static final QName PORT_TYPE_QNAME = new QName(NAMESPACE_URI, "portType", PREFIX);
+
+    public static final QName SERVICE_QNAME = new QName(NAMESPACE_URI, "service", PREFIX);
+
+    public static final QName TYPES_QNAME = new QName(NAMESPACE_URI, "types", PREFIX);
+
+    public static final String WSDL4J_VERBOSE_FLAG = "javax.wsdl.verbose";
+
+    private static void addNamespacePrefixes(Element nextSchema, Element finalSchema)
+    {
+        NamedNodeMap attributes = nextSchema.getAttributes();
+        
+        for (int i = 0; i < attributes.getLength(); i++)
+        {
+            Node attribute = attributes.item(i);
+
+            if (!finalSchema.hasAttribute(attribute.getNodeName()))
+            {
+                String nodePrefix = finalSchema.getPrefix();
+                String nodeValue = attribute.getLocalName();
+
+                if (nodePrefix == null || !nodePrefix.equals(nodeValue))
+                    finalSchema.setAttribute(attribute.getNodeName(), attribute.getNodeValue());
+            }
+        }
+    }
+
     /**
      * 
-     * This is a convenience method that resolves all of the schema imports 
-     * referenced in a WSDL. It iterates over every schema in the WSDL's 
+     * This is a convenience method that resolves all of the schema imports
+     * referenced in a WSDL. It iterates over every schema in the WSDL's
      * <em>types</em> section and processes it via XsdUtils.addImports().
      * 
-     * @return The given WSDL, now with the imported schemas added to its 
+     * @return The given WSDL, now with the imported schemas added to its
      *         <em>types</em> section.
-     *
+     * 
      */
-    public static Document addSchemaImports(Document wsdl, 
-                                            String wsdlPath, 
-                                            Environment environment, 
-                                            Set namespaces)
+    public static Document addSchemaImports(Document wsdl, String wsdlPath, Environment environment, Set namespaces)
     {
         Element root = XmlUtils.getFirstElement(wsdl);
         Element types = XmlUtils.getElement(root, TYPES_QNAME);
         Element[] schemas = XmlUtils.getElements(types, XsdUtils.SCHEMA_QNAME);
-        
+
         for (int n = 0; n < schemas.length; ++n)
             addSchemaImports(types, schemas[n], wsdlPath, environment, namespaces);
-        
+
         return wsdl;
     }
 
     /**
      * 
-     * This is a convenience method that resolves all of the schema includes 
-     * referenced in a WSDL. It iterates over every schema in the WSDL's 
+     * Reads all of the schemas that are imported by the given schema and adds
+     * their content to its parent Node. This method is recursive - it will read
+     * through the imported schemas and resolve their imports as well. The
+     * method tracks the namespaces is resolves so that no duplicates are
+     * imported.
+     * 
+     * @param schemaContainer
+     *            The Element that contains the schema being evaluated. Imported
+     *            schemas will be appended to this Element.
+     * 
+     * @param currentSchema
+     *            The schema whose imports will be resolved.
+     * 
+     * @param path
+     *            The path of the document that contains the current schema.
+     *            This is used to resolve the paths of the imported schemas.
+     * 
+     * @param environment
+     *            The Muse environment is used to load the imported schema
+     *            files.
+     * 
+     * @param namespaces
+     *            The set of namespace URIs that have already been processed.
+     *            This allows the method to skip those schemas that have already
+     *            been processed via other imports and not duplicate XML.
+     * 
+     */
+    private static void addSchemaImports(Element schemaContainer, Element currentSchema, String path, Environment environment, Set namespaces)
+    {
+        Element[] imports = XmlUtils.getElements(currentSchema, XsdUtils.IMPORT_QNAME);
+
+        Document doc = schemaContainer.getOwnerDocument();
+
+        for (int n = 0; n < imports.length; ++n)
+        {
+            String location = imports[n].getAttribute(XsdUtils.SCHEMA_LOCATION);
+
+            //
+            // This is to guard against imports that do not have a location
+            // such as imports in a WSDL types section that reference
+            // sibling schemas.
+            //            
+            if (location.length() == 0)
+                continue;
+
+            String nextPath = environment.createRelativePath(path, location);
+
+            Document importDoc = environment.getDocument(nextPath);
+
+            Element nextSchema = XmlUtils.getFirstElement(importDoc);
+            String targetNS = nextSchema.getAttribute(XmlUtils.TARGET_NS);
+
+            //
+            // if the target namespace hasn't been seen before, we can add it
+            //
+            if (!namespaces.contains(targetNS))
+            {
+                nextSchema = (Element)doc.importNode(nextSchema, true);
+                schemaContainer.appendChild(nextSchema);
+
+                //
+                // record that we found it before reading through the doc
+                // for more imports
+                //
+                namespaces.add(targetNS);
+
+                addSchemaImports(schemaContainer, nextSchema, nextPath, environment, namespaces);
+            }
+        }
+    }
+
+    /**
+     * 
+     * This is a convenience method that resolves all of the schema includes
+     * referenced in a WSDL. It iterates over every schema in the WSDL's
      * <em>types</em> section and processes it via XsdUtils.addIncludes().
      * 
-     * @return The given WSDL, now with the included schemas added to its 
+     * @return The given WSDL, now with the included schemas added to its
      *         <em>types</em> section.
-     *
+     * 
      */
-    public static Document addSchemaIncludes(Document wsdl, 
-                                             String wsdlPath, 
-                                             Environment environment, 
-                                             Set namespaces)
+    public static Document addSchemaIncludes(Document wsdl, String wsdlPath, Environment environment, Set namespaces)
     {
         Element root = XmlUtils.getFirstElement(wsdl);
         Element types = XmlUtils.getElement(root, TYPES_QNAME);
         Element[] schemas = XmlUtils.getElements(types, XsdUtils.SCHEMA_QNAME);
-        
+
         for (int n = 0; n < schemas.length; ++n)
             addSchemaIncludes(schemas[n], schemas[n], wsdlPath, environment, namespaces);
-        
+
         return wsdl;
     }
-    
+
+    /**
+     * 
+     * Reads all of the schemas that are included by the given schema and adds
+     * their content to it. The method is recursive - it will read through each
+     * included schema and resolve its imports and includes. The method tracks
+     * the namespaces is resolves so that no duplicates are imported.
+     * 
+     * @param finalSchema
+     *            The original schema whose includes are being resolved. All
+     *            included schema content will be added to this node.
+     * 
+     * @param currentSchema
+     *            The schema whose includes and imports are being resolved. In
+     *            the initial call to this method, finalSchema and currentSchema
+     *            should be the same node. As the method recurses, currentSchema
+     *            will be the included schema that is being processed.
+     * 
+     * @param path
+     *            The path of the document that contains the current schema.
+     *            This is used to resolve the paths of the imported schemas.
+     * 
+     * @param environment
+     *            The Muse environment is used to load the included schema
+     *            files.
+     * 
+     * @param namespaces
+     *            The set of namespace URIs that have already been processed.
+     *            This allows the method to skip those schemas that have already
+     *            been processed via other imports/includes and not duplicate
+     *            XML.
+     * 
+     */
+    private static void addSchemaIncludes(Element finalSchema, Element currentSchema, String path, Environment environment, Set namespaces)
+    {
+        Element[] includes = XmlUtils.getElements(currentSchema, XsdUtils.INCLUDE_QNAME);
+
+        for (int n = 0; n < includes.length; ++n)
+        {
+            String relative = includes[n].getAttribute(XsdUtils.SCHEMA_LOCATION);
+            String nextPath = environment.createRelativePath(path, relative);
+
+            //
+            // copy the included schema content into this schema directly
+            //
+            Document includeDoc = environment.getDocument(nextPath);
+            Element nextSchema = XmlUtils.getFirstElement(includeDoc);
+            XmlUtils.moveSubTree(nextSchema, finalSchema, includes[n]);
+
+            //
+            // copy namespace prefixes from the schema
+            //
+            addNamespacePrefixes(nextSchema, finalSchema);
+
+            //
+            // now resolve the imports in the included schema - any imports
+            // will be added to the schema's parent element (since they have
+            // different namespaces)
+            //
+            Element types = (Element)finalSchema.getParentNode();
+            addSchemaImports(types, nextSchema, nextPath, environment, namespaces);
+
+            //
+            // finally, recurse and process the new schema's includes
+            //
+            addSchemaIncludes(finalSchema, nextSchema, nextPath, environment, namespaces);
+        }
+    }
+
     public static Definition createDefinition(Document wsdlDoc, File wsdlDir)
-    {                
+    {
         //
         // use WSDL4J to parse/validate the WSDL
         //
@@ -184,76 +328,75 @@
         {
             WSDLFactory factory = WSDLFactory.newInstance();
             WSDLReader reader = factory.newWSDLReader();
-            
+
             //
-            // shut off verbose mode in WSDL4J - in a "real world" 
+            // shut off verbose mode in WSDL4J - in a "real world"
             // WSDL with many imports, this generates pages of output
-            // that no one can read. we will still get proper error 
+            // that no one can read. we will still get proper error
             // messages if a given XSD/WSDL could not be resolved.
             //
             reader.setFeature(WsdlUtils.WSDL4J_VERBOSE_FLAG, false);
-            
+
             return reader.readWSDL(wsdlDir.getAbsolutePath(), wsdlDoc);
         }
-        
+
         catch (Exception error)
         {
             throw new RuntimeException(error);
         }
     }
-    
+
     /**
      * 
      * Loads the WSDL at the given path, resolving any imports if desired.
-     *
+     * 
      * @param environment
-     *        The Muse environment is used to load the WSDL file.
+     *            The Muse environment is used to load the WSDL file.
      * 
      * @param wsdlPath
-     *        The relative path of the WSDL file.
+     *            The relative path of the WSDL file.
      * 
      * @param resolveReferences
-     *        True if you want the method to process and WSDL and XSD imports 
-     *        that are in the WSDL document. The resulting Document may be much 
-     *        larger depending on how many imports are discovered while the 
-     *        method recurses through the other WSDLs/XSDs.
-     * 
-     * @return A Document with the WSDL content. If the last parameter was 
-     *         'true', the Document will have the contents of other WSDLs 
-     *         and XSDs merged into it.
-     *
-     */
-    public static Document createWSDL(Environment environment, 
-                                      String wsdlPath, 
-                                      boolean resolveReferences)
+     *            True if you want the method to process and WSDL and XSD
+     *            imports that are in the WSDL document. The resulting Document
+     *            may be much larger depending on how many imports are
+     *            discovered while the method recurses through the other
+     *            WSDLs/XSDs.
+     * 
+     * @return A Document with the WSDL content. If the last parameter was
+     *         'true', the Document will have the contents of other WSDLs and
+     *         XSDs merged into it.
+     * 
+     */
+    public static Document createWSDL(Environment environment, String wsdlPath, boolean resolveReferences)
     {
         Document wsdl = environment.getDocument(wsdlPath);
-        
+
         //
         // if they just want the doc, we can quit now
         //
         if (!resolveReferences)
             return wsdl;
-        
+
         //
-        // otherwise we must process all imports/includes, then add in 
+        // otherwise we must process all imports/includes, then add in
         // any WSDL imports and merge them together
         //
-        
+
         Set namespaces = getSchemaNamespaces(wsdl);
-        
+
         //
         // take care of our imports first...
         //
         addSchemaIncludes(wsdl, wsdlPath, environment, namespaces);
         addSchemaImports(wsdl, wsdlPath, environment, namespaces);
-        
+
         //
         // ...then create all WSDLs that were imported...
         //
         Collection otherWSDLs = getWsdlImports(wsdl, wsdlPath, environment);
         Iterator i = otherWSDLs.iterator();
-        
+
         //
         // ...and merge them together
         //
@@ -262,29 +405,30 @@
             Document next = (Document)i.next();
             mergeWSDL(next, wsdl, namespaces);
         }
-        
+
         return wsdl;
     }
-    
+
     public static String getAction(Operation op)
     {
         Input input = op.getInput();
         Object attr = (QName)input.getExtensionAttribute(WsaConstants.ACTION_QNAME);
-        
+
         if (attr == null)
         {
-            Object[] filler = { op.getName(), input.getName(), input.getExtensionAttributes().keySet() };
+            Object[] filler = { op.getName(), input.getName(),
+                    input.getExtensionAttributes().keySet() };
             throw new RuntimeException(_MESSAGES.get("NoActionOnInput", filler));
         }
-        
+
         return attr instanceof String ? (String)attr : ((QName)attr).getLocalPart();
     }
-    
+
     public static QName getInputPartName(Operation op)
     {
         Input input = op.getInput();
         Map parts = input.getMessage().getParts();
-                
+
         //
         // one message, one part, one XSD element - that's the system
         //
@@ -293,48 +437,47 @@
             Object[] filler = { op.getName() };
             throw new RuntimeException(_MESSAGES.get("NotDocLiteral", filler));
         }
-        
+
         Part docLiteralPart = (Part)parts.values().iterator().next();
         QName partName = docLiteralPart.getElementName();
-        
+
         //
-        // HACK: this is for Axis/Axiom - they don't handle the default 
-        //       namespace/prefix well, so we always use a prefix
+        // HACK: this is for Axis/Axiom - they don't handle the default
+        // namespace/prefix well, so we always use a prefix
         //
         String prefix = partName.getPrefix();
-        
+
         if (prefix == null || prefix.length() == 0)
             partName = new QName(partName.getNamespaceURI(), partName.getLocalPart(), "muse-op");
-        
+
         return partName;
     }
-    
+
     /**
      * 
-     * This method is somewhat painful because of the lack of restrictions that 
-     * WSDL 1.1 has for how you can specify input and output names and types. 
-     * Similar to the problem of generating proxies that have the proper return 
-     * type/name, determining how to package response messages is hard because 
-     * there are multiple ways to say the same thing (void, xsd:any, etc.) and 
+     * This method is somewhat painful because of the lack of restrictions that
+     * WSDL 1.1 has for how you can specify input and output names and types.
+     * Similar to the problem of generating proxies that have the proper return
+     * type/name, determining how to package response messages is hard because
+     * there are multiple ways to say the same thing (void, xsd:any, etc.) and
      * almost everything is optional.
      * 
-     * This method is way too long, but I don't think breaking up the input 
-     * and output message processing would help clarify things. The output 
-     * message processing is most problematic, because each step of the way 
-     * is optional. This is going to be ugly no matter what.
-     *
+     * This method is way too long, but I don't think breaking up the input and
+     * output message processing would help clarify things. The output message
+     * processing is most problematic, because each step of the way is optional.
+     * This is going to be ugly no matter what.
+     * 
      */
     public static QName getOutputPartName(Operation op, Document wsdlDoc)
     {
         Output output = op.getOutput();
-        
+
         //
         // no output message = void
         //
         if (output == null)
             return null;
-        
-        
+
         Map parts = output.getMessage().getParts();
 
         //
@@ -345,39 +488,39 @@
             Object[] filler = { op.getName() };
             throw new RuntimeException(_MESSAGES.get("NotDocLiteral", filler));
         }
-    
+
         Part docLiteralPart = (Part)parts.values().iterator().next();
         QName responseType = docLiteralPart.getElementName();
-        
+
         //
         // no output type - this is a void operation
         //
         if (responseType == null)
             return null;
-        
+
         Element typeDef = WsdlUtils.getTypeDeclaration(wsdlDoc, responseType);
-        
+
         //
-        // empty output message also = pack simple return value into 
+        // empty output message also = pack simple return value into
         // response element (or void)
         //
         if (typeDef.getChildNodes().getLength() == 0)
             return null;
-        
+
         Element returnValueElement = XmlUtils.findFirstInSubTree(typeDef, XsdUtils.ELEMENT_QNAME);
-            
+
         //
-        // valid output message that is not a complex type or IS 
-        // a complex type but has an empty sequence(?) = pack 
+        // valid output message that is not a complex type or IS
+        // a complex type but has an empty sequence(?) = pack
         // simple return value into response element (or void)
         //
         // having fun yet?
         //
         if (returnValueElement == null)
             return null;
-        
+
         //
-        // complex type for output message - use element in the 
+        // complex type for output message - use element in the
         // type's sequence as name of the return value
         //
         // argh.
@@ -385,83 +528,84 @@
         String qname = returnValueElement.getAttribute(XsdUtils.REF);
         return XmlUtils.parseQName(qname, returnValueElement);
     }
-    
+
     /**
      * 
      * Searches a WSDL document for a portType defined with the given name.
-     *
+     * 
      * @param wsdl
-     *        The WDSL document to search.
+     *            The WDSL document to search.
      * 
      * @param qname
-     *        The name of the portType definition to find.
+     *            The name of the portType definition to find.
+     * 
+     * @return The definition of the given portType. The method returns null if
+     *         the portType is not found.
      * 
-     * @return The definition of the given portType. The method returns 
-     *         null if the portType is not found.
-     *
      */
     public static Element getPortType(Node wsdl, QName qname)
     {
         if (wsdl == null)
             throw new NullPointerException(_MESSAGES.get("NullWSDLDocument"));
-        
+
         if (qname == null)
-            throw new NullPointerException(_MESSAGES.get("NullPortTypeQName"));        
-        
+            throw new NullPointerException(_MESSAGES.get("NullPortTypeQName"));
+
         //
         // find all the wsdl:portTypes
         //
         Element root = null;
-        
+
         if (wsdl.getNodeType() == Node.ELEMENT_NODE)
             root = (Element)wsdl;
-        
+
         else
             root = XmlUtils.getFirstElement(wsdl);
-        
+
         Element[] portTypes = XmlUtils.getElements(root, PORT_TYPE_QNAME);
-        
+
         String localName = qname.getLocalPart();
         String uri = qname.getNamespaceURI();
-        
+
         if (uri == null)
         {
             Object[] filler = { qname };
             String message = _MESSAGES.get("NullPortTypeNamespaceURI", filler);
             throw new RuntimeException(message);
         }
-        
+
         String targetNS = root.getAttribute(XmlUtils.TARGET_NS);
-        
+
         //
         // check the @name of each wsdl:portType...
         //
         for (int n = 0; n < portTypes.length; ++n)
         {
             String next = portTypes[n].getAttribute(XsdUtils.NAME);
-            
+
             //
-            // if we find a match, we still need to check namespaces 
+            // if we find a match, we still need to check namespaces
             //
             if (next.equals(localName) && uri.equals(targetNS))
                 return portTypes[n];
         }
-        
+
         //
         // portType not found
         //
         return null;
     }
-    
+
     /**
      * 
-     * Gathers the target namespaces for each schema in the WSDL's <em>types</em> 
-     * section.
-     *
+     * Gathers the target namespaces for each schema in the WSDL's
+     * <em>types</em> section.
+     * 
      * @param wsdl
      * 
-     * @return The set of schema namespaces declared in the <em>types</em> section.
-     *
+     * @return The set of schema namespaces declared in the <em>types</em>
+     *         section.
+     * 
      */
     public static Set getSchemaNamespaces(Document wsdl)
     {
@@ -470,219 +614,215 @@
         Element[] schemas = XmlUtils.getElements(types, XsdUtils.SCHEMA_QNAME);
 
         Set namespaces = new HashSet();
-        
+
         //
         // each schema should have a targetNamespace attribute
         //
         for (int n = 0; n < schemas.length; ++n)
             namespaces.add(schemas[n].getAttribute(XmlUtils.TARGET_NS));
-        
+
         return namespaces;
     }
-    
+
     /**
      * 
-     * Searches a WSDL document's types section for a type defined with 
-     * the given name. The Element does not have to belong to a schema 
-     * element inside of types in order to match.
-     *
+     * Searches a WSDL document's types section for a type defined with the
+     * given name. The Element does not have to belong to a schema element
+     * inside of types in order to match.
+     * 
      * @param wsdl
-     *        The WDSL document to search.
+     *            The WDSL document to search.
      * 
      * @param qname
-     *        The name of the type definition to find.
+     *            The name of the type definition to find.
+     * 
+     * @return The schema definition of the given type. The method returns null
+     *         if the type is not found.
      * 
-     * @return The schema definition of the given type. The method returns 
-     *         null if the type is not found.
-     *
      */
     public static Element getTypeDeclaration(Node wsdl, QName qname)
     {
         if (wsdl == null)
             throw new NullPointerException(_MESSAGES.get("NullWSDLDocument"));
-        
+
         if (qname == null)
-            throw new NullPointerException(_MESSAGES.get("NullTypeQName"));        
-        
+            throw new NullPointerException(_MESSAGES.get("NullTypeQName"));
+
         Element definitions = null;
-        
+
         if (wsdl.getNodeType() == Node.DOCUMENT_NODE)
             definitions = XmlUtils.getFirstElement(wsdl);
-        
+
         else
             definitions = (Element)wsdl;
-        
+
         //
         // find all of the xsd:elements in the wsdl:types section
         //
         Element[] elements = XmlUtils.findInSubTree(definitions, XsdUtils.ELEMENT_QNAME);
-        
+
         String localName = qname.getLocalPart();
         String uri = qname.getNamespaceURI();
-        
+
         if (uri == null)
         {
             Object[] filler = { qname };
             String message = _MESSAGES.get("NullTypeNamespaceURI", filler);
             throw new RuntimeException(message);
         }
-        
+
         //
         // check the @name of each xsd:element...
         //
         for (int n = 0; n < elements.length; ++n)
         {
             String nextName = elements[n].getAttribute(XsdUtils.NAME);
-            
+
             //
-            // if we find a match, we still need to check namespaces 
+            // if we find a match, we still need to check namespaces
             //
             if (nextName.equals(localName))
             {
                 Element parent = (Element)elements[n].getParentNode();
                 String targetNS = parent.getAttribute(XmlUtils.TARGET_NS);
-                
+
                 if (uri.equals(targetNS))
                     return elements[n];
             }
         }
-        
+
         //
         // type declaration not found
         //
         return null;
     }
-    
+
     /**
      * 
-     * Creates the WSDLs that are imported in the given WSDL as independent 
-     * Documents. For each WSDL import, the Document is created via 
-     * createWSDL(), and then <em>its</em> imports are resolved. The 
-     * resulting set of Documents may have content overlap and should be 
-     * merged into the original WSDL with mergeWSDL().
-     *
+     * Creates the WSDLs that are imported in the given WSDL as independent
+     * Documents. For each WSDL import, the Document is created via
+     * createWSDL(), and then <em>its</em> imports are resolved. The resulting
+     * set of Documents may have content overlap and should be merged into the
+     * original WSDL with mergeWSDL().
+     * 
      * @param wsdl
-     *        The original WSDL whose imports must be resolved.
+     *            The original WSDL whose imports must be resolved.
      * 
      * @param wsdlPath
-     *        The relative path of the given WSDL. This is used to resolve 
-     *        the paths of the imported WSDLs.
+     *            The relative path of the given WSDL. This is used to resolve
+     *            the paths of the imported WSDLs.
      * 
      * @param environment
-     *        The Muse environment is used to load the WSDL files.
+     *            The Muse environment is used to load the WSDL files.
      * 
-     * @return A Collection of Documents - one for each WSDL imported by 
-     *         the given WSDL. The Collection may include WSDLs that were 
-     *         imported by <em>those</em> WSDLs (the method is recursive).
-     *
-     */
-    public static Collection getWsdlImports(Document wsdl, 
-                                            String wsdlPath, 
-                                            Environment environment)
+     * @return A Collection of Documents - one for each WSDL imported by the
+     *         given WSDL. The Collection may include WSDLs that were imported
+     *         by <em>those</em> WSDLs (the method is recursive).
+     * 
+     */
+    public static Collection getWsdlImports(Document wsdl, String wsdlPath, Environment environment)
     {
         return getWsdlImports(wsdl, wsdlPath, environment, new ArrayList());
     }
-    
+
     /**
      * 
-     * Creates the WSDLs that are imported in the given WSDL as independent 
-     * Documents. For each WSDL import, the Document is created via 
-     * createWSDL(), and then <em>its</em> imports are resolved. The 
-     * resulting set of Documents may have content overlap and should be 
-     * merged into the original WSDL with mergeWSDL().
-     *
+     * Creates the WSDLs that are imported in the given WSDL as independent
+     * Documents. For each WSDL import, the Document is created via
+     * createWSDL(), and then <em>its</em> imports are resolved. The resulting
+     * set of Documents may have content overlap and should be merged into the
+     * original WSDL with mergeWSDL().
+     * 
      * @param wsdl
-     *        The original WSDL whose imports must be resolved.
+     *            The original WSDL whose imports must be resolved.
      * 
      * @param wsdlPath
-     *        The relative path of the given WSDL. This is used to resolve 
-     *        the paths of the imported WSDLs.
+     *            The relative path of the given WSDL. This is used to resolve
+     *            the paths of the imported WSDLs.
      * 
      * @param environment
-     *        The Muse environment is used to load the WSDL files.
+     *            The Muse environment is used to load the WSDL files.
      * 
      * @param otherWSDLs
-     *        The Collection of WSDLs that has been created so far. This 
-     *        will ultimately be the return value once the recursion ends.
+     *            The Collection of WSDLs that has been created so far. This
+     *            will ultimately be the return value once the recursion ends.
+     * 
+     * @return A Collection of Documents - one for each WSDL imported by the
+     *         given WSDL. The Collection may include WSDLs that were imported
+     *         by <em>those</em> WSDLs (the method is recursive).
      * 
-     * @return A Collection of Documents - one for each WSDL imported by 
-     *         the given WSDL. The Collection may include WSDLs that were 
-     *         imported by <em>those</em> WSDLs (the method is recursive).
-     *
-     */
-    private static Collection getWsdlImports(Document wsdl, 
-                                             String wsdlPath, 
-                                             Environment environment, 
-                                             Collection otherWSDLs)
+     */
+    private static Collection getWsdlImports(Document wsdl, String wsdlPath, Environment environment, Collection otherWSDLs)
     {
         Element root = XmlUtils.getFirstElement(wsdl);
         Element[] imports = XmlUtils.getElements(root, IMPORT_QNAME);
-        
+
         for (int n = 0; n < imports.length; ++n)
         {
             String location = imports[n].getAttribute(LOCATION);
-            
-            if(location.length() == 0) {
-            	continue;
-            }
-            
+
+            if (location.length() == 0)
+                continue;
+
             String nextPath = environment.createRelativePath(wsdlPath, location);
-            
+
             Document nextWSDL = createWSDL(environment, nextPath, true);
             otherWSDLs.add(nextWSDL);
-            
+
             //
             // recurse - process the imports for this WSDL
             //
             getWsdlImports(nextWSDL, nextPath, environment, otherWSDLs);
         }
-        
+
         return otherWSDLs;
     }
-    
+
     /**
      * 
-     * Determines which schema content the first WSDL has that the second one 
-     * doesn't and adds that content to the second WSDL.
-     * <br><br>
-     * The method addresses the issue of duplicate schema namespaces by using 
-     * size: if both WSDLs have a schema for a given namespace, whichever schema 
-     * is the largest will be put in the final (second) WSDL. This is the best 
-     * heuristic to get all of the required schema content without analyzing every 
-     * node in the schema content.
-     *
+     * Determines which schema content the first WSDL has that the second one
+     * doesn't and adds that content to the second WSDL. <br>
+     * <br>
+     * The method addresses the issue of duplicate schema namespaces by using
+     * size: if both WSDLs have a schema for a given namespace, whichever schema
+     * is the largest will be put in the final (second) WSDL. This is the best
+     * heuristic to get all of the required schema content without analyzing
+     * every node in the schema content.
+     * 
      * @param from
-     *        The WSDL that may have unique schema content.
+     *            The WSDL that may have unique schema content.
      * 
      * @param to
-     *        The WSDL that will receive the first WSDL's unique schema content.
+     *            The WSDL that will receive the first WSDL's unique schema
+     *            content.
      * 
      * @param namespaces
-     *        The schema namespaces that have been processed by the second WSDL.
-     *
+     *            The schema namespaces that have been processed by the second
+     *            WSDL.
+     * 
      */
     public static void mergeWSDL(Document from, Document to, Set namespaces)
     {
         //
-        // this is an expensive operation, although not as expensive as doing 
-        // a real merge - analyzing every node and adding in the diffs. the 
-        // merge logic isn't perfect because it could drop some schema content 
+        // this is an expensive operation, although not as expensive as doing
+        // a real merge - analyzing every node and adding in the diffs. the
+        // merge logic isn't perfect because it could drop some schema content
         // if both WSDLs extend a given schema.
         //
-        
+
         Element fromRoot = XmlUtils.getFirstElement(from);
         Element toRoot = XmlUtils.getFirstElement(to);
-        
+
         Element fromTypes = XmlUtils.getElement(fromRoot, TYPES_QNAME);
         Element toTypes = XmlUtils.getElement(toRoot, TYPES_QNAME);
-        
+
         Element[] fromSchemas = XmlUtils.getElements(fromTypes, XsdUtils.SCHEMA_QNAME);
 
         Element[] toSchemas = XmlUtils.getElements(toTypes, XsdUtils.SCHEMA_QNAME);
         Map toSchemasByNS = new HashMap();
-        
+
         //
-        // to speed things up, let's lookup all the schemas once and put them 
+        // to speed things up, let's lookup all the schemas once and put them
         // in a table
         //
         for (int n = 0; n < toSchemas.length; ++n)
@@ -690,13 +830,13 @@
             String targetNS = toSchemas[n].getAttribute(XmlUtils.TARGET_NS);
             toSchemasByNS.put(targetNS, toSchemas[n]);
         }
-            
+
         for (int n = 0; n < fromSchemas.length; ++n)
         {
             String targetNS = fromSchemas[n].getAttribute(XmlUtils.TARGET_NS);
-            
+
             //
-            // if we've never seen this namespace before, just add all the 
+            // if we've never seen this namespace before, just add all the
             // schema content - done
             //
             if (!namespaces.contains(targetNS))
@@ -704,7 +844,7 @@
                 fromSchemas[n] = (Element)to.importNode(fromSchemas[n], true);
                 toTypes.appendChild(fromSchemas[n]);
             }
-            
+
             //
             // if we have seen the namespace before, we have to investigate
             //
@@ -713,15 +853,15 @@
                 Element schema = (Element)toSchemasByNS.get(targetNS);
                 Element[] toChildren = XmlUtils.getAllElements(schema);
                 Element[] fromChildren = XmlUtils.getAllElements(fromSchemas[n]);
-                
+
                 //
-                // NOTE: if the imported WSDL has a larger version of the 
-                // schema, chances are it includes the same base as the 
-                // target schema plus extensions, so we replace the target's 
+                // NOTE: if the imported WSDL has a larger version of the
+                // schema, chances are it includes the same base as the
+                // target schema plus extensions, so we replace the target's
                 // copy with the import's copy
                 //
-                // this is kind of a hack, but a full merge would be a real 
-                // bottleneck, especially since some standard schemas (like 
+                // this is kind of a hack, but a full merge would be a real
+                // bottleneck, especially since some standard schemas (like
                 // WS-A or WS-RP) are included in multiple other standards
                 //
                 if (fromChildren.length > toChildren.length)
@@ -730,244 +870,82 @@
 
                     fromSchemas[n] = (Element)to.importNode(fromSchemas[n], true);
                     toTypes.appendChild(fromSchemas[n]);
-                    
+
                     toSchemasByNS.put(targetNS, fromSchemas[n]);
                 }
             }
-            
+
             //
             // either way, make sure we record that we saw this NS
             //
             namespaces.add(targetNS);
         }
     }
-    
-    /**
-     * 
-     * Iterates over a WSDL document and removes all WSDL imports and XSD 
-     * imports. This is useful if you are trying to load a remote WSDL into 
-     * an API such as WSDL4J, which tries to resolve imports. WSDL4J allows 
-     * you to shut off WSDL imports, but not XSD imports, so removing these 
-     * before parsing is important.
-     *
-     * @param wsdl
-     *        The WSDL Document whose import elements will be removed.
-     *        
-     * @return The given WSDL Document.
-     *
-     */
-    public static Element removeWsdlReferences(Element wsdl)
+
+    private static Element removeSchemaImports(Element schema)
     {
         //
-        // first remove the <wsdl:import> elements
+        // remove <xsd:import> elements
         //
-        Element[] imports = XmlUtils.getElements(wsdl, WsdlUtils.IMPORT_QNAME);
-        
+        Element[] imports = XmlUtils.getElements(schema, XsdUtils.IMPORT_QNAME);
+
         for (int i = 0; i < imports.length; ++i)
-            wsdl.removeChild(imports[i]);
-        
-        return wsdl;
+            imports[i].removeAttribute(XsdUtils.SCHEMA_LOCATION);
+
+        return schema;
     }
-    
+
+    private static Element removeSchemaIncludes(Element schema)
+    {
+        //
+        // remove <xsd:include> elements
+        //
+        Element[] includes = XmlUtils.getElements(schema, XsdUtils.INCLUDE_QNAME);
+
+        for (int i = 0; i < includes.length; ++i)
+            schema.removeChild(includes[i]);
+
+        return schema;
+    }
+
     public static Element removeSchemaReferences(Element wsdl)
     {
         Element types = XmlUtils.getElement(wsdl, WsdlUtils.TYPES_QNAME);
         Element[] schemas = XmlUtils.getElements(types, XsdUtils.SCHEMA_QNAME);
-        
+
         for (int i = 0; i < schemas.length; ++i)
         {
             removeSchemaImports(schemas[i]);
             removeSchemaIncludes(schemas[i]);
         }
-        
-        return wsdl;
-    }
 
-    /**
-     * 
-     * Reads all of the schemas that are imported by the given schema and adds 
-     * their content to its parent Node. This method is recursive - it will read 
-     * through the imported schemas and resolve their imports as well. The method 
-     * tracks the namespaces is resolves so that no duplicates are imported.
-     *
-     * @param schemaContainer
-     *        The Element that contains the schema being evaluated. Imported 
-     *        schemas will be appended to this Element.
-     *        
-     * @param currentSchema
-     *        The schema whose imports will be resolved.
-     * 
-     * @param path
-     *        The path of the document that contains the current schema. This is 
-     *        used to resolve the paths of the imported schemas.
-     * 
-     * @param environment
-     *        The Muse environment is used to load the imported schema files.
-     * 
-     * @param namespaces
-     *        The set of namespace URIs that have already been processed. This 
-     *        allows the method to skip those schemas that have already been 
-     *        processed via other imports and not duplicate XML.
-     *
-     */
-    private static void addSchemaImports(Element schemaContainer, 
-                                         Element currentSchema, 
-                                         String path, 
-                                         Environment environment, 
-                                         Set namespaces)
-    {
-        Element[] imports = XmlUtils.getElements(currentSchema, XsdUtils.IMPORT_QNAME);
-        
-        Document doc = schemaContainer.getOwnerDocument();
-        
-        for (int n = 0; n < imports.length; ++n)
-        {
-            String location = imports[n].getAttribute(XsdUtils.SCHEMA_LOCATION);
-            
-            //
-            // This is to guard against imports that do not have a location
-            // such as imports in a WSDL types section that reference
-            // sibling schemas.
-            //            
-            if(location.length() == 0) {
-            	continue;
-            }
-            
-            String nextPath = environment.createRelativePath(path, location);
-            
-            Document importDoc = environment.getDocument(nextPath);
-            
-            Element nextSchema = XmlUtils.getFirstElement(importDoc);
-            String targetNS = nextSchema.getAttribute(XmlUtils.TARGET_NS);                       
-            
-            //
-            // if the target namespace hasn't been seen before, we can add it
-            //
-            if (!namespaces.contains(targetNS))
-            {
-                nextSchema = (Element)doc.importNode(nextSchema, true);                
-                schemaContainer.appendChild(nextSchema);
-                
-                //
-                // record that we found it before reading through the doc 
-                // for more imports
-                //
-                namespaces.add(targetNS);
-                
-                addSchemaImports(schemaContainer, nextSchema, nextPath, environment, namespaces);
-            }
-        }
+        return wsdl;
     }
 
     /**
      * 
-     * Reads all of the schemas that are included by the given schema and adds 
-     * their content to it. The method is recursive - it will read through 
-     * each included schema and resolve its imports and includes. The method 
-     * tracks the namespaces is resolves so that no duplicates are imported.
-     *
-     * @param finalSchema
-     *        The original schema whose includes are being resolved. All 
-     *        included schema content will be added to this node.
-     *        
-     * @param currentSchema
-     *        The schema whose includes and imports are being resolved. In the 
-     *        initial call to this method, finalSchema and currentSchema should 
-     *        be the same node. As the method recurses, currentSchema will be 
-     *        the included schema that is being processed.        
+     * Iterates over a WSDL document and removes all WSDL imports and XSD
+     * imports. This is useful if you are trying to load a remote WSDL into an
+     * API such as WSDL4J, which tries to resolve imports. WSDL4J allows you to
+     * shut off WSDL imports, but not XSD imports, so removing these before
+     * parsing is important.
      * 
-     * @param path
-     *        The path of the document that contains the current schema. This is 
-     *        used to resolve the paths of the imported schemas.
+     * @param wsdl
+     *            The WSDL Document whose import elements will be removed.
      * 
-     * @param environment
-     *        The Muse environment is used to load the included schema files.
+     * @return The given WSDL Document.
      * 
-     * @param namespaces
-     *        The set of namespace URIs that have already been processed. This 
-     *        allows the method to skip those schemas that have already been 
-     *        processed via other imports/includes and not duplicate XML.
-     *
-     */
-    private static void addSchemaIncludes(Element finalSchema, 
-                                          Element currentSchema, 
-                                          String path, 
-                                          Environment environment, 
-                                          Set namespaces)
-    {
-        Element[] includes = XmlUtils.getElements(currentSchema, XsdUtils.INCLUDE_QNAME);
-        
-        for (int n = 0; n < includes.length; ++n)
-        {
-            String relative = includes[n].getAttribute(XsdUtils.SCHEMA_LOCATION);
-            String nextPath = environment.createRelativePath(path, relative);
-            
-            //
-            // copy the included schema content into this schema directly
-            //
-            Document includeDoc = environment.getDocument(nextPath);            
-            Element nextSchema = XmlUtils.getFirstElement(includeDoc);
-            XmlUtils.moveSubTree(nextSchema, finalSchema, includes[n]);
-            
-            //
-            // copy namespace prefixes from the schema 
-            //
-            addNamespacePrefixes(nextSchema, finalSchema);
-            
-            //
-            // now resolve the imports in the included schema - any imports 
-            // will be added to the schema's parent element (since they have 
-            // different namespaces)
-            //
-            Element types = (Element)finalSchema.getParentNode();
-            addSchemaImports(types, nextSchema, nextPath, environment, namespaces);
-            
-            //
-            // finally, recurse and process the new schema's includes
-            //
-            addSchemaIncludes(finalSchema, nextSchema, nextPath, environment, namespaces);
-        }
-    }
-
-    private static void addNamespacePrefixes(Element nextSchema, Element finalSchema) {
-		NamedNodeMap attributes = nextSchema.getAttributes();
-		for(int i=0; i < attributes.getLength(); i++) {
-			Node attribute = attributes.item(i);
-	
-			if(!finalSchema.hasAttribute(attribute.getNodeName())) {
-				String nodePrefix = finalSchema.getPrefix();
-				String nodeValue = attribute.getLocalName();
-				
-				if(nodePrefix == null || !nodePrefix.equals(nodeValue)) {					
-					finalSchema.setAttribute(attribute.getNodeName(), attribute.getNodeValue());	
-				}				
-			}
-		}
-	}
-
-	private static Element removeSchemaImports(Element schema)
+     */
+    public static Element removeWsdlReferences(Element wsdl)
     {
         //
-        // remove <xsd:import> elements
+        // first remove the <wsdl:import> elements
         //
-        Element[] imports = XmlUtils.getElements(schema, XsdUtils.IMPORT_QNAME);
-        
+        Element[] imports = XmlUtils.getElements(wsdl, WsdlUtils.IMPORT_QNAME);
+
         for (int i = 0; i < imports.length; ++i)
-            imports[i].removeAttribute(XsdUtils.SCHEMA_LOCATION);
-        
-        return schema;
-    }
+            wsdl.removeChild(imports[i]);
 
-    private static Element removeSchemaIncludes(Element schema)
-    {        
-        //
-        // remove <xsd:include> elements
-        //
-        Element[] includes = XmlUtils.getElements(schema, XsdUtils.INCLUDE_QNAME);
-        
-        for (int i = 0; i < includes.length; ++i)
-            schema.removeChild(includes[i]);
-        
-        return schema;
+        return wsdl;
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: muse-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: muse-commits-help@ws.apache.org