KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > xam > spi > XsdBasedValidator


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.xml.xam.spi;
20
21 import java.io.File JavaDoc;
22 import java.io.FileInputStream JavaDoc;
23 import java.io.FileNotFoundException JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.logging.Level JavaDoc;
32 import java.util.logging.Logger JavaDoc;
33 import javax.swing.text.BadLocationException JavaDoc;
34 import javax.swing.text.Document JavaDoc;
35 import javax.xml.XMLConstants JavaDoc;
36 import javax.xml.transform.Source JavaDoc;
37 import javax.xml.transform.dom.DOMSource JavaDoc;
38 import javax.xml.transform.sax.SAXSource JavaDoc;
39 import javax.xml.transform.stream.StreamSource JavaDoc;
40 import javax.xml.validation.Schema JavaDoc;
41 import javax.xml.validation.SchemaFactory JavaDoc;
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 JavaDoc;
49 import org.xml.sax.ErrorHandler JavaDoc;
50 import org.xml.sax.InputSource JavaDoc;
51 import org.xml.sax.SAXException JavaDoc;
52 import org.xml.sax.SAXParseException JavaDoc;
53
54 /**
55  * Base class for Schema validator. Each domain specific schema validator can extend this.
56  * @author Shivanand Kini
57  * @author Nam Nguyen
58  * @author Praveen Savur
59  */

