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 }