CAY-2215 split cayenne-tools into cayenne-cgen and cayenne-ant
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/c63b6be2 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/c63b6be2 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/c63b6be2 Branch: refs/heads/master Commit: c63b6be2f27e1bad203d22cab950a87b4f514b38 Parents: 660dd4b Author: Nikita Timofeev <stari...@gmail.com> Authored: Wed Feb 1 16:05:31 2017 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Wed Feb 1 16:05:31 2017 +0300 ---------------------------------------------------------------------- assembly/pom.xml | 8 +- .../resources/assemblies/assembly-generic.xml | 3 +- .../main/resources/assemblies/assembly-mac.xml | 3 +- .../resources/assemblies/assembly-windows.xml | 3 +- build-tools/cayenne-coverage/pom.xml | 2 +- cayenne-ant/pom.xml | 180 +++++ .../cayenne/tools/AntDataPortDelegate.java | 170 +++++ .../org/apache/cayenne/tools/AntLogger.java | 108 +++ .../org/apache/cayenne/tools/AntTableType.java | 35 + .../cayenne/tools/CayenneGeneratorTask.java | 304 ++++++++ .../org/apache/cayenne/tools/CayenneTask.java | 161 ++++ .../org/apache/cayenne/tools/DataPortTask.java | 213 ++++++ .../apache/cayenne/tools/DbGeneratorTask.java | 155 ++++ .../apache/cayenne/tools/DbImporterTask.java | 241 ++++++ .../java/org/apache/cayenne/tools/package.html | 23 + .../org/apache/cayenne/tools/antlib.xml | 25 + .../cayenne/tools/AntDataPortDelegateTest.java | 53 ++ ...eGeneratorTaskCrossMapRelationshipsTest.java | 157 ++++ .../cayenne/tools/CayenneGeneratorTaskTest.java | 317 ++++++++ .../cayenne/tools/DbGeneratorTaskTest.java | 75 ++ .../cayenne/tools/DbImporterTaskTest.java | 229 ++++++ .../src/test/resources/embeddable.map.xml | 27 + .../cayenne/tools/build-catalog-and-schema.xml | 78 ++ .../org/apache/cayenne/tools/build-catalog.xml | 82 ++ .../org/apache/cayenne/tools/build-flat.xml | 73 ++ .../tools/build-include-table.map.xml-result | 37 + .../cayenne/tools/build-include-table.xml | 34 + .../cayenne/tools/build-include-table.xml.sql | 38 + .../org/apache/cayenne/tools/build-mapping.xml | 44 ++ ...ild-reverse-engineering-in-external-file.xml | 33 + .../org/apache/cayenne/tools/build-schema.xml | 83 +++ .../tools/build-skip-primary-key-loading.xml | 35 + .../tools/build-skip-relationships-loading.xml | 35 + .../apache/cayenne/tools/build-table-types.xml | 40 + .../apache/cayenne/tools/cgen-dependent.map.xml | 19 + .../org/apache/cayenne/tools/cgen.map.xml | 15 + .../org/apache/cayenne/tools/velotemplate.vm | 13 + cayenne-ant/src/test/resources/testmap.map.xml | 744 +++++++++++++++++++ cayenne-cgen/pom.xml | 81 ++ .../java/org/apache/cayenne/gen/Artifact.java | 65 ++ .../cayenne/gen/ArtifactGenerationMode.java | 28 + .../cayenne/gen/ArtifactsGenerationMode.java | 40 + .../cayenne/gen/ClassGenerationAction.java | 584 +++++++++++++++ .../gen/ClassGeneratorResourceLoader.java | 102 +++ .../gen/ClientClassGenerationAction.java | 80 ++ .../cayenne/gen/ClientDataMapArtifact.java | 50 ++ .../cayenne/gen/ClientEntityArtifact.java | 45 ++ .../org/apache/cayenne/gen/DataMapArtifact.java | 137 ++++ .../org/apache/cayenne/gen/DataMapUtils.java | 219 ++++++ .../apache/cayenne/gen/EmbeddableArtifact.java | 68 ++ .../org/apache/cayenne/gen/EntityArtifact.java | 98 +++ .../org/apache/cayenne/gen/EntityUtils.java | 274 +++++++ .../org/apache/cayenne/gen/ImportUtils.java | 266 +++++++ .../org/apache/cayenne/gen/StringUtils.java | 213 ++++++ .../org/apache/cayenne/gen/TemplateType.java | 55 ++ .../java/org/apache/cayenne/gen/package.html | 28 + .../CayenneGeneratorEntityFilterAction.java | 85 +++ .../tools/CayenneGeneratorMapLoaderAction.java | 78 ++ .../v1_2/client-datamap-singleclass.vm | 96 +++ .../templates/v1_2/client-datamap-subclass.vm | 47 ++ .../templates/v1_2/client-datamap-superclass.vm | 83 +++ .../resources/templates/v1_2/client-subclass.vm | 57 ++ .../templates/v1_2/client-superclass.vm | 248 +++++++ .../templates/v1_2/datamap-singleclass.vm | 96 +++ .../templates/v1_2/datamap-subclass.vm | 47 ++ .../templates/v1_2/datamap-superclass.vm | 87 +++ .../templates/v1_2/embeddable-singleclass.vm | 106 +++ .../templates/v1_2/embeddable-subclass.vm | 45 ++ .../templates/v1_2/embeddable-superclass.vm | 112 +++ .../resources/templates/v1_2/singleclass.vm | 147 ++++ .../main/resources/templates/v1_2/subclass.vm | 47 ++ .../main/resources/templates/v1_2/superclass.vm | 164 ++++ .../cayenne/gen/ClassGenerationActionTest.java | 256 +++++++ .../apache/cayenne/gen/ClassGenerationCase.java | 59 ++ .../gen/ClientSuperClassGenerationTest.java | 86 +++ .../org/apache/cayenne/gen/EntityUtilsTest.java | 75 ++ .../org/apache/cayenne/gen/ImportUtilsTest.java | 252 +++++++ .../cayenne/gen/SingleClassGenerationTest.java | 86 +++ .../org/apache/cayenne/gen/StringUtilsTest.java | 124 ++++ .../cayenne/gen/SuperClassGenerationTest.java | 86 +++ cayenne-client-jetty/pom.xml | 2 +- cayenne-client/pom.xml | 2 +- cayenne-dbcp2/pom.xml | 2 +- cayenne-dbsync/pom.xml | 2 +- .../dbsync/filter/NamePatternMatcher.java | 27 - .../dbsync/filter/NamePatternMatcherTest.java | 16 - cayenne-di/pom.xml | 2 +- cayenne-joda/pom.xml | 2 +- cayenne-lifecycle/pom.xml | 2 +- cayenne-project/pom.xml | 2 +- cayenne-protostuff/pom.xml | 2 +- cayenne-server/pom.xml | 2 +- cayenne-tools/pom.xml | 193 ----- .../java/org/apache/cayenne/gen/Artifact.java | 65 -- .../cayenne/gen/ArtifactGenerationMode.java | 28 - .../cayenne/gen/ArtifactsGenerationMode.java | 40 - .../cayenne/gen/ClassGenerationAction.java | 584 --------------- .../gen/ClassGeneratorResourceLoader.java | 102 --- .../gen/ClientClassGenerationAction.java | 79 -- .../cayenne/gen/ClientDataMapArtifact.java | 50 -- .../cayenne/gen/ClientEntityArtifact.java | 45 -- .../org/apache/cayenne/gen/DataMapArtifact.java | 137 ---- .../org/apache/cayenne/gen/DataMapUtils.java | 219 ------ .../apache/cayenne/gen/EmbeddableArtifact.java | 68 -- .../org/apache/cayenne/gen/EntityArtifact.java | 98 --- .../org/apache/cayenne/gen/EntityUtils.java | 274 ------- .../org/apache/cayenne/gen/ImportUtils.java | 266 ------- .../org/apache/cayenne/gen/StringUtils.java | 189 ----- .../org/apache/cayenne/gen/TemplateType.java | 55 -- .../java/org/apache/cayenne/gen/package.html | 28 - .../cayenne/tools/AntDataPortDelegate.java | 170 ----- .../org/apache/cayenne/tools/AntLogger.java | 108 --- .../org/apache/cayenne/tools/AntTableType.java | 35 - .../CayenneGeneratorEntityFilterAction.java | 85 --- .../tools/CayenneGeneratorMapLoaderAction.java | 79 -- .../cayenne/tools/CayenneGeneratorTask.java | 304 -------- .../org/apache/cayenne/tools/CayenneTask.java | 161 ---- .../org/apache/cayenne/tools/DataPortTask.java | 213 ------ .../apache/cayenne/tools/DbGeneratorTask.java | 155 ---- .../apache/cayenne/tools/DbImporterTask.java | 241 ------ .../java/org/apache/cayenne/tools/package.html | 23 - .../org/apache/cayenne/tools/antlib.xml | 25 - .../v1_2/client-datamap-singleclass.vm | 96 --- .../templates/v1_2/client-datamap-subclass.vm | 47 -- .../templates/v1_2/client-datamap-superclass.vm | 83 --- .../resources/templates/v1_2/client-subclass.vm | 57 -- .../templates/v1_2/client-superclass.vm | 248 ------- .../templates/v1_2/datamap-singleclass.vm | 96 --- .../templates/v1_2/datamap-subclass.vm | 47 -- .../templates/v1_2/datamap-superclass.vm | 87 --- .../templates/v1_2/embeddable-singleclass.vm | 106 --- .../templates/v1_2/embeddable-subclass.vm | 45 -- .../templates/v1_2/embeddable-superclass.vm | 112 --- .../resources/templates/v1_2/singleclass.vm | 147 ---- .../main/resources/templates/v1_2/subclass.vm | 47 -- .../main/resources/templates/v1_2/superclass.vm | 164 ---- .../cayenne/gen/ClassGenerationActionTest.java | 255 ------- .../apache/cayenne/gen/ClassGenerationCase.java | 59 -- .../gen/ClientSuperClassGenerationTest.java | 86 --- .../org/apache/cayenne/gen/EntityUtilsTest.java | 74 -- .../org/apache/cayenne/gen/ImportUtilsTest.java | 252 ------- .../cayenne/gen/SingleClassGenerationTest.java | 86 --- .../org/apache/cayenne/gen/StringUtilsTest.java | 110 --- .../cayenne/gen/SuperClassGenerationTest.java | 86 --- .../cayenne/tools/AntDataPortDelegateTest.java | 53 -- ...eGeneratorTaskCrossMapRelationshipsTest.java | 157 ---- .../cayenne/tools/CayenneGeneratorTaskTest.java | 317 -------- .../cayenne/tools/DbGeneratorTaskTest.java | 75 -- .../cayenne/tools/DbImporterTaskTest.java | 229 ------ .../src/test/resources/embeddable.map.xml | 27 - .../cayenne/tools/build-catalog-and-schema.xml | 78 -- .../org/apache/cayenne/tools/build-catalog.xml | 82 -- .../org/apache/cayenne/tools/build-flat.xml | 73 -- .../tools/build-include-table.map.xml-result | 37 - .../cayenne/tools/build-include-table.xml | 34 - .../cayenne/tools/build-include-table.xml.sql | 38 - .../org/apache/cayenne/tools/build-mapping.xml | 44 -- ...ild-reverse-engineering-in-external-file.xml | 33 - .../org/apache/cayenne/tools/build-schema.xml | 83 --- .../tools/build-skip-primary-key-loading.xml | 35 - .../tools/build-skip-relationships-loading.xml | 35 - .../apache/cayenne/tools/build-table-types.xml | 40 - .../apache/cayenne/tools/cgen-dependent.map.xml | 19 - .../org/apache/cayenne/tools/cgen.map.xml | 15 - .../org/apache/cayenne/tools/velotemplate.vm | 13 - .../src/test/resources/testmap.map.xml | 744 ------------------- itests/cayenne-tools-itest/pom.xml | 5 - modeler/cayenne-modeler/pom.xml | 8 +- plugins/cayenne-maven-plugin/pom.xml | 24 +- plugins/maven-cayenne-plugin/pom.xml | 6 - pom.xml | 7 +- 171 files changed, 8915 insertions(+), 8865 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/assembly/pom.xml ---------------------------------------------------------------------- diff --git a/assembly/pom.xml b/assembly/pom.xml index 47d73ea..74d643f 100644 --- a/assembly/pom.xml +++ b/assembly/pom.xml @@ -56,7 +56,13 @@ <dependency> <groupId>org.apache.cayenne</groupId> - <artifactId>cayenne-tools</artifactId> + <artifactId>cayenne-cgen</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.cayenne</groupId> + <artifactId>cayenne-ant</artifactId> <version>${project.version}</version> </dependency> http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/assembly/src/main/resources/assemblies/assembly-generic.xml ---------------------------------------------------------------------- diff --git a/assembly/src/main/resources/assemblies/assembly-generic.xml b/assembly/src/main/resources/assemblies/assembly-generic.xml index 5eb4a62..e297a8a 100644 --- a/assembly/src/main/resources/assemblies/assembly-generic.xml +++ b/assembly/src/main/resources/assemblies/assembly-generic.xml @@ -81,7 +81,8 @@ <include>org.apache.cayenne:cayenne-project</include> <include>org.apache.cayenne:cayenne-server</include> <include>org.apache.cayenne:cayenne-dbsync</include> - <include>org.apache.cayenne:cayenne-tools</include> + <include>org.apache.cayenne:cayenne-cgen</include> + <include>org.apache.cayenne:cayenne-ant</include> <include>org.apache.cayenne:cayenne-dbcp2</include> <include>org.apache.cayenne:cayenne-java8</include> </includes> http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/assembly/src/main/resources/assemblies/assembly-mac.xml ---------------------------------------------------------------------- diff --git a/assembly/src/main/resources/assemblies/assembly-mac.xml b/assembly/src/main/resources/assemblies/assembly-mac.xml index 11e3546..8d94bb6 100644 --- a/assembly/src/main/resources/assemblies/assembly-mac.xml +++ b/assembly/src/main/resources/assemblies/assembly-mac.xml @@ -81,7 +81,8 @@ <include>org.apache.cayenne:cayenne-project</include> <include>org.apache.cayenne:cayenne-server</include> <include>org.apache.cayenne:cayenne-dbsync</include> - <include>org.apache.cayenne:cayenne-tools</include> + <include>org.apache.cayenne:cayenne-cgen</include> + <include>org.apache.cayenne:cayenne-ant</include> <include>org.apache.cayenne:cayenne-dbcp2</include> <include>org.apache.cayenne:cayenne-java8</include> </includes> http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/assembly/src/main/resources/assemblies/assembly-windows.xml ---------------------------------------------------------------------- diff --git a/assembly/src/main/resources/assemblies/assembly-windows.xml b/assembly/src/main/resources/assemblies/assembly-windows.xml index efa451d..2dd3781 100644 --- a/assembly/src/main/resources/assemblies/assembly-windows.xml +++ b/assembly/src/main/resources/assemblies/assembly-windows.xml @@ -81,7 +81,8 @@ <include>org.apache.cayenne:cayenne-project</include> <include>org.apache.cayenne:cayenne-server</include> <include>org.apache.cayenne:cayenne-dbsync</include> - <include>org.apache.cayenne:cayenne-tools</include> + <include>org.apache.cayenne:cayenne-cgen</include> + <include>org.apache.cayenne:cayenne-ant</include> <include>org.apache.cayenne:cayenne-dbcp2</include> <include>org.apache.cayenne:cayenne-java8</include> </includes> http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/build-tools/cayenne-coverage/pom.xml ---------------------------------------------------------------------- diff --git a/build-tools/cayenne-coverage/pom.xml b/build-tools/cayenne-coverage/pom.xml index 2a15c13..aa09df8 100644 --- a/build-tools/cayenne-coverage/pom.xml +++ b/build-tools/cayenne-coverage/pom.xml @@ -57,7 +57,7 @@ </dependency> <dependency> <groupId>org.apache.cayenne</groupId> - <artifactId>cayenne-tools</artifactId> + <artifactId>cayenne-ant</artifactId> <version>${cayenne.version}</version> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/pom.xml ---------------------------------------------------------------------- diff --git a/cayenne-ant/pom.xml b/cayenne-ant/pom.xml new file mode 100644 index 0000000..3ef7426 --- /dev/null +++ b/cayenne-ant/pom.xml @@ -0,0 +1,180 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <parent> + <artifactId>cayenne-parent</artifactId> + <groupId>org.apache.cayenne</groupId> + <version>4.0.M5-SNAPSHOT</version> + </parent> + + <modelVersion>4.0.0</modelVersion> + + <artifactId>cayenne-ant</artifactId> + <packaging>jar</packaging> + <name>cayenne-ant: Cayenne Ant Tasks</name> + <dependencies> + <!-- Compile Dependencies --> + <dependency> + <groupId>org.apache.ant</groupId> + <artifactId>ant</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-collections</groupId> + <artifactId>commons-collections</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.velocity</groupId> + <artifactId>velocity</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.cayenne</groupId> + <artifactId>cayenne-cgen</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.cayenne</groupId> + <artifactId>cayenne-dbsync</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>foundrylogic.vpp</groupId> + <artifactId>vpp</artifactId> + <scope>compile</scope> + </dependency> + + <!-- Test Dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.cayenne</groupId> + <artifactId>cayenne-dbsync</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>org.apache.cayenne.build-tools</groupId> + <artifactId>cayenne-test-utilities</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.ant</groupId> + <artifactId>ant-testutil</artifactId> + <version>1.9.4</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.derby</groupId> + <artifactId>derby</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>xmlunit</groupId> + <artifactId>xmlunit</artifactId> + <scope>test</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <!-- This ensures LICENSE and NOTICE inclusion in all jars --> + <plugin> + <artifactId>maven-remote-resources-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>process</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + <profiles> + <profile> + <id>code-quality</id> + + <activation> + <property> + <name>!fast-and-dirty</name> + </property> + </activation> + <build> + <plugins> + <plugin> + <artifactId>maven-checkstyle-plugin</artifactId> + <!--<configuration> + <suppressionsLocation>${project.basedir}/cayenne-checkstyle-suppression.xml</suppressionsLocation> + </configuration>--> + </plugin> + <plugin> + <artifactId>maven-pmd-plugin</artifactId> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntDataPortDelegate.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntDataPortDelegate.java b/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntDataPortDelegate.java new file mode 100644 index 0000000..de001bd --- /dev/null +++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntDataPortDelegate.java @@ -0,0 +1,170 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.tools; + +import org.apache.cayenne.access.DataPort; +import org.apache.cayenne.access.DataPortDelegate; +import org.apache.cayenne.dbsync.filter.NamePatternMatcher; +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.query.Query; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; + +import java.util.Iterator; +import java.util.List; +import java.util.regex.Pattern; + +/** + * DataPortDelegate implementation that works in the context of Ant DataPortTask + * task execution, performing entity filtering and logging functions. + * + * @since 1.2: Prior to 1.2 DataPort classes were a part of cayenne-examples + * package. + * @deprecated since 4.0 + */ +@Deprecated +class AntDataPortDelegate implements DataPortDelegate { + + protected Task parentTask; + + protected Pattern[] mapFilters; + + protected long timestamp; + protected DbEntity lastEntity; + + protected NamePatternMatcher namePatternMatcher; + + // exists for testing and such + AntDataPortDelegate() { + mapFilters = new Pattern[] {}; + } + + AntDataPortDelegate(Task parentTask, String mapsPattern, + String includeEntitiesPattern, String excludeEntitiesPattern) { + this.parentTask = parentTask; + + AntLogger logger = new AntLogger(parentTask); + + this.namePatternMatcher = NamePatternMatcher.build(logger, includeEntitiesPattern, excludeEntitiesPattern); + this.mapFilters = NamePatternMatcher.createPatterns(logger, mapsPattern); + } + + /** + * Applies preconfigured list of filters to the list, removing entities that + * do not pass the filter. + */ + protected List filterEntities(List entities) { + if (entities == null || entities.isEmpty()) { + return entities; + } + + Iterator it = entities.iterator(); + while (it.hasNext()) { + DbEntity entity = (DbEntity) it.next(); + + if (!passedDataMapFilter(entity.getDataMap())) { + it.remove(); + } + } + + namePatternMatcher.filter(entities); + + return entities; + } + + /** + * Returns true if the DataMap passes a set of DataMap filters or if there + * is no DataMap filters. + */ + protected boolean passedDataMapFilter(DataMap map) { + if (mapFilters.length == 0) { + return true; + } + + if (map == null) { + return true; + } + + String mapName = map.getName(); + for (Pattern mapFilter : mapFilters) { + if (mapFilter.matcher(mapName).find()) { + return true; + } + } + + return false; + } + + /** + * Implements the delegate method to filter the list of entities applying + * filtering rules encapsulated by this object. + */ + public List willPortEntities(DataPort portTool, List entities) { + return filterEntities(entities); + } + + /** + * Logs entity porting event using Ant logger. + */ + public Query willPortEntity(DataPort portTool, DbEntity entity, Query query) { + parentTask.log("Porting '" + entity.getName() + "'"); + lastEntity = entity; + timestamp = System.currentTimeMillis(); + return query; + } + + public void didPortEntity(DataPort portTool, DbEntity entity, int rowCount) { + String timestampLabel = ""; + if (lastEntity == entity) { + timestampLabel = " in " + (System.currentTimeMillis() - timestamp) + + " ms."; + } + + String label = (rowCount == 1) ? "1 row transferred" : rowCount + + " rows transferred"; + parentTask.log("Done porting " + entity.getName() + ", " + label + + timestampLabel, Project.MSG_VERBOSE); + } + + public List willCleanData(DataPort portTool, List entities) { + return filterEntities(entities); + } + + public Query willCleanData(DataPort portTool, DbEntity entity, Query query) { + parentTask.log("Deleting " + entity.getName(), Project.MSG_VERBOSE); + lastEntity = entity; + timestamp = System.currentTimeMillis(); + return query; + } + + public void didCleanData(DataPort portTool, DbEntity entity, int rowCount) { + String timestampLabel = ""; + if (lastEntity == entity) { + timestampLabel = " in " + (System.currentTimeMillis() - timestamp) + + " ms."; + } + + String label = (rowCount == 1) ? "1 row deleted" : rowCount + + " rows deleted"; + parentTask.log("Done deleting " + entity.getName() + ", " + label + + timestampLabel, Project.MSG_VERBOSE); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntLogger.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntLogger.java b/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntLogger.java new file mode 100644 index 0000000..4e8e8b5 --- /dev/null +++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntLogger.java @@ -0,0 +1,108 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.tools; + +import org.apache.commons.logging.Log; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; + +/** + * @since 3.0 + */ +class AntLogger implements Log { + + private Task parentTask; + + public AntLogger(Task parentTask) { + this.parentTask = parentTask; + } + + public void debug(Object message, Throwable th) { + parentTask.log(String.valueOf(message), Project.MSG_DEBUG); + } + + public void debug(Object message) { + parentTask.log(String.valueOf(message), Project.MSG_DEBUG); + } + + public void error(Object message, Throwable th) { + parentTask.log(String.valueOf(message), Project.MSG_ERR); + } + + public void error(Object message) { + parentTask.log(String.valueOf(message), Project.MSG_ERR); + } + + public void fatal(Object message, Throwable th) { + parentTask.log(String.valueOf(message), Project.MSG_ERR); + } + + public void fatal(Object message) { + parentTask.log(String.valueOf(message), Project.MSG_ERR); + } + + public void info(Object message, Throwable th) { + parentTask.log(String.valueOf(message), Project.MSG_INFO); + } + + public void info(Object message) { + parentTask.log(String.valueOf(message), Project.MSG_INFO); + } + + public void trace(Object message, Throwable th) { + parentTask.log(String.valueOf(message), Project.MSG_VERBOSE); + } + + public void trace(Object message) { + parentTask.log(String.valueOf(message), Project.MSG_VERBOSE); + } + + public void warn(Object message, Throwable th) { + parentTask.log(String.valueOf(message), Project.MSG_WARN); + } + + public void warn(Object message) { + parentTask.log(String.valueOf(message), Project.MSG_WARN); + } + + public boolean isWarnEnabled() { + return true; + } + + public boolean isDebugEnabled() { + return true; + } + + public boolean isErrorEnabled() { + return true; + } + + public boolean isFatalEnabled() { + return true; + } + + public boolean isInfoEnabled() { + return true; + } + + public boolean isTraceEnabled() { + return true; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntTableType.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntTableType.java b/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntTableType.java new file mode 100644 index 0000000..d195f9a --- /dev/null +++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/AntTableType.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cayenne.tools; + +public class AntTableType { + private String name; + + public void addText(String string) { + setName(string); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/java/org/apache/cayenne/tools/CayenneGeneratorTask.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/CayenneGeneratorTask.java b/cayenne-ant/src/main/java/org/apache/cayenne/tools/CayenneGeneratorTask.java new file mode 100644 index 0000000..d57b350 --- /dev/null +++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/CayenneGeneratorTask.java @@ -0,0 +1,304 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ +package org.apache.cayenne.tools; + +import foundrylogic.vpp.VPPConfig; +import org.apache.cayenne.dbsync.filter.NamePatternMatcher; +import org.apache.cayenne.gen.ArtifactsGenerationMode; +import org.apache.cayenne.gen.ClassGenerationAction; +import org.apache.cayenne.gen.ClientClassGenerationAction; +import org.apache.cayenne.map.DataMap; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Path; +import org.apache.velocity.VelocityContext; + +import java.io.File; + +/** + * An Ant task to perform class generation based on CayenneDataMap. + * + * @since 3.0 + */ +public class CayenneGeneratorTask extends CayenneTask { + + protected String includeEntitiesPattern; + protected String excludeEntitiesPattern; + protected VPPConfig vppConfig; + + protected File map; + protected File additionalMaps[]; + protected boolean client; + protected File destDir; + protected String encoding; + protected boolean makepairs; + protected String mode; + protected String outputPattern; + protected boolean overwrite; + protected String superpkg; + protected String supertemplate; + protected String template; + protected String embeddabletemplate; + protected String embeddablesupertemplate; + protected String querytemplate; + protected String querysupertemplate; + protected boolean usepkgpath; + protected boolean createpropertynames; + + public CayenneGeneratorTask() { + this.makepairs = true; + this.mode = ArtifactsGenerationMode.ENTITY.getLabel(); + this.outputPattern = "*.java"; + this.usepkgpath = true; + } + + protected VelocityContext getVppContext() { + initializeVppConfig(); + return vppConfig.getVelocityContext(); + } + + protected ClassGenerationAction createGeneratorAction() { + ClassGenerationAction action = client ? new ClientClassGenerationAction() : new ClassGenerationAction(); + + action.setContext(getVppContext()); + action.setDestDir(destDir); + action.setEncoding(encoding); + action.setMakePairs(makepairs); + action.setArtifactsGenerationMode(mode); + action.setOutputPattern(outputPattern); + action.setOverwrite(overwrite); + action.setSuperPkg(superpkg); + action.setSuperTemplate(supertemplate); + action.setTemplate(template); + action.setEmbeddableSuperTemplate(embeddablesupertemplate); + action.setEmbeddableTemplate(embeddabletemplate); + action.setQueryTemplate(querytemplate); + action.setQuerySuperTemplate(querysupertemplate); + action.setUsePkgPath(usepkgpath); + action.setCreatePropertyNames(createpropertynames); + + return action; + } + + /** + * Executes the task. It will be called by ant framework. + */ + @Override + public void execute() throws BuildException { + validateAttributes(); + + AntLogger logger = new AntLogger(this); + CayenneGeneratorMapLoaderAction loadAction = new CayenneGeneratorMapLoaderAction(); + + loadAction.setMainDataMapFile(map); + loadAction.setAdditionalDataMapFiles(additionalMaps); + + CayenneGeneratorEntityFilterAction filterAction = new CayenneGeneratorEntityFilterAction(); + filterAction.setClient(client); + filterAction.setNameFilter(NamePatternMatcher.build(logger, includeEntitiesPattern, excludeEntitiesPattern)); + + try { + + DataMap dataMap = loadAction.getMainDataMap(); + + ClassGenerationAction generatorAction = createGeneratorAction(); + generatorAction.setLogger(logger); + generatorAction.setTimestamp(map.lastModified()); + generatorAction.setDataMap(dataMap); + generatorAction.addEntities(filterAction.getFilteredEntities(dataMap)); + generatorAction.addEmbeddables(filterAction.getFilteredEmbeddables(dataMap)); + generatorAction.addQueries(dataMap.getQueryDescriptors()); + generatorAction.execute(); + } + catch (Exception e) { + throw new BuildException(e); + } + } + + /** + * Validates attributes that are not related to internal DefaultClassGenerator. Throws + * BuildException if attributes are invalid. + */ + protected void validateAttributes() throws BuildException { + if (map == null && this.getProject() == null) { + throw new BuildException("either 'map' or 'project' is required."); + } + } + + /** + * Sets the map. + * + * @param map The map to set + */ + public void setMap(File map) { + this.map = map; + } + + /** + * Sets the additional DataMaps. + * + * @param additionalMapsPath The additional DataMaps to set + */ + public void setAdditionalMaps(Path additionalMapsPath) { + String additionalMapFilenames[] = additionalMapsPath.list(); + this.additionalMaps = new File[additionalMapFilenames.length]; + + for (int i = 0; i < additionalMapFilenames.length; i++) { + additionalMaps[i] = new File(additionalMapFilenames[i]); + } + } + + /** + * Sets the destDir. + */ + public void setDestDir(File destDir) { + this.destDir = destDir; + } + + /** + * Sets <code>overwrite</code> property. + */ + public void setOverwrite(boolean overwrite) { + this.overwrite = overwrite; + } + + /** + * Sets <code>makepairs</code> property. + */ + public void setMakepairs(boolean makepairs) { + this.makepairs = makepairs; + } + + /** + * Sets <code>template</code> property. + */ + public void setTemplate(String template) { + this.template = template; + } + + /** + * Sets <code>supertemplate</code> property. + */ + public void setSupertemplate(String supertemplate) { + this.supertemplate = supertemplate; + } + + /** + * Sets <code>querytemplate</code> property. + */ + public void setQueryTemplate(String querytemplate) { + this.querytemplate = querytemplate; + } + + /** + * Sets <code>querysupertemplate</code> property. + */ + public void setQuerySupertemplate(String querysupertemplate) { + this.querysupertemplate = querysupertemplate; + } + + /** + * Sets <code>usepkgpath</code> property. + */ + public void setUsepkgpath(boolean usepkgpath) { + this.usepkgpath = usepkgpath; + } + + /** + * Sets <code>superpkg</code> property. + */ + public void setSuperpkg(String superpkg) { + this.superpkg = superpkg; + } + + /** + * Sets <code>client</code> property. + */ + public void setClient(boolean client) { + this.client = client; + } + + /** + * Sets <code>encoding</code> property that allows to generate files using non-default + * encoding. + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * Sets <code>excludeEntitiesPattern</code> property. + */ + public void setExcludeEntities(String excludeEntitiesPattern) { + this.excludeEntitiesPattern = excludeEntitiesPattern; + } + + /** + * Sets <code>includeEntitiesPattern</code> property. + */ + public void setIncludeEntities(String includeEntitiesPattern) { + this.includeEntitiesPattern = includeEntitiesPattern; + } + + /** + * Sets <code>outputPattern</code> property. + */ + public void setOutputPattern(String outputPattern) { + this.outputPattern = outputPattern; + } + + /** + * Sets <code>mode</code> property. + */ + public void setMode(String mode) { + this.mode = mode; + } + + /** + * Sets <code>createpropertynames</code> property. + */ + public void setCreatepropertynames(boolean createpropertynames) { + this.createpropertynames = createpropertynames; + } + + public void setEmbeddabletemplate(String embeddabletemplate) { + this.embeddabletemplate = embeddabletemplate; + } + + public void setEmbeddablesupertemplate(String embeddablesupertemplate) { + this.embeddablesupertemplate = embeddablesupertemplate; + } + + /** + * Provides a <code>VPPConfig</code> object to configure. (Written with createConfig() + * instead of addConfig() to avoid run-time dependency on VPP). + */ + public Object createConfig() { + this.vppConfig = new VPPConfig(); + return this.vppConfig; + } + + /** + * If no VppConfig element specified, use the default one. + */ + private void initializeVppConfig() { + if (vppConfig == null) { + vppConfig = VPPConfig.getDefaultConfig(getProject()); + } + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/java/org/apache/cayenne/tools/CayenneTask.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/CayenneTask.java b/cayenne-ant/src/main/java/org/apache/cayenne/tools/CayenneTask.java new file mode 100644 index 0000000..2bff0e3 --- /dev/null +++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/CayenneTask.java @@ -0,0 +1,161 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.tools; + +import java.io.File; + +import javax.sql.DataSource; + +import org.apache.cayenne.configuration.DataNodeDescriptor; +import org.apache.cayenne.configuration.server.DbAdapterFactory; +import org.apache.cayenne.dba.DbAdapter; +import org.apache.cayenne.di.Injector; +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.map.MapLoader; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.Reference; +import org.xml.sax.InputSource; + +/** + * Base task for all Cayenne ant tasks, providing support for common + * configuration items. + * + * @since 1.2 + */ +public abstract class CayenneTask extends Task { + protected Path classpath; + + protected String adapter; + protected File map; + protected String driver; + protected String url; + protected String userName; + protected String password; + + /** + * Sets the classpath used by the task. + * + * @param path + * The classpath to set. + */ + public void setClasspath(Path path) { + createClasspath().append(path); + } + + /** + * Sets the classpath reference used by the task. + * + * @param reference + * The classpath reference to set. + */ + public void setClasspathRef(Reference reference) { + createClasspath().setRefid(reference); + } + + /** + * Convenience method for creating a classpath instance to be used for the + * task. + * + * @return The new classpath. + */ + private Path createClasspath() { + if (null == classpath) { + classpath = new Path(getProject()); + } + + return classpath.createPath(); + } + + /** + * Sets the map. + * + * @param map + * The map to set + */ + public void setMap(File map) { + this.map = map; + } + + /** + * Sets the db adapter. + * + * @param adapter + * The db adapter to set. + */ + public void setAdapter(String adapter) { + this.adapter = adapter; + } + + /** + * Sets the JDBC driver used to connect to the database server. + * + * @param driver + * The driver to set. + */ + public void setDriver(String driver) { + this.driver = driver; + } + + /** + * Sets the JDBC URL used to connect to the database server. + * + * @param url + * The url to set. + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * Sets the username used to connect to the database server. + */ + public void setUserName(String username) { + this.userName = username; + } + + /** + * Sets the password used to connect to the database server. + * + * @param password + * The password to set. + */ + public void setPassword(String password) { + this.password = password; + } + + /** Loads and returns DataMap based on <code>map</code> attribute. */ + protected DataMap loadDataMap() throws Exception { + InputSource in = new InputSource(map.getCanonicalPath()); + return new MapLoader().loadDataMap(in); + } + + protected DbAdapter getAdapter(Injector injector, DataSource dataSource) + throws Exception { + + DbAdapterFactory adapterFactory = injector + .getInstance(DbAdapterFactory.class); + + DataNodeDescriptor nodeDescriptor = new DataNodeDescriptor(); + nodeDescriptor.setAdapterType(adapter); + + return adapterFactory.createAdapter(nodeDescriptor, dataSource); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/java/org/apache/cayenne/tools/DataPortTask.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/DataPortTask.java b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DataPortTask.java new file mode 100644 index 0000000..4b24035 --- /dev/null +++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DataPortTask.java @@ -0,0 +1,213 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.tools; + +import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.access.DataNode; +import org.apache.cayenne.access.DataPort; +import org.apache.cayenne.configuration.Constants; +import org.apache.cayenne.configuration.server.ServerRuntime; +import org.apache.cayenne.di.Binder; +import org.apache.cayenne.di.Key; +import org.apache.cayenne.di.Module; +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.resource.FilesystemResourceLocator; +import org.apache.cayenne.resource.ResourceLocator; +import org.apache.cayenne.util.Util; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; + +import java.io.File; +import java.util.Collection; +import java.util.HashSet; + +/** + * A "cdataport" Ant task implementing a frontend to DataPort allowing porting + * database data using Ant build scripts. + * + * @since 1.2: Prior to 1.2 DataPort classes were a part of cayenne-examples + * package. + * @deprecated since 4.0 + */ +@Deprecated +public class DataPortTask extends CayenneTask { + + protected File projectFile; + protected String maps; + protected String srcNode; + protected String destNode; + protected String includeTables; + protected String excludeTables; + protected boolean cleanDest = true; + + public DataPortTask() { + // set defaults + this.cleanDest = true; + } + + @Override + public void execute() throws BuildException { + + log("*** 'cdataport' task is deprecated and will be removed after 4.0", + Project.MSG_WARN); + + validateParameters(); + + String projectFileLocation = projectFile.getName(); + Module dataPortModule = new Module() { + + public void configure(Binder binder) { + FilesystemResourceLocator filesystemResourceLocator = new FilesystemResourceLocator(projectFile); + binder.bind(ResourceLocator.class).toInstance(filesystemResourceLocator); + binder.bind(Key.get(ResourceLocator.class, Constants.SERVER_RESOURCE_LOCATOR)) + .toInstance(filesystemResourceLocator); + } + }; + + ServerRuntime runtime = new ServerRuntime(projectFileLocation, + dataPortModule); + DataDomain domain; + + ClassLoader threadContextClassLoader = Thread.currentThread() + .getContextClassLoader(); + try { + // need to set context class loader so that cayenne can find jdbc + // driver and + // PasswordEncoder + // TODO: andrus 04/11/2010 is this still relevant in 3.1? + Thread.currentThread().setContextClassLoader( + getClass().getClassLoader()); + + domain = runtime.getDataDomain(); + } catch (Exception ex) { + throw new BuildException( + "Error loading Cayenne configuration from " + projectFile, + ex); + } finally { + // set back to original ClassLoader + Thread.currentThread().setContextClassLoader( + threadContextClassLoader); + } + + // perform project validation + DataNode source = domain.getDataNode(srcNode); + if (source == null) { + throw new BuildException("srcNode not found in the project: " + + srcNode); + } + + DataNode destination = domain.getDataNode(destNode); + if (destination == null) { + throw new BuildException("destNode not found in the project: " + + destNode); + } + + log("Porting from '" + srcNode + "' to '" + destNode + "'."); + + AntDataPortDelegate portDelegate = new AntDataPortDelegate(this, maps, + includeTables, excludeTables); + DataPort dataPort = new DataPort(portDelegate); + dataPort.setEntities(getAllEntities(source, destination)); + dataPort.setCleaningDestination(cleanDest); + dataPort.setSourceNode(source); + dataPort.setDestinationNode(destination); + + try { + dataPort.execute(); + } catch (Exception e) { + Throwable topOfStack = Util.unwindException(e); + throw new BuildException("Error porting data: " + + topOfStack.getMessage(), topOfStack); + } + } + + protected Collection<DbEntity> getAllEntities(DataNode source, + DataNode target) { + // use a set to exclude duplicates, though a valid project will probably + // have + // none... + Collection<DbEntity> allEntities = new HashSet<DbEntity>(); + + for (DataMap map : source.getDataMaps()) { + allEntities.addAll(map.getDbEntities()); + } + + for (DataMap map : target.getDataMaps()) { + allEntities.addAll(map.getDbEntities()); + } + + log("Number of entities: " + allEntities.size(), Project.MSG_VERBOSE); + + if (allEntities.size() == 0) { + log("No entities found for either source or target."); + } + return allEntities; + } + + protected void validateParameters() throws BuildException { + if (projectFile == null) { + throw new BuildException( + "Required 'projectFile' parameter is missing."); + } + + if (!projectFile.exists()) { + throw new BuildException("'projectFile' does not exist: " + + projectFile); + } + + if (srcNode == null) { + throw new BuildException("Required 'srcNode' parameter is missing."); + } + + if (destNode == null) { + throw new BuildException( + "Required 'destNode' parameter is missing."); + } + } + + public void setDestNode(String destNode) { + this.destNode = destNode; + } + + public void setExcludeTables(String excludeTables) { + this.excludeTables = excludeTables; + } + + public void setIncludeTables(String includeTables) { + this.includeTables = includeTables; + } + + public void setMaps(String maps) { + this.maps = maps; + } + + public void setProjectFile(File projectFile) { + this.projectFile = projectFile; + } + + public void setSrcNode(String srcNode) { + this.srcNode = srcNode; + } + + public void setCleanDest(boolean flag) { + this.cleanDest = flag; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbGeneratorTask.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbGeneratorTask.java b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbGeneratorTask.java new file mode 100644 index 0000000..ce2e574 --- /dev/null +++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbGeneratorTask.java @@ -0,0 +1,155 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.tools; + +import org.apache.cayenne.access.DbGenerator; +import org.apache.cayenne.datasource.DriverDataSource; +import org.apache.cayenne.dba.DbAdapter; +import org.apache.cayenne.dbsync.DbSyncModule; +import org.apache.cayenne.di.DIBootstrap; +import org.apache.cayenne.di.Injector; +import org.apache.cayenne.log.NoopJdbcEventLogger; +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.dbsync.reverse.configuration.ToolsModule; +import org.apache.cayenne.util.Util; +import org.apache.commons.logging.Log; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; + +import java.sql.Driver; +import java.util.Collections; + +/** + * An Ant Task that is a frontend to Cayenne DbGenerator allowing schema + * generation from DataMap using Ant. + * + * @since 1.2 + */ +// TODO: support classpath attribute for loading the driver +public class DbGeneratorTask extends CayenneTask { + + // DbGenerator options... setup defaults similar to DbGenerator itself: + // all DROP set to false, all CREATE - to true + protected boolean dropTables; + protected boolean dropPK; + protected boolean createTables = true; + protected boolean createPK = true; + protected boolean createFK = true; + + @Override + public void execute() { + + Log logger = new AntLogger(this); + + log(String.format("connection settings - [driver: %s, url: %s, username: %s]", driver, url, userName), + Project.MSG_VERBOSE); + + log(String.format( + "generator options - [dropTables: %s, dropPK: %s, createTables: %s, createPK: %s, createFK: %s]", + dropTables, dropPK, createTables, createPK, createFK), Project.MSG_VERBOSE); + + validateAttributes(); + + ClassLoader loader = null; + Injector injector = DIBootstrap.createInjector(new DbSyncModule(), new ToolsModule(logger)); + try { + loader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(DbGeneratorTask.class.getClassLoader()); + + // Load the data map and run the db generator. + DataMap dataMap = loadDataMap(); + + // load driver taking custom CLASSPATH into account... + DriverDataSource dataSource = new DriverDataSource((Driver) Class.forName(driver).newInstance(), url, + userName, password); + + DbAdapter adapter = getAdapter(injector, dataSource); + + DbGenerator generator = new DbGenerator(adapter, dataMap, Collections.<DbEntity> emptyList(), null, + NoopJdbcEventLogger.getInstance()); + generator.setShouldCreateFKConstraints(createFK); + generator.setShouldCreatePKSupport(createPK); + generator.setShouldCreateTables(createTables); + generator.setShouldDropPKSupport(dropPK); + generator.setShouldDropTables(dropTables); + + generator.runGenerator(dataSource); + } catch (Exception ex) { + Throwable th = Util.unwindException(ex); + + String message = "Error generating database"; + + if (th.getLocalizedMessage() != null) { + message += ": " + th.getLocalizedMessage(); + } + + log(message, Project.MSG_ERR); + throw new BuildException(message, th); + } finally { + Thread.currentThread().setContextClassLoader(loader); + injector.shutdown(); + } + } + + /** + * Validates attributes that are not related to internal + * DefaultClassGenerator. Throws BuildException if attributes are invalid. + */ + protected void validateAttributes() throws BuildException { + StringBuilder error = new StringBuilder(""); + + if (map == null) { + error.append("The 'map' attribute must be set.\n"); + } + + if (driver == null) { + error.append("The 'driver' attribute must be set.\n"); + } + + if (url == null) { + error.append("The 'adapter' attribute must be set.\n"); + } + + if (error.length() > 0) { + throw new BuildException(error.toString()); + } + } + + public void setCreateFK(boolean createFK) { + this.createFK = createFK; + } + + public void setCreatePK(boolean createPK) { + this.createPK = createPK; + } + + public void setCreateTables(boolean createTables) { + this.createTables = createTables; + } + + public void setDropPK(boolean dropPK) { + this.dropPK = dropPK; + } + + public void setDropTables(boolean dropTables) { + this.dropTables = dropTables; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java new file mode 100644 index 0000000..6c939c1 --- /dev/null +++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/DbImporterTask.java @@ -0,0 +1,241 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ +package org.apache.cayenne.tools; + +import org.apache.cayenne.conn.DataSourceInfo; +import org.apache.cayenne.dbsync.DbSyncModule; +import org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator; +import org.apache.cayenne.dbsync.reverse.configuration.ToolsModule; +import org.apache.cayenne.dbsync.reverse.dbimport.Catalog; +import org.apache.cayenne.dbsync.reverse.dbimport.DbImportAction; +import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfigurationValidator; +import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfiguration; +import org.apache.cayenne.dbsync.reverse.dbimport.DbImportModule; +import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeColumn; +import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeProcedure; +import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable; +import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn; +import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure; +import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable; +import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering; +import org.apache.cayenne.dbsync.reverse.dbimport.Schema; +import org.apache.cayenne.dbsync.reverse.filters.FiltersConfigBuilder; +import org.apache.cayenne.di.DIBootstrap; +import org.apache.cayenne.di.Injector; +import org.apache.cayenne.util.Util; +import org.apache.commons.logging.Log; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; + +import java.io.File; + +public class DbImporterTask extends Task { + + private final DbImportConfiguration config; + private ReverseEngineering reverseEngineering; + + public DbImporterTask() { + this.config = new DbImportConfiguration(); + this.config.setUsePrimitives(true); + this.config.setNamingStrategy(DefaultObjectNameGenerator.class.getName()); + + // reverse engineering config is flattened into task... + this.reverseEngineering = new ReverseEngineering(); + } + + public void addIncludeColumn(IncludeColumn includeColumn) { + reverseEngineering.addIncludeColumn(includeColumn); + } + + public void addExcludeColumn(ExcludeColumn excludeColumn) { + reverseEngineering.addExcludeColumn(excludeColumn); + } + + public void addIncludeTable(IncludeTable includeTable) { + reverseEngineering.addIncludeTable(includeTable); + } + + public void addExcludeTable(ExcludeTable excludeTable) { + reverseEngineering.addExcludeTable(excludeTable); + } + + public void addIncludeProcedure(IncludeProcedure includeProcedure) { + reverseEngineering.addIncludeProcedure(includeProcedure); + } + + public void addExcludeProcedure(ExcludeProcedure excludeProcedure) { + reverseEngineering.addExcludeProcedure(excludeProcedure); + } + + public void setSkipRelationshipsLoading(boolean skipRelationshipsLoading) { + reverseEngineering.setSkipRelationshipsLoading(skipRelationshipsLoading); + } + + public void setSkipPrimaryKeyLoading(boolean skipPrimaryKeyLoading) { + reverseEngineering.setSkipPrimaryKeyLoading(skipPrimaryKeyLoading); + } + + public void addConfiguredTableType(AntTableType type) { + reverseEngineering.addTableType(type.getName()); + } + + public void addConfiguredSchema(Schema schema) { + reverseEngineering.addSchema(schema); + } + + public void addCatalog(Catalog catalog) { + reverseEngineering.addCatalog(catalog); + } + + @Override + public void execute() { + config.setFiltersConfig(new FiltersConfigBuilder(reverseEngineering).build()); + validateAttributes(); + + Log logger = new AntLogger(this); + config.setLogger(logger); + config.setSkipRelationshipsLoading(reverseEngineering.getSkipRelationshipsLoading()); + config.setSkipPrimaryKeyLoading(reverseEngineering.getSkipPrimaryKeyLoading()); + config.setTableTypes(reverseEngineering.getTableTypes()); + + Injector injector = DIBootstrap.createInjector(new DbSyncModule(), new ToolsModule(logger), new DbImportModule()); + DbImportConfigurationValidator validator = new DbImportConfigurationValidator(reverseEngineering, config, injector); + try { + validator.validate(); + } catch (Exception ex) { + throw new BuildException(ex.getMessage(), ex); + } + + try { + injector.getInstance(DbImportAction.class).execute(config); + } catch (Exception ex) { + Throwable th = Util.unwindException(ex); + + String message = "Error importing database schema"; + + if (th.getLocalizedMessage() != null) { + message += ": " + th.getLocalizedMessage(); + } + + log(message, Project.MSG_ERR); + throw new BuildException(message, th); + } finally { + injector.shutdown(); + } + } + + /** + * Validates attributes that are not related to internal + * DefaultClassGenerator. Throws BuildException if attributes are invalid. + */ + protected void validateAttributes() throws BuildException { + StringBuilder error = new StringBuilder(""); + + if (config.getTargetDataMap() == null) { + error.append("The 'map' attribute must be set.\n"); + } + + DataSourceInfo dataSourceInfo = config.getDataSourceInfo(); + if (dataSourceInfo.getJdbcDriver() == null) { + error.append("The 'driver' attribute must be set.\n"); + } + + if (dataSourceInfo.getDataSourceUrl() == null) { + error.append("The 'url' attribute must be set.\n"); + } + + if (error.length() > 0) { + throw new BuildException(error.toString()); + } + } + + /** + * @since 4.0 + */ + public void setDefaultPackage(String defaultPackage) { + config.setDefaultPackage(defaultPackage); + } + + /** + * @since 4.0 + */ + public void setMeaningfulPkTables(String meaningfulPkTables) { + config.setMeaningfulPkTables(meaningfulPkTables); + } + + public void setNamingStrategy(String namingStrategy) { + config.setNamingStrategy(namingStrategy); + } + + /** + * @since 4.0 + */ + public void setStripFromTableNames(String pattern) { + config.setStripFromTableNames(pattern); + } + + public void setAdapter(String adapter) { + config.setAdapter(adapter); + } + + public void setDriver(String driver) { + config.setDriver(driver); + } + + public void setPassword(String password) { + config.setPassword(password); + } + + public void setUrl(String url) { + config.setUrl(url); + } + + public void setUserName(String username) { + config.setUsername(username); + } + + public void setUsePrimitives(boolean flag) { + config.setUsePrimitives(flag); + } + + public void setForceDataMapCatalog(boolean flag) { + config.setForceDataMapCatalog(flag); + } + + public void setForceDataMapSchema(boolean flag) { + config.setForceDataMapSchema(flag); + } + + public ReverseEngineering getReverseEngineering() { + return reverseEngineering; + } + + public File getMap() { + return config.getTargetDataMap(); + } + + public void setMap(File map) { + config.setTargetDataMap(map); + } + + public DbImportConfiguration toParameters() { + return config; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/java/org/apache/cayenne/tools/package.html ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/java/org/apache/cayenne/tools/package.html b/cayenne-ant/src/main/java/org/apache/cayenne/tools/package.html new file mode 100644 index 0000000..f25bcbe --- /dev/null +++ b/cayenne-ant/src/main/java/org/apache/cayenne/tools/package.html @@ -0,0 +1,23 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<html> +<body> +Command line tools and Ant tasks. +</body> +</html> http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/main/resources/org/apache/cayenne/tools/antlib.xml ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/main/resources/org/apache/cayenne/tools/antlib.xml b/cayenne-ant/src/main/resources/org/apache/cayenne/tools/antlib.xml new file mode 100644 index 0000000..bfebaf6 --- /dev/null +++ b/cayenne-ant/src/main/resources/org/apache/cayenne/tools/antlib.xml @@ -0,0 +1,25 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<antlib> + <taskdef name="cgen" classname="org.apache.cayenne.tools.CayenneGeneratorTask"/> + <taskdef name="cdbgen" classname="org.apache.cayenne.tools.DbGeneratorTask"/> + <taskdef name="cdataport" classname="org.apache.cayenne.tools.DataPortTask"/> + <taskdef name="cdbimport" classname="org.apache.cayenne.tools.DbImporterTask"/> +</antlib> http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/test/java/org/apache/cayenne/tools/AntDataPortDelegateTest.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/test/java/org/apache/cayenne/tools/AntDataPortDelegateTest.java b/cayenne-ant/src/test/java/org/apache/cayenne/tools/AntDataPortDelegateTest.java new file mode 100644 index 0000000..584d4c8 --- /dev/null +++ b/cayenne-ant/src/test/java/org/apache/cayenne/tools/AntDataPortDelegateTest.java @@ -0,0 +1,53 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.tools; + +import org.apache.cayenne.map.DataMap; +import org.junit.Test; + +import java.util.regex.Pattern; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@Deprecated +public class AntDataPortDelegateTest { + + @Test + public void testPassedDataMapFilter() { + AntDataPortDelegate delegate = new AntDataPortDelegate(); + + // filtering should be done based on map name + + DataMap map = new DataMap(); + assertTrue(delegate.passedDataMapFilter(map)); + + map.setName("A"); + assertTrue(delegate.passedDataMapFilter(map)); + + delegate.mapFilters = new Pattern[] { + Pattern.compile("B") + }; + assertFalse(delegate.passedDataMapFilter(map)); + + map.setName("BBBB"); + assertTrue(delegate.passedDataMapFilter(map)); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/c63b6be2/cayenne-ant/src/test/java/org/apache/cayenne/tools/CayenneGeneratorTaskCrossMapRelationshipsTest.java ---------------------------------------------------------------------- diff --git a/cayenne-ant/src/test/java/org/apache/cayenne/tools/CayenneGeneratorTaskCrossMapRelationshipsTest.java b/cayenne-ant/src/test/java/org/apache/cayenne/tools/CayenneGeneratorTaskCrossMapRelationshipsTest.java new file mode 100644 index 0000000..40877b8 --- /dev/null +++ b/cayenne-ant/src/test/java/org/apache/cayenne/tools/CayenneGeneratorTaskCrossMapRelationshipsTest.java @@ -0,0 +1,157 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.tools; + +import org.apache.cayenne.test.file.FileUtil; +import org.apache.cayenne.test.resource.ResourceUtil; +import org.apache.tools.ant.Location; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.FileList; +import org.apache.tools.ant.types.Path; +import org.junit.Test; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.regex.Pattern; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class CayenneGeneratorTaskCrossMapRelationshipsTest { + + /** + * Tests pairs generation with a cross-DataMap relationship. + */ + @Test + public void testCrossDataMapRelationships() throws Exception { + + CayenneGeneratorTask task = new CayenneGeneratorTask(); + task.setProject(new Project()); + task.setTaskName("Test"); + task.setLocation(Location.UNKNOWN_LOCATION); + + // prepare destination directory + + File destDir = new File(FileUtil.baseTestDirectory(), "cgen12"); + // prepare destination directory + if (!destDir.exists()) { + assertTrue(destDir.mkdirs()); + } + + File map = new File(destDir, "cgen-dependent.map.xml"); + ResourceUtil.copyResourceToFile("org/apache/cayenne/tools/cgen-dependent.map.xml", map); + + File additionalMaps[] = new File[1]; + additionalMaps[0] = new File(destDir, "cgen.map.xml"); + ResourceUtil.copyResourceToFile("org/apache/cayenne/tools/cgen.map.xml", additionalMaps[0]); + + FileList additionalMapsFilelist = new FileList(); + additionalMapsFilelist.setDir(additionalMaps[0].getParentFile()); + additionalMapsFilelist.setFiles(additionalMaps[0].getName()); + + Path additionalMapsPath = new Path(task.getProject()); + additionalMapsPath.addFilelist(additionalMapsFilelist); + + // setup task + task.setMap(map); + task.setAdditionalMaps(additionalMapsPath); + task.setMakepairs(true); + task.setOverwrite(false); + task.setMode("entity"); + task.setIncludeEntities("MyArtGroup"); + task.setDestDir(destDir); + task.setSuperpkg("org.apache.cayenne.testdo.cgen2.auto"); + task.setUsepkgpath(true); + + // run task + task.execute(); + + // check results + File a = new File(destDir, convertPath("org/apache/cayenne/testdo/cgen2/MyArtGroup.java")); + assertTrue(a.isFile()); + assertContents(a, "MyArtGroup", "org.apache.cayenne.testdo.cgen2", "_MyArtGroup"); + + File _a = new File(destDir, convertPath("org/apache/cayenne/testdo/cgen2/auto/_MyArtGroup.java")); + assertTrue(_a.exists()); + assertContents(_a, "_MyArtGroup", "org.apache.cayenne.testdo.cgen2.auto", "CayenneDataObject"); + assertContents(_a, "import org.apache.cayenne.testdo.testmap.ArtGroup;"); + assertContents(_a, " ArtGroup getToParentGroup()"); + assertContents(_a, "setToParentGroup(ArtGroup toParentGroup)"); + } + + private String convertPath(String unixPath) { + return unixPath.replace('/', File.separatorChar); + } + + private void assertContents(File f, String content) throws Exception { + + try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(f)));) { + String s = null; + while ((s = in.readLine()) != null) { + if (s.contains(content)) + return; + } + + fail("<" + content + "> not found in " + f.getAbsolutePath() + "."); + } + + } + + private void assertContents(File f, String className, String packageName, String extendsName) throws Exception { + + try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(f)));) { + assertPackage(in, packageName); + assertClass(in, className, extendsName); + } + } + + private void assertPackage(BufferedReader in, String packageName) throws Exception { + + String s = null; + while ((s = in.readLine()) != null) { + + if (Pattern.matches("^package\\s+([^\\s;]+);", s)) { + assertTrue(s.contains(packageName)); + return; + } + } + + fail("No package declaration found."); + } + + private void assertClass(BufferedReader in, String className, String extendsName) throws Exception { + + Pattern classPattern = Pattern.compile("^public\\s+"); + + String s = null; + while ((s = in.readLine()) != null) { + if (classPattern.matcher(s).find()) { + assertTrue(s.contains(className)); + assertTrue(s.contains(extendsName)); + assertTrue(s.indexOf(className) < s.indexOf(extendsName)); + return; + } + } + + fail("No class declaration found."); + } +}