This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 4662ae16ae3c816a4026c670d6e9adac0039728c Author: Andrus Adamchik <[email protected]> AuthorDate: Sun Jul 19 19:24:19 2026 +0200 ObjectNameGenerator cleanup splitting cases of Obj and Db relationship names generation --- .../tools/utils/CustomObjectNameGenerator.java | 101 +-------------------- .../dbsync/merge/context/EntityMergeSupport.java | 2 +- .../merge/token/model/AddRelationshipToModel.java | 2 +- .../dbsync/naming/DefaultObjectNameGenerator.java | 46 ++++++---- .../cayenne/dbsync/naming/ObjectNameGenerator.java | 21 +++-- .../dbimport/ManyToManyCandidateEntity.java | 2 +- .../dbsync/reverse/dbload/RelationshipLoader.java | 2 +- .../naming/DefaultObjectNameGeneratorTest.java | 41 ++++++--- .../cayenne/stubs/CustomObjectNameGenerator.java | 9 +- .../modeler/ui/action/DbEntitySyncAction.java | 6 +- .../autorelationship/InferRelationshipsDialog.java | 2 +- 11 files changed, 90 insertions(+), 144 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 fa831f564..cd9eafa22 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 @@ -19,110 +19,17 @@ package org.apache.cayenne.tools.utils; -import java.util.List; -import java.util.Objects; - import org.apache.cayenne.dbsync.naming.DbEntityNameStemmer; -import org.apache.cayenne.dbsync.naming.EnglishInflector; +import org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator; 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; - -public class CustomObjectNameGenerator implements ObjectNameGenerator { - private DbEntityNameStemmer dbEntityNameStemmer; +public class CustomObjectNameGenerator extends DefaultObjectNameGenerator { public CustomObjectNameGenerator() { - this.dbEntityNameStemmer = NoStemStemmer.getInstance(); + super(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()); - - // by default we use English rules here... - return EnglishInflector.pluralOf(baseName.toLowerCase()); - } - - 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); + super(dbEntityNameStemmer); } } diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/context/EntityMergeSupport.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/context/EntityMergeSupport.java index 6f37b18b4..2b4162dfe 100644 --- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/context/EntityMergeSupport.java +++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/context/EntityMergeSupport.java @@ -202,7 +202,7 @@ public class EntityMergeSupport { private boolean createObjRelationship(ObjEntity entity, DbRelationship dr, String targetEntityName) { ObjRelationship or = new ObjRelationship(); or.setName(NameBuilder.of(or, entity) - .baseName(nameGenerator.relationshipName(dr)) + .baseName(nameGenerator.objRelationshipName(dr)) .name()); or.addDbRelationship(dr); diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/AddRelationshipToModel.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/AddRelationshipToModel.java index da4422c47..92abdc831 100644 --- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/AddRelationshipToModel.java +++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/model/AddRelationshipToModel.java @@ -69,7 +69,7 @@ public class AddRelationshipToModel extends AbstractToModelToken.Entity { // Set name to relationship if it was created without it, e.g. in createReverse() action if (relationship.getName() == null) { relationship.setName(NameBuilder.of(relationship, getEntity()) - .baseName(context.getNameGenerator().relationshipName(relationship)) + .baseName(context.getNameGenerator().dbRelationshipName(relationship.getJoins(), relationship.isToMany())) .name()); } diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DefaultObjectNameGenerator.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DefaultObjectNameGenerator.java index 909dbe50b..f1da0a527 100644 --- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DefaultObjectNameGenerator.java +++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DefaultObjectNameGenerator.java @@ -41,18 +41,35 @@ public class DefaultObjectNameGenerator implements ObjectNameGenerator { } @Override - public String relationshipName(DbRelationship... relationshipChain) { + public String objRelationshipName(DbRelationship... relationshipChain) { if (relationshipChain == null || relationshipChain.length < 1) { - throw new IllegalArgumentException("At least on relationship is expected: " + relationshipChain); + throw new IllegalArgumentException("At least one relationship is expected"); } - // ignore the name of DbRelationship itself (FWIW we may be generating a new name for it here)... + // ignore the name of DbRelationships themselves... // generate the name based on join semantics... - String name = isToMany(relationshipChain) - ? toManyRelationshipName(relationshipChain) - : toOneRelationshipName(relationshipChain); + DbRelationship first = relationshipChain[0]; + DbRelationship last = relationshipChain[relationshipChain.length - 1]; + return relationshipName(first.getJoins(), last.getTargetEntityName(), isToMany(relationshipChain)); + } + + @Override + public String dbRelationshipName(List<DbJoin> joins, boolean toMany) { + + if (joins == null || joins.isEmpty()) { + throw new IllegalArgumentException("At least one join is expected"); + } + + String targetEntityName = joins.getFirst().getRelationship().getTargetEntityName(); + return relationshipName(joins, targetEntityName, toMany); + } + + protected String relationshipName(List<DbJoin> joins, String targetEntityName, boolean toMany) { + String name = toMany + ? toManyRelationshipName(targetEntityName) + : toOneRelationshipName(joins, targetEntityName); return Util.underscoredToJava(name, false); } @@ -72,22 +89,17 @@ public class DefaultObjectNameGenerator implements ObjectNameGenerator { return dbEntityNameStemmer.stem(Objects.requireNonNull(dbEntityName)); } - protected String toManyRelationshipName(DbRelationship... relationshipChain) { - DbRelationship last = relationshipChain[relationshipChain.length - 1]; - String baseName = stemmed(last.getTargetEntityName()); + protected String toManyRelationshipName(String targetEntityName) { + String baseName = stemmed(targetEntityName); return EnglishInflector.pluralOf(baseName.toLowerCase()); } - protected String toOneRelationshipName(DbRelationship... relationshipChain) { - - DbRelationship first = relationshipChain[0]; - DbRelationship last = relationshipChain[relationshipChain.length - 1]; + protected String toOneRelationshipName(List<DbJoin> joins, String targetEntityName) { - 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()); + return stemmed(targetEntityName); } DbJoin join1 = joins.getFirst(); @@ -97,13 +109,13 @@ public class DefaultObjectNameGenerator implements ObjectNameGenerator { // return the name of the FK column sans ID String fkColName = join1.getSourceName(); if (fkColName == null) { - return stemmed(last.getTargetEntityName()); + return stemmed(targetEntityName); } 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()); + return stemmed(targetEntityName); } } diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/ObjectNameGenerator.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/ObjectNameGenerator.java index 8e19dbbd9..13f934976 100644 --- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/ObjectNameGenerator.java +++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/ObjectNameGenerator.java @@ -20,12 +20,13 @@ package org.apache.cayenne.dbsync.naming; 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 java.util.List; + /** - * A strategy for creating names for object layer metadata artifacts based on their DB counterpart naming or structure. - * Generated names should normally be further cleaned by passing them through - * {@link org.apache.cayenne.dbsync.naming.NameBuilder}, that will resolve duplication conflicts. + * A strategy for creating mapping artifact names based on DB tier metadata. * * @since 4.0 */ @@ -42,13 +43,19 @@ public interface ObjectNameGenerator { String objAttributeName(DbAttribute dbAttribute); /** - * Generates a String that can be used as a name of an ObjRelationship, derived from join semantics of a chain of - * connected DbRelationships. + * Generates a name for an ObjRelationship, derived from join semantics of a chain of connected DbRelationships. * <p>The chain must contain at least one relationship. Though if we are dealing with a flattened * relationship, more than one can be passed, in the same order as they are present in a flattened * relationship. - * <p>Generated name can be used for DbRelationship itself (in which case the chain must have exactly one parameter). + * + * @since 5.0 */ - String relationshipName(DbRelationship... relationshipChain); + String objRelationshipName(DbRelationship... relationshipChain); + /** + * Generates a name for a DbRelationship, derived from the semantics of its joins and direction. + * + * @since 5.0 + */ + String dbRelationshipName(List<DbJoin> joins, boolean toMany); } diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntity.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntity.java index 6b5954258..2e6a0e91b 100644 --- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntity.java +++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbimport/ManyToManyCandidateEntity.java @@ -101,7 +101,7 @@ class ManyToManyCandidateEntity { ObjRelationship newRelationship = new ObjRelationship(); newRelationship.setName(NameBuilder .of(newRelationship, srcEntity) - .baseName(nameGenerator.relationshipName(rel1, rel2)) + .baseName(nameGenerator.objRelationshipName(rel1, rel2)) .name()); newRelationship.setSourceEntity(srcEntity); diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java index 1b224b2e5..aa7a90680 100644 --- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java +++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/dbload/RelationshipLoader.java @@ -105,7 +105,7 @@ public class RelationshipLoader extends AbstractLoader { private void setRelationshipName(DbEntity entity, DbRelationship relationship) { relationship.setName(NameBuilder .of(relationship, entity) - .baseName(nameGenerator.relationshipName(relationship)) + .baseName(nameGenerator.dbRelationshipName(relationship.getJoins(), relationship.isToMany())) .name()); } diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/DefaultObjectNameGeneratorTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/DefaultObjectNameGeneratorTest.java index 495f0a49b..ba680ab21 100644 --- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/DefaultObjectNameGeneratorTest.java +++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/DefaultObjectNameGeneratorTest.java @@ -43,47 +43,60 @@ public class DefaultObjectNameGeneratorTest { } @Test - public void relationshipName_LowerCase_Underscores() { + public void objRelationshipName_LowerCase_Underscores() { DbRelationship r1 = makeRelationship("painting", "artist_id", "artist", "artist_id", false); - assertEquals("artist", generator.relationshipName(r1)); + assertEquals("artist", generator.objRelationshipName(r1)); DbRelationship r2 = makeRelationship("artist", "artist_id", "painting", "artist_id", true); - assertEquals("paintings", generator.relationshipName(r2)); + assertEquals("paintings", generator.objRelationshipName(r2)); DbRelationship r3 = makeRelationship("person", "mother_id", "person", "person_id", false); - assertEquals("mother", generator.relationshipName(r3)); + assertEquals("mother", generator.objRelationshipName(r3)); DbRelationship r4 = makeRelationship("person", "person_id", "person", "mother_id", true); - assertEquals("people", generator.relationshipName(r4)); + assertEquals("people", generator.objRelationshipName(r4)); DbRelationship r5 = makeRelationship("person", "shipping_address_id", "address", "id", false); - assertEquals("shippingAddress", generator.relationshipName(r5)); + assertEquals("shippingAddress", generator.objRelationshipName(r5)); DbRelationship r6 = makeRelationship("person", "id", "address", "person_id", true); - assertEquals("addresses", generator.relationshipName(r6)); + assertEquals("addresses", generator.objRelationshipName(r6)); } @Test - public void relationshipName_UpperCase_Underscores() { + public void objRelationshipName_UpperCase_Underscores() { DbRelationship r1 = makeRelationship("PAINTING", "ARTIST_ID", "ARTIST", "ARTIST_ID", false); - assertEquals("artist", generator.relationshipName(r1)); + assertEquals("artist", generator.objRelationshipName(r1)); DbRelationship r2 = makeRelationship("ARTIST", "ARTIST_ID", "PAINTING", "ARTIST_ID", true); - assertEquals("paintings", generator.relationshipName(r2)); + assertEquals("paintings", generator.objRelationshipName(r2)); DbRelationship r3 = makeRelationship("PERSON", "MOTHER_ID", "PERSON", "PERSON_ID", false); - assertEquals("mother", generator.relationshipName(r3)); + assertEquals("mother", generator.objRelationshipName(r3)); DbRelationship r4 = makeRelationship("PERSON", "PERSON_ID", "PERSON", "MOTHER_ID", true); - assertEquals("people", generator.relationshipName(r4)); + assertEquals("people", generator.objRelationshipName(r4)); DbRelationship r5 = makeRelationship("PERSON", "SHIPPING_ADDRESS_ID", "ADDRESS", "ID", false); - assertEquals("shippingAddress", generator.relationshipName(r5)); + assertEquals("shippingAddress", generator.objRelationshipName(r5)); DbRelationship r6 = makeRelationship("PERSON", "ID", "ADDRESS", "PERSON_ID", true); - assertEquals("addresses", generator.relationshipName(r6)); + assertEquals("addresses", generator.objRelationshipName(r6)); + } + + @Test + public void dbRelationshipName() { + + DbRelationship r1 = makeRelationship("painting", "artist_id", "artist", "artist_id", false); + assertEquals("artist", generator.dbRelationshipName(r1.getJoins(), r1.isToMany())); + + DbRelationship r2 = makeRelationship("artist", "artist_id", "painting", "artist_id", true); + assertEquals("paintings", generator.dbRelationshipName(r2.getJoins(), r2.isToMany())); + + DbRelationship r3 = makeRelationship("person", "shipping_address_id", "address", "id", false); + assertEquals("shippingAddress", generator.dbRelationshipName(r3.getJoins(), r3.isToMany())); } @Test diff --git a/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java b/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java index 07e47119d..bea713b69 100644 --- a/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java +++ b/cayenne-maven-plugin/src/test/java/org/apache/cayenne/stubs/CustomObjectNameGenerator.java @@ -19,6 +19,7 @@ package org.apache.cayenne.stubs; +import java.util.List; import java.util.Objects; import org.apache.cayenne.dbsync.naming.DbEntityNameStemmer; @@ -26,6 +27,7 @@ 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; @@ -42,7 +44,12 @@ public class CustomObjectNameGenerator implements ObjectNameGenerator { } @Override - public String relationshipName(DbRelationship... relationshipChain) { + public String objRelationshipName(DbRelationship... relationshipChain) { + return null; + } + + @Override + public String dbRelationshipName(List<DbJoin> joins, boolean toMany) { return null; } diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/DbEntitySyncAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/DbEntitySyncAction.java index d1c05ac39..fb8afcc91 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/DbEntitySyncAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/DbEntitySyncAction.java @@ -134,14 +134,14 @@ public class DbEntitySyncAction extends AppAction { } @Override - public String relationshipName(DbRelationship... relationshipChain) { + public String objRelationshipName(DbRelationship... relationshipChain) { if (relationshipChain.length == 0) { - return super.relationshipName(relationshipChain); + return super.objRelationshipName(relationshipChain); } DbRelationship last = relationshipChain[relationshipChain.length - 1]; if (last.getName().startsWith("untitledRel")) { - return super.relationshipName(relationshipChain); + return super.objRelationshipName(relationshipChain); } // keep manually set relationship name diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/autorelationship/InferRelationshipsDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/autorelationship/InferRelationshipsDialog.java index 521ee7c2b..11acb7dbf 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/autorelationship/InferRelationshipsDialog.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/autorelationship/InferRelationshipsDialog.java @@ -312,7 +312,7 @@ public class InferRelationshipsDialog extends ProjectDialog { } myir.setName(NameBuilder.of(localRelationship, localRelationship.getSourceEntity()) - .baseName(strategy.relationshipName(localRelationship)) + .baseName(strategy.dbRelationshipName(localRelationship.getJoins(), localRelationship.isToMany())) .name()); } }
