|
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
//============================================================
//
// File: WsdlWriter.cs
//<EMAIL>
// Author: Peter de Jong (Microsoft)
//</EMAIL>
// Purpose: Defines WsdlWriter that parses a given Wsdl document
// and generates types defined in it.
//
// Date: November 15, 2000
//
//============================================================
namespace System.Runtime.Remoting.MetadataServices
{
using System;
using System.Threading;
using System.Collections;
using System.Reflection;
using System.Xml;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Net;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Metadata;
using System.Runtime.Serialization;
using System.Runtime.Remoting.Channels; // This is so we can get the resource strings.
using System.Globalization;
// This class generates SUDS documents
internal class WsdlGenerator
{
// Constructor
internal WsdlGenerator(Type[] types, TextWriter output)
{
Util.Log("WsdlGenerator.WsdlGenerator 1");
_textWriter = output;
_queue = new Queue();
_name = null;
_namespaces = new ArrayList();
_dynamicAssembly = null;
_serviceEndpoint = null;
for (int i=0;i<types.Length;i++)
{
if (types[i] != null)
{
if (types[i].BaseType != null)
{
Util.Log("WsdlGenerator.WsdlGenerator ProcessTypeAttributes 1 "+types[i]);
ProcessTypeAttributes(types[i]);
_queue.Enqueue(types[i]);
}
}
}
}
// Constructor
internal WsdlGenerator(Type[] types, SdlType sdlType, TextWriter output)
{
Util.Log("WsdlGenerator.WsdlGenerator 2");
_textWriter = output;
_queue = new Queue();
_name = null;
_namespaces = new ArrayList();
_dynamicAssembly = null;
_serviceEndpoint = null;
for (int i=0;i<types.Length;i++)
{
if (types[i] != null)
{
if (types[i].BaseType != null)
{
Util.Log("WsdlGenerator.WsdlGenerator ProcessTypeAttributes 2 "+types[i].BaseType);
ProcessTypeAttributes(types[i]);
_queue.Enqueue(types[i]);
}
}
}
}
// Constructor
internal WsdlGenerator(Type[] types, TextWriter output, Assembly assembly, String url)
: this(types, output)
{
Util.Log("WsdlGenerator.WsdlGenerator 3 "+url);
_dynamicAssembly = assembly;
_serviceEndpoint = url;
}
// Constructor
internal WsdlGenerator(Type[] types, SdlType sdlType, TextWriter output, Assembly assembly, String url)
: this(types, output)
{
Util.Log("WsdlGenerator.WsdlGenerator 4 "+url);
_dynamicAssembly = assembly;
_serviceEndpoint = url;
}
internal WsdlGenerator(ServiceType[] serviceTypes, SdlType sdlType, TextWriter output)
{
Util.Log("WsdlGenerator.WsdlGenerator 5 ");
_textWriter = output;
_queue = new Queue();
_name = null;
_namespaces = new ArrayList();
_dynamicAssembly = null;
_serviceEndpoint = null;
for (int i=0; i<serviceTypes.Length; i++)
{
if (serviceTypes[i] != null)
{
if (serviceTypes[i].ObjectType.BaseType != null)
{
Util.Log("WsdlGenerator.WsdlGenerator ProcessTypeAttributes 3 objectType "+serviceTypes[i].ObjectType+" basetype "+serviceTypes[i].ObjectType.BaseType);
ProcessTypeAttributes(serviceTypes[i].ObjectType);
_queue.Enqueue(serviceTypes[i].ObjectType);
}
}
// Associate serviceEndpoint with type. A type can have multiple serviceEndpoints
if (serviceTypes[i].Url != null)
{
if (_typeToServiceEndpoint == null)
_typeToServiceEndpoint = new Hashtable(10);
if (_typeToServiceEndpoint.ContainsKey(serviceTypes[i].ObjectType.Name))
{
ArrayList serviceEndpoints = (ArrayList)_typeToServiceEndpoint[serviceTypes[i].ObjectType.Name];
serviceEndpoints.Add(serviceTypes[i].Url);
}
else
{
ArrayList serviceEndpoints = new ArrayList(10);
serviceEndpoints.Add(serviceTypes[i].Url);
_typeToServiceEndpoint[serviceTypes[i].ObjectType.Name] = serviceEndpoints;
}
}
}
}
internal static void QualifyName(StringBuilder sb, String ns, String name)
{
if (!(ns == null || ns.Length == 0))
{
sb.Append(ns);
sb.Append('.');
}
sb.Append(name);
}
internal static String RefName(Type type)
{
String refName = type.Name;
if (!(type.IsPublic || type.IsNotPublic))
{
Util.Log("WsdlGenerator.WsdlGenerator RefName nested "+type);
// nested name
refName = type.FullName;
int index = refName.LastIndexOf('.');
if (index > 0)
{
// nested type, type.Name returns full type rather then simple type
refName = refName.Substring(index+1);
}
refName = refName.Replace('+', '.');
}
return refName;
}
internal void ProcessTypeAttributes(Type type)
{
// Check to see if the xsd and xsi schema types should be 1999 instead of 2000. This is a temporary fix for an interop problem
SoapTypeAttribute att = InternalRemotingServices.GetCachedSoapAttribute(type) as SoapTypeAttribute;
if (att != null)
{
SoapOption soapOption = att.SoapOptions;
if ((soapOption &= SoapOption.Option1) == SoapOption.Option1)
_xsdVersion = XsdVersion.V1999;
else if ((soapOption &= SoapOption.Option2) == SoapOption.Option2)
_xsdVersion = XsdVersion.V2000;
else
_xsdVersion = XsdVersion.V2001;
}
Util.Log("WsdlGenerator.ProcessTypeAttributes "+type+" SoapOptions "+((Enum)att.SoapOptions).ToString()+" _xsdVersion "+((Enum)_xsdVersion).ToString());
}
// Generates SUDS
internal void Generate()
{
Util.Log("WsdlGenerator.Generate");
// Generate the trasitive closure of the types reachable from
// the supplied types
while (_queue.Count > 0)
{
// Dequeue from not yet seen queue
Type type = (Type) _queue.Dequeue();
ProcessType(type);
}
// At this point we have the complete list of types
// to be processed. Resolve cross references between
// them
Resolve();
// At this stage, we are ready to print the schemas
PrintWsdl();
// Flush cached buffers
_textWriter.Flush();
return;
}
internal void ProcessType(Type type)
{
// Check if the type was encountered earlier
String ns;
Assembly assem;
bool bInteropType = GetNSAndAssembly(type, out ns, out assem);
Util.Log("WsdlGenerator.ProcessType Dequeue "+type+" ns "+ns+" assem "+assem);
XMLNamespace xns = LookupNamespace(ns, assem);
if (xns != null)
{
String searchName = WsdlGenerator.RefName(type);
if (xns.LookupSchemaType(searchName) != null)
{
return;
}
}
else
{
xns = AddNamespace(ns, assem, bInteropType);
}
_typeToInteropNS[type] = xns;
if (!type.IsArray)
{
// Check if type needs to be represented as a SimpleSchemaType
SimpleSchemaType ssType = SimpleSchemaType.GetSimpleSchemaType(type, xns, false);
Util.Log("WsdlGenerator.ProcessType simpleType "+ssType);
if (ssType != null)
{
// Add to namespace as a SimpleSchemaType
xns.AddSimpleSchemaType(ssType);
}
else
{
// Check for the first MarshalByRef type
bool bUnique = false;
String connectURL = null;
Hashtable connectTypeToServiceEndpoint = null;
if (_name == null && s_marshalByRefType.IsAssignableFrom(type))
{
Util.Log("WsdlGenerator.ProcessType need new type "+type+" typename "+type.Name);
_name = type.Name;
_targetNS = xns.Namespace;
_targetNSPrefix = xns.Prefix;
connectURL = _serviceEndpoint;
connectTypeToServiceEndpoint = _typeToServiceEndpoint;
bUnique = true;
}
RealSchemaType rsType = new RealSchemaType(type, xns, connectURL, connectTypeToServiceEndpoint, bUnique, this);
// Add to namespace as a RealSchemaType
xns.AddRealSchemaType(rsType);
// Enqueue types reachable from this type
EnqueueReachableTypes(rsType);
}
}
}
// Adds types reachable from the given type
private void EnqueueReachableTypes(RealSchemaType rsType)
{
Util.Log("WsdlGenerator.EnqueueReachableTypes "+rsType.Name+" "+rsType.XNS.Name);
// Get the XML namespace object
XMLNamespace xns = rsType.XNS;
// Process base type
if (rsType.Type.BaseType != null)
{
if (rsType.Type.BaseType != s_valueType || rsType.Type.BaseType != s_objectType)
AddType(rsType.Type.BaseType, GetNamespace(rsType.Type.BaseType));
}
// Check if this is a suds type
bool bSUDSType = rsType.Type.IsInterface ||
s_marshalByRefType.IsAssignableFrom(rsType.Type) ||
s_delegateType.IsAssignableFrom(rsType.Type);
if (bSUDSType)
{
Util.Log("WsdlGenerator.EnqueueReachableTypes suds type "+rsType.Name+" "+rsType.XNS.Name);
// Process fields
FieldInfo[] fields = rsType.GetInstanceFields();
for (int i=0;i<fields.Length;i++)
{
if (fields[i].FieldType == null)
continue;
AddType(fields[i].FieldType, xns);
}
// Process implemented interfaces
Type[] interfaces = rsType.GetIntroducedInterfaces();
if (interfaces.Length > 0)
{
for (int i=0;i<interfaces.Length;i++)
{
Util.Log("WsdlGenerator.EnqueueReachableTypes Interfaces "+interfaces[i].Name+" "+xns.Name);
AddType(interfaces[i], xns);
}
}
ProcessMethods(rsType);
}
else
{
// Process fields
FieldInfo[] fields = rsType.GetInstanceFields();
for (int i=0;i<fields.Length;i++)
{
if (fields[i].FieldType == null)
continue;
AddType(fields[i].FieldType, xns);
}
}
return;
}
private void ProcessMethods(RealSchemaType rsType)
{
Util.Log("WsdlGenerator.ProcessMethods "+rsType);
XMLNamespace xns = rsType.XNS;
MethodInfo[] methods = rsType.GetIntroducedMethods();
if (methods.Length > 0)
{
String methodNSString = null;
XMLNamespace methodXNS = null;
if (xns.IsInteropType)
{
methodNSString = xns.Name;
methodXNS = xns;
}
else
{
StringBuilder sb = new StringBuilder();
WsdlGenerator.QualifyName(sb, xns.Name, rsType.Name);
methodNSString = sb.ToString();
methodXNS = AddNamespace(methodNSString, xns.Assem);
xns.DependsOnSchemaNS(methodXNS, false);
}
for (int i=0;i<methods.Length;i++)
{
MethodInfo method = methods[i];
Util.Log("WsdlGenerator.ProcessMethods methods "+method.Name+" "+methodXNS.Name);
AddType(method.ReturnType, methodXNS);
ParameterInfo[] parameters = method.GetParameters();
for (int j=0;j<parameters.Length;j++)
AddType(parameters[j].ParameterType, methodXNS);
}
}
}
// Adds the given type if it has not been encountered before
private void AddType(Type type, XMLNamespace xns)
{
Util.Log("WsdlGenerator.AddType "+type+" ns "+xns.Namespace);
// System.Array says that it has element type, but returns null
// when asked for the element type.<
// Need to get underlying element type
// For arrays of arrays, want element, not embedded array
Type elementType = type.GetElementType();
Type nextelementType = elementType;
while(nextelementType != null)
{
nextelementType = elementType.GetElementType();
if (nextelementType != null)
elementType = nextelementType;
}
Util.Log("WsdlGenerator.AddType elementType "+type+" elementType "+elementType);
if (elementType != null)
EnqueueType(elementType, xns);
if (!type.IsArray && !type.IsByRef)
EnqueueType(type, xns);
if (!(type.IsPublic || type.IsNotPublic))
{
// nested type, enqueue parent
String refTypeName = type.FullName;
int index = refTypeName.IndexOf("+");
if (index > 0)
{
String parentName = refTypeName.Substring(0, index);
Assembly assembly = type.Module.Assembly;
Util.Log("WsdlGenerator.AddType parentName "+parentName+" assembly "+assembly);
Type parentType = assembly.GetType(parentName, true);
Util.Log("WsdlGenerator.AddType parentType "+parentType);
if (parentType == null)
{
//Error nested type
}
EnqueueType(parentType, xns);
}
}
}
private void EnqueueType(Type type, XMLNamespace xns)
{
Util.Log("WsdlGenerator.EnqueueType "+type+" ns "+xns.Namespace);
if (!type.IsPrimitive || type == s_charType) //char is not a xsd type
{
String ns;
Assembly assem;
XMLNamespace dependsOnNS = null;
bool bInteropType = GetNSAndAssembly(type, out ns, out assem);
// Lookup the namespace
dependsOnNS = LookupNamespace(ns, assem);
// Creat a new namespace if neccessary
if (dependsOnNS == null)
dependsOnNS = AddNamespace(ns, assem, bInteropType);
// The supplied namespace depends directly on the namespace of the type
String typeString = SudsConverter.MapClrTypeToXsdType(type); //see if this is a xsd type
if (type.IsInterface || typeString != null || type == s_voidType)
{
// Interfaces aren't in schema section
// Any xsd type
xns.DependsOnSchemaNS(dependsOnNS, false);
}
else
xns.DependsOnSchemaNS(dependsOnNS, true);
// Enqueue the type if does not belong to system namespace
if (!type.FullName.StartsWith("System."))
{
Util.Log("WsdlGenerator.EnqueueType place on queue "+type+" ns "+xns.Namespace);
_queue.Enqueue(type);
}
}
}
private static bool GetNSAndAssembly(Type type, out String ns, out Assembly assem)
{
Util.Log("WsdlGenerator.GetNSAndAssembly enter "+type);
String xmlNamespace = null;
String xmlElement = null;
bool bInterop = false;
SoapServices.GetXmlElementForInteropType(type, out xmlElement, out xmlNamespace);
if (xmlNamespace != null)
{
ns = xmlNamespace;
assem = type.Module.Assembly;
bInterop = true;
}
else
{
// Return the namespace and assembly in which the type is defined
ns = type.Namespace;
assem = type.Module.Assembly;
bInterop = false;
}
Util.Log("WsdlGenerator.GetNSAndAssembly exit ns "+ns+" assem "+assem+" bInterop "+bInterop);
return bInterop;
}
private XMLNamespace LookupNamespace(String name, Assembly assem)
{
Util.Log("WsdlGenerator.LookupNamespace "+name);
for (int i=0;i<_namespaces.Count;i++)
{
XMLNamespace xns = (XMLNamespace) _namespaces[i];
if (name == xns.Name)
return(xns);
}
return(null);
}
private XMLNamespace AddNamespace(String name, Assembly assem)
{
return AddNamespace(name, assem, false);
}
private XMLNamespace AddNamespace(String name, Assembly assem, bool bInteropType)
{
Util.Log("WsdlGenerator.AddNamespace "+name);
Debug.Assert(LookupNamespace(name, assem) == null, "Duplicate Type found");
XMLNamespace xns = new XMLNamespace(name, assem,
_serviceEndpoint,
_typeToServiceEndpoint,
"ns" + _namespaces.Count,
bInteropType, this);
_namespaces.Add(xns);
return(xns);
}
private XMLNamespace GetNamespace(Type type)
{
Util.Log("WsdlGenerator.GetNamespace "+type);
String ns = null;
Assembly assem = null;
bool bInteropType = GetNSAndAssembly(type, out ns, out assem);
XMLNamespace xns = LookupNamespace(ns, assem);
if (xns == null)
{
xns = AddNamespace(ns, assem, bInteropType);
}
return xns;
}
private void Resolve()
{
Util.Log("WsdlGenerator.Resolve ");
for (int i=0;i<_namespaces.Count;i++)
((XMLNamespace) _namespaces[i]).Resolve();
return;
}
private void PrintWsdl()
{
if (_targetNS == null || _targetNS.Length == 0)
{
// No marshalbyRef object so use another target
// Find a namespace
if (_namespaces.Count > 0)
_targetNS = ((XMLNamespace)_namespaces[0]).Namespace;
else
_targetNS = "http://schemas.xmlsoap.org/wsdl/";
}
String indent = "";
String indent1 = IndentP(indent);
String indent2 = IndentP(indent1);
String indent3 = IndentP(indent2);
String indent4 = IndentP(indent3);
StringBuilder sb = new StringBuilder(256);
Util.Log("WsdlGenerator.PrintWsdl");
_textWriter.WriteLine("<?xml version='1.0' encoding='UTF-8'?>");
sb.Length = 0;
sb.Append("<definitions ");
if (_name != null)
{
sb.Append("name='");
sb.Append(_name);
sb.Append("' ");
}
sb.Append("targetNamespace='");
sb.Append(_targetNS);
sb.Append("'");
_textWriter.WriteLine(sb);
PrintWsdlNamespaces(_textWriter, sb, indent3);
// See if there are any schema information to print.
bool bPrintTypeSection = false;
for (int i=0;i<_namespaces.Count;i++)
{
if (((XMLNamespace) _namespaces[i]).CheckForSchemaContent())
{
bPrintTypeSection = true;
break;
}
}
if (bPrintTypeSection)
{
PrintTypesBeginWsdl(_textWriter, sb, indent1);
for (int i=0;i<_namespaces.Count;i++)
{
if (((XMLNamespace) _namespaces[i]).CheckForSchemaContent())
{
Util.Log("WsdlGenerator.PrintWsdl call PrintWsdlNamespaces "+((XMLNamespace) _namespaces[i]).Namespace);
((XMLNamespace) _namespaces[i]).PrintSchemaWsdl(_textWriter, sb, indent2);
}
}
PrintTypesEndWsdl(_textWriter, sb, indent1);
}
ArrayList refNames = new ArrayList(25);
for (int i=0;i<_namespaces.Count;i++)
((XMLNamespace) _namespaces[i]).PrintMessageWsdl(_textWriter, sb, indent1, refNames);
PrintServiceWsdl(_textWriter, sb, indent1, refNames);
_textWriter.WriteLine("</definitions>");
return;
}
private void PrintWsdlNamespaces(TextWriter textWriter, StringBuilder sb, String indent)
{
Util.Log("WsdlGenerator.PrintWsdlNamespaces");
sb.Length = 0;
sb.Append(indent);
sb.Append("xmlns='http://schemas.xmlsoap.org/wsdl/'");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent);
sb.Append("xmlns:tns='");
sb.Append(_targetNS);
sb.Append("'");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent);
sb.Append("xmlns:xsd='");
sb.Append(SudsConverter.GetXsdVersion(_xsdVersion));
sb.Append("'");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent);
sb.Append("xmlns:xsi='");
sb.Append(SudsConverter.GetXsiVersion(_xsdVersion));
sb.Append("'");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent);
sb.Append("xmlns:suds='http://www.w3.org/2000/wsdl/suds'");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent);
sb.Append("xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent);
sb.Append("xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'");
textWriter.WriteLine(sb);
Hashtable usedNames = new Hashtable(10);
for (int i=0;i<_namespaces.Count;i++)
((XMLNamespace) _namespaces[i]).PrintDependsOnWsdl(_textWriter, sb, indent, usedNames);
// This should be last because it closes off the definitions element
sb.Length = 0;
sb.Append(indent);
sb.Append("xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'>");
textWriter.WriteLine(sb);
}
private void PrintTypesBeginWsdl(TextWriter textWriter, StringBuilder sb, String indent)
{
Util.Log("WsdlGenerator.PrintTypesBeginWsdl");
sb.Length = 0;
sb.Append(indent);
sb.Append("<types>");
textWriter.WriteLine(sb);
}
private void PrintTypesEndWsdl(TextWriter textWriter, StringBuilder sb, String indent)
{
Util.Log("WsdlGenerator.PrintTypesEndWsdl");
sb.Length = 0;
sb.Append(indent);
sb.Append("</types>");
textWriter.WriteLine(sb);
}
internal void PrintServiceWsdl(TextWriter textWriter, StringBuilder sb, String indent, ArrayList refNames)
{
Util.Log("WsdlGenerator.PrintServiceWsdl");
String indent1 = IndentP(indent);
String indent2 = IndentP(indent1);
String indent3 = IndentP(indent2);
sb.Length = 0;
sb.Append("\n");
sb.Append(indent);
sb.Append("<service name='");
sb.Append(_name);
sb.Append("Service'");
sb.Append(">");
textWriter.WriteLine(sb);
for (int i=0; i<refNames.Count; i++)
{
if (((_typeToServiceEndpoint != null) && (_typeToServiceEndpoint.ContainsKey(refNames[i]))) ||
(_serviceEndpoint != null))
{
sb.Length = 0;
sb.Append(indent1);
sb.Append("<port name='");
sb.Append(refNames[i]);
sb.Append("Port'");
sb.Append(" ");
sb.Append("binding='tns:");
sb.Append(refNames[i]);
sb.Append("Binding");
sb.Append("'>");
textWriter.WriteLine(sb);
if ((_typeToServiceEndpoint != null) && (_typeToServiceEndpoint.ContainsKey(refNames[i])))
{
foreach (String url in (ArrayList)_typeToServiceEndpoint[refNames[i]])
{
sb.Length = 0;
sb.Append(indent2);
sb.Append("<soap:address location='");
sb.Append(UrlEncode(url));
sb.Append("'/>");
textWriter.WriteLine(sb);
}
}
else if (_serviceEndpoint != null)
{
sb.Length = 0;
sb.Append(indent2);
sb.Append("<soap:address location='");
sb.Append(_serviceEndpoint);
sb.Append("'/>");
textWriter.WriteLine(sb);
}
sb.Length = 0;
sb.Append(indent1);
sb.Append("</port>");
textWriter.WriteLine(sb);
}
}
sb.Length = 0;
sb.Append(indent);
sb.Append("</service>");
textWriter.WriteLine(sb);
}
private String UrlEncode(String url)
{
if (url == null || url.Length == 0)
return url;
int index = url.IndexOf("&");
if (index > -1)
{
// Assume it's encoded
return url;
}
index = url.IndexOf('&');
if (index > -1)
{
return url.Replace("&", "&");
}
return url;
}
// Private fields
private TextWriter _textWriter;
internal Queue _queue;
private String _name;
private String _targetNS;
private String _targetNSPrefix;
private ArrayList _namespaces;
private Assembly _dynamicAssembly;
private String _serviceEndpoint; //service endpoint for all types
private XsdVersion _xsdVersion; // Temporary, specifies what xsd and xsi schema to put out
internal Hashtable _typeToServiceEndpoint; //service endpoint for each type
internal Hashtable _typeToInteropNS = new Hashtable(); // If interop type, then XMLNamespace the type is in.
private static Type s_marshalByRefType = typeof(System.MarshalByRefObject);
private static Type s_contextBoundType = typeof(System.ContextBoundObject);
private static Type s_delegateType = typeof(System.Delegate);
private static Type s_valueType = typeof(System.ValueType);
private static Type s_objectType = typeof(System.Object);
private static Type s_charType = typeof(System.Char);
private static Type s_voidType = typeof(void);
private static Type s_remotingClientProxyType = typeof(System.Runtime.Remoting.Services.RemotingClientProxy);
private static SchemaBlockType blockDefault = SchemaBlockType.SEQUENCE;
/***************************************************************
**
** Private classes used by SUDS generator
**
***************************************************************/
private interface IAbstractElement
{
void Print(TextWriter textWriter, StringBuilder sb, String indent);
}
private class EnumElement : IAbstractElement
{
internal EnumElement(String value)
{
Util.Log("EnumElement.EnumElement "+value);
_value = value;
}
public void Print(TextWriter textWriter, StringBuilder sb, String indent)
{
Util.Log("EnumElement.Print");
sb.Length = 0;
sb.Append(indent);
sb.Append("<enumeration value='");
sb.Append(_value);
sb.Append("'/>");
textWriter.WriteLine(sb);
return;
}
// Fields
private String _value;
}
/*
private class ComplexContent : IAbstractElement
{
internal ComplexContent()
{
}
internal void Add(Restriction restriction)
{
_restriction = restriction;
}
public void Print(TextWriter textWriter, StringBuilder sb, String indent)
{
Util.Log("EnumElement.Print");
sb.Length = 0;
sb.Append(indent);
sb.Append("<enumeration value='");
sb.Append(_value);
sb.Append("'/>");
textWriter.WriteLine(sb);
return;
}
Restriction _restriction;
}
*/
private class Restriction : Particle
{
internal enum RestrictionType
{
None = 0,
Array = 1,
Enum = 2
}
internal Restriction()
{
Util.Log("Restriction.Restriction ");
}
internal Restriction(String baseName, XMLNamespace baseNS)
{
Util.Log("Restriction.Restriction "+baseName+" "+baseNS.Namespace);
_baseName = baseName;
_baseNS = baseNS;
}
internal void AddArray(SchemaAttribute attribute)
{
Util.Log("Restriction.AddArray ");
_rtype = RestrictionType.Array;
_attribute = attribute;
}
public override String Name()
{
return _baseName;
}
public override void Print(TextWriter textWriter, StringBuilder sb, String indent)
{
Util.Log("Restriction.Print "+_baseName);
String indent1 = IndentP(indent);
sb.Length = 0;
sb.Append(indent);
if (_rtype == RestrictionType.Array)
sb.Append("<restriction base='soapenc:Array'>");
else if (_rtype == RestrictionType.Enum)
{
sb.Append("<restriction base='xsd:string'>");
}
else
{
sb.Append("<restriction base='");
sb.Append(_baseNS.Prefix);
sb.Append(':');
sb.Append(_baseName);
sb.Append("'>");
}
textWriter.WriteLine(sb);
foreach (IAbstractElement elem in _abstractElms)
elem.Print(textWriter, sb, IndentP(indent1));
if (_attribute != null)
_attribute.Print(textWriter, sb, IndentP(indent1));
sb.Length = 0;
sb.Append(indent);
sb.Append("</restriction>");
textWriter.WriteLine(sb);
}
String _baseName;
XMLNamespace _baseNS;
internal RestrictionType _rtype;
SchemaAttribute _attribute;
internal ArrayList _abstractElms = new ArrayList();
}
private class SchemaAttribute : IAbstractElement
{
internal SchemaAttribute()
{
Util.Log("SchemaAttribute ");
}
internal void AddArray(String wireQname)
{
Util.Log("SchemaAttribute wireQname "+wireQname);
_wireQname = wireQname;
}
public void Print(TextWriter textWriter, StringBuilder sb, String indent)
{
sb.Length = 0;
sb.Append(indent);
sb.Append("<attribute ref='soapenc:arrayType'");
sb.Append(" wsdl:arrayType ='");
sb.Append(_wireQname);
sb.Append("'/>");
textWriter.WriteLine(sb);
return;
}
// Fields
private String _wireQname;
}
private abstract class Particle : IAbstractElement
{
protected Particle(){}
public abstract String Name();
public abstract void Print(TextWriter textWriter, StringBuilder sb, String indent);
}
private class SchemaElement : Particle
{
internal SchemaElement(String name, Type type, bool bEmbedded, XMLNamespace xns)
: base(){
Util.Log("SchemaElement.SchemaElement Particle "+name+" type "+type+" bEmbedded "+bEmbedded);
_name = name;
_typeString = null;
_schemaType = SimpleSchemaType.GetSimpleSchemaType(type, xns, true);
_typeString = RealSchemaType.TypeName(type, bEmbedded, xns);
}
public override String Name()
{
return _name;
}
public override void Print(TextWriter textWriter, StringBuilder sb, String indent){
Util.Log("SchemaElement.Print "+_name+" _schemaType "+_schemaType+" _typeString "+_typeString );
String indent1 = IndentP(indent);
sb.Length = 0;
sb.Append(indent);
sb.Append("<element name='");
sb.Append(_name);
if (_schemaType != null && !(_schemaType is SimpleSchemaType && ((SimpleSchemaType)_schemaType).Type.IsEnum))
{
sb.Append("'>");
textWriter.WriteLine(sb);
_schemaType.PrintSchemaType(textWriter, sb, IndentP(indent1), true);
sb.Length = 0;
sb.Append(indent);
sb.Append("</element>");
}
else
{
if (_typeString != null)
{
sb.Append("' type='");
sb.Append(_typeString);
sb.Append('\'');
}
sb.Append("/>");
}
textWriter.WriteLine(sb);
return;
}
// Fields
private String _name;
private String _typeString;
private SchemaType _schemaType;
}
private abstract class SchemaType
{
internal abstract void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous);
}
private class SimpleSchemaType : SchemaType
{
private SimpleSchemaType(Type type, XMLNamespace xns)
{
Util.Log("SimpleSchemaType.SimpleSchemaType "+type+" xns "+((xns != null) ? xns.Name : "Null"));
_type = type;
_xns = xns;
_abstractElms = new ArrayList();
_fullRefName = WsdlGenerator.RefName(type);
}
internal Type Type
{
get{ return(_type);}
}
internal String FullRefName
{
get{ return _fullRefName;}
}
internal String BaseName{
get{ return(_baseName);}
}
internal override void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous){
Util.Log("SimpleSchemaType.PrintSchemaType _type.Name "+_type.Name);
sb.Length = 0;
sb.Append(indent);
if (bAnonymous == false)
{
sb.Append("<simpleType name='");
sb.Append(FullRefName);
sb.Append("'");
if (BaseName != null)
{
sb.Append(" base='");
sb.Append(BaseName);
sb.Append("'");
}
if (_restriction._rtype == Restriction.RestrictionType.Enum)
{
sb.Append(" suds:enumType='");
sb.Append(_restriction.Name());
sb.Append("'");
}
}
else
{
if (BaseName != null)
{
sb.Append("<simpleType base='");
sb.Append(BaseName);
sb.Append("'");
}
else
sb.Append("<simpleType");
}
bool bEmpty = (_abstractElms.Count == 0 && _restriction == null);
if (bEmpty)
sb.Append("/>");
else
sb.Append(">");
textWriter.WriteLine(sb);
if (bEmpty)
return;
if (_abstractElms.Count > 0)
{
for (int i=0;i<_abstractElms.Count; i++)
((IAbstractElement) _abstractElms[i]).Print(textWriter, sb, IndentP(indent));
}
if (_restriction != null)
_restriction.Print(textWriter, sb, IndentP(indent));
textWriter.Write(indent);
textWriter.WriteLine("</simpleType>");
return;
}
internal static SimpleSchemaType GetSimpleSchemaType(Type type, XMLNamespace xns, bool fInline)
{
Util.Log("SimpleSchemaType.GetSimpleSchemaType "+type+" xns "+xns.Name);
SimpleSchemaType ssType = null;
if (type.IsEnum)
{
ssType = new SimpleSchemaType(type, xns);
String baseName = RealSchemaType.TypeName(Enum.GetUnderlyingType(type), true, xns);
ssType._restriction = new Restriction(baseName, xns);
String[] values = Enum.GetNames(type);
for (int i=0;i<values.Length;i++)
ssType._restriction._abstractElms.Add(new EnumElement(values[i]));
ssType._restriction._rtype = Restriction.RestrictionType.Enum;
}
else
{
}
return(ssType);
}
private Type _type;
internal String _baseName = null; //get rid of warning, not used for now
private XMLNamespace _xns;
internal Restriction _restriction;
private String _fullRefName;
private ArrayList _abstractElms = new ArrayList();
}
private abstract class ComplexSchemaType : SchemaType
{
internal ComplexSchemaType(String name, bool bSealed)
{
_name = name;
_fullRefName = _name;
_blockType = SchemaBlockType.ALL;
_baseName = null;
_elementName = name;
_bSealed = bSealed;
_particles = new ArrayList();
_abstractElms = new ArrayList();
}
internal ComplexSchemaType(String name, SchemaBlockType blockType, bool bSealed)
{
_name = name;
_fullRefName = _name;
_blockType = blockType;
_baseName = null;
_elementName = name;
_bSealed = bSealed;
_particles = new ArrayList();
_abstractElms = new ArrayList();
}
internal ComplexSchemaType(Type type)
{
Util.Log("ComplexSchemaType.ComplexSchemaType "+type);
_blockType = SchemaBlockType.ALL;
_type = type;
Init();
}
private void Init()
{
_name = _type.Name;
_bSealed = _type.IsSealed;
_baseName = null;
_elementName = _name;
_particles = new ArrayList();
_abstractElms = new ArrayList();
_fullRefName = WsdlGenerator.RefName(_type);
}
internal String Name{
get{ return(_name);}
}
internal String FullRefName
{
get{ return(_fullRefName);}
}
protected String BaseName{
get{ return(_baseName);}
set{ _baseName = value;}
}
internal String ElementName{
get{ return(_elementName);}
set{ _elementName = value;}
}
protected bool IsSealed{
get{ return(_bSealed);}
}
protected bool IsEmpty{
get{
return((_abstractElms.Count == 0) &&
(_particles.Count == 0));
}
}
internal void AddParticle(Particle particle){
Util.Log("ComplexSchemaType.AddParticle "+particle.Name());
_particles.Add(particle);
}
protected void PrintBody(TextWriter textWriter, StringBuilder sb, String indent){
Util.Log("ComplexSchemaType.PrintBody "+_name);
int particleCount = _particles.Count;
String indent1 = IndentP(indent);
String indent2 = IndentP(indent1);
if (particleCount > 0)
{
bool bPrintBlockElms = /*(particleCount > 1) && */(WsdlGenerator.blockDefault != _blockType);
if (bPrintBlockElms)
{
sb.Length = 0;
sb.Append(indent1);
sb.Append(schemaBlockBegin[(int) _blockType]);
textWriter.WriteLine(sb);
}
for (int i=0;i<particleCount; i++)
((Particle) _particles[i]).Print(textWriter, sb, IndentP(indent2));
if (bPrintBlockElms)
{
sb.Length = 0;
sb.Append(indent1);
sb.Append(schemaBlockEnd[(int) _blockType]);
textWriter.WriteLine(sb);
}
}
int abstractElmCount = _abstractElms.Count;
for (int i=0;i<abstractElmCount; i++)
((IAbstractElement) _abstractElms[i]).Print(textWriter, sb, IndentP(indent));
return;
}
private String _name;
private Type _type;
private String _fullRefName;
private String _baseName;
private String _elementName;
private bool _bSealed;
private SchemaBlockType _blockType;
private ArrayList _particles;
private ArrayList _abstractElms;
static private String[] schemaBlockBegin = { "<all>", "<sequence>", "<choice>", "<complexContent>"};
static private String[] schemaBlockEnd = { "</all>", "</sequence>", "</choice>", "</complexContent>"};
}
private class PhonySchemaType : ComplexSchemaType
{
internal PhonySchemaType(String name) : base(name, true)
{
Util.Log("PhonySchemaType.PhonySchemaType "+name);
_numOverloadedTypes = 0;
}
internal int OverloadedType(){
Util.Log("PhonySchemaType.OverLoadedTypeType");
return(++_numOverloadedTypes);
}
internal override void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous){
Util.Log("PhonySchemaType.PrintSchemaType");
Debug.Assert(bAnonymous == true, "PhonySchemaType should always be printed as anonymous types");
// Wsdl Phony is not printed, instead the message section contains the parameters.
return;
}
private int _numOverloadedTypes;
internal ArrayList _inParamTypes;
internal ArrayList _inParamNames;
internal ArrayList _outParamTypes;
internal ArrayList _outParamNames;
internal ArrayList _paramNamesOrder;
internal String _returnType;
internal String _returnName;
}
private class ArraySchemaType : ComplexSchemaType
{
internal ArraySchemaType(Type type, String name, SchemaBlockType blockType, bool bSealed)
: base(name, blockType, bSealed)
{
Util.Log("ArraySchemaType.ArrayComplexSchemaType");
_type = type;
}
internal Type Type
{
get { return _type;}
}
internal override void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous)
{
Util.Log("ArrayType.PrintSchemaType");
String indent1 = IndentP(indent);
sb.Length = 0;
sb.Append(indent);
sb.Append("<complexType name='");
sb.Append(FullRefName);
sb.Append("\'>");
textWriter.WriteLine(sb);
PrintBody(textWriter, sb, indent1);
sb.Length = 0;
sb.Append(indent);
sb.Append("</complexType>");
textWriter.WriteLine(sb);
return;
}
private Type _type;
}
private class RealSchemaType : ComplexSchemaType
{
internal RealSchemaType(Type type, XMLNamespace xns, String serviceEndpoint, Hashtable typeToServiceEndpoint, bool bUnique, WsdlGenerator WsdlGenerator)
: base(type)
{
Util.Log("RealSchemaType.RealSchemaType "+type+" xns "+xns.Name+" serviceEndpoint "+serviceEndpoint+" bUnique "+bUnique);
_type = type;
_serviceEndpoint = serviceEndpoint;
_typeToServiceEndpoint = typeToServiceEndpoint;
_bUnique = bUnique;
_WsdlGenerator = WsdlGenerator;
_bStruct = type.IsValueType;
_xns = xns;
_implIFaces = null;
_iFaces = null;
_methods = null;
_fields = null;
_methodTypes = null;
_nestedTypes = type.GetNestedTypes();
if (_nestedTypes != null)
{
foreach (Type ntype in _nestedTypes)
{
Util.Log("RealSchemaType.RealSchemaType nested classes"+ntype);
_WsdlGenerator.AddType(ntype, xns);
}
}
}
internal Type Type{
get{ return(_type);}
}
internal XMLNamespace XNS{
get{ return(_xns);}
}
internal bool IsUnique{
get{ return(_bUnique);}
}
internal bool IsSUDSType{
/*
get{ return((_fields == null) &&
((_iFaces.Length > 0) || (_methods.Length > 0) ||
(_type.IsInterface) || (s_delegateType.IsAssignableFrom(_type))));}
*/
get{ return((_iFaces != null && _iFaces.Length > 0) ||
(_methods != null && _methods.Length > 0) ||
(_type != null && _type.IsInterface) ||
(s_delegateType != null && s_delegateType.IsAssignableFrom(_type)));}
}
internal Type[] GetIntroducedInterfaces(){
Util.Log("RealSchemaType.GetIntroducedInterfaces");
Debug.Assert(_iFaces == null, "variable set");
_iFaces = GetIntroducedInterfaces(_type);
return(_iFaces);
}
internal MethodInfo[] GetIntroducedMethods(){
Util.Log("RealSchemaType.GetIntroducedMethods");
Debug.Assert(_methods == null, "variable set");
_methods = GetIntroducedMethods(_type, ref _methodAttributes);
_methodTypes = new String[2*_methods.Length];
return(_methods);
}
internal FieldInfo[] GetInstanceFields(){
Util.Log("RealSchemaType.GetInstanceFields");
Debug.Assert(_fields == null, "variable set");
//Debug.Assert(!WsdlGenerator.s_marshalByRefType.IsAssignableFrom(_type), "Invalid Type");
_fields = GetInstanceFields(_type);
return(_fields);
}
private bool IsNotSystemDefinedRoot(Type type, Type baseType)
{
if (!type.IsInterface &&
!type.IsValueType &&
baseType != null &&
baseType.BaseType != null &&
baseType != WsdlGenerator.s_marshalByRefType &&
baseType != WsdlGenerator.s_valueType &&
baseType != WsdlGenerator.s_objectType &&
baseType != WsdlGenerator.s_contextBoundType &&
baseType != WsdlGenerator.s_remotingClientProxyType &&
baseType.FullName != "System.EnterpriseServices.ServicedComponent" &&
baseType.FullName != "System.__ComObject")
return true;
else
return false;
}
internal void Resolve(StringBuilder sb){
Util.Log("RealSchemaType.Resolve "+_type);
sb.Length = 0;
// Check if this is a suds type
bool bSUDSType = IsSUDSType;
// Resolve base type eliminating system defined roots of the class heirarchy
Type baseType = _type.BaseType;
if (IsNotSystemDefinedRoot(_type, baseType))
{
Util.Log("RealSchemaType.Resolve Not System Defined root "+baseType);
XMLNamespace xns = _WsdlGenerator.GetNamespace(baseType);
Debug.Assert(xns != null, "Namespace should have been found");
sb.Append(xns.Prefix);
sb.Append(':');
sb.Append(baseType.Name);
BaseName = sb.ToString();
if (bSUDSType)
_xns.DependsOnSUDSNS(xns);
Type ltype= _type;
Type lbaseType = ltype.BaseType;
while(lbaseType != null && IsNotSystemDefinedRoot(ltype, lbaseType))
{
if (_typeToServiceEndpoint != null && !_typeToServiceEndpoint.ContainsKey(lbaseType.Name) && _typeToServiceEndpoint.ContainsKey(ltype.Name))
{
// type contains endpoints, but baseType doesn't, so assign the type's endpoints to the baseType.
// This is needed when a child has endpoints but the parent doesn't. A cast to the parent won't
// find the object's endpoint
_typeToServiceEndpoint[lbaseType.Name] = _typeToServiceEndpoint[ltype.Name];
}
ltype = lbaseType;
lbaseType = ltype.BaseType;
}
Util.Log("RealSchemaType.Resolve Not System Defined root BaseName "+BaseName);
}
// The element definition of this type depends on itself
_xns.DependsOnSchemaNS(_xns, false);
if (bSUDSType)
{
Util.Log("RealSchemaType.Resolve AddRealSUDSType "+_type);
_xns.AddRealSUDSType(this);
// Resolve interfaces introduced by this type
if (_iFaces.Length > 0)
{
_implIFaces = new String[_iFaces.Length];
for (int i=0;i<_iFaces.Length;i++)
{
String ns;
Assembly assem;
Util.Log("RealSchemaType.Resolve iFace "+_iFaces[i].Name);
bool bInteropType = WsdlGenerator.GetNSAndAssembly(_iFaces[i], out ns, out assem);
XMLNamespace xns = _xns.LookupSchemaNamespace(ns, assem);
Debug.Assert(xns != null, "SchemaType should have been found");
sb.Length = 0;
sb.Append(xns.Prefix);
sb.Append(':');
sb.Append(_iFaces[i].Name);
_implIFaces[i] = sb.ToString();
_xns.DependsOnSUDSNS(xns);
}
}
// Resolve methods introduced by this type
if (_methods.Length > 0)
{
String useNS = null;
if (_xns.IsInteropType)
useNS = _xns.Name;
else
{
sb.Length = 0;
WsdlGenerator.QualifyName(sb, _xns.Name, Name);
useNS = sb.ToString();
}
XMLNamespace methodXNS = _xns.LookupSchemaNamespace(useNS, _xns.Assem);
Debug.Assert(methodXNS != null, "Namespace is null");
_xns.DependsOnSUDSNS(methodXNS);
_phony = new PhonySchemaType[_methods.Length];
for (int i=0;i<_methods.Length;i++)
{
// Process the request
MethodInfo method = _methods[i];
String methodRequestName = method.Name;
ParameterInfo[] parameters = method.GetParameters();
PhonySchemaType methodRequest = new PhonySchemaType(methodRequestName);
// Wsdl
Util.Log("RealSchemaType.Resolve Wsdl "+methodRequestName);
methodRequest._inParamTypes = new ArrayList(10);
methodRequest._inParamNames = new ArrayList(10);
methodRequest._outParamTypes = new ArrayList(10);
methodRequest._outParamNames = new ArrayList(10);
methodRequest._paramNamesOrder = new ArrayList(10);
int paramNameCnt = 0;
foreach (ParameterInfo param in parameters){
bool bmarshalIn = false;
bool bmarshalOut = false;
methodRequest._paramNamesOrder.Add(param.Name);
ParamInOut(param, out bmarshalIn, out bmarshalOut);
Type type = param.ParameterType;
String paramName = param.Name;
if (paramName == null || paramName.Length == 0)
paramName = "param"+paramNameCnt++;
// Find the Wsdl type name
String stringType = TypeName(type, true, methodXNS);
// add to the method parameters
if (bmarshalIn)
{
methodRequest._inParamNames.Add(paramName);
methodRequest._inParamTypes.Add(stringType);
}
if (bmarshalOut)
{
methodRequest._outParamNames.Add(paramName);
methodRequest._outParamTypes.Add(stringType);
}
}
methodXNS.AddPhonySchemaType(methodRequest);
_phony[i] = methodRequest;
_methodTypes[2*i] = methodRequest.ElementName;
if (!RemotingServices.IsOneWay(method))
{
// Process response (look at custom attributes to get values
String returnName = null;
SoapMethodAttribute soapAttribute = (SoapMethodAttribute)InternalRemotingServices.GetCachedSoapAttribute(method);
if (soapAttribute.ReturnXmlElementName != null)
returnName = soapAttribute.ReturnXmlElementName;
else
returnName = "return";
String responseName = null;
if (soapAttribute.ResponseXmlElementName != null)
responseName = soapAttribute.ResponseXmlElementName;
else
responseName = methodRequestName + "Response";
PhonySchemaType methodResponse = new PhonySchemaType(responseName);
//Wsdl type
// out paramters alread processed above.
// return name stored in methodRequest PhonySchemaType
methodRequest._returnName = returnName;
Type returnType = method.ReturnType;
if (!((returnType == null) || (returnType == typeof(void))))
{
methodRequest._returnType = TypeName(returnType, true, methodXNS);
}
methodXNS.AddPhonySchemaType(methodResponse);
_methodTypes[2*i+1] = methodResponse.ElementName;
}
}
}
}
// Resolve fields
if (_fields != null)
{
for (int i=0;i<_fields.Length;i++)
{
FieldInfo field = _fields[i];
Debug.Assert(!field.IsStatic, "Static field");
Type fieldType = field.FieldType;
if (fieldType == null)
fieldType = typeof(Object);
Util.Log("RealSchemaType.Resolve fields "+field.Name+" type "+fieldType);
AddParticle(new SchemaElement(field.Name, fieldType, false, _xns));
}
}
// Resolve attribute elements
return;
}
private void ParamInOut(ParameterInfo param, out bool bMarshalIn, out bool bMarshalOut)
{
bool bIsIn = param.IsIn; // [In]
bool bIsOut = param.IsOut; // [Out] note: out int a === [Out] ref int b
bool bIsByRef = param.ParameterType.IsByRef; // (ref or normal)
bMarshalIn = false;
bMarshalOut = false;
if (bIsByRef)
{
if (bIsIn == bIsOut)
{
// "ref int a" or "[In, Out] ref int a"
bMarshalIn = true;
bMarshalOut = true;
}
else
{
// "[In] ref int a" or "out int a"
bMarshalIn = bIsIn;
bMarshalOut = bIsOut;
}
}
else
{
// "int a" or "[In, Out] a"
bMarshalIn = true;
bMarshalOut = bIsOut;
}
Util.Log("RealSchemaType.ParamInOut "+param.Name+" ref,in,out "+bIsByRef+","+bIsIn+","+bIsOut+" bMarshalIn,bMarshalOut "+bMarshalIn+","+bMarshalOut);
}
internal override void PrintSchemaType(TextWriter textWriter, StringBuilder sb, String indent, bool bAnonymous)
{
Util.Log("RealSchemaType.PrintSchemaType");
if (bAnonymous == false)
{
sb.Length = 0;
sb.Append(indent);
sb.Append("<element name='");
sb.Append(ElementName);
sb.Append("' type='");
sb.Append(_xns.Prefix);
sb.Append(':');
sb.Append(FullRefName);
sb.Append("'/>");
textWriter.WriteLine(sb);
}
sb.Length = 0;
sb.Append(indent);
if (bAnonymous == false)
{
sb.Append("<complexType name='");
sb.Append(FullRefName);
sb.Append('\'');
}
else
{
sb.Append("<complexType ");
}
if (BaseName != null)
{
sb.Append(" base='");
sb.Append(BaseName);
sb.Append('\'');
}
if ((IsSealed == true) &&
(bAnonymous == false))
sb.Append(" final='#all'");
bool bEmpty = IsEmpty;
if (bEmpty)
sb.Append("/>");
else
sb.Append('>');
textWriter.WriteLine(sb);
if (bEmpty)
return;
base.PrintBody(textWriter, sb, indent);
textWriter.Write(indent);
textWriter.WriteLine("</complexType>");
return;
}
internal void PrintMessageWsdl(TextWriter textWriter, StringBuilder sb, String indent, ArrayList refNames)
{
Util.Log("RealSchemaType.PrintMessageWsdl "+Name);
String indent1 = IndentP(indent);
String indent2 = IndentP(indent1);
String indent3 = IndentP(indent2);
String ns = null;
String nsPrefix = null;
MethodInfo method = null;
String methodName = null;
String overloadedName = null;
bool bIsOneWay = false;
String useNS = null;
if (_xns.IsInteropType)
useNS = _xns.Name;
else
{
sb.Length = 0;
WsdlGenerator.QualifyName(sb, _xns.Name, Name);
useNS = sb.ToString();
}
XMLNamespace methodXns = _xns.LookupSchemaNamespace(useNS, _xns.Assem);
//Debug.Assert(methodXns != null, "Namespace is null");
int methodsLength = 0;
if (_methods != null)
methodsLength = _methods.Length;
if (methodsLength > 0)
{
ns = methodXns.Namespace;
nsPrefix = methodXns.Prefix;
}
refNames.Add(Name);
for (int i=0;i<methodsLength;i++)
{
method = _methods[i];
bIsOneWay = RemotingServices.IsOneWay(method);
methodName = PrintMethodName(method);
sb.Length = 0;
WsdlGenerator.QualifyName(sb, Name, _methodTypes[2*i]);
overloadedName = sb.ToString();
// Message element
sb.Length = 0;
sb.Append("\n");
sb.Append(indent);
sb.Append("<message name='");
sb.Append(overloadedName+"Input");
sb.Append("'>");
textWriter.WriteLine(sb);
PhonySchemaType phony = _phony[i];
if (phony._inParamTypes != null)
{
for (int iparam=0; iparam<phony._inParamTypes.Count; iparam++)
{
sb.Length = 0;
sb.Append(indent1);
sb.Append("<part name='");
sb.Append(phony._inParamNames[iparam]);
sb.Append("' type='");
sb.Append(phony._inParamTypes[iparam]);
sb.Append("'/>");
textWriter.WriteLine(sb);
}
sb.Length = 0;
sb.Append(indent);
sb.Append("</message>");
textWriter.WriteLine(sb);
if (!bIsOneWay)
{
sb.Length = 0;
sb.Append(indent);
sb.Append("<message name='");
sb.Append(overloadedName+"Output");
sb.Append("'>");
textWriter.WriteLine(sb);
if (phony._returnType != null || phony._outParamTypes != null)
{
if (phony._returnType != null)
{
sb.Length = 0;
sb.Append(indent1);
sb.Append("<part name='");
sb.Append(phony._returnName);
sb.Append("' type='");
sb.Append(phony._returnType);
sb.Append("'/>");
textWriter.WriteLine(sb);
}
if (phony._outParamTypes != null)
{
for (int iparam=0; iparam<phony._outParamTypes.Count; iparam++)
{
sb.Length = 0;
sb.Append(indent1);
sb.Append("<part name='");
sb.Append(phony._outParamNames[iparam]);
sb.Append("' type='");
sb.Append(phony._outParamTypes[iparam]);
sb.Append("'/>");
textWriter.WriteLine(sb);
}
}
}
sb.Length = 0;
sb.Append(indent);
sb.Append("</message>");
textWriter.WriteLine(sb);
}
}
}
// PortType Element
sb.Length = 0;
sb.Append("\n");
sb.Append(indent);
sb.Append("<portType name='");
sb.Append(Name);
sb.Append("PortType");
sb.Append("'>");
textWriter.WriteLine(sb);
for (int i=0;i<methodsLength;i++)
{
method = _methods[i];
PhonySchemaType phony = _phony[i];
bIsOneWay = RemotingServices.IsOneWay(method);
methodName = PrintMethodName(method);
sb.Length = 0;
sb.Append("tns:");
WsdlGenerator.QualifyName(sb, Name, _methodTypes[2*i]);
overloadedName = sb.ToString();
sb.Length = 0;
sb.Append(indent1);
sb.Append("<operation name='");
sb.Append(methodName);
sb.Append("'");
if (phony != null && phony._paramNamesOrder.Count > 0)
{
sb.Append(" parameterOrder='");
bool bfirst = true;
foreach (String param in phony._paramNamesOrder)
{
if (!bfirst)
sb.Append(" ");
sb.Append(param);
bfirst = false;
}
sb.Append("'");
}
sb.Append(">");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent2);
sb.Append("<input name='");
sb.Append(_methodTypes[2*i]);
sb.Append("Request' ");
sb.Append("message='");
sb.Append(overloadedName);
sb.Append("Input");
sb.Append("'/>");
textWriter.WriteLine(sb);
if (!bIsOneWay)
{
sb.Length = 0;
sb.Append(indent2);
sb.Append("<output name='");
sb.Append(_methodTypes[2*i]);
sb.Append("Response' ");
sb.Append("message='");
sb.Append(overloadedName);
sb.Append("Output");
sb.Append("'/>");
textWriter.WriteLine(sb);
}
sb.Length = 0;
sb.Append(indent1);
sb.Append("</operation>");
textWriter.WriteLine(sb);
}
sb.Length = 0;
sb.Append(indent);
sb.Append("</portType>");
textWriter.WriteLine(sb);
// Binding
sb.Length = 0;
sb.Append("\n");
sb.Append(indent);
sb.Append("<binding name='");
sb.Append(Name);
sb.Append("Binding");
sb.Append("' ");
sb.Append("type='tns:");
sb.Append(Name);
sb.Append("PortType");
sb.Append("'>");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent1);
sb.Append("<soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/>");
textWriter.WriteLine(sb);
if (_type.IsInterface || IsSUDSType)
PrintSuds(_type, _implIFaces, _nestedTypes, textWriter, sb, indent); // Some namespaces have no suds types
if (!_xns.IsClassesPrinted)
{
for (int i=0;i<_xns._realSchemaTypes.Count;i++)
{
RealSchemaType rsType = (RealSchemaType) _xns._realSchemaTypes[i];
Type type = rsType._type;
Util.Log("RealSchemaType.PrintMessageWsd suds realSchemaType "+type);
if (!rsType.Type.IsInterface && !rsType.IsSUDSType)
{
Util.Log("RealSchemaType.PrintMessageWsd suds realSchemaType 2 "+type.BaseType+" "+typeof(MulticastDelegate).IsAssignableFrom(type));;
Type[] iFaces = GetIntroducedInterfaces(rsType._type);
String[] implIFaces = null;
bool bUsedFaces = false;
if (iFaces.Length > 0)
{
implIFaces = new String[iFaces.Length];
for (int j=0;i<iFaces.Length;i++)
{
String fns;
Assembly fassem;
Util.Log("RealSchemaType.PrintMessageWsdl iFace "+iFaces[j].Name);
bool bInteropType = WsdlGenerator.GetNSAndAssembly(iFaces[j], out fns, out fassem);
XMLNamespace xns = _xns.LookupSchemaNamespace(fns, fassem);
Debug.Assert(xns != null, "SchemaType should have been found");
sb.Length = 0;
sb.Append(xns.Prefix);
sb.Append(':');
sb.Append(iFaces[j].Name);
implIFaces[j] = sb.ToString();
if (implIFaces[j].Length > 0)
bUsedFaces = true;
}
}
if (!bUsedFaces)
implIFaces = null;
PrintSuds(type, implIFaces, rsType._nestedTypes, textWriter, sb, indent);
}
}
_xns.IsClassesPrinted = true;
}
for (int i=0;i<methodsLength;i++)
{
method = _methods[i];
methodName = PrintMethodName(method);
bIsOneWay = RemotingServices.IsOneWay(method);
//binding operation
sb.Length = 0;
sb.Append(indent1);
sb.Append("<operation name='");
sb.Append(methodName);
sb.Append("'>");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent2);
sb.Append("<soap:operation soapAction='");
String soapAction = SoapServices.GetSoapActionFromMethodBase(method);
if ((soapAction != null) || (soapAction.Length > 0))
{
sb.Append(soapAction);
}
else
{
sb.Append(ns);
sb.Append('#');
sb.Append(methodName);
}
sb.Append("'/>");
textWriter.WriteLine(sb);
if (_methodAttributes != null && (i < _methodAttributes.Length) && _methodAttributes[i] != null)
{
// Suds for method attributes
// Attributes are only for public methods,
// _method contains public and additional qualified interface methods
// The public methods are at the beginning of _methods
sb.Length = 0;
sb.Append(indent2);
sb.Append("<suds:method attributes='");
sb.Append(_methodAttributes[i]);
sb.Append("'/>");
textWriter.WriteLine(sb);
}
sb.Length = 0;
sb.Append(indent2);
sb.Append("<input name='");
sb.Append(_methodTypes[2*i]);
sb.Append("Request'>");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent3);
sb.Append("<soap:body use='encoded' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' namespace='");
String interopNamespace = SoapServices.GetXmlNamespaceForMethodCall(method);
if (interopNamespace == null)
sb.Append(ns);
else
sb.Append(interopNamespace);
sb.Append("'/>");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent2);
sb.Append("</input>");
textWriter.WriteLine(sb);
if (!bIsOneWay)
{
sb.Length = 0;
sb.Append(indent2);
sb.Append("<output name='");
sb.Append(_methodTypes[2*i]);
sb.Append("Response'>");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent3);
sb.Append("<soap:body use='encoded' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' namespace='");
interopNamespace = SoapServices.GetXmlNamespaceForMethodResponse(method);
if (interopNamespace == null)
sb.Append(ns);
else
sb.Append(interopNamespace);
sb.Append("'/>");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent2);
sb.Append("</output>");
textWriter.WriteLine(sb);
}
sb.Length = 0;
sb.Append(indent1);
sb.Append("</operation>");
textWriter.WriteLine(sb);
}
sb.Length=0;
sb.Append(indent);
sb.Append("</binding>");
textWriter.WriteLine(sb);
}
private void PrintSuds(Type type, String[] implIFaces, Type[] nestedTypes, TextWriter textWriter, StringBuilder sb, String indent)
{
Util.Log("RealSchemaType.PrintSuds "+type+" implIFaces "+implIFaces+" nestedTypes "+nestedTypes);
String indent1 = IndentP(indent);
String indent2 = IndentP(indent1);
String indent3 = IndentP(indent2);
String sudsEnd = null;
// Type, interface, extends information
sb.Length = 0;
sb.Append(indent1);
if (type.IsInterface)
{
sb.Append("<suds:interface type='");
sudsEnd = "</suds:interface>";
}
else if (type.IsValueType)
{
sb.Append("<suds:struct type='");
sudsEnd = "</suds:struct>";
}
else
{
sb.Append("<suds:class type='");
sudsEnd = "</suds:class>";
}
sb.Append(_xns.Prefix);
sb.Append(':');
sb.Append(WsdlGenerator.RefName(type));
sb.Append("'");
Type baseType = type.BaseType;
if (IsNotSystemDefinedRoot(type, baseType))
{
XMLNamespace xns = _WsdlGenerator.GetNamespace(baseType);
sb.Append(" extends='");
sb.Append(xns.Prefix);
sb.Append(':');
sb.Append(baseType.Name);
sb.Append("'");
}
if (baseType != null && baseType.FullName == "System.EnterpriseServices.ServicedComponent")
sb.Append(" rootType='ServicedComponent'");
else if (typeof(Delegate).IsAssignableFrom(type) || typeof(MulticastDelegate).IsAssignableFrom(type))
sb.Append(" rootType='Delegate'");
else if (typeof(MarshalByRefObject).IsAssignableFrom(type))
sb.Append(" rootType='MarshalByRefObject'");
else if (typeof(ISerializable).IsAssignableFrom(type))
sb.Append(" rootType='ISerializable'");
if (implIFaces == null && nestedTypes == null)
sb.Append("/>");
else
sb.Append(">");
textWriter.WriteLine(sb);
String extendAttribute = null;
if (type.IsInterface)
extendAttribute = "<suds:extends type='";
else
extendAttribute = "<suds:implements type='";
if (implIFaces != null)
{
for (int j=0;j<implIFaces.Length;j++)
{
if (!(implIFaces[j] == null || implIFaces[j] == String.Empty))
{
sb.Length = 0;
sb.Append(indent2);
sb.Append(extendAttribute);
sb.Append(implIFaces[j]);
sb.Append("'/>");
textWriter.WriteLine(sb);
}
}
}
if (nestedTypes != null)
{
for (int j=0;j<nestedTypes.Length;j++)
{
sb.Length = 0;
sb.Append(indent2);
sb.Append("<suds:nestedType name='");
sb.Append(nestedTypes[j].Name);
sb.Append("' type='");
sb.Append(_xns.Prefix);
sb.Append(':');
sb.Append(WsdlGenerator.RefName(nestedTypes[j]));
sb.Append("'/>");
textWriter.WriteLine(sb);
}
}
if (implIFaces != null || nestedTypes != null)
{
sb.Length = 0;
sb.Append(indent1);
sb.Append(sudsEnd);
textWriter.WriteLine(sb);
}
}
private static String ProcessArray(Type type, XMLNamespace xns)
{
Util.Log("RealSchemaType.ProcessArray Enter "+type);
String qname = null;
bool bbinary = false;
Type elementType = type.GetElementType();
String elementTypeName = "ArrayOf";
while (elementType.IsArray)
{
elementTypeName = elementTypeName+"ArrayOf";
elementType = elementType.GetElementType();
}
qname = RealSchemaType.TypeName(elementType, true, xns);
int index = qname.IndexOf(":");
String prefix = qname.Substring(0, index);
String wireName = qname.Substring(index+1);
Util.Log("RealSchemaType.ProcessArray qname "+qname+" wirename "+wireName);
int rank = type.GetArrayRank();
String rankStr = "";
if (rank > 1)
rankStr = rank.ToString(CultureInfo.InvariantCulture);
String csname =elementTypeName+wireName.Substring(0,1).ToUpper(CultureInfo.InvariantCulture)+wireName.Substring(1)+rankStr;
csname = csname.Replace('+','N'); // need to get rid of + in nested classes
ArraySchemaType ast = xns.LookupArraySchemaType(csname);
if (ast == null)
{
ArraySchemaType cstype = new ArraySchemaType(type, csname, SchemaBlockType.ComplexContent, false);
Restriction restriction = new Restriction();
SchemaAttribute attribute = new SchemaAttribute();
if (bbinary)
attribute.AddArray(qname);
else
{
String arrayTypeName = type.Name;
index = arrayTypeName.IndexOf("[");
attribute.AddArray(qname+arrayTypeName.Substring(index));
}
restriction.AddArray(attribute);
cstype.AddParticle(restriction);
xns.AddArraySchemaType(cstype);
}
String returnStr = xns.Prefix+":"+csname;
Util.Log("RealSchemaType.ProcessArray Exit "+returnStr);
return returnStr;
}
internal static String TypeName(Type type, bool bEmbedded, XMLNamespace thisxns)
{
Util.Log("RealSchemaType.TypeName entry "+type+" bEmbedded "+bEmbedded+" xns "+thisxns.Name);
String typeName = null;
if (type.IsArray)
return ProcessArray(type, thisxns);
String clrTypeName = WsdlGenerator.RefName(type);
Type clrType = type;
// If ref type the name ends in &
if (type.IsByRef)
{
clrType = type.GetElementType();
clrTypeName = WsdlGenerator.RefName(clrType);
if (clrType.IsArray)
return ProcessArray(clrType, thisxns);
}
typeName = SudsConverter.MapClrTypeToXsdType(clrType);
if (typeName == null)
{
String ns = type.Namespace;
Assembly assem = type.Module.Assembly;
XMLNamespace xns = null;
Util.Log("RealSchemaType.TypeName realNS "+ns);
xns = (XMLNamespace)thisxns.Generator._typeToInteropNS[type];
if (xns == null)
{
xns = thisxns.LookupSchemaNamespace(ns, assem);
if (xns == null)
{
xns = thisxns.Generator.LookupNamespace(ns,assem);
if (xns == null)
{
xns = thisxns.Generator.AddNamespace(ns, assem);
}
thisxns.DependsOnSchemaNS(xns, false);
}
Util.Log("RealSchemaType.TypeName depended NS with assem equals "+xns.Name);
}
StringBuilder sb = new StringBuilder(256);
sb.Append(xns.Prefix);
sb.Append(':');
sb.Append(clrTypeName);
typeName = sb.ToString();
}
Util.Log("RealSchemaType.TypeName exit "+typeName);
return typeName;
}
static private Type[] GetIntroducedInterfaces(Type type)
{
ArrayList ifaceA = new ArrayList();
Type[] typeA = type.GetInterfaces();
// remove system interfaces.
foreach (Type itype in typeA)
{
if (!itype.FullName.StartsWith("System."))
{
ifaceA.Add(itype);
Util.Log("RealSchemaType.GetIntroducedInterfaces "+type+" Interfaces "+itype);
}
}
Util.Log("RealSchemaType.GetIntroducedInterfaces "+type+" typeInterface? "+type.IsInterface+" number of interfaces "+typeA.Length);
Type[] ifaceTypes = new Type[ifaceA.Count];
for(int i=0; i<ifaceA.Count; i++)
ifaceTypes[i] = (Type)ifaceA[i];
return ifaceTypes;
}
static private void FindMethodAttributes(Type type, MethodInfo[] infos, ref String[] methodAttributes, BindingFlags bFlags)
{
Util.Log("RealSchemaType.FindMethodAttributes Enter "+type);
Type baseType = type;
ArrayList inherit = new ArrayList();
while (true)
{
baseType = baseType.BaseType;
Util.Log("RealSchemaType.FindMethodAttributes baseType "+baseType);
if (baseType != null && !baseType.FullName.StartsWith("System."))
inherit.Add(baseType);
else
break;
}
StringBuilder sb = new StringBuilder();
for(int i=0; i<infos.Length; i++)
{
MethodBase info = (MethodBase)infos[i];
sb.Length = 0;
MethodAttributes ma = info.Attributes;
bool bVirtual = info.IsVirtual;
bool bNewSlot = ((ma & MethodAttributes.NewSlot) == MethodAttributes.NewSlot);
Util.Log("RealSchemaType.FindMethodAttributes "+info.Name+" bVirtual "+bVirtual+" bNewSlot "+bNewSlot+" hidebysig "+info.IsHideBySig);
if (info.IsPublic)
sb.Append("public");
else if (info.IsFamily)
sb.Append("protected");
else if (info.IsAssembly)
sb.Append("internal");
// See if method hides inherited methods
bool bHides = false;
for (int j=0; j<inherit.Count; j++)
{
baseType = (Type)inherit[j];
ParameterInfo[] paramInfos = info.GetParameters();
Type[] types = new Type[paramInfos.Length];
for (int itype=0; itype<types.Length; itype++)
{
types[itype] = paramInfos[itype].ParameterType;
}
MethodInfo baseInfo = baseType.GetMethod(info.Name, types);
if (baseInfo != null)
{
// Hides
if (sb.Length > 0)
sb.Append(" ");
if (bNewSlot || baseInfo.IsFinal)
sb.Append("new");
else if (baseInfo.IsVirtual && bVirtual)
sb.Append("override");
else
sb.Append("new");
bHides = true;
break;
}
}
if (!bHides && bVirtual)
{
if (sb.Length > 0)
sb.Append(" ");
sb.Append("virtual");
}
if (sb.Length > 0)
{
methodAttributes[i] = sb.ToString();
Util.Log("RealSchemaType.FindMethodAttributes Exit "+info.Name+" "+methodAttributes[i]);
}
}
}
static private MethodInfo[] GetIntroducedMethods(Type type, ref String[] methodAttributes)
{
Util.Log("RealSchemaType.GetIntroducedMethods "+type);
// Methods in the class are either the class public methods or interface qualified methods
BindingFlags bFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public;
MethodInfo[] methodInfos = type.GetMethods(bFlags); //public methods (including unqualified interface methods)
if (type.IsInterface)
return methodInfos;
// Find method attributes for public methods
methodAttributes = new String[methodInfos.Length];
FindMethodAttributes(type, methodInfos, ref methodAttributes, bFlags);
// Get any class methods which are interface qualifed methods.
// interface qualified methods are not public in the metadata.
ArrayList additionalInfos = new ArrayList();
Type[] itypeA = type.GetInterfaces();
foreach (Type itype in itypeA )
{
InterfaceMapping im = type.GetInterfaceMap(itype);
foreach (MethodInfo mi in im.TargetMethods)
{
if (!mi.IsPublic && type.GetMethod(mi.Name, bFlags | BindingFlags.NonPublic) != null)
{
additionalInfos.Add(mi);
}
}
}
// Combine all the methodinfos into one structure
MethodInfo[] finalMethodInfos = null;
if (additionalInfos.Count > 0)
{
finalMethodInfos = new MethodInfo[methodInfos.Length + additionalInfos.Count];
for(int i=0; i<methodInfos.Length; i++)
finalMethodInfos[i] = methodInfos[i];
for(int i=0; i<additionalInfos.Count; i++)
finalMethodInfos[methodInfos.Length+i] = (MethodInfo)additionalInfos[i];
}
else
finalMethodInfos = methodInfos;
return finalMethodInfos;
}
internal static String PrintMethodName(MethodInfo methodInfo)
{
String methodName = methodInfo.Name;
int lastDot = 0;
int prevDot = 0;
for (int i=0; i<methodName.Length; i++)
{
if (methodName[i] == '.')
{
prevDot = lastDot;
lastDot = i;
}
}
String iname = methodName;
if (prevDot > 0)
iname = methodName.Substring(prevDot+1);
return iname;
}
static private FieldInfo[] GetInstanceFields(Type type){
Util.Log("RealSchemaType.GetIntroducedFields "+type);
BindingFlags bFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance |
BindingFlags.Public;
if (!s_marshalByRefType.IsAssignableFrom(type))
bFlags |= BindingFlags.NonPublic;
FieldInfo[] fields = type.GetFields(bFlags);
Util.Log("RealSchemaType.GetIntroducedFields length "+fields.Length);
int actualLength = fields.Length;
if (actualLength == 0)
return(emptyFieldSet);
for (int i=0;i<fields.Length;i++)
{
Util.Log("RealSchemaType.GetInstanceFields field "+fields[i].Name+" "+fields[i].FieldType+" type "+type);
if (fields[i].IsStatic)
{
Debug.Assert(false, "Static Field");
Util.Log("RealSchemaType.GetInstanceFields field static "+fields[i].FieldType);
--actualLength;
fields[i] = fields[actualLength];
fields[actualLength] = null;
}
}
if (actualLength < fields.Length)
{
FieldInfo[] ifields = new FieldInfo[actualLength];
Array.Copy(fields, ifields, actualLength);
Util.Log("RealSchemaType.GetInstanceFields adjust length "+actualLength);
return(ifields);
}
return(fields);
}
// Instance fields
private WsdlGenerator _WsdlGenerator;
private Type _type;
private String _serviceEndpoint;
private Hashtable _typeToServiceEndpoint;
private bool _bUnique;
private XMLNamespace _xns;
private bool _bStruct;
private String[] _implIFaces;
private Type[] _iFaces;
private MethodInfo[] _methods;
private String[] _methodAttributes;
private String[] _methodTypes;
private FieldInfo[] _fields;
private PhonySchemaType[] _phony;
internal Type[] _nestedTypes;
// Static fields
private static Type[] emptyTypeSet = new Type[0];
private static MethodInfo[] emptyMethodSet = new MethodInfo[0];
private static FieldInfo[] emptyFieldSet = new FieldInfo[0];
}
private class XMLNamespace
{
internal XMLNamespace(String name, Assembly assem, String serviceEndpoint, Hashtable typeToServiceEndpoint, String prefix, bool bInteropType, WsdlGenerator generator ){
Util.Log("XMLNamespace.XMLNamespace Enter "+name+" serviceEndpoint "+serviceEndpoint+" prefix "+prefix+" bInteropType "+bInteropType);
_name = name;
_assem = assem;
_bUnique = false;
_bInteropType = bInteropType;
_generator = generator;
StringBuilder sb = new StringBuilder(256);
Assembly systemAssembly = typeof(String).Module.Assembly;
// Remove leading . for an empty namespace
if (!_bInteropType)
{
if (assem == systemAssembly)
{
sb.Append(SoapServices.CodeXmlNamespaceForClrTypeNamespace(name, null));
}
else if (assem != null)
{
sb.Append(SoapServices.CodeXmlNamespaceForClrTypeNamespace(name, assem.FullName));
}
}
else
{
sb.Append(name);
}
_namespace = sb.ToString();
_prefix = prefix;
_dependsOnSchemaNS = new ArrayList();
_realSUDSTypes = new ArrayList();
_dependsOnSUDSNS = new ArrayList();
_realSchemaTypes = new ArrayList();
_phonySchemaTypes = new ArrayList();
_simpleSchemaTypes = new ArrayList();
_arraySchemaTypes = new ArrayList();
_xnsImports = new ArrayList();
_serviceEndpoint = serviceEndpoint;
_typeToServiceEndpoint = typeToServiceEndpoint;
Util.Log("XMLNamespace.XMLNamespace exit "+_namespace);
}
internal String Name{
get{ return(_name);}
}
internal Assembly Assem{
get{ return(_assem);}
}
internal String Prefix{
get{ return(_prefix);}
}
internal String Namespace{
get{ return(_namespace);}
}
internal bool IsInteropType{
get{return(_bInteropType);}
}
internal WsdlGenerator Generator
{
get {return (_generator);}
}
internal bool IsClassesPrinted
{
get {return _bClassesPrinted;}
set {_bClassesPrinted = value;}
}
//internal XMLNamespace(String name, Assembly assem, String serviceEndpoint, Hashtable typeToServiceEndpoint, String prefix, bool bInteropType, WsdlGenerator generator ){
/*
internal SchemaType LookupSchemaType(Type type)
{
return (SchemaType)_typeToSchemaType[type];
}
internal Type LookupType(SchemaType stype)
{
return (Type)_schemaTypeToType[stype];
}
*/
internal Type LookupSchemaType(String name)
{
Type returnType = null;
RealSchemaType rsType = LookupRealSchemaType(name);
if (rsType != null)
returnType = rsType.Type;
SimpleSchemaType ssType = LookupSimpleSchemaType(name);
if (ssType != null)
returnType = ssType.Type;
ArraySchemaType asType = LookupArraySchemaType(name);
if (asType != null)
returnType = asType.Type;
Util.Log("XMLNamespace.LookupSchemaType "+name+" return "+returnType);
return(returnType);
}
internal SimpleSchemaType LookupSimpleSchemaType(String name){
Util.Log("XMLNamespace.LookupSimpleSchemaType "+name);
for (int i=0;i<_simpleSchemaTypes.Count;i++)
{
SimpleSchemaType ssType = (SimpleSchemaType) _simpleSchemaTypes[i];
if (ssType.FullRefName == name)
return(ssType);
}
return(null);
}
internal bool CheckForSchemaContent()
{
if (_arraySchemaTypes.Count > 0 ||
_simpleSchemaTypes.Count > 0)
return true;
if (_realSchemaTypes.Count == 0)
return false;
bool bRealSchema = false;
for (int i=0;i<_realSchemaTypes.Count;i++)
{
RealSchemaType rsType = (RealSchemaType) _realSchemaTypes[i];
if (!rsType.Type.IsInterface && !rsType.IsSUDSType)
{
bRealSchema = true;
break;
}
}
if (bRealSchema)
return true;
else
return false;
}
internal RealSchemaType LookupRealSchemaType(String name){
Util.Log("XMLNamespace.LookupRealSchemaType "+name);
Debug.Assert(_phonySchemaTypes.Count == 0, "PhonyTypes present");
for (int i=0;i<_realSchemaTypes.Count;i++)
{
RealSchemaType rsType = (RealSchemaType) _realSchemaTypes[i];
if (rsType.FullRefName == name)
return(rsType);
}
return(null);
}
internal ArraySchemaType LookupArraySchemaType(String name){
Util.Log("XMLNamespace.LookupArraySchemaType "+name);
//Debug.Assert(_phonySchemaTypes.Count == 0, "PhonyTypes present");
for (int i=0;i<_arraySchemaTypes.Count;i++)
{
ArraySchemaType asType = (ArraySchemaType) _arraySchemaTypes[i];
if (asType.Name == name)
return(asType);
}
return(null);
}
internal void AddRealSUDSType(RealSchemaType rsType){
Util.Log("XMLNamespace.AddRealSUDSType "+rsType.Type);
_realSUDSTypes.Add(rsType);
//_typeToSchemaType[rsType.Type] = rsType;
//_schemaTypeToType[rsType] = rsType.Type;
return;
}
internal void AddRealSchemaType(RealSchemaType rsType){
Util.Log("XMLNamespace.AddRealSchemaType "+rsType.Type);
Debug.Assert(LookupRealSchemaType(rsType.Name) == null, "Duplicate Type found");
_realSchemaTypes.Add(rsType);
if (rsType.IsUnique)
_bUnique = true;
//_typeToSchemaType[rsType.Type] = rsType;
//_schemaTypeToType[rsType] = rsType.Type;
return;
}
internal void AddArraySchemaType(ArraySchemaType asType){
Debug.Assert(LookupArraySchemaType(asType.Name) == null, "Duplicate Type found");
_arraySchemaTypes.Add(asType);
//_typeToSchemaType[asType.Type] = asType;
//_schemaTypeToType[asType] = asType.Type;
return;
}
internal void AddSimpleSchemaType(SimpleSchemaType ssType){
Util.Log("XMLNamespace.AddSimpleSchemaType "+ssType.Type);
Debug.Assert(LookupSimpleSchemaType(ssType.Type.Name) == null, "Duplicate Type found");
_simpleSchemaTypes.Add(ssType);
//_typeToSchemaType[ssType.Type] = ssType;
//_schemaTypeToType[ssType] = ssType.Type;
return;
}
internal PhonySchemaType LookupPhonySchemaType(String name){
Util.Log("XMLNamespace.LookupPhonySchemaType "+name);
for (int i=0;i<_phonySchemaTypes.Count;i++)
{
PhonySchemaType type = (PhonySchemaType) _phonySchemaTypes[i];
if (type.Name == name)
return(type);
}
return(null);
}
internal void AddPhonySchemaType(PhonySchemaType phType){
Util.Log("XMLNamespace.AddPhonySchemaType "+phType.Name);
PhonySchemaType overloadedType = LookupPhonySchemaType(phType.Name);
if (overloadedType != null)
phType.ElementName = phType.Name + overloadedType.OverloadedType();
_phonySchemaTypes.Add(phType);
return;
}
internal XMLNamespace LookupSchemaNamespace(String ns, Assembly assem){
Util.Log("XMLNamespace.LookupSchemaNamespace "+ns);
for (int i=0;i<_dependsOnSchemaNS.Count;i++)
{
XMLNamespace xns = (XMLNamespace) _dependsOnSchemaNS[i];
if ((xns.Name == ns) && (xns.Assem == assem))
return(xns);
}
return(null);
}
internal void DependsOnSchemaNS(XMLNamespace xns, bool bImport){
Util.Log("XMLNamespace.DependsOnSchemaNS "+Namespace+" depends on "+xns.Namespace+" bImport "+bImport);
if (LookupSchemaNamespace(xns.Name, xns.Assem) != null)
return;
_dependsOnSchemaNS.Add(xns);
if (bImport && Namespace != xns.Namespace)
_xnsImports.Add(xns);
return;
}
private XMLNamespace LookupSUDSNamespace(String ns, Assembly assem){
Util.Log("XMLNamespace.LookupSUDSNamespace "+ns);
for (int i=0;i<_dependsOnSUDSNS.Count;i++)
{
XMLNamespace xns = (XMLNamespace) _dependsOnSUDSNS[i];
if ((xns.Name == ns) && (xns.Assem == assem))
return(xns);
}
return(null);
}
internal void DependsOnSUDSNS(XMLNamespace xns){
Util.Log("XMLNamespace.DependsOnSUDSNS "+xns.Name+" "+xns.Assem);
if (LookupSUDSNamespace(xns.Name, xns.Assem) != null)
return;
_dependsOnSUDSNS.Add(xns);
return;
}
internal void Resolve(){
Util.Log("XMLNamespace.Resolve");
StringBuilder sb = new StringBuilder(256);
for (int i=0;i<_realSchemaTypes.Count;i++)
((RealSchemaType) _realSchemaTypes[i]).Resolve(sb);
return;
}
internal void PrintDependsOnWsdl(TextWriter textWriter, StringBuilder sb, String indent, Hashtable usedNames)
{
Util.Log("XMLNamespace.PrintDependsOn "+_name+" targetNameSpace "+Namespace);
if (_dependsOnSchemaNS.Count > 0)
{
for (int i=0;i<_dependsOnSchemaNS.Count;i++)
{
XMLNamespace xns = (XMLNamespace) _dependsOnSchemaNS[i];
if (!usedNames.ContainsKey(xns.Prefix))
{
usedNames[xns.Prefix] = null;
sb.Length = 0;
sb.Append(indent);
sb.Append("xmlns:");
sb.Append(xns.Prefix);
sb.Append("='");
sb.Append(xns.Namespace);
sb.Append("'");
textWriter.WriteLine(sb);
}
}
}
}
internal void PrintSchemaWsdl(TextWriter textWriter, StringBuilder sb, String indent){
Util.Log("XMLNamespace.PrintSchemaWsdl "+Namespace+" _realSchemaTypes.Count "+_realSchemaTypes.Count);
// Print schema types
bool bReal = false;
/*
for(int i=0;i<_realSchemaTypes.Count;i++)
{
RealSchemaType rsType = (RealSchemaType) _realSchemaTypes[i];
if(!rsType.Type.IsInterface && !rsType.IsSUDSType)
bReal = true;
}
*/
if ((_simpleSchemaTypes.Count > 0) || (_realSchemaTypes.Count > 0) || (_arraySchemaTypes.Count > 0))
{
bReal = true;
}
// Print schema types
if (bReal)
{
// schema begin
String indent1 = IndentP(indent);
String indent2 = IndentP(indent1);
String indent3 = IndentP(indent2);
String indent4 = IndentP(indent3);
sb.Length = 0;
sb.Append(indent);
sb.Append("<schema ");
sb.Append("targetNamespace='");
sb.Append(Namespace);
sb.Append("'");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent2);
sb.Append("xmlns='");
sb.Append(SudsConverter.GetXsdVersion(_generator._xsdVersion));
sb.Append("'");
textWriter.WriteLine(sb);
sb.Length = 0;
sb.Append(indent2);
sb.Append("elementFormDefault='unqualified' attributeFormDefault='unqualified'>");
textWriter.WriteLine(sb);
// Write import statements
foreach (XMLNamespace xns in _xnsImports)
{
sb.Length = 0;
sb.Append(indent1);
sb.Append("<import namespace='");
sb.Append(xns.Namespace);
sb.Append("'/>");
textWriter.WriteLine(sb);
}
for (int i=0;i<_simpleSchemaTypes.Count;i++)
{
SimpleSchemaType ssType = (SimpleSchemaType) _simpleSchemaTypes[i];
ssType.PrintSchemaType(textWriter, sb, indent1, false);
}
for (int i=0;i<_realSchemaTypes.Count;i++)
{
RealSchemaType rsType = (RealSchemaType) _realSchemaTypes[i];
if (!rsType.Type.IsInterface && !rsType.IsSUDSType)
rsType.PrintSchemaType(textWriter, sb, indent1, false);
}
for (int i=0;i<_arraySchemaTypes.Count;i++)
{
ArraySchemaType asType = (ArraySchemaType) _arraySchemaTypes[i];
asType.PrintSchemaType(textWriter, sb, indent1, false);
}
/*
for(int i=0;i<_phonySchemaTypes.Count;i++)
{
PhonySchemaType psType = (PhonySchemaType) _phonySchemaTypes[i];
psType.PrintSchemaType(textWriter, sb, indent1, true);
}
*/
sb.Length = 0;
sb.Append(indent);
sb.Append("</schema>");
textWriter.WriteLine(sb);
}
}
internal void PrintMessageWsdl(TextWriter textWriter, StringBuilder sb, String indent, ArrayList refNames)
{
Util.Log("XmlNamespace.PrintMessageWsdl");
for (int i=0;i<_realSUDSTypes.Count;i++)
((RealSchemaType) _realSUDSTypes[i]).PrintMessageWsdl(textWriter, sb, indent, refNames);
if (_realSUDSTypes.Count == 0 && _realSchemaTypes.Count > 0)
{
// If no suds type, we still generate a binding section to print the Suds Extendsions
// We only need to do this once, because all the realschema types will be placed into
// one binding
((RealSchemaType) _realSchemaTypes[0]).PrintMessageWsdl(textWriter, sb, indent, new ArrayList());
}
}
// Fields
private String _name;
private Assembly _assem;
private String _namespace;
private String _prefix;
// disable csharp compiler warning #0414: field assigned unused value
#pragma warning disable 0414
internal bool _bUnique;
#pragma warning restore 0414
private ArrayList _dependsOnSUDSNS;
private ArrayList _realSUDSTypes;
private ArrayList _dependsOnSchemaNS;
internal ArrayList _realSchemaTypes;
private ArrayList _phonySchemaTypes;
private ArrayList _simpleSchemaTypes;
private ArrayList _arraySchemaTypes;
private bool _bInteropType;
private String _serviceEndpoint;
private Hashtable _typeToServiceEndpoint;
private WsdlGenerator _generator;
private ArrayList _xnsImports;
private bool _bClassesPrinted = false;
//private Hashtable _typeToSchemaType = new Hashtable();
//private Hashtable _schemaTypeToType = new Hashtable();
}
internal static String IndentP(String indentStr){
return indentStr+" ";
}
}
}
|