1 package org.netbeans.modules.xml.wsdl.validator; 2 3 import java.io.File ; 4 import java.io.FileInputStream ; 5 import java.io.FileNotFoundException ; 6 import java.io.InputStream ; 7 import java.io.Reader ; 8 import java.io.StringReader ; 9 import java.net.URI ; 10 import java.net.URISyntaxException ; 11 import java.util.ArrayList ; 12 import java.util.Collection ; 13 import java.util.Collections ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 import java.util.Map ; 17 import java.util.Vector ; 18 import java.util.logging.Level ; 19 import java.util.logging.Logger ; 20 import java.util.regex.Matcher ; 21 import java.util.regex.Pattern ; 22 23 import javax.swing.text.BadLocationException ; 24 import javax.swing.text.Document ; 25 import javax.xml.XMLConstants ; 26 import javax.xml.parsers.DocumentBuilderFactory ; 27 import javax.xml.parsers.ParserConfigurationException ; 28 import javax.xml.transform.Source ; 29 import javax.xml.transform.sax.SAXSource ; 30 import javax.xml.validation.Schema ; 31 import javax.xml.validation.SchemaFactory ; 32 import org.netbeans.modules.xml.schema.model.SchemaModel; 33 34 import org.netbeans.modules.xml.schema.model.SchemaModelFactory; 35 import org.netbeans.modules.xml.wsdl.model.Definitions; 36 import org.netbeans.modules.xml.wsdl.model.Types; 37 import org.netbeans.modules.xml.wsdl.model.WSDLModel; 38 import org.netbeans.modules.xml.wsdl.model.extensions.xsd.WSDLSchema; 39 import org.netbeans.modules.xml.xam.Model; 40 import org.netbeans.modules.xml.xam.ModelSource; 41 import org.netbeans.modules.xml.xam.Model.State; 42 import org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent; 43 import org.netbeans.modules.xml.xam.dom.DocumentModel; 44 import org.netbeans.modules.xml.xam.locator.CatalogModel; 45 import org.netbeans.modules.xml.xam.locator.CatalogModelException; 46 import org.netbeans.modules.xml.xam.locator.CatalogModelFactory; 47 import org.netbeans.modules.xml.xam.spi.Validation; 48 import org.netbeans.modules.xml.xam.spi.ValidationResult; 49 import org.netbeans.modules.xml.xam.spi.Validator; 50 import org.netbeans.modules.xml.xam.spi.XsdBasedValidator; 51 import org.netbeans.modules.xml.xam.spi.Validation.ValidationType; 52 import org.w3c.dom.DOMImplementation ; 53 import org.w3c.dom.ls.DOMImplementationLS ; 54 import org.w3c.dom.ls.LSInput ; 55 import org.w3c.dom.ls.LSResourceResolver ; 56 import org.xml.sax.InputSource ; 57 import org.xml.sax.SAXException ; 58 59 public class WSDLInlineSchemaValidator extends XsdBasedValidator { 60 61 @SuppressWarnings ("unchecked") 62 public static final ValidationResult EMPTY_RESULT = 63 new ValidationResult( Collections.EMPTY_SET, 64 Collections.EMPTY_SET); 65 66 public String getName() { 67 return "WSDLInlineSchemaValidator"; } 69 70 @Override 71 public ValidationResult validate(Model model, Validation validation, 72 ValidationType validationType) { 73 if (model instanceof WSDLModel) { 74 WSDLModel wsdlModel = (WSDLModel) model; 75 76 List <Model> validatedModels = new ArrayList <Model>(); 77 Vector <ResultItem> resultItems = new Vector <ResultItem>(); 78 if (validationType.equals(ValidationType.COMPLETE) || 79 validationType.equals(ValidationType.PARTIAL)) { 80 81 if (wsdlModel.getState() == State.NOT_WELL_FORMED) { 82 return EMPTY_RESULT; 83 } 84 85 Definitions def = wsdlModel.getDefinitions(); 86 Map <String , String > prefixes = ((AbstractDocumentComponent)def).getPrefixes(); 87 String systemId = getSystemId(wsdlModel); 88 Types types = def.getTypes(); 89 if (types != null) { 90 Collection <WSDLSchema> schemas = types.getExtensibilityElements(WSDLSchema.class); 91 92 String text = getWSDLText(wsdlModel); 93 94 assert text != null : "there is no content in the wsdl document or couldnt be read"; 95 96 List <Integer > linePositions = setupLinePositions(text); 97 98 WSDLLSResourceResolver resolver = new WSDLLSResourceResolver(wsdlModel, 99 systemId, 100 text, 101 prefixes, 102 linePositions); 103 104 for (WSDLSchema schema : schemas) { 105 Reader in = createInlineSchemaSource(text, prefixes, linePositions, schema); 106 if(in != null) { 107 SAXSource source = new SAXSource (new InputSource (in)); 108 source.setSystemId(systemId); 109 int start = schema.findPosition(); 110 int lineNumber = getLineNumber(start, linePositions); 112 Handler handler = new InlineSchemaValidatorHandler(wsdlModel, lineNumber); 114 validate(wsdlModel, source, handler, resolver); 115 resultItems.addAll(handler.getResultItems()); 116 } 117 } 118 119 120 validatedModels.add(model); 121 return new ValidationResult(resultItems, validatedModels); 122 } 123 } 124 } 125 return new ValidationResult(new ArrayList <ResultItem>(), new ArrayList <Model>()); 126 } 127 128 private String getSystemId(WSDLModel model) { 129 Source source = (Source ) model.getModelSource().getLookup().lookup(Source .class); 130 131 if(source == null) { 133 File file = (File ) model.getModelSource().getLookup().lookup(File .class); 134 if(file != null) { 135 try { 136 source = new SAXSource (new InputSource (new FileInputStream (file))); 137 } catch (FileNotFoundException ex) { 138 Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getSystemId", ex); } 140 } 141 } 142 143 if (source != null) { 144 return source.getSystemId(); 145 } 146 return null; 147 148 } 149 150 private void validate(WSDLModel model, 151 Source saxSource, 152 XsdBasedValidator.Handler handler, 153 LSResourceResolver resolver) { 154 try { 155 SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 156 if (resolver != null) { 157 sf.setResourceResolver(resolver); 158 } 159 sf.setErrorHandler(handler); 160 if (saxSource == null) { 161 return; 162 } 163 sf.newSchema(saxSource); 164 } catch(SAXException sax) { 165 } catch(Exception ex) { 167 handler.logValidationErrors(Validator.ResultType.ERROR, ex.getMessage()); 168 } 169 } 170 171 175 Pattern pattern = Pattern.compile("(<\\s*)(\\S*schema)(\\s*)"); 176 177 private String getEndTag(String startTag) { 178 Matcher matcher = pattern.matcher(startTag); 179 if (matcher.find()) { 180 return "</" + matcher.group(2) + ">"; } 182 return null; 183 } 184 185 private List <Integer > setupLinePositions(String str) { 186 List <Integer > linePositions = new ArrayList <Integer >(); 187 String [] lines = str.split("\n"); linePositions.add(Integer.valueOf(-1)); 189 int pos = 0; 190 for (String line : lines) { 191 linePositions.add(pos); 192 pos += line.length() + 1; } 194 return linePositions; 195 } 196 197 private int getLineNumber(int position, List <Integer > linePositions) { 198 for (int i = 0; i < linePositions.size(); i++) { 199 if (position < linePositions.get(i).intValue()) { 200 return i - 1; 201 } 202 } 203 return -1; 204 205 } 206 207 208 class InlineSchemaValidatorHandler extends XsdBasedValidator.Handler { 209 int startingLineNumber; 210 public InlineSchemaValidatorHandler(Model model, int lineNumber) { 211 super(model); 212 startingLineNumber = lineNumber - 1; 213 } 214 215 @Override 216 public void logValidationErrors(ResultType resultType, String errorDescription, int lineNumber, int columnNumber) { 217 super.logValidationErrors(resultType, errorDescription, startingLineNumber + lineNumber, 218 columnNumber); 219 } 220 221 222 223 } 224 225 @Override 226 protected Schema getSchema(Model model) { 227 return null; 229 } 230 231 private String getWSDLText(WSDLModel model) { 232 javax.swing.text.Document d = (Document ) model.getModelSource().getLookup().lookup(Document .class); 233 try { 234 return d.getText(0, d.getLength()); 235 } catch (BadLocationException e) { 236 Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getWSDLText", e); } 239 return null; 240 } 241 242 @Override 243 public DocumentModel resolveResource(String systemId, Model currentModel) { 244 if (currentModel instanceof WSDLModel && systemId.equals(getSystemId((WSDLModel)currentModel))) { 245 return (WSDLModel) currentModel; 246 } 247 try { 248 CatalogModel cm = (CatalogModel) currentModel.getModelSource().getLookup() 249 .lookup(CatalogModel.class); 250 ModelSource ms = cm.getModelSource(new URI (systemId)); 251 if (ms != null) { 252 return SchemaModelFactory.getDefault().getModel(ms); 253 } 254 } catch(URISyntaxException ex) { 255 Logger.getLogger(getClass().getName()).log(Level.FINE, "resolveResource", ex); } catch(CatalogModelException ex) { 257 Logger.getLogger(getClass().getName()).log(Level.FINE, "resolveResource", ex); } 259 return null; 260 } 261 262 private Reader createInlineSchemaSource(String wsdlText, 263 Map <String , String > wsdlPrefixes, 264 List <Integer > wsdlLinePositions, 265 WSDLSchema oneInlineSchema) { 266 Reader source = null; 267 int start = oneInlineSchema.findPosition(); 268 int lineNumber = getLineNumber(start, wsdlLinePositions); String schemaString = oneInlineSchema.getContentFragment(); int index = wsdlText.indexOf(schemaString, start); 271 if (schemaString != null && schemaString.trim().length() > 0) { assert index != -1 : "the text content under schema couldnt be found in the wsdl document"; 273 String schemaTop = wsdlText.substring(start, index); String [] splits = schemaTop.split(">"); 275 StringBuffer strBuf = new StringBuffer (); 276 if (splits.length > 0) { 277 strBuf.append(splits[0]); 278 Map <String , String > schemaPrefixes = ((AbstractDocumentComponent)oneInlineSchema.getSchemaModel().getSchema()).getPrefixes(); 279 for (String prefix : wsdlPrefixes.keySet()) { 280 if (!(prefix == null || prefix.length() == 0 || schemaPrefixes.containsKey(prefix))) { 281 strBuf.append(" ").append("xmlns:").append(prefix).append("=\"").append(wsdlPrefixes.get(prefix)).append("\""); 282 } 283 } 284 285 for (int i = 1; i < splits.length; i++) { 286 strBuf.append(">").append(splits[i]); 287 } 288 strBuf.append(">"); 289 strBuf.append(schemaString).append(getEndTag(splits[0])); 290 schemaString = null; 291 splits = null; 292 schemaTop = null; 293 } 294 295 296 source = new StringReader (strBuf.toString()); 297 strBuf = null; 299 } 300 301 return source; 302 } 303 304 class WSDLLSResourceResolver implements LSResourceResolver { 305 306 private WSDLModel mModel; 307 308 private LSResourceResolver mDelegate; 309 310 private String mWsdlSystemId; 311 private String mWsdlText; 312 private Map <String , String > mWsdlPrefixes; 313 private List <Integer > mWsdlLinePositions; 314 315 public WSDLLSResourceResolver(WSDLModel wsdlmodel, 316 String wsdlSystemId, 317 String wsdlText, 318 Map <String , String > wsdlPrefixes, 319 List <Integer > wsdlLinePositions) { 320 mModel = wsdlmodel; 321 mWsdlSystemId = wsdlSystemId; 322 mWsdlText = wsdlText; 323 mWsdlPrefixes = wsdlPrefixes; 324 mWsdlLinePositions = wsdlLinePositions; 325 326 mDelegate = CatalogModelFactory.getDefault().getLSResourceResolver(); 327 328 } 329 public LSInput resolveResource(String type, 330 String namespaceURI, 331 String publicId, 332 String systemId, 333 String baseURI) { 334 335 LSInput lsi = mDelegate.resolveResource(type, namespaceURI, publicId, systemId, baseURI); 336 if(lsi == null) { 337 WSDLSchema schema = findSchema(namespaceURI); 341 if(schema != null) { 342 Reader in = createInlineSchemaSource(mWsdlText, mWsdlPrefixes, mWsdlLinePositions, schema); 343 if(in != null) { 344 DOMImplementation domImpl = null; 346 try { 347 domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation(); 348 } catch (ParserConfigurationException ex) { 349 Logger.getLogger(getClass().getName()).log(Level.SEVERE, "resolveResource", ex); return null; 351 } 352 353 DOMImplementationLS dols = (DOMImplementationLS ) domImpl.getFeature("LS","3.0"); 354 lsi = dols.createLSInput(); 355 if(in != null) { 356 lsi.setCharacterStream(in); 357 } 358 359 if(mWsdlSystemId != null) { 360 lsi.setSystemId(mWsdlSystemId); 361 } 362 return lsi; 363 } 364 } 365 } 366 return lsi; 367 } 368 369 private WSDLSchema findSchema(String namespaceURI) { 370 WSDLSchema schema = null; 371 Definitions def = mModel.getDefinitions(); 372 Types types = def.getTypes(); 373 if (types != null) { 374 Collection <WSDLSchema> schemas = types.getExtensibilityElements(WSDLSchema.class); 375 Iterator <WSDLSchema> it = schemas.iterator(); 376 while(it.hasNext()) { 377 WSDLSchema sch = it.next(); 378 SchemaModel model = sch.getSchemaModel(); 379 if(model != null) { 380 org.netbeans.modules.xml.schema.model.Schema s = model.getSchema(); 381 if(s != null && s.getTargetNamespace() != null && s.getTargetNamespace().equals(namespaceURI)) { 382 schema = sch; 383 break; 384 } 385 } 386 } 387 } 388 389 return schema; 390 } 391 392 } 393 } 394 | Popular Tags |