View Javadoc

1   /**********************************************
2    * Copyright (C) 2010 Lukas Laag
3    * This file is part of lib-gwt-svg.
4    * 
5    * libgwtsvg is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU Lesser General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * libgwtsvg is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU Lesser General Public License for more details.
14   * 
15   * You should have received a copy of the GNU Lesser General Public License
16   * along with libgwtsvg.  If not, see http://www.gnu.org/licenses/
17   **********************************************/
18  package org.vectomatic.dev.svg.impl.gen;
19  
20  import java.io.ByteArrayInputStream;
21  import java.io.InputStream;
22  import java.io.Reader;
23  import java.io.StringReader;
24  import java.net.URL;
25  
26  import javax.xml.XMLConstants;
27  import javax.xml.transform.Source;
28  import javax.xml.transform.stream.StreamSource;
29  import javax.xml.validation.Schema;
30  import javax.xml.validation.SchemaFactory;
31  import javax.xml.validation.Validator;
32  
33  import org.w3c.dom.ls.LSInput;
34  import org.w3c.dom.ls.LSResourceResolver;
35  import org.xml.sax.SAXParseException;
36  
37  import com.google.gwt.core.ext.TreeLogger;
38  import com.google.gwt.core.ext.UnableToCompleteException;
39  import com.google.gwt.uibinder.rebind.UiBinderWriter;
40  
41  /**
42   * Class to validate an SVG file against the SVG 1.1 XSD schema
43   * @author laaglu
44   */
45  public class SVGValidator {
46  	private static Validator validator;
47  	
48  	/**
49  	 * Constructor (block instantiation)
50  	 */
51  	private SVGValidator() {
52  	}
53  	/**
54  	 * Validates the specified SVG input
55  	 * @param rawSvg The SVG input to validate 
56  	 * @param systemId The URL of the resource being validated
57  	 * @param logger A logger to report validation errors (if the method is invoked
58  	 * to validate an {@link org.vectomatic.dom.svg.ui.SVGResource} or an
59  	 * {@link org.vectomatic.dom.svg.ui.ExternalSVGResource})
60  	 * @param writer A writer to report validation errors (if the method is
61  	 * invoked to validate a UiBinder template)
62  	 * @throws UnableToCompleteException If validation error occur
63  	 */
64  	public static void validate(String rawSvg, String systemId, final TreeLogger logger, final UiBinderWriter writer) throws UnableToCompleteException {
65  	    try {
66  	    	if (validator == null) {
67  	    		SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
68  	    		URL svgSchemaURL = SVGValidator.class.getResource("SVG.xsd");
69  	    	    Source schemaFile = new StreamSource(svgSchemaURL.openStream(), svgSchemaURL.toExternalForm());
70  	    	    Schema schema = factory.newSchema(schemaFile);
71  	    	    validator = schema.newValidator();
72  	    	    validator.setResourceResolver(new LSResourceResolver() {
73  					@Override
74  					public LSInput resolveResource(String type, String namespaceURI,
75  							final String publicId, final String systemId, final String baseURI) {
76  						if (logger != null) {
77  				    		logger.log(TreeLogger.INFO, "resolveResource(" + type + ", " + namespaceURI + ", " + publicId + ", " + systemId + ", " + baseURI + ")");
78  				    	}
79  						return new LSInput() {
80  
81  							@Override
82  							public Reader getCharacterStream() {
83  								return new StringReader("");
84  							}
85  
86  							@Override
87  							public void setCharacterStream(
88  									Reader characterStream) {
89  							}
90  
91  							@Override
92  							public InputStream getByteStream() {
93  								return new ByteArrayInputStream(new byte[0]);
94  							}
95  
96  							@Override
97  							public void setByteStream(InputStream byteStream) {
98  							}
99  
100 							@Override
101 							public String getStringData() {
102 								return "";
103 							}
104 
105 							@Override
106 							public void setStringData(String stringData) {							
107 							}
108 
109 							@Override
110 							public String getSystemId() {
111 								return systemId;
112 							}
113 
114 							@Override
115 							public void setSystemId(String systemId) {
116 							}
117 
118 							@Override
119 							public String getPublicId() {
120 								return publicId;
121 							}
122 
123 							@Override
124 							public void setPublicId(String publicId) {
125 							}
126 
127 							@Override
128 							public String getBaseURI() {
129 								return baseURI;
130 							}
131 
132 							@Override
133 							public void setBaseURI(String baseURI) {
134 							}
135 
136 							@Override
137 							public String getEncoding() {
138 								return null;
139 							}
140 
141 							@Override
142 							public void setEncoding(String encoding) {
143 							}
144 
145 							@Override
146 							public boolean getCertifiedText() {
147 								return false;
148 							}
149 
150 							@Override
151 							public void setCertifiedText(boolean certifiedText) {
152 							}
153 							
154 						};
155 					}
156 				});
157 	    	}
158 	        validator.validate(new StreamSource(new StringReader(rawSvg), systemId));
159 	    } catch (SAXParseException e) {
160 	    	if (writer != null) {
161 	    		writer.die(e.getMessage() + " @" + e.getSystemId() + " L:" + e.getLineNumber() + ",C:" + e.getColumnNumber());
162 	    	} else if (logger != null) {
163 	    		logger.log(TreeLogger.ERROR, "Invalid SVG input @" + e.getSystemId() + " L:" + e.getLineNumber() + ",C:" + e.getColumnNumber(), e);
164 				throw new UnableToCompleteException();
165 	    	}
166 	    } catch (Throwable t) {
167 	    	if (writer != null) {
168 	    		writer.die(t.getMessage());
169 	    	} else if (logger != null) {
170 	    		logger.log(TreeLogger.ERROR, "Invalid SVG input", t);
171 				throw new UnableToCompleteException();
172 	    	}
173 	    }
174 	}
175 }