8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.internal.xjc; 27 28 import java.net.URL; 29 30 import javax.xml.validation.Schema; 31 import javax.xml.validation.SchemaFactory; 32 import javax.xml.validation.ValidatorHandler; 33 34 import com.sun.xml.internal.bind.v2.util.XmlFactory; 35 import javax.xml.XMLConstants; 36 import org.xml.sax.SAXException; 37 38 import static com.sun.xml.internal.bind.v2.util.XmlFactory.allowExternalAccess; 39 40 /** 41 * Wraps a JAXP {@link Schema} object and lazily instantiate it. 42 * 43 * This object is thread-safe. There should be only one instance of 44 * this for the whole VM. 45 * 46 * @author Kohsuke Kawaguchi 47 */ 48 public final class SchemaCache { 49 50 private Schema schema; 51 52 private final URL source; 53 54 public SchemaCache(URL source) { 55 this.source = source; 56 } 57 58 public ValidatorHandler newValidator() { 59 synchronized(this) { 60 if(schema==null) { 61 try { 62 // do not disable secure processing - these are well-known schemas 63 SchemaFactory sf = XmlFactory.createSchemaFactory(XMLConstants.W3C_XML_SCHEMA_NS_URI, false); 64 schema = allowExternalAccess(sf, "file", false).newSchema(source); 65 } catch (SAXException e) { 66 // we make sure that the schema is correct before we ship. 67 throw new AssertionError(e); 68 } 69 } 70 } 71 72 ValidatorHandler handler = schema.newValidatorHandler(); 73 return handler; 74 } 75 76 } | 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.internal.xjc; 27 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.io.Reader; 31 import java.util.ArrayList; 32 import java.util.Collections; 33 import java.util.List; 34 35 import javax.xml.transform.stream.StreamSource; 36 import javax.xml.validation.Schema; 37 import javax.xml.validation.SchemaFactory; 38 import javax.xml.validation.ValidatorHandler; 39 40 import com.sun.xml.internal.bind.v2.util.XmlFactory; 41 import javax.xml.XMLConstants; 42 43 import org.w3c.dom.ls.LSInput; 44 import org.w3c.dom.ls.LSResourceResolver; 45 import org.xml.sax.SAXException; 46 47 import static com.sun.xml.internal.bind.v2.util.XmlFactory.allowExternalAccess; 48 49 /** 50 * Wraps a JAXP {@link Schema} object and lazily instantiate it. 51 * 52 * This object is thread-safe. There should be only one instance of 53 * this for the whole VM. 54 * 55 * @author Kohsuke Kawaguchi 56 */ 57 public final class SchemaCache { 58 59 private final boolean createResolver; 60 private final String resourceName; 61 private final Class<?> clazz; 62 63 private Schema schema; 64 65 public SchemaCache(String resourceName, Class<?> classToResolveResources) { 66 this(resourceName, classToResolveResources, false); 67 } 68 69 public SchemaCache(String resourceName, Class<?> classToResolveResources, boolean createResolver) { 70 this.resourceName = resourceName; 71 this.createResolver = createResolver; 72 this.clazz = classToResolveResources; 73 } 74 75 public ValidatorHandler newValidator() { 76 if (schema==null) { 77 synchronized (this) { 78 if (schema == null) { 79 80 ResourceResolver resourceResolver = null; 81 try (InputStream is = clazz.getResourceAsStream(resourceName)) { 82 83 StreamSource source = new StreamSource(is); 84 source.setSystemId(resourceName); 85 // do not disable secure processing - these are well-known schemas 86 87 SchemaFactory sf = XmlFactory.createSchemaFactory(XMLConstants.W3C_XML_SCHEMA_NS_URI, false); 88 SchemaFactory schemaFactory = allowExternalAccess(sf, "file", false); 89 90 if (createResolver) { 91 resourceResolver = new ResourceResolver(clazz); 92 schemaFactory.setResourceResolver(resourceResolver); 93 } 94 schema = schemaFactory.newSchema(source); 95 96 } catch (IOException | SAXException e) { 97 throw new InternalError(e); 98 } finally { 99 if (resourceResolver != null) resourceResolver.closeStreams(); 100 } 101 } 102 } 103 } 104 return schema.newValidatorHandler(); 105 } 106 107 class ResourceResolver implements LSResourceResolver { 108 109 private List<InputStream> streamsToClose = Collections.synchronizedList(new ArrayList<InputStream>()); 110 private Class<?> clazz; 111 112 ResourceResolver(Class<?> clazz) { 113 this.clazz = clazz; 114 } 115 116 @Override 117 public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { 118 // XSOM passes the namespace URI to the publicID parameter. 119 // we do the same here . 120 InputStream is = clazz.getResourceAsStream(systemId); 121 streamsToClose.add(is); 122 return new Input(is, publicId, systemId); 123 } 124 125 void closeStreams() { 126 for (InputStream is : streamsToClose) { 127 if (is != null) { 128 try { 129 is.close(); 130 } catch (IOException e) { 131 // nothing to do ... 132 } 133 } 134 } 135 } 136 } 137 138 } 139 140 class Input implements LSInput { 141 142 private InputStream is; 143 private String publicId; 144 private String systemId; 145 146 public Input(InputStream is, String publicId, String systemId) { 147 this.is = is; 148 this.publicId = publicId; 149 this.systemId = systemId; 150 } 151 152 @Override 153 public Reader getCharacterStream() { 154 return null; 155 } 156 157 @Override 158 public void setCharacterStream(Reader characterStream) { 159 } 160 161 @Override 162 public InputStream getByteStream() { 163 return is; 164 } 165 166 @Override 167 public void setByteStream(InputStream byteStream) { 168 } 169 170 @Override 171 public String getStringData() { 172 return null; 173 } 174 175 @Override 176 public void setStringData(String stringData) { 177 } 178 179 @Override 180 public String getSystemId() { 181 return systemId; 182 } 183 184 @Override 185 public void setSystemId(String systemId) { 186 } 187 188 @Override 189 public String getPublicId() { 190 return publicId; 191 } 192 193 @Override 194 public void setPublicId(String publicId) { 195 } 196 197 @Override 198 public String getBaseURI() { 199 return null; 200 } 201 202 @Override 203 public void setBaseURI(String baseURI) { 204 } 205 206 @Override 207 public String getEncoding() { 208 return null; 209 } 210 211 @Override 212 public void setEncoding(String encoding) { 213 } 214 215 @Override 216 public boolean getCertifiedText() { 217 return false; 218 } 219 220 @Override 221 public void setCertifiedText(boolean certifiedText) { 222 } 223 } 224 225 |