From fbb4a7e56f3bb1f49e3a70eb3640239bea7dc443 Mon Sep 17 00:00:00 2001 From: Olyutorskii Date: Tue, 25 Jun 2019 15:28:14 +0900 Subject: [PATCH] close schema files explicitly. --- src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java | 116 ++++++++------------- 1 file changed, 45 insertions(+), 71 deletions(-) diff --git a/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java b/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java index 9e2ae10..c0f9eb2 100644 --- a/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java +++ b/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java @@ -10,11 +10,9 @@ package jp.sfjp.mikutoga.xml; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; -import java.net.MalformedURLException; import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; -import java.util.ArrayList; -import java.util.List; import javax.xml.XMLConstants; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; @@ -27,6 +25,8 @@ import org.xml.sax.SAXNotSupportedException; /** * XML schema (XSD) utilities. + * + *

RELAX NG is not supported. */ public final class SchemaUtil { @@ -51,11 +51,16 @@ public final class SchemaUtil { static{ - URL redirectRes = THISCLASS.getResource(LOCAL_SCHEMA_XML); - String redirectResName = redirectRes.toString(); + URL localXsdUrl = THISCLASS.getResource(LOCAL_SCHEMA_XML); + URI localXsdUri; + try{ + localXsdUri = localXsdUrl.toURI(); + }catch(URISyntaxException e){ + throw new ExceptionInInitializerError(e); + } URI_XSD_ORIG = URI.create(SCHEMA_XML); - URI_XSD_LOCAL = URI.create(redirectResName); + URI_XSD_LOCAL = localXsdUri; assert ALLOWED_USCHEMA.equalsIgnoreCase(URI_XSD_ORIG.getScheme()); } @@ -104,23 +109,23 @@ public final class SchemaUtil { XMLConstants.W3C_XML_SCHEMA_NS_URI); try{ - // Prevent denial of service attack. + // Prevent denial-of-service attack. schemaFactory.setFeature( XMLConstants.FEATURE_SECURE_PROCESSING, true); }catch(SAXNotRecognizedException | SAXNotSupportedException e){ - // FEATURE MUST BE SUPPORTED + // THIS FEATURE MUST BE SUPPORTED assert false; } try{ - // Disallow external entity reference & external DTD access. + // Disallow external entity reference & external DTD access. schemaFactory.setProperty( XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Allow only HTTP external schema file. schemaFactory.setProperty( XMLConstants.ACCESS_EXTERNAL_SCHEMA, ALLOWED_USCHEMA); }catch(SAXNotRecognizedException | SAXNotSupportedException e){ - // PROPERTY MUST BE SUPPORTED JAXP1.5 or later + // THIS PROPERTY MUST BE SUPPORTED JAXP1.5 or later assert false; } @@ -133,79 +138,48 @@ public final class SchemaUtil { } /** - * ローカルリソースをSourceに変換する。 - * @param resource ローカルリソース - * @return XML Source - * @throws MalformedURLException 不正なURI - * @throws IOException オープンエラー - */ - private static Source toLocalSource(LocalXmlResource resource) - throws MalformedURLException, IOException{ - URI localUri = resource.getLocalResource(); - URL localUrl = localUri.toURL(); - - InputStream is = localUrl.openStream(); - is = new BufferedInputStream(is); - - Source result = new StreamSource(is); - return result; - } - - /** - * ローカルリソース群をSource群に変換する。 - * @param resArray ローカルリソースURI並び - * @return XML Source並び - * @throws MalformedURLException 不正なURI - * @throws IOException オープンエラー + * pre-load & pre-compile local schema files. + * + * @param localSchemaUris local schema resources. + * @return schema + * @throws SAXException invalid schema definition + * @throws IOException local resource i/o error */ - private static Source[] toLocalSourceArray(LocalXmlResource... resArray) - throws MalformedURLException, IOException{ - List sourceList = new ArrayList<>(resArray.length); + public static Schema newSchema(URI... localSchemaUris) + throws SAXException, IOException{ + SchemaFactory schemaFactory = newSchemaFactory(); - for(LocalXmlResource resource : resArray){ - Source localSource = toLocalSource(resource); - sourceList.add(localSource); + int uris = localSchemaUris.length; + if(uris <= 0){ + // on-demand xml-schema with schemaLocation attribute. + return schemaFactory.newSchema(); } - Source[] result = new Source[sourceList.size()]; - result = sourceList.toArray(result); - return result; - } - - /** - * ローカルスキーマをロードする。 - * - *

任意のリゾルバを指定可能 - * - * @param resArray ローカルスキーマ情報並び - * @return スキーマ - */ - public static Schema newSchema(LocalXmlResource... resArray){ - Source[] sources; - try{ - sources = toLocalSourceArray(resArray); - }catch(IOException e){ // ビルド障害 - assert false; - throw new AssertionError(e); + InputStream[] iss = new InputStream[uris]; + for(int idx = 0; idx < uris; idx++){ + URI localUri = localSchemaUris[idx]; + URL localUrl = localUri.toURL(); + InputStream is; + is = localUrl.openStream(); + is = new BufferedInputStream(is); + iss[idx] = is; } - SchemaFactory schemaFactory = newSchemaFactory(); + Source[] sources = new Source[uris]; + for(int idx = 0; idx < uris; idx++){ + InputStream is = iss[idx]; + sources[idx] = new StreamSource(is); + } Schema result; try{ - if(sources.length <= 0){ - // ドキュメント埋め込みスキーマURLにリゾルバ経由でアクセス - result = schemaFactory.newSchema(); - }else{ - result = schemaFactory.newSchema(sources); + result = schemaFactory.newSchema(sources); + }finally{ + for(InputStream is : iss){ + is.close(); } - }catch(SAXException e){ // Build error - assert false; - throw new AssertionError(e); } - // TODO: Sourceを閉めるのは誰の責務? - return result; } -- 2.11.0