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