View Javadoc

1   package org.codehaus.xfire.wsdl;
2   
3   import java.io.IOException;
4   import java.io.OutputStream;
5   import java.util.ArrayList;
6   import java.util.HashMap;
7   import java.util.Iterator;
8   import java.util.List;
9   import java.util.Map;
10  import java.util.Set;
11  
12  import javax.wsdl.Definition;
13  import javax.wsdl.WSDLException;
14  import javax.wsdl.factory.WSDLFactory;
15  
16  import org.codehaus.xfire.SOAPConstants;
17  import org.codehaus.xfire.util.NamespaceHelper;
18  import org.codehaus.xfire.service.Service;
19  import org.dom4j.Document;
20  import org.dom4j.DocumentFactory;
21  import org.dom4j.Element;
22  import org.dom4j.Namespace;
23  import org.dom4j.Node;
24  import org.dom4j.io.DOMReader;
25  import org.dom4j.io.OutputFormat;
26  import org.dom4j.io.XMLWriter;
27  
28  /***
29   * AbstractWSDL
30   * 
31   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
32   */
33  public abstract class AbstractWSDL
34      implements WSDL
35  {
36      private Definition def;
37      private String targetNamespace;
38      private Service service;
39      private Document wsdlDocument;
40      private Map dependencies;
41      private Element schemaTypes;
42      private Map typeMap;
43  
44      /*-------------------------------------------------
45       * Namespace and QName definitions for easy access.
46       *-------------------------------------------------*/
47  
48      protected Namespace xsdNs = new Namespace( "xsd", SOAPConstants.XSD );
49      
50      protected org.dom4j.QName schemaQ = new org.dom4j.QName("schema", xsdNs);
51  
52      protected org.dom4j.QName elementQ = new org.dom4j.QName("element", xsdNs);
53  
54      /*** A QName for elements which hold the schema that a WSDL type writes out. */
55      protected org.dom4j.QName xfireTypeQ = org.dom4j.QName.get( "xfire", "http://xfire.codehaus.org" );
56      
57      public AbstractWSDL( Service service )
58          throws WSDLException
59      {
60          dependencies = new HashMap();
61          this.service = service;
62          
63          setDefinition( WSDLFactory.newInstance().newDefinition() );
64          getDefinition().setTargetNamespace( service.getDefaultNamespace() );
65          
66          Document paramDoc = DocumentFactory.getInstance().createDocument();
67          setSchemaTypes( paramDoc.addElement( "root" ) );
68          getSchemaTypes().add(xsdNs);
69          
70          addNamespace( "soap", service.getSoapVersion() );
71          addNamespace( "xsd", SOAPConstants.XSD );
72          addNamespace( "wsdl", WSDL11_NS );
73          addNamespace( "wsdlsoap", WSDL11_SOAP_NS );
74          addNamespace( "tns", service.getDefaultNamespace() );
75  
76          typeMap = new HashMap();
77      }
78      
79      protected void writeDocument() 
80          throws WSDLException
81      {
82          org.w3c.dom.Document doc = WSDLFactory.newInstance().newWSDLWriter().getDocument( def );
83          
84          wsdlDocument = new DOMReader().read(doc);
85          wsdlDocument.getRootElement().addNamespace( "tns", service.getDefaultNamespace() );
86          
87          writeComplexTypes();
88      }
89      
90      protected void writeComplexTypes()
91          throws WSDLException
92      {
93          Element rootEl = getDocument().getRootElement();
94          
95          Namespace wsdlNs = rootEl.getNamespaceForURI( WSDL11_NS );
96          org.dom4j.QName typeQ = new org.dom4j.QName("types", wsdlNs);   
97          Element types = rootEl.addElement( typeQ );
98      
99          // put the types as the first thing in the document
100         List list = rootEl.content();
101         list.remove( types );
102         list.set(0, types);
103 
104         for ( Iterator nsItr = typeMap.keySet().iterator(); nsItr.hasNext(); )
105         {
106             String schemaNs = (String) nsItr.next();
107     
108             Element schema = types.addElement( schemaQ );
109             schema.addAttribute( "targetNamespace", schemaNs );
110             schema.addAttribute( "elementFormDefault", "qualified" );
111             schema.addAttribute( "attributeFormDefault", "qualified" );
112             
113             writeSchemaForNamespace( schema, schemaNs );
114         }
115         
116     }
117 
118     public void addDependency(WSDLType type)
119     {
120         if ( !type.isComplex() )
121             return;
122             
123         if ( !dependencies.containsKey( type.getSchemaType() ) )
124         {
125             dependencies.put( type.getSchemaType(), type );
126             
127             Element e = createSchemaType( type.getSchemaType().getNamespaceURI() );
128             type.writeSchema( e );
129         }
130 
131         Set deps = type.getDependencies();
132         
133         if ( deps != null )
134         {
135             for ( Iterator itr = deps.iterator(); itr.hasNext(); )
136             {
137                 addDependency( (WSDLType) itr.next() );
138             }
139         }
140     }
141     
142     /***
143      * Write the schema types for a particular namespace.
144      * 
145      * @param schema The schema definition for this namespace. 
146      * Attach the types to this.
147      * @param schemaNs The namespace to write the types for.
148      */
149 	protected void writeSchemaForNamespace(Element schema, String schemaNs)
150 	{
151         List types = (List) typeMap.get(schemaNs);
152         
153         if ( types != null )
154         {
155         	for ( Iterator itr = types.iterator(); itr.hasNext(); )
156             {
157                 Element el = (Element) itr.next();
158                 
159                 for ( Iterator eitr = el.elements().iterator(); eitr.hasNext(); )
160                 {
161                      Node n = ((Element) eitr.next()).detach();
162                      schema.add(n);
163                 }
164 
165                 Namespace ns = NamespaceHelper.getNamespace(el, schemaNs);
166 
167                 getDocument().getRootElement().add( ns );
168             }
169         }
170 	}
171 
172 	/***
173      * @see org.codehaus.xfire.wsdl.WSDL#write(java.io.OutputStream)
174      */
175     public void write(OutputStream out) throws IOException
176     {
177         XMLWriter writer = new XMLWriter( OutputFormat.createCompactFormat() );
178         writer.setOutputStream( out );
179         writer.write( getDocument() );
180         writer.flush();
181     }
182     
183     public void addNamespace(String prefix, String uri)
184     {
185         def.addNamespace( prefix, uri );
186         schemaTypes.addNamespace( prefix, uri );
187     }
188     
189     public Namespace getNamespace( String uri )
190     {
191         return NamespaceHelper.getNamespace( schemaTypes, uri );
192     }
193     
194     /***
195      * @see org.codehaus.xfire.wsdl.WSDL#getDocument()
196      */
197     public Document getDocument()
198     {
199         return wsdlDocument;
200     }
201 
202     public Definition getDefinition()
203     {
204         return def;
205     }
206     
207     public void setDefinition(Definition definition)
208     {
209         this.def = definition;
210     }
211     
212     public Service getService()
213     {
214         return service;
215     }
216     
217     public void setService(Service service)
218     {
219         this.service = service;
220     }
221     
222     /***
223      * Create a shcema type element and store it to be written later on.
224      * 
225      * @param namespace The namespace to create the type in.
226      * @return
227      */
228     public Element createSchemaType( String namespace )
229     {
230         Element e = getSchemaTypes().addElement( xfireTypeQ );
231         
232         List types = (List) typeMap.get( namespace );
233         if ( types == null )
234         {
235         	types = new ArrayList();
236             typeMap.put( namespace, types );
237         }
238         
239         types.add(e);
240         
241         return e;
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 }