1 19 package org.netbeans.modules.xml.xam.spi; 20 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.FileNotFoundException ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.Collections ; 29 import java.util.HashMap ; 30 import java.util.List ; 31 import java.util.logging.Level ; 32 import java.util.logging.Logger ; 33 import javax.swing.text.BadLocationException ; 34 import javax.swing.text.Document ; 35 import javax.xml.XMLConstants ; 36 import javax.xml.transform.Source ; 37 import javax.xml.transform.dom.DOMSource ; 38 import javax.xml.transform.sax.SAXSource ; 39 import javax.xml.transform.stream.StreamSource ; 40 import javax.xml.validation.Schema ; 41 import javax.xml.validation.SchemaFactory ; 42 import org.netbeans.modules.xml.xam.Component; 43 import org.netbeans.modules.xml.xam.Model; 44 import org.netbeans.modules.xml.xam.dom.AbstractDocumentModel; 45 import org.netbeans.modules.xml.xam.dom.DocumentModel; 46 import org.netbeans.modules.xml.xam.spi.Validator.ResultItem; 47 import org.openide.util.NbBundle; 48 import org.w3c.dom.ls.LSResourceResolver ; 49 import org.xml.sax.ErrorHandler ; 50 import org.xml.sax.InputSource ; 51 import org.xml.sax.SAXException ; 52 import org.xml.sax.SAXParseException ; 53 54 60 public abstract class XsdBasedValidator implements Validator { 61 62 63 64 public XsdBasedValidator() { 65 } 66 67 68 69 70 77 abstract protected Schema getSchema(Model model); 78 79 80 87 public ValidationResult validate(Model model, Validation validation, Validation.ValidationType validationType) { 88 Collection <ResultItem> results = Collections.emptyList(); 89 List <Model> validateds = Collections.emptyList(); 90 Schema schema = getSchema(model); 91 if (schema == null) { 92 return new ValidationResult(results, validateds); 93 } 94 95 Handler handler = new Handler (model); 96 validate(model, schema, handler); 97 results = handler.getResultItems(); 98 validateds = Collections.singletonList(model); 99 100 return new ValidationResult(results, validateds); 101 } 102 103 104 105 111 protected Source getSource(Model model, Handler handler) { 112 Source source = (Source ) model.getModelSource().getLookup().lookup(Source .class); 113 114 if(source == null) { 116 File file = (File ) model.getModelSource().getLookup().lookup(File .class); 117 if(file != null) { 118 try { 119 source = new SAXSource (new InputSource (new FileInputStream (file))); 120 source.setSystemId(file.toURI().toString()); 121 } catch (FileNotFoundException ex) { 122 } 124 } 125 } 126 127 if (source == null) { 128 String msg = NbBundle.getMessage(XsdBasedValidator.class, "MSG_NoSAXSource"); 129 handler.logValidationErrors(Validator.ResultType.WARNING, msg); 130 } 131 return source; 132 } 133 134 135 136 142 protected void validate(Model model, Schema schema, Handler handler) { 143 144 javax.xml.validation.Validator validator = schema.newValidator(); 145 Source source = getSource(model, handler); 146 147 if(source != null) { 148 validator.setErrorHandler(handler); 149 150 assert ((source instanceof SAXSource ) || (source instanceof DOMSource )): 152 "Source is not instance of SAXSource or DOMSource"; 154 try { 155 validator.validate(source); 156 } catch (IOException ex) { 157 Logger.getLogger(getClass().getName()).log(Level.FINE, "validate", ex); 158 } catch (SAXException ex) { 159 } 162 } 163 } 164 165 166 172 protected Schema getCompiledSchema(InputStream [] schemas, 173 LSResourceResolver lsResourceResolver) { 174 175 Schema schema = null; 176 StreamSource [] schemaStreamSources = new StreamSource [schemas.length]; 178 for(int index1=0 ; index1<schemas.length ; index1++) 179 schemaStreamSources[index1] = new StreamSource (schemas[index1]); 180 181 SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 183 schemaFactory.setResourceResolver(lsResourceResolver); 184 try { 185 schema = schemaFactory.newSchema(schemaStreamSources); 186 } catch(SAXException ex) { 187 Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getCompiledSchema", ex); 188 } 189 190 return schema; 191 } 192 193 protected Schema getCompiledSchema(Source [] schemas, 194 LSResourceResolver lsResourceResolver, 195 ErrorHandler errorHandler) { 196 197 Schema schema = null; 198 199 SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 201 schemaFactory.setResourceResolver(lsResourceResolver); 202 schemaFactory.setErrorHandler(errorHandler); 203 try { 204 schema = schemaFactory.newSchema(schemas); 205 } catch(SAXException ex) { 206 Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getCompiledSchema", ex); 207 } 208 209 return schema; 210 } 211 212 215 protected class Handler implements ErrorHandler { 216 private Collection <ResultItem> resultItems; 217 private List <Integer > linePositions = null; 218 private DocumentModel model; 219 private HashMap <DocumentModel,Handler > relatedHandlers = new HashMap <DocumentModel,Handler >(); 220 221 225 public Handler(Model model) { 226 assert model instanceof DocumentModel : "Invalid model class"; resultItems = new ArrayList <ResultItem>(); 228 this.model = (DocumentModel) model; 229 } 230 231 235 public Collection <ResultItem> getResultItems() { 236 addResultsFromHandlers(relatedHandlers.values()); 237 return resultItems; 238 } 239 240 247 public void addResultsFromHandlers(Collection <Handler > handlers) { 248 for(Handler handler: handlers) { 249 resultItems.addAll(handler.getResultItems()); 250 } 251 } 252 253 254 255 private void setupLinePositions() { 256 linePositions = new ArrayList <Integer >(); 257 Document document = ((AbstractDocumentModel) model).getBaseDocument(); 258 if (document == null) { 259 return; 260 } 261 try { 262 String str = document.getText(0, document.getLength() - 1); 263 String [] lines = str.split("\n"); linePositions.add(Integer.valueOf(-1)); 265 int pos = 0; 266 for (String line : lines) { 267 linePositions.add(pos); 268 pos += line.length() + 1; } 270 } catch (BadLocationException e) { 271 Logger.getLogger(getClass().getName()).log(Level.FINE, "setupLinePositions", e); } 273 } 274 275 279 private int getPosition(int lineNumber, int columnNumber) { 280 if (linePositions == null) { 281 setupLinePositions(); 282 } 283 if (lineNumber < 1 || lineNumber > linePositions.size()) { 284 return 0; 285 } 286 Integer beginningPos = linePositions.get(lineNumber); 287 return beginningPos == null ? 0 : beginningPos.intValue() + columnNumber-1; 288 } 289 290 295 public void error(SAXParseException exception) throws SAXException { 296 logValidationErrors( Validator.ResultType.ERROR, exception); 297 } 298 299 304 public void fatalError(SAXParseException exception) throws SAXException { 305 logValidationErrors( Validator.ResultType.ERROR, exception); 306 } 307 308 313 public void warning(SAXParseException exception) throws SAXException { 314 logValidationErrors( Validator.ResultType.WARNING, exception); 315 } 316 317 public void logValidationErrors(Validator.ResultType resultType, SAXParseException sax) { 318 String systemId = sax.getSystemId(); 319 DocumentModel errorModel = null; 320 if (systemId != null) { 321 errorModel = resolveResource(systemId, model); 322 } 323 324 Handler h = null; 325 if (errorModel != null && model != errorModel) { 326 h = relatedHandlers.get(errorModel); 327 if (h == null) { 328 h = new Handler (errorModel); 329 relatedHandlers.put(errorModel, h); 330 } 331 } 332 333 if (h == null) { 334 h = this; 335 } 336 h.logValidationErrors(resultType, sax.getMessage(), sax.getLineNumber(), sax.getColumnNumber()-1); 337 } 338 339 346 public void logValidationErrors(Validator.ResultType resultType, 347 String errorDescription, 348 int lineNumber, 349 int columnNumber) { 350 351 if(columnNumber <= 0) 353 columnNumber = 1; 354 355 if(model.getState().equals(Model.State.VALID)) { 358 int position = getPosition(lineNumber, columnNumber); 359 assert position >= 0 : "Invalid position value "+position; 360 Component component = model.findComponent(position); 361 if (component == null) { 362 component = model.getRootComponent(); 363 } 364 resultItems.add(new ResultItem( 365 XsdBasedValidator.this, resultType, component, errorDescription)); 366 } else { 367 resultItems.add(new ResultItem(XsdBasedValidator.this, resultType, 368 errorDescription, lineNumber, columnNumber, model)); 369 } 370 } 371 372 377 public void logValidationErrors(Validator.ResultType resultType, String errorDescription) { 378 logValidationErrors(resultType, errorDescription,1,1); 379 } 380 } 381 382 public DocumentModel resolveResource(String systemId, Model currentModel) { 383 return null; 384 } 385 386 } 387 | Popular Tags |