Index: .classpath =================================================================== --- .classpath (revision 18778) +++ .classpath (working copy) @@ -57,11 +57,24 @@ - - - - - + + + + + + + + + + + + + + + + + + Index: src/java/org/hibernate/tool/ant/ExporterTask.java =================================================================== --- src/java/org/hibernate/tool/ant/ExporterTask.java (revision 16604) +++ src/java/org/hibernate/tool/ant/ExporterTask.java (working copy) @@ -27,6 +27,7 @@ File destdir; private Path templatePath; private String templatePrefix = null; + private String mergeMethod; public ExporterTask(HibernateToolTask parent) { this.parent = parent; @@ -63,6 +64,10 @@ templatePrefix = s; } + public void setMergeMethod(String mergeMethod) { + this.mergeMethod = mergeMethod; + } + public void validateParameters() { if(getDestdir()==null) { throw new BuildException("destdir must be set, either locally or on "); @@ -86,7 +91,14 @@ } } + public String getMergeMethod() { + if(mergeMethod==null) { + return parent.getMergemethod(); + } + return mergeMethod; + } + abstract String getName(); protected Exporter configureExporter(Exporter exporter) { @@ -96,7 +108,8 @@ exporter.setProperties(prop); exporter.setConfiguration( parent.getConfiguration() ); exporter.setOutputDirectory( getDestdir() ); - exporter.setTemplatePath( getTemplatePath().list() ); + exporter.setTemplatePath( getTemplatePath().list() ); + exporter.setMergeMethod(getMergeMethod()); return exporter; } } Index: src/java/org/hibernate/tool/ant/Hbm2CfgXmlExporterTask.java =================================================================== --- src/java/org/hibernate/tool/ant/Hbm2CfgXmlExporterTask.java (revision 16604) +++ src/java/org/hibernate/tool/ant/Hbm2CfgXmlExporterTask.java (working copy) @@ -30,6 +30,7 @@ protected Exporter configureExporter(Exporter exporter) { HibernateConfigurationExporter hce = (HibernateConfigurationExporter)super.configureExporter( exporter ); hce.getProperties().setProperty("ejb3", ""+ejb3); + hce.setMergeMethod(getMergeMethod()); return hce; } } Index: src/java/org/hibernate/tool/ant/Hbm2DAOExporterTask.java =================================================================== --- src/java/org/hibernate/tool/ant/Hbm2DAOExporterTask.java (revision 16604) +++ src/java/org/hibernate/tool/ant/Hbm2DAOExporterTask.java (working copy) @@ -12,11 +12,11 @@ super(parent); } - protected Exporter configureExporter(Exporter exp) { + /*protected Exporter configureExporter(Exporter exp) { DAOExporter exporter = (DAOExporter)exp; super.configureExporter(exp); return exporter; - } + }*/ protected Exporter createExporter() { return new DAOExporter(parent.getConfiguration(), parent.getDestDir()) ; Index: src/java/org/hibernate/tool/ant/Hbm2DDLExporterTask.java =================================================================== --- src/java/org/hibernate/tool/ant/Hbm2DDLExporterTask.java (revision 16604) +++ src/java/org/hibernate/tool/ant/Hbm2DDLExporterTask.java (working copy) @@ -43,7 +43,8 @@ exporter.setCreate(create); exporter.setFormat(format); exporter.setOutputFileName(outputFileName); - exporter.setHaltonerror(haltOnError); + exporter.setHaltonerror(haltOnError); + exporter.setMergeMethod(getMergeMethod()); return exporter; } Index: src/java/org/hibernate/tool/ant/HibernateToolTask.java =================================================================== --- src/java/org/hibernate/tool/ant/HibernateToolTask.java (revision 16604) +++ src/java/org/hibernate/tool/ant/HibernateToolTask.java (working copy) @@ -35,7 +35,8 @@ private List generators = new ArrayList(); private Path classPath; private Path templatePath; - private Properties properties = new Properties(); + private Properties properties = new Properties(); + private String mergeMethod; private void checkConfiguration() { if(configurationTask!=null) { @@ -294,6 +295,14 @@ public void setDestDir(File file) { destDir = file; } + + public String getMergemethod() { + return mergeMethod; + } + + public void setMergeMethod(String mergeMethod) { + this.mergeMethod = mergeMethod; + } /** * @return Index: src/java/org/hibernate/tool/hbm2x/AbstractExporter.java =================================================================== --- src/java/org/hibernate/tool/hbm2x/AbstractExporter.java (revision 16604) +++ src/java/org/hibernate/tool/hbm2x/AbstractExporter.java (working copy) @@ -30,6 +30,7 @@ private TemplateHelper vh; private Properties properties = new Properties(); private ArtifactCollector collector = new ArtifactCollector(); + private String mergeMethod = MERGE; private Iterator iterator; @@ -254,4 +255,12 @@ public Cfg2JavaTool getCfg2JavaTool() { return c2j; } + + public void setMergeMethod(String mergeMethod){ + this.mergeMethod = mergeMethod; + } + + public String getMergeMethod(){ + return this.mergeMethod; + } } Index: src/java/org/hibernate/tool/hbm2x/DocExporter.java =================================================================== --- src/java/org/hibernate/tool/hbm2x/DocExporter.java (revision 16604) +++ src/java/org/hibernate/tool/hbm2x/DocExporter.java (working copy) @@ -610,7 +610,7 @@ protected void processTemplate(Map parameters, String templateName, File outputFile) { - TemplateProducer producer = new TemplateProducer(getTemplateHelper(), getArtifactCollector() ); + TemplateProducer producer = new TemplateProducer(getTemplateHelper(), getArtifactCollector(), getMergeMethod() ); producer.produce(parameters, templateName, outputFile, templateName); } Index: src/java/org/hibernate/tool/hbm2x/Exporter.java =================================================================== --- src/java/org/hibernate/tool/hbm2x/Exporter.java (revision 16604) +++ src/java/org/hibernate/tool/hbm2x/Exporter.java (working copy) @@ -13,6 +13,10 @@ * */ public interface Exporter { + + public static final String OVERWRITE = "overwrite"; + public static final String SKIP = "skip"; + public static final String MERGE = "merge"; /** * @param cfg An Hibernate {@link org.hibernate.Configuration} or subclass instance that defines the hibernate meta model to be exported. @@ -60,4 +64,8 @@ */ public void start(); + public void setMergeMethod(String mergeMethod); + + public String getMergeMethod(); + } Index: src/java/org/hibernate/tool/hbm2x/GenericExporter.java =================================================================== --- src/java/org/hibernate/tool/hbm2x/GenericExporter.java (revision 16604) +++ src/java/org/hibernate/tool/hbm2x/GenericExporter.java (working copy) @@ -27,7 +27,7 @@ modelIterators.put( "configuration", new ModelIterator() { void process(GenericExporter ge) { - TemplateProducer producer = new TemplateProducer(ge.getTemplateHelper(),ge.getArtifactCollector()); + TemplateProducer producer = new TemplateProducer(ge.getTemplateHelper(),ge.getArtifactCollector(), ge.getMergeMethod()); producer.produce(new HashMap(), ge.getTemplateName(), new File(ge.getOutputDirectory(),ge.filePattern), ge.templateName, "Configuration"); } @@ -138,7 +138,7 @@ } protected void exportPOJO(Map additionalContext, POJOClass element) { - TemplateProducer producer = new TemplateProducer(getTemplateHelper(),getArtifactCollector()); + TemplateProducer producer = new TemplateProducer(getTemplateHelper(),getArtifactCollector(), getMergeMethod()); additionalContext.put("pojo", element); additionalContext.put("clazz", element.getDecoratedObject()); String filename = resolveFilename( element ); Index: src/java/org/hibernate/tool/hbm2x/HibernateMappingExporter.java =================================================================== --- src/java/org/hibernate/tool/hbm2x/HibernateMappingExporter.java (revision 16604) +++ src/java/org/hibernate/tool/hbm2x/HibernateMappingExporter.java (working copy) @@ -38,7 +38,7 @@ Cfg2HbmTool c2h = getCfg2HbmTool(); Configuration cfg = getConfiguration(); if(c2h.isImportData(cfg) && (c2h.isNamedQueries(cfg)) && (c2h.isNamedSQLQueries(cfg)) && (c2h.isFilterDefinitions(cfg))) { - TemplateProducer producer = new TemplateProducer(getTemplateHelper(),getArtifactCollector()); + TemplateProducer producer = new TemplateProducer(getTemplateHelper(),getArtifactCollector(), getMergeMethod()); producer.produce(new HashMap(), "hbm/generalhbm.hbm.ftl", new File(getOutputDirectory(),"GeneralHbmSettings.hbm.xml"), getTemplateName(), "General Settings"); } } Index: src/java/org/hibernate/tool/hbm2x/SourceMerger.java =================================================================== --- src/java/org/hibernate/tool/hbm2x/SourceMerger.java (revision 0) +++ src/java/org/hibernate/tool/hbm2x/SourceMerger.java (revision 0) @@ -0,0 +1,87 @@ +package org.hibernate.tool.hbm2x; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.log4j.Logger; +import org.eclipse.emf.codegen.merge.java.JControlModel; +import org.eclipse.emf.codegen.merge.java.JMerger; +import org.eclipse.emf.codegen.merge.java.facade.JCompilationUnit; +import org.eclipse.emf.codegen.merge.java.facade.jdom.JDOMFacadeHelper; +import org.eclipse.emf.codegen.merge.java.facade.jdom.JDOMJCompilationUnit; + +public class SourceMerger { + + protected static final Logger log = Logger.getLogger(SourceMerger.class); + + private JControlModel jControlModel; + + /** + * Does the merge operation and returns the new content. + */ + protected String merge(File targetFile, String newContent) { + try { + final String newSource; + if (targetFile.exists()) { + log.debug("Current source exists, use JMerge"); + final JControlModel jControlModel = getJControlModel(); + final JMerger jMerger = new JMerger(jControlModel); + + jMerger.setFixInterfaceBrace(jControlModel.getFacadeHelper().fixInterfaceBrace()); + jMerger.setTargetCompilationUnit(jMerger.createCompilationUnitForInputStream(getStringInputStream(newContent))); + jMerger.setSourceCompilationUnit(jMerger.createCompilationUnitForInputStream( + loadFileContent(targetFile))); + + jMerger.merge(); + newSource = jMerger.getTargetCompilationUnitContents(); + + jControlModel.getFacadeHelper().reset(); + + return newSource; + } else { + log.debug("Current source does not exist, create one"); + targetFile.createNewFile(); + FileWriter fw = new FileWriter(targetFile); + fw.write(newContent); + fw.flush(); + return newContent; + } + } catch (Exception e) { + throw new RuntimeException("Exception while merging and saving source file " + targetFile, e); + } + } + + public InputStream getStringInputStream(String s){ + return new ByteArrayInputStream(s.getBytes()); + } + + public InputStream loadFileContent(File file) throws IOException{ + return new FileInputStream(file); + } + + /** @return the jMerge control model */ + private JControlModel getJControlModel() { + if (jControlModel == null) { + jControlModel = new JControlModel(); + jControlModel.initialize(new MyJDomFacadeHelper(), this.getClass().getResource("merge.xml") + .toExternalForm()); + } + return jControlModel; + } + + // override method to prevent NPE (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=308069) + class MyJDomFacadeHelper extends JDOMFacadeHelper { + public JCompilationUnit createCompilationUnit(String name, + String contents) { + JDOMJCompilationUnit compilationUnit = (JDOMJCompilationUnit) convertToNode(getJDOMFactory() + .createCompilationUnit(contents, name)); + compilationUnit.setOriginalContent(contents); + + return compilationUnit; + } + } + +} Index: src/java/org/hibernate/tool/hbm2x/TemplateProducer.java =================================================================== --- src/java/org/hibernate/tool/hbm2x/TemplateProducer.java (revision 16604) +++ src/java/org/hibernate/tool/hbm2x/TemplateProducer.java (working copy) @@ -17,13 +17,24 @@ private static final Log log = LogFactory.getLog(TemplateProducer.class); private final TemplateHelper th; private ArtifactCollector ac; + private String mergeMethod; + private SourceMerger merger; - public TemplateProducer(TemplateHelper th, ArtifactCollector ac) { + /*public TemplateProducer(TemplateHelper th, ArtifactCollector ac) { + this(th, ac, Exporter.OVERWRITE); + }*/ + + public TemplateProducer(TemplateHelper th, ArtifactCollector ac, String mergeMethod) { this.th = th; this.ac = ac; + this.mergeMethod = mergeMethod; } public void produce(Map additionalContext, String templateName, File destination, String identifier, String fileType, String rootContext) { + if (Exporter.SKIP.equalsIgnoreCase(mergeMethod) && destination.exists()){ + log.warn("Skipped creation for file " + destination + " as the file already exists."); + return; + } String tempResult = produceToString( additionalContext, templateName, rootContext ); @@ -31,6 +42,12 @@ log.warn("Generated output is empty. Skipped creation for file " + destination); return; } + if ("java".equals(fileType) && Exporter.MERGE.equalsIgnoreCase(mergeMethod) && destination.exists()){ + log.debug("Merging " + identifier + " with " + destination.getAbsolutePath() ); + if (merger == null) merger = new SourceMerger(); + tempResult = merger.merge(destination, tempResult); + } + FileWriter fileWriter = null; try { Index: src/java/org/hibernate/tool/hbm2x/merge.xml =================================================================== --- src/java/org/hibernate/tool/hbm2x/merge.xml (revision 0) +++ src/java/org/hibernate/tool/hbm2x/merge.xml (revision 0) @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: src/test/org/hibernate/tool/ant/AntHibernateToolTest.java =================================================================== --- src/test/org/hibernate/tool/ant/AntHibernateToolTest.java (revision 16604) +++ src/test/org/hibernate/tool/ant/AntHibernateToolTest.java (working copy) @@ -5,6 +5,7 @@ package org.hibernate.tool.ant; import java.io.File; +import java.io.IOException; import junit.framework.Test; import junit.framework.TestSuite; @@ -35,6 +36,10 @@ protected void setUp() throws Exception { super.setUp(); configureProject("src/testsupport/anttest-build.xml"); + property = project.getProperty("build.dir"); + if (new File(property).exists()) { + System.out.println("exists"); + } executeTarget( "cleanup" ); } @@ -223,6 +228,17 @@ assertTrue(new File(property, "generic/org/hibernate/tool/hbm2x/ant/TopDown.quote").exists()); } + public void testGenericExportMerge() throws IOException { + property = project.getProperty("build.dir"); + //create an empty file + File emptyFile = new File(property, "generic\\org\\hibernate\\tool\\hbm2x\\ant\\TopDown.java"); + if (!emptyFile.getParentFile().exists()) emptyFile.getParentFile().mkdirs(); + emptyFile.createNewFile(); + executeTarget("testgeneric_merge"); + assertTrue(emptyFile.exists()); + assertTrue("Empty file was owerriten", emptyFile.length() == 0); + } + public void testNoConnInfoExport() { executeTarget("noconinfoexport"); File baseDir = new File(project.getProperty("build.dir"), "noconinfo"); Index: src/testsupport/anttest-build.xml =================================================================== --- src/testsupport/anttest-build.xml (revision 16604) +++ src/testsupport/anttest-build.xml (working copy) @@ -190,7 +190,21 @@ + + + + + + + + + + + + + +