You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by ab...@apache.org on 2019/04/24 11:27:36 UTC

[cayenne] branch STABLE-4.1 updated (e8772c0 -> 954f391)

This is an automated email from the ASF dual-hosted git repository.

abulatski pushed a change to branch STABLE-4.1
in repository https://gitbox.apache.org/repos/asf/cayenne.git.


    from e8772c0  CAY-2566 Flush action generates update for PK attribute in case of toDepPK relationship
     new 87e3402  CAY-2569 Custom 'Naming Strategy' in Cayenne Modeler
     new 954f391  CAY-2569 Custom 'Naming Strategy' in Cayenne Modeler

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 RELEASE-NOTES.txt                                  |  1 +
 .../tools/utils/CustomObjectNameGenerator.java     | 25 +++++----
 .../org/apache/cayenne/tools/build-schema.xml      |  3 +-
 .../tools/build-skip-primary-key-loading.xml       |  3 +-
 .../reverse/dbimport/DbImportConfiguration.java    | 13 ++---
 .../cayenne/tools/dbimport_excludeRel.gradle       |  1 +
 .../cayenne/stubs/CustomObjectNameGenerator.java   | 63 ++++++++++++++++++++++
 .../apache/cayenne/tools/DbImporterMojoTest.java   | 35 ++++++------
 .../tools/dbimport/testExcludeRelationship-pom.xml |  1 +
 .../tools/dbimport/testNamingStrategy-pom.xml}     | 26 +++++----
 ...ml-result => testNamingStrategy.map.xml-result} | 10 +---
 ...ImportNewDataMap.sql => testNamingStrategy.sql} |  7 +--
 .../modeler/editor/dbimport/DbImportView.java      | 23 ++++----
 .../dbimport/ReverseEngineeringConfigPanel.java    | 53 +++++++++++-------
 14 files changed, 174 insertions(+), 90 deletions(-)
 copy cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DefaultObjectNameGenerator.java => cayenne-ant/src/test/java/org/apache/cayenne/tools/utils/CustomObjectNameGenerator.java (92%)
 create mode 100644 maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java
 copy maven-plugins/cayenne-maven-plugin/src/test/resources/{cgen/project-to-test/cgen-pom.xml => org/apache/cayenne/tools/dbimport/testNamingStrategy-pom.xml} (60%)
 copy maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/{testImportNewDataMap.map.xml-result => testNamingStrategy.map.xml-result} (69%)
 copy maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/{testImportNewDataMap.sql => testNamingStrategy.sql} (90%)


[cayenne] 01/02: CAY-2569 Custom 'Naming Strategy' in Cayenne Modeler

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

abulatski pushed a commit to branch STABLE-4.1
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit 87e340211cb737130c95ead4fce1b6a51bf633f5
Author: Arseni Bulatski <an...@gmail.com>
AuthorDate: Wed Apr 24 10:48:33 2019 +0300

    CAY-2569 Custom 'Naming Strategy' in Cayenne Modeler
    
    (cherry picked from commit e7193b42e15dc3226e8da9b2eef88115463fab19)
---
 RELEASE-NOTES.txt                                  |   1 +
 .../tools/utils/CustomObjectNameGenerator.java     | 140 +++++++++++++++++++++
 .../org/apache/cayenne/tools/build-schema.xml      |   3 +-
 .../tools/build-skip-primary-key-loading.xml       |   3 +-
 .../reverse/dbimport/DbImportConfiguration.java    |  13 +-
 .../cayenne/tools/dbimport_excludeRel.gradle       |   1 +
 .../cayenne/stubs/CustomObjectNameGenerator.java   | 140 +++++++++++++++++++++
 .../tools/dbimport/testDefaultPackage-pom.xml      |   1 +
 .../tools/dbimport/testExcludeRelationship-pom.xml |   1 +
 .../modeler/editor/dbimport/DbImportView.java      |  23 ++--
 .../dbimport/ReverseEngineeringConfigPanel.java    |  53 +++++---
 11 files changed, 342 insertions(+), 37 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 539574a..e088f47 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -18,6 +18,7 @@ CAY-2559 Modeler: Warning dialog shows wrong information after changing target e
 CAY-2561 Modeler: cgen type combobox doesn't set templates
 CAY-2564 No import for Property after generation classes with pk properties
 CAY-2566 Flush action generates update for PK attribute in case of toDepPK relationship
