KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > schema > cookies > ValidateSchemaSupport


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
20 package org.netbeans.modules.xml.schema.cookies;
21
22 import java.io.*;
23 import java.net.*;
24
25 import org.xml.sax.*;
26
27 import org.netbeans.spi.xml.cookies.*;
28 import org.netbeans.api.xml.parsers.SAXEntityParser;
29 import org.netbeans.api.xml.services.UserCatalog;
30 import org.openide.xml.XMLUtil;
31 import org.xml.sax.helpers.DefaultHandler JavaDoc;
32
33 /**
34  * CheckXMLCookie and ValidateXMLCookie implementation for XML Schemas.
35  *
36  * @author Petr Kuzel
37  */

38 public final class ValidateSchemaSupport extends ValidateXMLSupport {
39     
40     /** Creates a new instance of CheckSchemaSupport */
41     public ValidateSchemaSupport(InputSource inputSource) {
42         super( inputSource);
43     }
44
45     /**
46      * In validating mode create XMLReader able to parse XML Schemas.
47      */

48     protected XMLReader createParser(boolean validate) {
49         final String JavaDoc XERCES_FEATURE_PREFIX = "http://apache.org/xml/features/"; // NOI18N
50

51         XMLReader parser = super.createParser(validate);
52         if (parser == null) return null;
53         
54         // for validaton use wrapping parser
55
if (validate) {
56             // we urgently need XML Schema aware parser
57
try {
58                 if (parser.getFeature(XERCES_FEATURE_PREFIX + "validation/schema") == false) { // NOI18N
59
//??? try get Xerces explicitly, no such library except ou outdate X2b4 exists
60
return null;
61                 } else {
62                     // check all schema oddities with Xerces parser
63
parser.setFeature(XERCES_FEATURE_PREFIX + "validation/schema-full-checking", true); // NOI18N
64
return new SchemaChecker(parser);
65                 }
66             } catch (SAXException ex) {
67                 return null;
68             }
69             
70         } else {
71             return parser;
72         }
73     }
74
75     /**
76      * Redefine wrapping policy.
77      */

78     private static class SchemaChecker extends SAXEntityParser {
79         
80         private static String JavaDoc SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
81         
82         // schema target ns
83
private String JavaDoc ns = null;
84         
85         public SchemaChecker(XMLReader parser) {
86             super( parser);
87         }
88
89         /**
90          * Create fake document referencing XML Schema document.
91          * Besides it must guarantee that the first entity resolution
92          * query caused by parsing of wrapped document is
93          * resolved at a context where XML Schema InputSource
94          * is expected. It is SAXEntityParser logic.
95          */

96         protected InputSource wrapInputSource(InputSource inputSource) {
97             String JavaDoc targetNamespace = getTargetNamespace();
98             String JavaDoc url = inputSource.getSystemId();
99             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(256);
100             String JavaDoc namespace = "http://www.w3.org/2001/XMLSchema-instance"; // NOI18N
101
buffer.append("<schemaWrapper xmlns:xsi='" + namespace + "' "); // NOI18N
102

103             
104             if (targetNamespace != null) {
105                 buffer.append("xmlns='").append(targetNamespace).append("' "); // NOI18N
106
buffer.append("xsi:schemaLocation='").append(targetNamespace).append(' ').append(url).append("'/>"); // NOI18N
107
} else {
108                 buffer.append("xsi:noNamespaceSchemaLocation='").append(url).append("'/>"); // NOI18N
109
}
110             StringReader reader = new StringReader(buffer.toString());
111             InputSource input = new InputSource();
112             input.setCharacterStream(reader);
113             return input;
114         }
115         
116         /**
117          * Filter out all complains about wrong namespace.
118          */

119         protected boolean propagateException(SAXParseException ex) {
120             if (super.propagateException(ex)) {
121                 //??? it works with most parser impls :-(
122
String JavaDoc message = ex.getMessage();
123                 if (message == null) return true; //???
124
if (getTargetNamespace() == null || message.indexOf(getTargetNamespace()) < 0) {
125                     return message.indexOf("schemaWrapper") < 0; // NOI18N
126
}
127             }
128             return false;
129         }
130
131         public void parse(InputSource input) throws SAXException, IOException {
132             ShareableInputSource shared = ShareableInputSource.create(input);
133             try {
134                 ns = parseForTargetNamespace(shared);
135                 shared.reset();
136                 super.parse(shared);
137             } finally {
138                 shared.closeAll();
139             }
140         }
141         
142         /**
143          * @return ns or <code>null</code> is chameleon schema.
144          */

145         private String JavaDoc getTargetNamespace() {
146             return ns;
147         }
148
149         private String JavaDoc parseForTargetNamespace(InputSource schema) throws SAXException, IOException {
150             try {
151                 XMLReader reader = XMLUtil.createXMLReader(false, true);
152                 EntityResolver resolver = UserCatalog.getDefault().getEntityResolver();
153                 if (resolver != null) {
154                     reader.setEntityResolver(resolver);
155                 }
156
157                 TargetNSScanner sniffer = new TargetNSScanner();
158                 reader.setContentHandler(sniffer);
159                 reader.setErrorHandler(sniffer);
160                 reader.parse(schema);
161             } catch (Stop ex) {
162                 return ex.getNamespace();
163             }
164             return null;
165         }
166
167         // root element must be schema element
168
private class TargetNSScanner extends DefaultHandler JavaDoc {
169             public void startElement(String JavaDoc uri, String JavaDoc local, String JavaDoc qname, Attributes attrs) throws SAXException {
170                 if ("schema".equals(local) && SCHEMA_NS.equals(uri)) { // NOI18N
171
String JavaDoc targetNS = attrs.getValue("targetNamespace"); // NOI18N
172
throw new Stop(targetNS);
173                 }
174                 // no schema root element
175
throw new SAXException(Util.THIS.getString("MSG_missing_schema"));
176             }
177         }
178         
179         private static class Stop extends SAXException {
180             Stop(String JavaDoc ns) {
181                 super(ns);
182             }
183
184             String JavaDoc getNamespace() {
185                 return getMessage();
186             }
187         }
188     }
189 }
190
Popular Tags