View Javadoc

    1   package org.codehaus.xfire.wsdl11.builder;
    2
    3   import java.io.IOException;
    4   import java.io.OutputStream;
    5   import java.util.HashMap;
    6   import java.util.Iterator;
    7   import java.util.Map;
    8   import java.util.Set;
    9
    10  import javax.wsdl.Definition;
    11  import javax.wsdl.WSDLException;
    12  import javax.wsdl.factory.WSDLFactory;
    13
    14  import org.codehaus.xfire.XFireRuntimeException;
    15  import org.codehaus.xfire.service.Service;
    16  import org.codehaus.xfire.soap.SoapConstants;
    17  import org.codehaus.xfire.util.NamespaceHelper;
    18  import org.codehaus.xfire.wsdl.SchemaType;
    19  import org.codehaus.xfire.wsdl.WSDLWriter;
    20  import org.codehaus.yom.Attribute;
    21  import org.codehaus.yom.Document;
    22  import org.codehaus.yom.Element;
    23  import org.codehaus.yom.Serializer;
    24  import org.codehaus.yom.converters.DOMConverter;
    25
    26  /***
    27   * AbstractWSDL
    28   *
    29   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
    30   */
    31  public abstract class AbstractWSDL
    32      implements WSDLWriter
    33  {
    34      private Definition def;
    35
    36      private String targetNamespace;
    37
    38      private Service service;
    39
    40      private Document wsdlDocument;
    41
    42      private Map dependencies;
    43
    44      private Element schemaTypes;
    45
    46      private Map typeMap;
    47
    48      private WSDLBuilderInfo info;
    49
    50      /*-------------------------------------------------
    51       * Namespace and QName definitions for easy access.
    52       *-------------------------------------------------*/
    53
    54      public final static String schemaQ = SoapConstants.XSD_PREFIX + ":" + "schema";
    55
    56      public final static String elementQ = SoapConstants.XSD_PREFIX + ":" + "element";
    57
    58      public final static String complexQ = SoapConstants.XSD_PREFIX + ":" + "complexType";
    59
    60      public final static String sequenceQ = SoapConstants.XSD_PREFIX + ":" + "sequence";
    61
    62      public AbstractWSDL(Service service) throws WSDLException
    63      {
    64          dependencies = new HashMap();
    65          this.service = service;
    66          this.info = (WSDLBuilderInfo) service.getProperty(WSDLBuilderInfo.KEY);
    67
    68          if (info == null)
    69              info = new WSDLBuilderInfo(service);
    70
    71          setDefinition(WSDLFactory.newInstance().newDefinition());
    72          getDefinition().setTargetNamespace(info.getTargetNamespace());
    73
    74          Element root = new Element("wsdl:types", WSDL11_NS);
    75          Document paramDoc = new Document(root);
    76          setSchemaTypes(root);
    77          root.addNamespaceDeclaration(SoapConstants.XSD_PREFIX, SoapConstants.XSD);
    78
    79          addNamespace("soap", service.getSoapVersion().getNamespace());
    80          addNamespace("soapenc", service.getSoapVersion().getSoapEncodingStyle());
    81          addNamespace("xsd", SoapConstants.XSD);
    82          addNamespace("wsdl", WSDL11_NS);
    83          addNamespace("wsdlsoap", WSDL11_SOAP_NS);
    84          addNamespace("tns", info.getTargetNamespace());
    85
    86          typeMap = new HashMap();
    87      }
    88
    89      protected void writeDocument()
    90          throws WSDLException
    91      {
    92          org.w3c.dom.Document doc = WSDLFactory.newInstance().newWSDLWriter().getDocument(def);
    93
    94          wsdlDocument = DOMConverter.convert(doc);
    95
    96          writeComplexTypes();
    97      }
    98
    99      protected void writeComplexTypes()
    100         throws WSDLException
    101     {
    102         Element rootEl = getDocument().getRootElement();
    103
    104         if (schemaTypes.getChildCount() > 0)
    105         {
    106             schemaTypes.detach();
    107             rootEl.insertChild(schemaTypes, 0);
    108         }
    109
    110     }
    111
    112     public void addDependency(SchemaType type)
    113     {
    114         if (!type.isComplex())
    115         {
    116             return;
    117         }
    118
    119         if (!hasDependency(type))
    120         {
    121             dependencies.put(type.getSchemaType(), type);
    122
    123             Element e = createSchemaType(type.getSchemaType().getNamespaceURI());
    124             type.writeSchema(e);
    125
    126             Set deps = type.getDependencies();
    127
    128             if (deps != null)
    129             {
    130                 for (Iterator itr = deps.iterator(); itr.hasNext();)
    131                 {
    132                     addDependency((SchemaType) itr.next());
    133                 }
    134             }
    135         }
    136     }
    137
    138     protected boolean hasDependency(SchemaType type)
    139     {
    140         return dependencies.containsKey(type.getSchemaType());
    141     }
    142
    143     /***
    144      * @see org.codehaus.xfire.wsdl.WSDLWriter#write(java.io.OutputStream)
    145      */
    146     public void write(OutputStream out)
    147         throws IOException
    148     {
    149         Serializer writer = new Serializer(out);
    150         writer.write(getDocument());
    151         writer.flush();
    152     }
    153
    154     public void addNamespace(String prefix, String uri)
    155     {
    156         def.addNamespace(prefix, uri);
    157
    158         String declaredUri = schemaTypes.getNamespaceURI(prefix);
    159         if (declaredUri == null)
    160         {
    161             schemaTypes.addNamespaceDeclaration(prefix, uri);
    162         }
    163         else if (!declaredUri.equals(uri))
    164         {
    165             throw new XFireRuntimeException("Namespace conflict: " + declaredUri
    166                     + " was declared but " + uri + " was attempted.");
    167         }
    168     }
    169
    170     public String getNamespacePrefix(String uri)
    171     {
    172         return NamespaceHelper.getUniquePrefix(schemaTypes, uri);
    173     }
    174
    175     public WSDLBuilderInfo getInfo()
    176     {
    177         return info;
    178     }
    179
    180     /***
    181      * @see org.codehaus.xfire.wsdl.WSDLWriter#getDocument()
    182      */
    183     public Document getDocument()
    184     {
    185         return wsdlDocument;
    186     }
    187
    188     public Definition getDefinition()
    189     {
    190         return def;
    191     }
    192
    193     public void setDefinition(Definition definition)
    194     {
    195         this.def = definition;
    196     }
    197
    198     public Service getService()
    199     {
    200         return service;
    201     }
    202
    203     public void setService(Service service)
    204     {
    205         this.service = service;
    206     }
    207
    208     /***
    209      * Create a shcema type element and store it to be written later on.
    210      *
    211      * @param namespace
    212      *            The namespace to create the type in.
    213      * @return
    214      */
    215     public Element createSchemaType(String namespace)
    216     {
    217         Element e = (Element) typeMap.get(namespace);
    218
    219         if (e == null)
    220         {
    221             e = new Element(schemaQ, SoapConstants.XSD);
    222
    223             e.addAttribute(new Attribute("targetNamespace", namespace));
    224             e.addAttribute(new Attribute("elementFormDefault", "qualified"));
    225             e.addAttribute(new Attribute("attributeFormDefault", "qualified"));
    226
    227             setSchema(namespace, e);
    228         }
    229
    230         return e;
    231     }
    232
    233     protected boolean hasSchema(String namespace)
    234     {
    235         return typeMap.containsKey(namespace);
    236     }
    237
    238     protected void setSchema(String namespace, Element schema)
    239     {
    240         typeMap.put(namespace, schema);
    241         getSchemaTypes().appendChild(schema);
    242     }
    243
    244     protected Element getSchemaTypes()
    245     {
    246         return schemaTypes;
    247     }
    248
    249     protected void setSchemaTypes(Element schemaTypes)
    250     {
    251         this.schemaTypes = schemaTypes;
    252     }
    253 }