From d501e8bd93faa6a9ca1fc002ca6db0784b18dcea Mon Sep 17 00:00:00 2001 From: lukaseder Date: Tue, 11 Nov 2014 14:49:32 +0100 Subject: [PATCH] [#3756] Regenerate files only if there is a difference --- .../java/org/jooq/util/AbstractGenerator.java | 16 ++++-- .../java/org/jooq/util/GeneratorWriter.java | 42 +++++++++++---- .../java/org/jooq/util/JavaGenerator.java | 54 +++++++++++-------- 3 files changed, 77 insertions(+), 35 deletions(-) diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/AbstractGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/util/AbstractGenerator.java index 5820de9f6b..57e41a9ced 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/AbstractGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/AbstractGenerator.java @@ -41,6 +41,8 @@ package org.jooq.util; import java.io.File; +import java.util.Collections; +import java.util.Set; /** @@ -261,20 +263,28 @@ abstract class AbstractGenerator implements Generator { /** * If file is a directory, recursively empty its children. - * If file is a file, delete it + * If file is a file, delete it. */ protected void empty(File file, String suffix) { + empty(file, suffix, Collections.emptySet()); + } + + /** + * If file is a directory, recursively empty its children. + * If file is a file, delete it, except if it is in the list of files to keep. + */ + protected void empty(File file, String suffix, Set keep) { if (file != null) { if (file.isDirectory()) { File[] children = file.listFiles(); if (children != null) { for (File child : children) { - empty(child, suffix); + empty(child, suffix, keep); } } } else { - if (file.getName().endsWith(suffix)) { + if (file.getName().endsWith(suffix) && !keep.contains(file)) { file.delete(); } } diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/GeneratorWriter.java b/jOOQ-codegen/src/main/java/org/jooq/util/GeneratorWriter.java index 00abf96476..266128b7f4 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/GeneratorWriter.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/GeneratorWriter.java @@ -45,6 +45,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; +import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -78,7 +79,6 @@ public abstract class GeneratorWriter> { private final File file; - private final PrintWriter writer; private final StringBuilder sb; private int indentTabs; private boolean newline = true; @@ -87,12 +87,6 @@ public abstract class GeneratorWriter> { file.getParentFile().mkdirs(); this.file = file; - try { - this.writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); - } - catch (IOException e) { - throw new GeneratorException("Error writing " + file.getAbsolutePath()); - } this.sb = new StringBuilder(); } @@ -235,11 +229,37 @@ public abstract class GeneratorWriter> { } public final void close() { - String string = beforeClose(sb.toString()); + String newContent = beforeClose(sb.toString()); - writer.append(string); - writer.flush(); - writer.close(); + try { + // [#3756] Regenerate files only if there is a difference + String oldContent = null; + if (file.exists()) { + RandomAccessFile old = null; + + try { + old = new RandomAccessFile(file, "r"); + byte[] oldBytes = new byte[(int) old.length()]; + old.readFully(oldBytes); + oldContent = new String(oldBytes, "UTF-8"); + } + finally { + if (old != null) + old.close(); + } + } + + if (oldContent == null || !oldContent.equals(newContent)) { + PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); + + writer.append(newContent); + writer.flush(); + writer.close(); + } + } + catch (IOException e) { + throw new GeneratorException("Error writing " + file.getAbsolutePath()); + } } protected String beforeClose(String string) { diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java index 77f7b79041..6b1caf5ab2 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java @@ -57,6 +57,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -158,6 +159,11 @@ public class JavaGenerator extends AbstractGenerator { */ private Map schemaVersions; + /** + * All files modified by this generator + */ + private Set files = new LinkedHashSet(); + @Override public final void generate(Database db) { this.isoDate = DatatypeConverter.printDateTime(Calendar.getInstance(TimeZone.getTimeZone("UTC"))); @@ -273,9 +279,6 @@ public class JavaGenerator extends AbstractGenerator { // ---------------------------------------------------------------------- // XXX Initialising // ---------------------------------------------------------------------- - log.info("Emptying", targetPackage.getAbsolutePath()); - empty(getStrategy().getFile(schema).getParentFile(), ".java"); - generateSchema(schema); if (generateGlobalObjectReferences() && database.getSequences(schema).size() > 0) { @@ -356,8 +359,12 @@ public class JavaGenerator extends AbstractGenerator { x xx [/pro] */ + log.info("Removing excess files"); + empty(getStrategy().getFile(schema).getParentFile(), ".java", files); + files.clear(); + // XXX [#651] Refactoring-cursor - watch.splitInfo("GENERATION FINISHED!"); + watch.splitInfo("GENERATION FINISHED: " + schema.getQualifiedName()); } private class AvoidAmbiguousClassesFilter implements Database.Filter { @@ -399,7 +406,7 @@ public class JavaGenerator extends AbstractGenerator { xxxxxxxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxx x xxxxxxxxxxxxxxxx xxxxxxxxx - xxxxxxxxxx xxx x xxx xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx + xxxxxxxxxx xxx x xxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx xxxxxx xx xxx xxxxxx xx x x xxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx @@ -438,7 +445,7 @@ public class JavaGenerator extends AbstractGenerator { protected void generateRelations(SchemaDefinition schema) { log.info("Generating Keys"); - JavaWriter out = new JavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "Keys.java")); + JavaWriter out = newJavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "Keys.java")); printPackage(out, schema); printClassJavadoc(out, "A class modelling foreign key relationships between tables of the " + schema.getOutputName() + " schema"); @@ -664,7 +671,7 @@ public class JavaGenerator extends AbstractGenerator { final List interfaces = getStrategy().getJavaClassImplements(tableOrUdt, Mode.RECORD); final List> columns = getTypedElements(tableOrUdt); - JavaWriter out = new JavaWriter(getStrategy().getFile(tableOrUdt, Mode.RECORD)); + JavaWriter out = newJavaWriter(getStrategy().getFile(tableOrUdt, Mode.RECORD)); printPackage(out, tableOrUdt, Mode.RECORD); if (tableOrUdt instanceof TableDefinition) @@ -957,7 +964,7 @@ public class JavaGenerator extends AbstractGenerator { final String className = getStrategy().getJavaClassName(tableOrUDT, Mode.INTERFACE); final List interfaces = getStrategy().getJavaClassImplements(tableOrUDT, Mode.INTERFACE); - JavaWriter out = new JavaWriter(getStrategy().getFile(tableOrUDT, Mode.INTERFACE)); + JavaWriter out = newJavaWriter(getStrategy().getFile(tableOrUDT, Mode.INTERFACE)); printPackage(out, tableOrUDT, Mode.INTERFACE); if (tableOrUDT instanceof TableDefinition) generateInterfaceClassJavadoc((TableDefinition) tableOrUDT, out); @@ -1053,7 +1060,7 @@ public class JavaGenerator extends AbstractGenerator { final String schemaId = getStrategy().getFullJavaIdentifier(schema); final String udtId = getStrategy().getJavaIdentifier(udt); - JavaWriter out = new JavaWriter(getStrategy().getFile(udt)); + JavaWriter out = newJavaWriter(getStrategy().getFile(udt)); printPackage(out, udt); generateUDTClassJavadoc(udt, out); printClassAnnotations(out, schema); @@ -1258,7 +1265,7 @@ public class JavaGenerator extends AbstractGenerator { protected void generateUDTReferences(SchemaDefinition schema) { log.info("Generating UDT references"); - JavaWriter out = new JavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "UDTs.java")); + JavaWriter out = newJavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "UDTs.java")); printPackage(out, schema); printClassJavadoc(out, "Convenience access to all UDTs in " + schema.getOutputName()); printClassAnnotations(out, schema); @@ -1305,7 +1312,7 @@ public class JavaGenerator extends AbstractGenerator { xxxxx xxxxxx xxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx xxxxxx xxxxxxxxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - xxxxxxxxxx xxx x xxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxx + xxxxxxxxxx xxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx xxxxxx xxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx @@ -1401,7 +1408,7 @@ public class JavaGenerator extends AbstractGenerator { final String className = getStrategy().getJavaClassName(e, Mode.ENUM); final List interfaces = getStrategy().getJavaClassImplements(e, Mode.ENUM); - JavaWriter out = new JavaWriter(getStrategy().getFile(e, Mode.ENUM)); + JavaWriter out = newJavaWriter(getStrategy().getFile(e, Mode.ENUM)); printPackage(out, e); generateEnumClassJavadoc(e, out); printClassAnnotations(out, e.getSchema()); @@ -1473,7 +1480,7 @@ public class JavaGenerator extends AbstractGenerator { protected void generateRoutines(SchemaDefinition schema) { log.info("Generating routines and table-valued functions"); - JavaWriter out = new JavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "Routines.java")); + JavaWriter out = newJavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "Routines.java")); printPackage(out, schema); printClassJavadoc(out, "Convenience access to all stored procedures and functions in " + schema.getOutputName()); printClassAnnotations(out, schema); @@ -1548,7 +1555,7 @@ public class JavaGenerator extends AbstractGenerator { final List interfaces = getStrategy().getJavaClassImplements(pkg, Mode.DEFAULT); // Static convenience methods - JavaWriter out = new JavaWriter(getStrategy().getFile(pkg)); + JavaWriter out = newJavaWriter(getStrategy().getFile(pkg)); printPackage(out, pkg); generatePackageClassJavadoc(pkg, out); printClassAnnotations(out, schema); @@ -1596,7 +1603,7 @@ public class JavaGenerator extends AbstractGenerator { protected void generateTableReferences(SchemaDefinition schema) { log.info("Generating table references"); - JavaWriter out = new JavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "Tables.java")); + JavaWriter out = newJavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "Tables.java")); printPackage(out, schema); printClassJavadoc(out, "Convenience access to all tables in " + schema.getOutputName()); printClassAnnotations(out, schema); @@ -1672,7 +1679,7 @@ public class JavaGenerator extends AbstractGenerator { log.info("Generating DAO", getStrategy().getFileName(table, Mode.DAO)); - JavaWriter out = new JavaWriter(getStrategy().getFile(table, Mode.DAO)); + JavaWriter out = newJavaWriter(getStrategy().getFile(table, Mode.DAO)); printPackage(out, table, Mode.DAO); generateDaoClassJavadoc(table, out); printClassAnnotations(out, table.getSchema()); @@ -1795,7 +1802,7 @@ public class JavaGenerator extends AbstractGenerator { interfaces.add(getStrategy().getFullJavaClassName(tableOrUDT, Mode.INTERFACE)); } - JavaWriter out = new JavaWriter(getStrategy().getFile(tableOrUDT, Mode.POJO)); + JavaWriter out = newJavaWriter(getStrategy().getFile(tableOrUDT, Mode.POJO)); printPackage(out, tableOrUDT, Mode.POJO); if (tableOrUDT instanceof TableDefinition) @@ -2048,7 +2055,7 @@ public class JavaGenerator extends AbstractGenerator { ", pk=" + (primaryKey != null ? primaryKey.getName() : "N/A") + "]"); - JavaWriter out = new JavaWriter(getStrategy().getFile(table)); + JavaWriter out = newJavaWriter(getStrategy().getFile(table)); printPackage(out, table); generateTableClassJavadoc(table, out); printClassAnnotations(out, schema); @@ -2302,7 +2309,7 @@ public class JavaGenerator extends AbstractGenerator { protected void generateSequences(SchemaDefinition schema) { log.info("Generating sequences"); - JavaWriter out = new JavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "Sequences.java")); + JavaWriter out = newJavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "Sequences.java")); printPackage(out, schema); printClassJavadoc(out, "Convenience access to all sequences in " + schema.getOutputName()); printClassAnnotations(out, schema); @@ -2334,7 +2341,7 @@ public class JavaGenerator extends AbstractGenerator { final String className = getStrategy().getJavaClassName(schema); final List interfaces = getStrategy().getJavaClassImplements(schema, Mode.DEFAULT); - JavaWriter out = new JavaWriter(getStrategy().getFile(schema)); + JavaWriter out = newJavaWriter(getStrategy().getFile(schema)); printPackage(out, schema); generateSchemaClassJavadoc(schema, out); printClassAnnotations(out, schema); @@ -2571,7 +2578,7 @@ public class JavaGenerator extends AbstractGenerator { final String schemaId = getStrategy().getFullJavaIdentifier(schema); final List packageId = getStrategy().getFullJavaIdentifiers(routine.getPackage()); - JavaWriter out = new JavaWriter(getStrategy().getFile(routine)); + JavaWriter out = newJavaWriter(getStrategy().getFile(routine)); printPackage(out, routine); generateRoutineClassJavadoc(routine, out); printClassAnnotations(out, schema); @@ -3379,4 +3386,9 @@ public class JavaGenerator extends AbstractGenerator { return result; } + + private final JavaWriter newJavaWriter(File file) { + files.add(file); + return new JavaWriter(file); + } }