60 public abstract class XsdBasedValidator implements Validator {
61     
62    
63     /** Creates a new instance of XsdBasedValidation */
64     public XsdBasedValidator() {
65     }
66     
67     
68     
69     
70     /**
71      * Get Schemas that the model has to be validated against.
72      * Returns compiled Schema to be used in validation of the given
73      * model; or null if this validator does not know how to validate the model.
74      * @param model Get Schemas that the model has to be validated against.
75      * @return Compiled Schema object.
76      */

77     abstract protected Schema JavaDoc getSchema(Model model);
78     
79     
80     /**
81      * Entry point to validate a model.
82      * @param model Model to validate.
83      * @param validation Reference to Validation object.
84      * @param validationType Type of validation. Complete(slow) or partial(fast).
85      * @return ValidationResults.
86      */

87     public ValidationResult validate(Model model, Validation validation, Validation.ValidationType validationType) {
88         Collection JavaDoc<ResultItem> results = Collections.emptyList();
89         List JavaDoc<Model> validateds = Collections.emptyList();
90         Schema JavaDoc schema = getSchema(model);
91         if (schema == null) {
92             return new ValidationResult(results, validateds);
93         }
94         
95         Handler JavaDoc handler = new Handler JavaDoc(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     /**
106      *
107      * @param model
108      * @param handler
109      * @return Source input source stream for the validation.
110      */

111     protected Source JavaDoc getSource(Model model, Handler JavaDoc handler) {
112         Source JavaDoc source = (Source JavaDoc) model.getModelSource().getLookup().lookup(Source JavaDoc.class);
113
114         // Try to get Source via File from lookup.
115
if(source == null) {
116             File JavaDoc file = (File JavaDoc) model.getModelSource().getLookup().lookup(File JavaDoc.class);
117             if(file != null) {
118                 try {
119                     source = new SAXSource JavaDoc(new InputSource JavaDoc(new FileInputStream JavaDoc(file)));
120             source.setSystemId(file.toURI().toString());
121                 } catch (FileNotFoundException JavaDoc ex) {
122                     // catch error.
123
}
124             }
125         }
126         
127         if (source == null) {
128             String JavaDoc msg = NbBundle.getMessage(XsdBasedValidator.class, "MSG_NoSAXSource");
129             handler.logValidationErrors(Validator.ResultType.WARNING, msg);
130         }
131         return source;
132     }
133     
134     
135     
136     /**
137      * Validates the model against the schema. Errors are sent to the handler.
138      * @param model Model to be validated.
139      * @param schema Compiled schema against which the model is validated.
140      * @param handler Handler to receive validation messages.
141      */

142     protected void validate(Model model, Schema JavaDoc schema, Handler JavaDoc handler) {
143
144         javax.xml.validation.Validator JavaDoc validator = schema.newValidator();
145         Source JavaDoc source = getSource(model, handler);
146         
147         if(source != null) {
148             validator.setErrorHandler(handler);
149             
150             // validate needs SAX or DOMSource.
151
assert ((source instanceof SAXSource JavaDoc) || (source instanceof DOMSource JavaDoc)):
152                 "Source is not instance of SAXSource or DOMSource"; // NOI18N
153

154             try {
155                 validator.validate(source);
156             } catch (IOException JavaDoc ex) {
157                 Logger.getLogger(getClass().getName()).log(Level.FINE, "validate", ex);
158             } catch (SAXException JavaDoc ex) {
159                 // If there is a fatal error (for example not well formed xml),
160
// a SAXException is thrown. Simply ignore this error.
161
}
162         }
163     }
164     
165     
166     /**
167      * Subclasses can use this to get a compiled schema object.
168      * @param schemas Input stream of schemas.
169      * @param lsResourceResolver resolver can be supplied optionally. Otherwise pass null.
170      * @return Compiled Schema object.
171      */

172     protected Schema JavaDoc getCompiledSchema(InputStream JavaDoc[] schemas,
173             LSResourceResolver JavaDoc lsResourceResolver) {
174         
175         Schema JavaDoc schema = null;
176         // Convert InputStream[] to StreamSource[]
177
StreamSource JavaDoc[] schemaStreamSources = new StreamSource JavaDoc[schemas.length];
178         for(int index1=0 ; index1<schemas.length ; index1++)
179             schemaStreamSources[index1] = new StreamSource JavaDoc(schemas[index1]);
180         
181         // Create a compiled Schema object.
182
SchemaFactory JavaDoc schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
183         schemaFactory.setResourceResolver(lsResourceResolver);
184         try {
185             schema = schemaFactory.newSchema(schemaStreamSources);
186         } catch(SAXException JavaDoc ex) {
187             Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getCompiledSchema", ex);
188         }
189         
190         return schema;
191     }
192     
193     protected Schema JavaDoc getCompiledSchema(Source JavaDoc[] schemas,
194             LSResourceResolver JavaDoc lsResourceResolver,
195             ErrorHandler JavaDoc errorHandler) {
196         
197         Schema JavaDoc schema = null;
198         
199         // Create a compiled Schema object.
200
SchemaFactory JavaDoc 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 JavaDoc ex) {
206             Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getCompiledSchema", ex);
207         }
208         
209         return schema;
210     }
211     
212     /**
213      * Handler to receive parse events.
214      */

215     protected class Handler implements ErrorHandler JavaDoc {
216         private Collection JavaDoc<ResultItem> resultItems;
217         private List JavaDoc<Integer JavaDoc> linePositions = null;
218         private DocumentModel model;
219         private HashMap JavaDoc<DocumentModel,Handler JavaDoc> relatedHandlers = new HashMap JavaDoc<DocumentModel,Handler JavaDoc>();
220         
221         /**
222          * Constructor to create a SAX Error Handler.
223          * @param model Model which is being validated.
224          */

225         public Handler(Model model) {
226             assert model instanceof DocumentModel : "Invalid model class"; //NOI18N
227
resultItems = new ArrayList JavaDoc<ResultItem>();
228             this.model = (DocumentModel) model;
229         }
230         
231         /**
232          * Return validation results.
233          * @return Return results.
234          */

235         public Collection JavaDoc<ResultItem> getResultItems() {
236             addResultsFromHandlers(relatedHandlers.values());
237             return resultItems;
238         }
239         
240         /**
241          * Adds resultItems from the handler collection to the resultItems of the
242          * current handler. One user of this will be the schema validator
243          * (which will use a handler instance for each model)
244          * and will pass in the list of handlers it has created.
245          * @param handlers Handlers from which resultItems have to be collected.
246          */

247         public void addResultsFromHandlers(Collection JavaDoc<Handler JavaDoc> handlers) {
248             for(Handler JavaDoc handler: handlers) {
249                 resultItems.addAll(handler.getResultItems());
250             }
251         }
252         
253         
254         
255         private void setupLinePositions() {
256             linePositions = new ArrayList JavaDoc<Integer JavaDoc>();
257             Document JavaDoc document = ((AbstractDocumentModel) model).getBaseDocument();
258             if (document == null) {
259                 return;
260             }
261             try {
262                 String JavaDoc str = document.getText(0, document.getLength() - 1);
263                 String JavaDoc[] lines = str.split("\n"); //NOI18N
264
linePositions.add(Integer.valueOf(-1));
265                 int pos = 0;
266                 for (String JavaDoc line : lines) {
267                     linePositions.add(pos);
268                     pos += line.length() + 1; // make sure we also count the \n
269
}
270             } catch (BadLocationException JavaDoc e) {
271                 Logger.getLogger(getClass().getName()).log(Level.FINE, "setupLinePositions", e); //NOI18N
272
}
273         }
274         
275         /**
276          * Given 1-based line number and 1-based column number,
277          * @returns 0-base position.
278          */

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 JavaDoc beginningPos = linePositions.get(lineNumber);
287             return beginningPos == null ? 0 : beginningPos.intValue() + columnNumber-1;
288         }
289         
290         /**
291          *
292          * @param exception
293          * @throws org.xml.sax.SAXException
294          */

295         public void error(SAXParseException JavaDoc exception) throws SAXException JavaDoc {
296             logValidationErrors( Validator.ResultType.ERROR, exception);
297         }
298         
299         /**
300          *
301          * @param exception
302          * @throws org.xml.sax.SAXException
303          */

304         public void fatalError(SAXParseException JavaDoc exception) throws SAXException JavaDoc {
305             logValidationErrors( Validator.ResultType.ERROR, exception);
306         }
307         
308         /**
309          *
310          * @param exception
311          * @throws org.xml.sax.SAXException
312          */

313         public void warning(SAXParseException JavaDoc exception) throws SAXException JavaDoc {
314             logValidationErrors( Validator.ResultType.WARNING, exception);
315         }
316         
317         public void logValidationErrors(Validator.ResultType resultType, SAXParseException JavaDoc sax) {
318             String JavaDoc systemId = sax.getSystemId();
319             DocumentModel errorModel = null;
320             if (systemId != null) {
321                 errorModel = resolveResource(systemId, model);
322             }
323             
324             Handler JavaDoc h = null;
325             if (errorModel != null && model != errorModel) {
326                 h = relatedHandlers.get(errorModel);
327                 if (h == null) {
328                     h = new Handler JavaDoc(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         /**
340          *
341          * @param resultType
342          * @param errorDescription
343          * @param lineNumber
344          * @param columnNumber
345          */

346         public void logValidationErrors(Validator.ResultType resultType,
347                 String JavaDoc errorDescription,
348                 int lineNumber,
349                 int columnNumber) {
350             
351             // Double check if columnNumber becomes invalid.
352
if(columnNumber <= 0)
353                 columnNumber = 1;
354             
355             // Create Result Item using a constructor based on whether
356
// model is valid or not.
357
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         /**
373          *
374          * @param resultType
375          * @param errorDescription
376          */

377         public void logValidationErrors(Validator.ResultType resultType, String JavaDoc errorDescription) {
378             logValidationErrors(resultType, errorDescription,1,1);
379         }
380     }
381
382     public DocumentModel resolveResource(String JavaDoc systemId, Model currentModel) {
383         return null;
384     }
385     
386 }
387
Popular Tags