diff --git a/jOOQ-meta-extensions/src/main/java/org/jooq/meta/extensions/ddl/DDLDatabase.java b/jOOQ-meta-extensions/src/main/java/org/jooq/meta/extensions/ddl/DDLDatabase.java index c81baa83b7..16e40c2f20 100644 --- a/jOOQ-meta-extensions/src/main/java/org/jooq/meta/extensions/ddl/DDLDatabase.java +++ b/jOOQ-meta-extensions/src/main/java/org/jooq/meta/extensions/ddl/DDLDatabase.java @@ -42,7 +42,7 @@ import static org.jooq.impl.DSL.name; import static org.jooq.tools.StringUtils.isBlank; import java.io.File; -import java.io.InputStream; +import java.io.Reader; import java.sql.SQLException; import java.util.Comparator; import java.util.Scanner; @@ -55,6 +55,7 @@ import org.jooq.Name.Quoted; import org.jooq.Queries; import org.jooq.Query; import org.jooq.ResultQuery; +import org.jooq.Source; import org.jooq.VisitContext; import org.jooq.conf.ParseUnknownFunctions; import org.jooq.conf.Settings; @@ -66,6 +67,7 @@ import org.jooq.meta.extensions.AbstractInterpretingDatabase; import org.jooq.meta.tools.FilePattern; import org.jooq.meta.tools.FilePattern.Loader; import org.jooq.tools.JooqLogger; +import org.jooq.tools.jdbc.JDBCUtils; import org.h2.api.ErrorCode; @@ -146,8 +148,8 @@ public class DDLDatabase extends AbstractInterpretingDatabase { FilePattern.load(encoding, scripts, fileComparator, new Loader() { @Override - public void load(String e, InputStream in) { - DDLDatabase.this.load(ctx, e, in); + public void load(Source source) { + DDLDatabase.this.load(ctx, source); } }); } @@ -157,9 +159,11 @@ public class DDLDatabase extends AbstractInterpretingDatabase { } } - private void load(DSLContext ctx, String encoding, InputStream in) { + private void load(DSLContext ctx, Source source) { + Reader r = null; + try { - Scanner s = new Scanner(in, encoding).useDelimiter("\\A"); + Scanner s = new Scanner(r = source.reader()).useDelimiter("\\A"); Queries queries = ctx.parser().parse(s.hasNext() ? s.next() : ""); for (Query query : queries) { @@ -214,11 +218,7 @@ public class DDLDatabase extends AbstractInterpretingDatabase { throw e; } finally { - if (in != null) - try { - in.close(); - } - catch (Exception ignore) {} + JDBCUtils.safeClose(r); } } } diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/tools/FilePattern.java b/jOOQ-meta/src/main/java/org/jooq/meta/tools/FilePattern.java index b4770f1f7c..832b2460f7 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/tools/FilePattern.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/tools/FilePattern.java @@ -38,13 +38,13 @@ package org.jooq.meta.tools; import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; +import java.net.URL; import java.util.Arrays; import java.util.Comparator; import java.util.regex.Pattern; import org.jooq.Internal; +import org.jooq.Source; import org.jooq.tools.JooqLogger; /** @@ -98,58 +98,47 @@ public final class FilePattern { Comparator fileComparator, Loader loader ) throws Exception { - InputStream in = null; boolean loaded = false; + URL url = FilePattern.class.getResource(pattern); - try { - in = FilePattern.class.getResourceAsStream(pattern); + if (url != null) { + log.info("Reading from classpath: " + pattern); + loader.load(Source.of(new File(url.toURI()), encoding)); + loaded = true; + } + else { + File file = new File(pattern); - if (in != null) { - log.info("Reading from classpath: " + pattern); - loader.load(encoding, in); + if (file.exists()) { + load(encoding, file, fileComparator, null, loader); loaded = true; } else { - File file = new File(pattern); - if (file.exists()) { - load(encoding, file, fileComparator, null, loader); - loaded = true; - } - else { + // [#8336] Relative paths aren't necessarily relative to the + // working directory, but maybe to some subdirectory + if (pattern.contains("*") || pattern.contains("?")) + file = new File(pattern.replaceAll("[*?].*", "")).getCanonicalFile(); + else + file = new File(".").getCanonicalFile(); - // [#8336] Relative paths aren't necessarily relative to the - // working directory, but maybe to some subdirectory - if (pattern.contains("*") || pattern.contains("?")) - file = new File(pattern.replaceAll("[*?].*", "")).getCanonicalFile(); - else - file = new File(".").getCanonicalFile(); + Pattern regex = Pattern.compile("^.*?" + + pattern + .replace("\\", "/") + .replace(".", "\\.") + .replace("?", ".") + .replace("**", ".+?") + .replace("*", "[^/]*") + + "$" + ); - Pattern regex = Pattern.compile("^.*?" - + pattern - .replace("\\", "/") - .replace(".", "\\.") - .replace("?", ".") - .replace("**", ".+?") - .replace("*", "[^/]*") - + "$" - ); - - load(encoding, file, fileComparator, regex, loader); - loaded = true; - } + load(encoding, file, fileComparator, regex, loader); + loaded = true; } + } - if (!loaded) - log.error("Could not find source(s) : " + pattern); - } - finally { - try { - if (in != null) - in.close(); - } - catch (Exception ignore) {} - } + if (!loaded) + log.error("Could not find source(s) : " + pattern); } private static final void load( @@ -162,7 +151,7 @@ public final class FilePattern { if (file.isFile()) { if (pattern == null || pattern.matcher(file.getCanonicalPath().replace("\\", "/")).matches()) { log.info("Reading from: " + file + " [*]"); - loader.load(encoding, new FileInputStream(file)); + loader.load(Source.of(file, encoding)); } } else if (file.isDirectory()) { @@ -186,6 +175,6 @@ public final class FilePattern { } public interface Loader { - void load(String encoding, InputStream in) throws Exception; + void load(Source source) throws Exception; } } diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java b/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java index b2fe16496c..89f53c745f 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java @@ -45,10 +45,10 @@ import static org.jooq.tools.StringUtils.isBlank; import static org.jooq.util.xml.jaxb.TableConstraintType.PRIMARY_KEY; import static org.jooq.util.xml.jaxb.TableConstraintType.UNIQUE; -import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; @@ -78,6 +78,7 @@ import org.jooq.DSLContext; import org.jooq.Name; import org.jooq.SQLDialect; import org.jooq.SortOrder; +import org.jooq.Source; import org.jooq.impl.DSL; import org.jooq.meta.AbstractDatabase; import org.jooq.meta.AbstractIndexDefinition; @@ -103,6 +104,7 @@ import org.jooq.meta.tools.FilePattern; import org.jooq.meta.tools.FilePattern.Loader; import org.jooq.tools.JooqLogger; import org.jooq.tools.StringUtils; +import org.jooq.tools.jdbc.JDBCUtils; import org.jooq.util.jaxb.tools.MiniJAXB; import org.jooq.util.xml.jaxb.Index; import org.jooq.util.xml.jaxb.IndexColumnUsage; @@ -150,60 +152,60 @@ public class XMLDatabase extends AbstractDatabase { try { FilePattern.load("UTF-8", xml, FilePattern.fileComparator(sort), new Loader() { @Override - public void load(String enc, InputStream in) throws Exception { + public void load(Source source) throws Exception { String content; + Reader reader = null; - if (StringUtils.isBlank(xsl)) { - byte[] bytes = bytes(in); + try { + if (StringUtils.isBlank(xsl)) { - // [#7414] Default to reading UTF-8 - content = new String(bytes, "UTF-8"); + // [#7414] Default to reading UTF-8 + content = string(reader = source.reader()); - // [#7414] Alternatively, read the encoding from the XML file - try { - XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(content)); - String encoding = reader.getCharacterEncodingScheme(); + // [#7414] Alternatively, read the encoding from the XML file + try { + XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(content)); + String encoding = xmlReader.getCharacterEncodingScheme(); - // Returned encoding can be null in the presence of a BOM - // See https://stackoverflow.com/a/27147259/521799 - if (encoding != null && !"UTF-8".equals(encoding)) - content = new String(bytes, encoding); - } - catch (XMLStreamException e) { - log.warn("Could not open XML Stream: " + e.getMessage()); - } - catch (UnsupportedEncodingException e) { - log.warn("Unsupported encoding: " + e.getMessage()); - } - } - else { - InputStream xslIs = null; - - try { - log.info("Using XSL file", xsl); - - xslIs = XMLDatabase.class.getResourceAsStream(xsl); - if (xslIs == null) - xslIs = new FileInputStream(xsl); - - StringWriter writer = new StringWriter(); - TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer = factory.newTransformer(new StreamSource(xslIs)); - - transformer.transform(new StreamSource(in), new StreamResult(writer)); - content = writer.getBuffer().toString(); - } - catch (TransformerException e) { - throw new RuntimeException("Error while transforming XML file " + xml + " with XSL file " + xsl, e); - } - finally { - if (xslIs != null) { - try { - xslIs.close(); - } - catch (Exception ignore) {} + // Returned encoding can be null in the presence of a BOM + // See https://stackoverflow.com/a/27147259/521799 + if (encoding != null && !"UTF-8".equals(encoding)) + content = new String(content.getBytes("UTF-8"), encoding); + } + catch (XMLStreamException e) { + log.warn("Could not open XML Stream: " + e.getMessage()); + } + catch (UnsupportedEncodingException e) { + log.warn("Unsupported encoding: " + e.getMessage()); } } + else { + InputStream xslIs = null; + + try { + log.info("Using XSL file", xsl); + + xslIs = XMLDatabase.class.getResourceAsStream(xsl); + if (xslIs == null) + xslIs = new FileInputStream(xsl); + + StringWriter writer = new StringWriter(); + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(new StreamSource(xslIs)); + + transformer.transform(new StreamSource(reader), new StreamResult(writer)); + content = writer.getBuffer().toString(); + } + catch (TransformerException e) { + throw new RuntimeException("Error while transforming XML file " + xml + " with XSL file " + xsl, e); + } + finally { + JDBCUtils.safeClose(xslIs); + } + } + } + finally { + JDBCUtils.safeClose(reader); } // TODO [#1201] Add better error handling here @@ -218,15 +220,15 @@ public class XMLDatabase extends AbstractDatabase { info = MiniJAXB.append(info, MiniJAXB.unmarshal(content, InformationSchema.class)); } - private byte[] bytes(InputStream in) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + private String string(Reader reader) throws IOException { + StringWriter writer = new StringWriter(); int read; - byte[] buffer = new byte[16384]; + char[] buffer = new char[16384]; - while ((read = in.read(buffer, 0, buffer.length)) != -1) - bos.write(buffer, 0, read); + while ((read = reader.read(buffer, 0, buffer.length)) != -1) + writer.write(buffer, 0, read); - return bos.toByteArray(); + return writer.toString(); } }); }