PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/eclipse-wtp-webservices-R3.4.0/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDLReaderImpl.java

#
Java | 423 lines | 283 code | 36 blank | 104 comment | 21 complexity | 9deb1213b1f9c1af7a67747c7f7bcb61 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2001, 2009 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. *******************************************************************************/
  11. package org.eclipse.wst.wsdl.validation.internal.wsdl11;
  12. import java.io.InputStream;
  13. import java.net.URL;
  14. import java.util.ArrayList;
  15. import java.util.Hashtable;
  16. import java.util.Iterator;
  17. import java.util.List;
  18. import java.util.Map;
  19. import java.util.Set;
  20. import java.util.SortedSet;
  21. import java.util.TreeSet;
  22. import javax.wsdl.Import;
  23. import javax.wsdl.WSDLException;
  24. import org.apache.xerces.impl.XMLErrorReporter;
  25. import org.apache.xerces.parsers.DOMParser;
  26. import org.apache.xerces.parsers.StandardParserConfiguration;
  27. import org.apache.xerces.xni.XNIException;
  28. import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
  29. import org.eclipse.wst.wsdl.validation.internal.xml.LineNumberDOMParser;
  30. import org.w3c.dom.Document;
  31. import org.w3c.dom.Element;
  32. import org.xml.sax.ErrorHandler;
  33. import org.xml.sax.InputSource;
  34. import org.xml.sax.SAXException;
  35. import org.xml.sax.SAXParseException;
  36. import com.ibm.wsdl.DefinitionImpl;
  37. import com.ibm.wsdl.util.StringUtils;
  38. /**
  39. * A WSDL reader that supports cyclic WSDL imports, schema imports and inline schemas.
  40. * This reader is based on the WSDLReaderImpl from WSDL4J.
  41. */
  42. public class WSDLReaderImpl
  43. {
  44. protected MessageGenerator messagegenerator;
  45. protected IWSDL11ValidationInfo wsdlvalinfo;
  46. /**
  47. * Constructor.
  48. *
  49. * @param wsdlvalinfo The WSDL 1.1 validation info object to use.
  50. */
  51. public WSDLReaderImpl(IWSDL11ValidationInfo wsdlvalinfo)
  52. {
  53. this.wsdlvalinfo = wsdlvalinfo;
  54. }
  55. /**
  56. * Parse the root document. This method will find all imports and parse them as
  57. * well creating a WSDLDocument for each unique WSDL file. This method supports
  58. * cyclic WSDL import statements such that file A can import file B and file B
  59. * can import file A.
  60. *
  61. * @param documentBaseURI The base URI of the root document.
  62. * @param defEl The definition element of the root document.
  63. * @return An array of WSDLDocuments containing all of the unique files in the description.
  64. * @throws WSDLException
  65. */
  66. protected WSDLDocument[] parseDocument(String documentBaseURI, Element defEl) throws WSDLException
  67. {
  68. int initialImportArraySize = 20;
  69. List[] filesAtDepth = new ArrayList[initialImportArraySize];
  70. Map filesImporting = new Hashtable();
  71. SortedSet parsedImports = new TreeSet();
  72. SortedSet importsToParse = new TreeSet();
  73. int maxdepth = 0;
  74. WSDLDocument rootdoc = new WSDLDocument(documentBaseURI, defEl, 0, messagegenerator, wsdlvalinfo);
  75. String targetNamespace = rootdoc.getDefinition().getTargetNamespace();
  76. ImportHolder rootImport = new ImportHolder(targetNamespace, documentBaseURI, documentBaseURI, rootdoc, 0, null, messagegenerator, wsdlvalinfo);
  77. rootImport.createWSDLImport(rootdoc);
  78. parsedImports.add(rootImport);
  79. List rootList = new ArrayList();
  80. filesImporting.put(rootImport.getLocation(), new ArrayList());
  81. rootList.add(rootdoc);
  82. filesAtDepth[0] = rootList;
  83. importsToParse.addAll(rootdoc.getImports());
  84. Set imps = rootdoc.getImports();
  85. Iterator impIter = imps.iterator();
  86. while(impIter.hasNext())
  87. {
  88. ImportHolder imp = (ImportHolder)impIter.next();
  89. List tempList = new ArrayList();
  90. tempList.add(imp.getImportingDocument());
  91. filesImporting.put(imp.getLocation(), tempList);
  92. }
  93. while(!importsToParse.isEmpty())
  94. {
  95. ImportHolder imp = (ImportHolder)importsToParse.first();
  96. // It's important to initialize the import here so each import
  97. // is only created once. In the case of reciprical imports this
  98. // avoids an infinite loop.
  99. imp.initialize();
  100. WSDLDocument impDoc = imp.getWSDLDocument();
  101. importsToParse.remove(imp);
  102. parsedImports.add(imp);
  103. // Add new imports to the list of imports to parse.
  104. // Remove all the imports that have already been parsed.
  105. if(impDoc != null)
  106. {
  107. // Increate import array if necessary.
  108. if(imp.getDepth() >= initialImportArraySize)
  109. {
  110. List[] tempArray = new List[filesAtDepth.length + initialImportArraySize];
  111. System.arraycopy(filesAtDepth, 0, tempArray, 0, filesAtDepth.length);
  112. filesAtDepth = tempArray;
  113. }
  114. // Create the list for the depth if necessary.
  115. int impDepth = imp.getDepth();
  116. if(filesAtDepth[impDepth] == null)
  117. {
  118. if(maxdepth < impDepth)
  119. {
  120. maxdepth = impDepth;
  121. }
  122. filesAtDepth[impDepth] = new ArrayList();
  123. }
  124. filesAtDepth[imp.getDepth()].add(impDoc);
  125. Set imports = impDoc.getImports();
  126. ImportHolder[] importsArray = (ImportHolder[])imports.toArray(new ImportHolder[imports.size()]);
  127. for(int i = 0; i < importsArray.length; i++)
  128. {
  129. ImportHolder ih = importsArray[i];
  130. // If already parsed, add the definition importing this file to the list.
  131. if(filesImporting.containsKey(ih.getLocation()))
  132. {
  133. ((List)filesImporting.get(ih.getLocation())).add(ih.getImportingDocument());
  134. }
  135. // Otherwise add it to the list to parse.
  136. else
  137. {
  138. // Add this import to the list of files importing list.
  139. List tempList = new ArrayList();
  140. tempList.add(ih.getImportingDocument());
  141. filesImporting.put(ih.getLocation(), tempList);
  142. importsToParse.add(ih);
  143. }
  144. }
  145. }
  146. }
  147. // Add all of the imports to the respective documents.
  148. Iterator importElementsIter = parsedImports.iterator();
  149. while(importElementsIter.hasNext())
  150. {
  151. ImportHolder imp = (ImportHolder)importElementsIter.next();
  152. List files = (List)filesImporting.get(imp.getLocation());
  153. Iterator filesIter = files.iterator();
  154. while(filesIter.hasNext())
  155. {
  156. WSDLDocument doc = (WSDLDocument)filesIter.next();
  157. DefinitionImpl def = (DefinitionImpl)doc.getDefinition();
  158. Import impElem = imp.getImport();
  159. if(impElem != null)
  160. {
  161. def.addImport(impElem);
  162. if(!imp.isWSDLFileImport())
  163. {
  164. doc.addSchemas(imp.getSchemas());
  165. }
  166. }
  167. }
  168. }
  169. // Parse the WSDL documents.
  170. // Parse the Messages.
  171. for(int i = maxdepth; i >=0; i--)
  172. {
  173. List docs = filesAtDepth[i];
  174. Iterator docsIter = docs.iterator();
  175. while(docsIter.hasNext())
  176. {
  177. WSDLDocument doc = (WSDLDocument)docsIter.next();
  178. doc.parseMessages();
  179. }
  180. }
  181. // Parse the Porttypes.
  182. for(int i = maxdepth; i >=0; i--)
  183. {
  184. List docs = filesAtDepth[i];
  185. Iterator docsIter = docs.iterator();
  186. while(docsIter.hasNext())
  187. {
  188. WSDLDocument doc = (WSDLDocument)docsIter.next();
  189. doc.parsePorttypes();
  190. }
  191. }
  192. // Parse the Bindings.
  193. for(int i = maxdepth; i >=0; i--)
  194. {
  195. List docs = filesAtDepth[i];
  196. Iterator docsIter = docs.iterator();
  197. while(docsIter.hasNext())
  198. {
  199. WSDLDocument doc = (WSDLDocument)docsIter.next();
  200. doc.parseBindings();
  201. }
  202. }
  203. // Parse the Services.
  204. for(int i = maxdepth; i >=0; i--)
  205. {
  206. List docs = filesAtDepth[i];
  207. Iterator docsIter = docs.iterator();
  208. while(docsIter.hasNext())
  209. {
  210. WSDLDocument doc = (WSDLDocument)docsIter.next();
  211. doc.parseServices();
  212. }
  213. }
  214. // Parse the Extensibility Elements.
  215. for(int i = maxdepth; i >=0; i--)
  216. {
  217. List docs = filesAtDepth[i];
  218. Iterator docsIter = docs.iterator();
  219. while(docsIter.hasNext())
  220. {
  221. WSDLDocument doc = (WSDLDocument)docsIter.next();
  222. doc.parseExtensibilityElements();
  223. }
  224. }
  225. List wsdlDocs = new ArrayList();
  226. for(int i = maxdepth; i >=0; i--)
  227. {
  228. List docs = filesAtDepth[i];
  229. Iterator docsIter = docs.iterator();
  230. while(docsIter.hasNext())
  231. {
  232. WSDLDocument doc = (WSDLDocument)docsIter.next();
  233. wsdlDocs.add(doc);
  234. }
  235. }
  236. return (WSDLDocument[])wsdlDocs.toArray(new WSDLDocument[wsdlDocs.size()]);
  237. }
  238. /**
  239. * Get the WSDL document.
  240. *
  241. * @param inputSource The source of the document being retrieved.
  242. * @param desc The description of the document being retrieved.
  243. * @return The WSDL document.
  244. * @throws WSDLException
  245. */
  246. public static Document getDocument(InputSource inputSource, String desc) throws WSDLException
  247. {
  248. try
  249. {
  250. StandardParserConfiguration configuration = new StandardParserConfiguration()
  251. {
  252. protected XMLErrorReporter createErrorReporter()
  253. {
  254. return new XMLErrorReporter()
  255. {
  256. public String reportError(String domain, String key, Object[] arguments, short severity) throws XNIException
  257. {
  258. if (key.equals("PrematureEOF"))
  259. {
  260. return ""; //not returning an error? I don't know circumstances, so just returning blank string
  261. }
  262. //otherwise error
  263. return super.reportError(domain, key, arguments, severity);
  264. }
  265. };
  266. }
  267. };
  268. ErrorHandler errorHandler = new ErrorHandler()
  269. {
  270. /* (non-Javadoc)
  271. * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
  272. */
  273. public void error(SAXParseException exception) throws SAXException
  274. {
  275. // TODO Auto-generated method stub
  276. }
  277. /* (non-Javadoc)
  278. * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
  279. */
  280. public void fatalError(SAXParseException exception) throws SAXException
  281. {
  282. // TODO Auto-generated method stub
  283. }
  284. /* (non-Javadoc)
  285. * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
  286. */
  287. public void warning(SAXParseException exception) throws SAXException
  288. {
  289. // TODO Auto-generated method stub
  290. }
  291. };
  292. DOMParser builder = new LineNumberDOMParser(configuration);
  293. builder.setErrorHandler(errorHandler);
  294. builder.parse(inputSource);
  295. Document doc = builder.getDocument();
  296. return doc;
  297. }
  298. catch (Throwable t)
  299. {
  300. throw new WSDLException(WSDLException.PARSER_ERROR, "Problem parsing '" + desc + "'.", t);
  301. }
  302. }
  303. /**
  304. * Read a WSDL document using a context URI and file URI.
  305. *
  306. * @param contextURI The context URI to use.
  307. * @param wsdlURI The WSDL URI to use.
  308. * @return An array of WSDLDocuments.
  309. * @throws WSDLException
  310. */
  311. public WSDLDocument[] readWSDL(String contextURI, String wsdlURI) throws WSDLException
  312. {
  313. try
  314. {
  315. URL contextURL = (contextURI != null) ? StringUtils.getURL(null, contextURI) : null;
  316. URL url = StringUtils.getURL(contextURL, wsdlURI);
  317. InputStream reader = StringUtils.getContentAsInputStream(url);
  318. InputSource inputSource = new InputSource(reader);
  319. Document doc = getDocument(inputSource, wsdlURI);
  320. reader.close();
  321. WSDLDocument[] wsdlDocs = null;
  322. // only parse the document if it isn't empty
  323. if(doc.getDocumentElement() != null)
  324. {
  325. wsdlDocs = readWSDL(url.toString(), doc);
  326. }
  327. return wsdlDocs;
  328. }
  329. catch (WSDLException e)
  330. {
  331. throw e;
  332. }
  333. catch (Throwable t)
  334. {
  335. throw new WSDLException(
  336. WSDLException.OTHER_ERROR,
  337. "Unable to resolve imported document at '" + wsdlURI + "'.",
  338. t);
  339. }
  340. }
  341. /**
  342. * Set the messagegenerator for the reader.
  343. *
  344. * @param mg The message generator to set.
  345. */
  346. public void setMessageGenerator(MessageGenerator mg)
  347. {
  348. messagegenerator = mg;
  349. }
  350. /**
  351. * Read the WSDL document accessible via the specified
  352. * URI into a WSDL definition.
  353. *
  354. * @param wsdlURI A URI pointing to a WSDL file.
  355. * @return An array of WSDLDocuments.
  356. */
  357. public WSDLDocument[] readWSDL(String wsdlURI) throws WSDLException
  358. {
  359. return readWSDL(null, wsdlURI);
  360. }
  361. /**
  362. * Read the WSDL document described by a URI and its definitions element.
  363. *
  364. * @param documentBaseURI The URI of the WSDL document.
  365. * @param definitionsElement The definitions element for the WSDL document.
  366. * @return An array of WSDLDocuments.
  367. * @throws WSDLException
  368. */
  369. protected WSDLDocument[] readWSDL(String documentBaseURI,
  370. Element definitionsElement)
  371. throws WSDLException
  372. {
  373. return parseDocument(documentBaseURI, definitionsElement);
  374. }
  375. /**
  376. * Read the specified WSDL document.
  377. *
  378. * @param documentBaseURI The document base URI.
  379. * @param wsdlDocument The WSDL document.
  380. * @return An array of WSDLDocuments.
  381. */
  382. public WSDLDocument[] readWSDL(String documentBaseURI, Document wsdlDocument)
  383. throws WSDLException
  384. {
  385. return readWSDL(documentBaseURI, wsdlDocument.getDocumentElement());
  386. }
  387. }