[jOOQ/jOOQ#9470] FilePatter.Loader should accept Source, instead of InputStream

This commit is contained in:
Lukas Eder 2019-10-30 15:30:23 +01:00
parent 3b3294563c
commit 3f4ffd72e6
3 changed files with 100 additions and 109 deletions

View File

@ -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);
}
}
}

View File

@ -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<File> 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;
}
}

View File

@ -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();
}
});
}