+CAY-2569 Custom 'Naming Strategy' in Cayenne Modeler
 
 ----------------------------------
 Release: 4.1.B1
diff --git a/cayenne-ant/src/test/java/org/apache/cayenne/tools/utils/CustomObjectNameGenerator.java b/cayenne-ant/src/test/java/org/apache/cayenne/tools/utils/CustomObjectNameGenerator.java
new file mode 100644
index 0000000..8305c19
--- /dev/null
+++ b/cayenne-ant/src/test/java/org/apache/cayenne/tools/utils/CustomObjectNameGenerator.java
@@ -0,0 +1,140 @@
+/*****************************************************************
+ *   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.utils;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+
+import org.apache.cayenne.dbsync.naming.DbEntityNameStemmer;
+import org.apache.cayenne.dbsync.naming.NoStemStemmer;
+import org.apache.cayenne.dbsync.naming.ObjectNameGenerator;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.util.Util;
+import org.jvnet.inflector.Noun;
+
+/**
+ * @since 4.2
+ */
+public class CustomObjectNameGenerator implements ObjectNameGenerator {
+
+    private DbEntityNameStemmer dbEntityNameStemmer;
+
+    public CustomObjectNameGenerator() {
+        this.dbEntityNameStemmer = NoStemStemmer.getInstance();
+    }
+
+    public CustomObjectNameGenerator(DbEntityNameStemmer dbEntityNameStemmer) {
+        this.dbEntityNameStemmer = dbEntityNameStemmer;
+    }
+
+    @Override
+    public String relationshipName(DbRelationship... relationshipChain) {
+
+        if (relationshipChain == null || relationshipChain.length < 1) {
+            throw new IllegalArgumentException("At least on relationship is expected: " + relationshipChain);
+        }
+
+        // ignore the name of DbRelationship itself (FWIW we may be generating a new name for it here)...
+        // generate the name based on join semantics...
+
+        String name = isToMany(relationshipChain)
+                ? toManyRelationshipName(relationshipChain)
+                : toOneRelationshipName(relationshipChain);
+
+        return Util.underscoredToJava(name, false);
+    }
+
+    protected boolean isToMany(DbRelationship... relationshipChain) {
+
+        for (DbRelationship r : relationshipChain) {
+            if (r.isToMany()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    protected String stemmed(String dbEntityName) {
+        return dbEntityNameStemmer.stem(Objects.requireNonNull(dbEntityName));
+    }
+
+    protected String toManyRelationshipName(DbRelationship... relationshipChain) {
+
+        DbRelationship last = relationshipChain[relationshipChain.length - 1];
+
+        String baseName = stemmed(last.getTargetEntityName());
+
+        try {
+            // by default we use English rules here...
+            return Noun.pluralOf(baseName.toLowerCase(), Locale.ENGLISH);
+        } catch (Exception inflectorError) {
+            //  seems that Inflector cannot be trusted. For instance, it
+            // throws an exception when invoked for word "ADDRESS" (although
+            // lower case works fine). To feel safe, we use superclass'
+            // behavior if something's gone wrong
+            return baseName;
+        }
+    }
+
+    protected String toOneRelationshipName(DbRelationship... relationshipChain) {
+
+        DbRelationship first = relationshipChain[0];
+        DbRelationship last = relationshipChain[relationshipChain.length - 1];
+
+        List<DbJoin> joins = first.getJoins();
+        if (joins.isEmpty()) {
+            // In case, when uses EditRelationship button, relationship doesn't exist => it doesn't have joins
+            // and just return targetName
+            return stemmed(last.getTargetEntityName());
+        }
+
+        DbJoin join1 = joins.get(0);
+
+        // TODO: multi-join relationships
+
+        // return the name of the FK column sans ID
+        String fkColName = join1.getSourceName();
+        if (fkColName == null) {
+            return stemmed(last.getTargetEntityName());
+        } else if (fkColName.toUpperCase().endsWith("_ID") && fkColName.length() > 3) {
+            return fkColName.substring(0, fkColName.length() - 3);
+        } else if (fkColName.toUpperCase().endsWith("ID") && fkColName.length() > 2) {
+            return fkColName.substring(0, fkColName.length() - 2);
+        } else {
+            return stemmed(last.getTargetEntityName());
+        }
+    }
+
+    @Override
+    public String objEntityName(DbEntity dbEntity) {
+        String baseName = stemmed(dbEntity.getName());
+        return Util.underscoredToJava(baseName, true);
+    }
+
+    @Override
+    public String objAttributeName(DbAttribute attr) {
+        return Util.underscoredToJava(attr.getName(), false);
+    }
+}
diff --git a/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-schema.xml b/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-schema.xml
index 911af23..eb1db2b 100644
--- a/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-schema.xml
+++ b/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-schema.xml
@@ -27,7 +27,8 @@
                    adapter="org.apache.cayenne.dba.hsqldb.HSQLDBAdapter"
                    driver="org.hsqldb.jdbcDriver"
                    url="jdbc:hsqldb:hsql://localhost/bookmarker"
-                   username="sa">
+                   username="sa"
+                   namingStrategy="org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator">
 
                 <schema>schema-name-01</schema>
 
diff --git a/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-skip-primary-key-loading.xml b/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-skip-primary-key-loading.xml
index 396b603..32d01b8 100644
--- a/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-skip-primary-key-loading.xml
+++ b/cayenne-ant/src/test/resources/org/apache/cayenne/tools/build-skip-primary-key-loading.xml
@@ -27,7 +27,8 @@
                    adapter="org.apache.cayenne.dba.hsqldb.HSQLDBAdapter"
                    driver="org.hsqldb.jdbcDriver"
                    url="jdbc:hsqldb:hsql://localhost/bookmarker"
-                   username="sa" skipPrimaryKeyLoading="true">
+                   username="sa" skipPrimaryKeyLoading="true"
+                   namingStrategy="org.apache.cayenne.tools.utils.CustomObjectNameGenerator">
         </cdbimport>
     </target>
 
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
index 87d249f..83678cc 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/DbImportConfiguration.java
@@ -18,14 +18,15 @@
  ****************************************************************/
 package org.apache.cayenne.dbsync.reverse.dbimport;
 
+import java.io.File;
+import java.util.regex.Pattern;
+
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
 import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbsync.filter.NameFilter;
 import org.apache.cayenne.dbsync.filter.NamePatternMatcher;
-import org.apache.cayenne.dbsync.reverse.dbload.DefaultModelMergeDelegate;
-import org.apache.cayenne.dbsync.reverse.dbload.ModelMergeDelegate;
 import org.apache.cayenne.dbsync.naming.DbEntityNameStemmer;
 import org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator;
 import org.apache.cayenne.dbsync.naming.NoStemStemmer;
@@ -34,13 +35,12 @@ import org.apache.cayenne.dbsync.naming.PatternStemmer;
 import org.apache.cayenne.dbsync.reverse.dbload.DbLoaderConfiguration;
 import org.apache.cayenne.dbsync.reverse.dbload.DbLoaderDelegate;
 import org.apache.cayenne.dbsync.reverse.dbload.DefaultDbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.dbload.DefaultModelMergeDelegate;
 import org.apache.cayenne.dbsync.reverse.dbload.LoggingDbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.dbload.ModelMergeDelegate;
 import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
 import org.slf4j.Logger;
 
-import java.io.File;
-import java.util.regex.Pattern;
-
 /**
  * @since 4.0
  */
@@ -190,7 +190,8 @@ public class DbImportConfiguration {
         String namingStrategy = getNamingStrategy();
         if (namingStrategy != null && !namingStrategy.equals(DefaultObjectNameGenerator.class.getName())) {
             try {
-                return (ObjectNameGenerator) Class.forName(namingStrategy).newInstance();
+                Class<?> generatorClass = Thread.currentThread().getContextClassLoader().loadClass(namingStrategy);
+                return (ObjectNameGenerator) generatorClass.newInstance();
             } catch (Exception e) {
                 throw new CayenneRuntimeException("Error creating name generator: " + namingStrategy, e);
             }
diff --git a/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/dbimport_excludeRel.gradle b/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/dbimport_excludeRel.gradle
index 79b41db..9eb400f 100644
--- a/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/dbimport_excludeRel.gradle
+++ b/cayenne-gradle-plugin/src/test/resources/org/apache/cayenne/tools/dbimport_excludeRel.gradle
@@ -37,6 +37,7 @@ cdbimport {
             name 'SCHEMA_01'
             excludeRelationship 'test2s'
             excludeRelationship 'test1'
+            namingStrategy 'org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator'
         }
 
     }
diff --git a/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java b/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java
new file mode 100644
index 0000000..55f51f6
--- /dev/null
+++ b/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java
@@ -0,0 +1,140 @@
+/*****************************************************************
+ *   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.stubs;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+
+import org.apache.cayenne.dbsync.naming.DbEntityNameStemmer;
+import org.apache.cayenne.dbsync.naming.NoStemStemmer;
+import org.apache.cayenne.dbsync.naming.ObjectNameGenerator;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.util.Util;
+import org.jvnet.inflector.Noun;
+
+/**
+ * @since 4.2
+ */
+public class CustomObjectNameGenerator implements ObjectNameGenerator {
+
+    private DbEntityNameStemmer dbEntityNameStemmer;
+
+    public CustomObjectNameGenerator() {
+        this.dbEntityNameStemmer = NoStemStemmer.getInstance();
+    }
+
+    public CustomObjectNameGenerator(DbEntityNameStemmer dbEntityNameStemmer) {
+        this.dbEntityNameStemmer = dbEntityNameStemmer;
+    }
+
+    @Override
+    public String relationshipName(DbRelationship... relationshipChain) {
+
+        if (relationshipChain == null || relationshipChain.length < 1) {
+            throw new IllegalArgumentException("At least on relationship is expected: " + relationshipChain);
+        }
+
+        // ignore the name of DbRelationship itself (FWIW we may be generating a new name for it here)...
+        // generate the name based on join semantics...
+
+        String name = isToMany(relationshipChain)
+                ? toManyRelationshipName(relationshipChain)
+                : toOneRelationshipName(relationshipChain);
+
+        return Util.underscoredToJava(name, false);
+    }
+
+    protected boolean isToMany(DbRelationship... relationshipChain) {
+
+        for (DbRelationship r : relationshipChain) {
+            if (r.isToMany()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    protected String stemmed(String dbEntityName) {
+        return dbEntityNameStemmer.stem(Objects.requireNonNull(dbEntityName));
+    }
+
+    protected String toManyRelationshipName(DbRelationship... relationshipChain) {
+
+        DbRelationship last = relationshipChain[relationshipChain.length - 1];
+
+        String baseName = stemmed(last.getTargetEntityName());
+
+        try {
+            // by default we use English rules here...
+            return Noun.pluralOf(baseName.toLowerCase(), Locale.ENGLISH);
+        } catch (Exception inflectorError) {
+            //  seems that Inflector cannot be trusted. For instance, it
+            // throws an exception when invoked for word "ADDRESS" (although
+            // lower case works fine). To feel safe, we use superclass'
+            // behavior if something's gone wrong
+            return baseName;
+        }
+    }
+
+    protected String toOneRelationshipName(DbRelationship... relationshipChain) {
+
+        DbRelationship first = relationshipChain[0];
+        DbRelationship last = relationshipChain[relationshipChain.length - 1];
+
+        List<DbJoin> joins = first.getJoins();
+        if (joins.isEmpty()) {
+            // In case, when uses EditRelationship button, relationship doesn't exist => it doesn't have joins
+            // and just return targetName
+            return stemmed(last.getTargetEntityName());
+        }
+
+        DbJoin join1 = joins.get(0);
+
+        // TODO: multi-join relationships
+
+        // return the name of the FK column sans ID
+        String fkColName = join1.getSourceName();
+        if (fkColName == null) {
+            return stemmed(last.getTargetEntityName());
+        } else if (fkColName.toUpperCase().endsWith("_ID") && fkColName.length() > 3) {
+            return fkColName.substring(0, fkColName.length() - 3);
+        } else if (fkColName.toUpperCase().endsWith("ID") && fkColName.length() > 2) {
+            return fkColName.substring(0, fkColName.length() - 2);
+        } else {
+            return stemmed(last.getTargetEntityName());
+        }
+    }
+
+    @Override
+    public String objEntityName(DbEntity dbEntity) {
+        String baseName = stemmed(dbEntity.getName());
+        return Util.underscoredToJava(baseName, true);
+    }
+
+    @Override
+    public String objAttributeName(DbAttribute attr) {
+        return Util.underscoredToJava(attr.getName(), false);
+    }
+}
diff --git a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml
index b4bc513..f8bcebb 100644
--- a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml
+++ b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml
@@ -42,6 +42,7 @@
                     <dbimport>
                         <defaultPackage>com.example.test</defaultPackage>
                         <schema>SCHEMA_01</schema>
+                        <namingStrategy>org.apache.cayenne.stubs.CustomObjectNameGenerator</namingStrategy>
                     </dbimport>
                     <project implementation="org.apache.cayenne.stubs.CayenneProjectStub"/>
 
diff --git a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testExcludeRelationship-pom.xml b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testExcludeRelationship-pom.xml
index 184326e..368addc 100644
--- a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testExcludeRelationship-pom.xml
+++ b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testExcludeRelationship-pom.xml
@@ -50,6 +50,7 @@
                             <excludeRelationship>test12s</excludeRelationship>
                             <excludeRelationship>test11</excludeRelationship>
                         </schema>
+                        <namingStrategy>org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator</namingStrategy>
                     </dbimport>
                     <project implementation="org.apache.cayenne.stubs.CayenneProjectStub"/>
 
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportView.java
index f1a33b6..f0fc44e 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportView.java
@@ -18,6 +18,17 @@
  ****************************************************************/
 package org.apache.cayenne.modeler.editor.dbimport;
 
+import javax.swing.AbstractAction;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.border.EmptyBorder;
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+
 import com.jgoodies.forms.builder.DefaultFormBuilder;
 import com.jgoodies.forms.layout.FormLayout;
 import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
@@ -30,17 +41,6 @@ import org.apache.cayenne.modeler.dialog.db.load.TransferableNode;
 import org.apache.cayenne.modeler.util.CayenneAction;
 import org.apache.cayenne.modeler.util.ModelerUtil;
 
-import javax.swing.AbstractAction;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JProgressBar;
-import javax.swing.border.EmptyBorder;
-import java.awt.BorderLayout;
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-
 /**
  * @since 4.1
  */
@@ -202,6 +202,7 @@ public class DbImportView extends JPanel {
             }
             configPanel.fillCheckboxes(reverseEngineering);
             configPanel.initializeTextFields(reverseEngineering);
+            configPanel.initStrategy(reverseEngineering);
             treePanel.updateTree();
             DbImportTreeNode root = draggableTreePanel.getSourceTree().getRootNode();
             root.removeAllChildren();
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/ReverseEngineeringConfigPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/ReverseEngineeringConfigPanel.java
index 8f3993a..dc40cff 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/ReverseEngineeringConfigPanel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/ReverseEngineeringConfigPanel.java
@@ -19,20 +19,23 @@
 
 package org.apache.cayenne.modeler.editor.dbimport;
 
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import java.util.Vector;
+
 import com.jgoodies.forms.builder.DefaultFormBuilder;
 import com.jgoodies.forms.layout.FormLayout;
 import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
 import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.util.NameGeneratorPreferences;
 import org.apache.cayenne.modeler.util.TextAdapter;
-
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-import java.util.Vector;
+import org.apache.cayenne.modeler.util.combo.AutoCompletion;
 
 /**
  * @since 4.1
@@ -73,7 +76,7 @@ public class ReverseEngineeringConfigPanel extends JPanel {
         panelBuilder.append("Force datamap schema:", forceDataMapSchema);
         panelBuilder.append("Use Java primitive types:", usePrimitives);
         panelBuilder.append("Use java.util.Date type:", useJava7Types);
-        panelBuilder.append(strategyCombo);
+        panelBuilder.append("Naming strategy:", strategyCombo);
 
         add(panelBuilder.getPanel());
     }
@@ -97,22 +100,18 @@ public class ReverseEngineeringConfigPanel extends JPanel {
         return projectController.getApplication().getMetaData().get(dataMap, ReverseEngineering.class);
     }
 
-    private void initStrategy() {
+    void initStrategy(ReverseEngineering reverseEngineering) {
         Vector<String> arr = NameGeneratorPreferences
                 .getInstance()
                 .getLastUsedStrategies();
         strategyCombo.setModel(new DefaultComboBoxModel<>(arr));
+        strategyCombo.setSelectedItem(reverseEngineering.getNamingStrategy());
     }
 
     private void initFormElements() {
-        strategyCombo = new JComboBox<>();
-        strategyCombo.addActionListener(e -> {
-            getReverseEngineeringBySelectedMap().setNamingStrategy(
-                    (String) ReverseEngineeringConfigPanel.this.getStrategyCombo().getSelectedItem()
-            );
-            projectController.setDirty(true);
-        });
-        strategyCombo.setVisible(false);
+        strategyCombo = Application.getWidgetFactory().createComboBox();
+        AutoCompletion.enable(strategyCombo, false, true);
+        strategyCombo.setToolTipText("Naming strategy to use");
 
         JTextField meaningfulPkField = new JTextField();
         meaningfulPkField.setToolTipText("<html>Regular expression to filter tables with meaningful primary keys.<br>" +
@@ -152,7 +151,6 @@ public class ReverseEngineeringConfigPanel extends JPanel {
                 "By default <b>java.time.*</b> types will be used.</html>");
         usePrimitives = new JCheckBox();
         usePrimitives.setToolTipText("<html>Use primitive types (e.g. int) or Object types (e.g. java.lang.Integer)</html>");
-        initStrategy();
     }
 
     private void initListeners() {
@@ -180,6 +178,25 @@ public class ReverseEngineeringConfigPanel extends JPanel {
             getReverseEngineeringBySelectedMap().setUseJava7Types(useJava7Types.isSelected());
             projectController.setDirty(true);
         });
+        strategyCombo.addActionListener(e -> {
+            String strategy = (String) ReverseEngineeringConfigPanel.this.getStrategyCombo().getSelectedItem();
+            checkStrategy(strategy);
+            getReverseEngineeringBySelectedMap().setNamingStrategy(strategy);
+            NameGeneratorPreferences.getInstance().addToLastUsedStrategies(strategy);
+            projectController.setDirty(true);
+        });
+    }
+
+    private void checkStrategy(String strategy) {
+        try{
+            Thread.currentThread().getContextClassLoader().loadClass(strategy);
+        } catch(Exception ex) {
+            JOptionPane.showMessageDialog(
+                    this,
+                    strategy + " not found. Please, add naming strategy to classpath.",
+                    "Error",
+                    JOptionPane.WARNING_MESSAGE);
+        }
     }
 
     JComboBox<String> getStrategyCombo() {


[cayenne] 02/02: CAY-2569 Custom 'Naming Strategy' in Cayenne Modeler

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

abulatski pushed a commit to branch STABLE-4.1
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit 954f391283450bbd6589f84bb351ebbb829f2f87
Author: Arseni Bulatski <an...@gmail.com>
AuthorDate: Wed Apr 24 13:57:15 2019 +0300

    CAY-2569 Custom 'Naming Strategy' in Cayenne Modeler
    
    (cherry picked from commit 9fa1eb94cb598459a69256cd61dddfd65d4b32b2)
---
 .../tools/utils/CustomObjectNameGenerator.java     |  3 -
 .../cayenne/stubs/CustomObjectNameGenerator.java   | 83 +---------------------
 .../apache/cayenne/tools/DbImporterMojoTest.java   | 35 +++++----
 .../tools/dbimport/testDefaultPackage-pom.xml      |  1 -
 ...tPackage-pom.xml => testNamingStrategy-pom.xml} | 40 +++++------
 .../dbimport/testNamingStrategy.map.xml-result     | 31 ++++++++
 .../cayenne/tools/dbimport/testNamingStrategy.sql  | 22 ++++++
 7 files changed, 94 insertions(+), 121 deletions(-)

diff --git a/cayenne-ant/src/test/java/org/apache/cayenne/tools/utils/CustomObjectNameGenerator.java b/cayenne-ant/src/test/java/org/apache/cayenne/tools/utils/CustomObjectNameGenerator.java
index 8305c19..4b3336b 100644
--- a/cayenne-ant/src/test/java/org/apache/cayenne/tools/utils/CustomObjectNameGenerator.java
+++ b/cayenne-ant/src/test/java/org/apache/cayenne/tools/utils/CustomObjectNameGenerator.java
@@ -33,9 +33,6 @@ import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.util.Util;
 import org.jvnet.inflector.Noun;
 
-/**
- * @since 4.2
- */
 public class CustomObjectNameGenerator implements ObjectNameGenerator {
 
     private DbEntityNameStemmer dbEntityNameStemmer;
diff --git a/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java b/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java
index 55f51f6..375cf83 100644
--- a/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java
+++ b/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java
@@ -19,8 +19,6 @@
 
 package org.apache.cayenne.stubs;
 
-import java.util.List;
-import java.util.Locale;
 import java.util.Objects;
 
 import org.apache.cayenne.dbsync.naming.DbEntityNameStemmer;
@@ -28,14 +26,9 @@ import org.apache.cayenne.dbsync.naming.NoStemStemmer;
 import org.apache.cayenne.dbsync.naming.ObjectNameGenerator;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.util.Util;
-import org.jvnet.inflector.Noun;
 
-/**
- * @since 4.2
- */
 public class CustomObjectNameGenerator implements ObjectNameGenerator {
 
     private DbEntityNameStemmer dbEntityNameStemmer;
@@ -50,91 +43,21 @@ public class CustomObjectNameGenerator implements ObjectNameGenerator {
 
     @Override
     public String relationshipName(DbRelationship... relationshipChain) {
-
-        if (relationshipChain == null || relationshipChain.length < 1) {
-            throw new IllegalArgumentException("At least on relationship is expected: " + relationshipChain);
-        }
-
-        // ignore the name of DbRelationship itself (FWIW we may be generating a new name for it here)...
-        // generate the name based on join semantics...
-
-        String name = isToMany(relationshipChain)
-                ? toManyRelationshipName(relationshipChain)
-                : toOneRelationshipName(relationshipChain);
-
-        return Util.underscoredToJava(name, false);
-    }
-
-    protected boolean isToMany(DbRelationship... relationshipChain) {
-
-        for (DbRelationship r : relationshipChain) {
-            if (r.isToMany()) {
-                return true;
-            }
-        }
-
-        return false;
+        return null;
     }
 
     protected String stemmed(String dbEntityName) {
         return dbEntityNameStemmer.stem(Objects.requireNonNull(dbEntityName));
     }
 
-    protected String toManyRelationshipName(DbRelationship... relationshipChain) {
-
-        DbRelationship last = relationshipChain[relationshipChain.length - 1];
-
-        String baseName = stemmed(last.getTargetEntityName());
-
-        try {
-            // by default we use English rules here...
-            return Noun.pluralOf(baseName.toLowerCase(), Locale.ENGLISH);
-        } catch (Exception inflectorError) {
-            //  seems that Inflector cannot be trusted. For instance, it
-            // throws an exception when invoked for word "ADDRESS" (although
-            // lower case works fine). To feel safe, we use superclass'
-            // behavior if something's gone wrong
-            return baseName;
-        }
-    }
-
-    protected String toOneRelationshipName(DbRelationship... relationshipChain) {
-
-        DbRelationship first = relationshipChain[0];
-        DbRelationship last = relationshipChain[relationshipChain.length - 1];
-
-        List<DbJoin> joins = first.getJoins();
-        if (joins.isEmpty()) {
-            // In case, when uses EditRelationship button, relationship doesn't exist => it doesn't have joins
-            // and just return targetName
-            return stemmed(last.getTargetEntityName());
-        }
-
-        DbJoin join1 = joins.get(0);
-
-        // TODO: multi-join relationships
-
-        // return the name of the FK column sans ID
-        String fkColName = join1.getSourceName();
-        if (fkColName == null) {
-            return stemmed(last.getTargetEntityName());
-        } else if (fkColName.toUpperCase().endsWith("_ID") && fkColName.length() > 3) {
-            return fkColName.substring(0, fkColName.length() - 3);
-        } else if (fkColName.toUpperCase().endsWith("ID") && fkColName.length() > 2) {
-            return fkColName.substring(0, fkColName.length() - 2);
-        } else {
-            return stemmed(last.getTargetEntityName());
-        }
-    }
-
     @Override
     public String objEntityName(DbEntity dbEntity) {
         String baseName = stemmed(dbEntity.getName());
-        return Util.underscoredToJava(baseName, true);
+        return "Custom" + Util.underscoredToJava(baseName, true);
     }
 
     @Override
     public String objAttributeName(DbAttribute attr) {
-        return Util.underscoredToJava(attr.getName(), false);
+        return "custom_" + Util.underscoredToJava(attr.getName(), false);
     }
 }
diff --git a/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java b/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
index dd0e81a..a836910 100644
--- a/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
+++ b/maven-plugins/cayenne-maven-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
@@ -18,6 +18,18 @@
  ****************************************************************/
 package org.apache.cayenne.tools;
 
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Iterator;
+import java.util.Objects;
+
 import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
 import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfiguration;
 import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
@@ -26,12 +38,11 @@ import org.apache.cayenne.test.jdbc.SQLReader;
 import org.apache.cayenne.test.resource.ResourceUtil;
 import org.apache.maven.execution.DefaultMavenExecutionRequest;
 import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.ProjectBuilder;
 import org.apache.maven.project.ProjectBuildingRequest;
-import org.slf4j.Logger;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.codehaus.plexus.util.FileUtils;
 import org.custommonkey.xmlunit.DetailedDiff;
 import org.custommonkey.xmlunit.Diff;
@@ -41,18 +52,7 @@ import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.net.URL;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Iterator;
-import java.util.Objects;
+import org.slf4j.Logger;
 
 import static org.apache.cayenne.util.Util.isBlank;
 import static org.mockito.Mockito.mock;
@@ -178,6 +178,11 @@ public class DbImporterMojoTest extends AbstractMojoTestCase {
         test("testExcludeRelationshipFirst");
     }
 
+    @Test
+    public void testNamingStrategy() throws Exception {
+        test("testNamingStrategy");
+    }
+
     /**
      * Q: what happens if an attribute or relationship is unmapped in the object layer, but then the underlying table
      * changes.
diff --git a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml
index f8bcebb..b4bc513 100644
--- a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml
+++ b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml
@@ -42,7 +42,6 @@
                     <dbimport>
                         <defaultPackage>com.example.test</defaultPackage>
                         <schema>SCHEMA_01</schema>
-                        <namingStrategy>org.apache.cayenne.stubs.CustomObjectNameGenerator</namingStrategy>
                     </dbimport>
                     <project implementation="org.apache.cayenne.stubs.CayenneProjectStub"/>
 
diff --git a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testNamingStrategy-pom.xml
similarity index 55%
copy from maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml
copy to maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testNamingStrategy-pom.xml
index f8bcebb..0cbf06b 100644
--- a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testDefaultPackage-pom.xml
+++ b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testNamingStrategy-pom.xml
@@ -1,22 +1,22 @@
 <?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.
-  -->
+	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/xsd/maven-4.0.0.xsd">
@@ -32,16 +32,12 @@
             <plugin>
                 <artifactId>cayenne-maven-plugin</artifactId>
                 <configuration>
-                    <map>target/test-classes/org/apache/cayenne/tools/dbimport/testDefaultPackage.map.xml</map>
-
+                    <map>target/test-classes/org/apache/cayenne/tools/dbimport/testNamingStrategy.map.xml</map>
                     <dataSource>
                         <driver>org.apache.derby.jdbc.EmbeddedDriver</driver>
                         <url>jdbc:derby:memory:DbImporterMojoTest;create=true</url>
                     </dataSource>
-
                     <dbimport>
-                        <defaultPackage>com.example.test</defaultPackage>
-                        <schema>SCHEMA_01</schema>
                         <namingStrategy>org.apache.cayenne.stubs.CustomObjectNameGenerator</namingStrategy>
                     </dbimport>
                     <project implementation="org.apache.cayenne.stubs.CayenneProjectStub"/>
diff --git a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testNamingStrategy.map.xml-result b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testNamingStrategy.map.xml-result
new file mode 100644
index 0000000..e5f3c2a
--- /dev/null
+++ b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testNamingStrategy.map.xml-result
@@ -0,0 +1,31 @@
+<?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.
+-->
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd"
+	 project-version="10">
+	<db-entity name="TEST_TABLE" schema="APP">
+		<db-attribute name="COL1" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+		<db-attribute name="COL2" type="CHAR" length="25"/>
+	</db-entity>
+	<obj-entity name="CustomTestTable" className="CustomTestTable" dbEntityName="TEST_TABLE">
+	    <obj-attribute name="custom_col2" type="java.lang.String" db-attribute-path="COL2"/>
+	</obj-entity>
+</data-map>
diff --git a/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testNamingStrategy.sql b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testNamingStrategy.sql
new file mode 100644
index 0000000..11d3433
--- /dev/null
+++ b/maven-plugins/cayenne-maven-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testNamingStrategy.sql
@@ -0,0 +1,22 @@
+--  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.
+
+CREATE TABLE TEST_TABLE (
+  COL1 INTEGER NOT NULL,
+  COL2 CHAR(25),
+  PRIMARY KEY (COL1)
+)
\ No newline at end of file