diff --git a/.gitignore b/.gitignore index 147a718ec4..6196d801e6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ target derby.log .metadata bin/ + +.idea diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java index 8b1521cd42..b45ce195d8 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java @@ -47,9 +47,9 @@ import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.map.Procedure; import org.apache.cayenne.map.ProcedureParameter; -import org.apache.cayenne.map.naming.BasicNamingStrategy; +import org.apache.cayenne.map.naming.BasicNameGenerator; import org.apache.cayenne.map.naming.ExportedKey; -import org.apache.cayenne.map.naming.NamingStrategy; +import org.apache.cayenne.map.naming.ObjectNameGenerator; import org.apache.cayenne.util.EntityMergeSupport; import org.apache.cayenne.util.Util; import org.apache.commons.logging.Log; @@ -106,13 +106,13 @@ private static String uniqueRelName(Entity entity, String preferredName) { /** * Strategy for choosing names for entities, attributes and relationships */ - protected NamingStrategy namingStrategy; + protected ObjectNameGenerator nameGenerator; /** * Creates new DbLoader. */ public DbLoader(Connection connection, DbAdapter adapter, DbLoaderDelegate delegate) { - this(connection, adapter, delegate, new BasicNamingStrategy()); + this(connection, adapter, delegate, new BasicNameGenerator()); } /** @@ -120,12 +120,12 @@ public DbLoader(Connection connection, DbAdapter adapter, DbLoaderDelegate deleg * * @since 3.0 */ - public DbLoader(Connection connection, DbAdapter adapter, DbLoaderDelegate delegate, NamingStrategy strategy) { + public DbLoader(Connection connection, DbAdapter adapter, DbLoaderDelegate delegate, ObjectNameGenerator strategy) { this.adapter = adapter; this.connection = connection; this.delegate = delegate; - setNamingStrategy(strategy); + setNameGenerator(strategy); } /** @@ -526,7 +526,7 @@ public void loadObjEntities(DataMap map) { continue; } - String objEntityName = namingStrategy.createObjEntityName(dbEntity); + String objEntityName = nameGenerator.createObjEntityName(dbEntity); // this loop will terminate even if no valid name is found // to prevent loader from looping forever (though such case is very // unlikely) @@ -553,7 +553,7 @@ public void loadObjEntities(DataMap map) { * @since 3.2 */ protected EntityMergeSupport createEntityMerger(DataMap map) { - return new EntityMergeSupport(map, namingStrategy, !creatingMeaningfulPK); + return new EntityMergeSupport(map, nameGenerator, !creatingMeaningfulPK); } /** Loads database relationships into a DataMap. */ @@ -621,14 +621,14 @@ private void loadDbRelationships(DbEntity pkEntity, DataMap map) throws SQLExcep continue; } else { // init relationship - String forwardPreferredName = namingStrategy.createDbRelationshipName(key, true); + String forwardPreferredName = nameGenerator.createDbRelationshipName(key, true); forwardRelationship = new DbRelationship(uniqueRelName(pkEntity, forwardPreferredName)); forwardRelationship.setSourceEntity(pkEntity); forwardRelationship.setTargetEntity(fkEntity); pkEntity.addRelationship(forwardRelationship); - String reversePreferredName = namingStrategy.createDbRelationshipName(key, false); + String reversePreferredName = nameGenerator.createDbRelationshipName(key, false); reverseRelationship = new DbRelationshipDetected(uniqueRelName(fkEntity, reversePreferredName)); reverseRelationship.setFkName(fkName); reverseRelationship.setToMany(false); @@ -706,7 +706,7 @@ protected void postprocessMasterDbRelationship(DbRelationship relationship, Expo if (!toMany) { Entity source = relationship.getSourceEntity(); source.removeRelationship(relationship.getName()); - relationship.setName(DbLoader.uniqueRelName(source, namingStrategy.createDbRelationshipName(key, false))); + relationship.setName(DbLoader.uniqueRelName(source, nameGenerator.createDbRelationshipName(key, false))); source.addRelationship(relationship); } @@ -721,10 +721,10 @@ private void flattenManyToManyRelationships(DataMap map) { List entitiesForDelete = new ArrayList(); for (ObjEntity curEntity : map.getObjEntities()) { - ManyToManyCandidateEntity entity = new ManyToManyCandidateEntity(curEntity); + ManyToManyCandidateEntity entity = ManyToManyCandidateEntity.build(curEntity); - if (entity.isRepresentManyToManyTable()) { - entity.optimizeRelationships(); + if (entity != null) { + entity.optimizeRelationships(getNameGenerator()); entitiesForDelete.add(curEntity); } } @@ -1009,20 +1009,20 @@ public void loadProcedures(DataMap dataMap, String catalogPattern, String schema * * @since 3.0 */ - public void setNamingStrategy(NamingStrategy strategy) { + public void setNameGenerator(ObjectNameGenerator strategy) { // null values are not allowed if (strategy == null) { throw new NullPointerException("Null strategy not allowed"); } - this.namingStrategy = strategy; + this.nameGenerator = strategy; } /** * @return naming strategy for reverse engineering * @since 3.0 */ - public NamingStrategy getNamingStrategy() { - return namingStrategy; + public ObjectNameGenerator getNameGenerator() { + return nameGenerator; } } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/ManyToManyCandidateEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/access/ManyToManyCandidateEntity.java index 74508976c2..9ef4782d87 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/ManyToManyCandidateEntity.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/ManyToManyCandidateEntity.java @@ -24,88 +24,87 @@ import org.apache.cayenne.map.DbRelationship; import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.map.ObjRelationship; -import org.apache.cayenne.util.NamedObjectFactory; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.ExportedKey; +import org.apache.cayenne.map.naming.NameCheckers; +import org.apache.cayenne.map.naming.ObjectNameGenerator; /** * Class represent ObjEntity that may be optimized using flattened relationships * as many to many table */ class ManyToManyCandidateEntity { - private ObjEntity entity; + private final ObjEntity joinEntity; - public ManyToManyCandidateEntity(ObjEntity entityValue) { - entity = entityValue; - } + private final DbRelationship dbRel1; + private final DbRelationship dbRel2; - public ObjEntity getEntity() { - return entity; - } + private final ObjEntity entity1; + private final ObjEntity entity2; - private boolean isTargetEntitiesDifferent() { - return !getTargetEntity1().equals(getTargetEntity2()); - } + private final DbRelationship reverseRelationship1; + private final DbRelationship reverseRelationship2; - private boolean isRelationshipsHasDependentPK() { - boolean isRelationship1HasDepPK = getDbRelationship1().getReverseRelationship().isToDependentPK(); - boolean isRelationship2HasDepPK = getDbRelationship2().getReverseRelationship().isToDependentPK(); + private ManyToManyCandidateEntity(ObjEntity entityValue, List relationships) { + joinEntity = entityValue; - return isRelationship1HasDepPK && isRelationship2HasDepPK; - } + ObjRelationship rel1 = relationships.get(0); + ObjRelationship rel2 = relationships.get(1); - private ObjRelationship getRelationship1() { - List relationships = new ArrayList(entity.getRelationships()); - return relationships.get(0); - } + dbRel1 = rel1.getDbRelationships().get(0); + dbRel2 = rel2.getDbRelationships().get(0); - private ObjRelationship getRelationship2() { - List relationships = new ArrayList(entity.getRelationships()); - return relationships.get(1); - } + reverseRelationship1 = dbRel1.getReverseRelationship(); + reverseRelationship2 = dbRel2.getReverseRelationship(); - private ObjEntity getTargetEntity1() { - return (ObjEntity) getRelationship1().getTargetEntity(); - } - - private ObjEntity getTargetEntity2() { - return (ObjEntity) getRelationship2().getTargetEntity(); - } - - private DbRelationship getDbRelationship1() { - return getRelationship1().getDbRelationships().get(0); - } - - private DbRelationship getDbRelationship2() { - return getRelationship2().getDbRelationships().get(0); + entity1 = rel1.getTargetEntity(); + entity2 = rel2.getTargetEntity(); } /** * Method check - if current entity represent many to many temporary table * @return true if current entity is represent many to many table; otherwise returns false */ - public boolean isRepresentManyToManyTable() { - boolean hasTwoRelationships = entity.getRelationships().size() == 2; - boolean isNotHaveAttributes = entity.getAttributes().size() == 0; + public static ManyToManyCandidateEntity build(ObjEntity joinEntity) { + ArrayList relationships = new ArrayList(joinEntity.getRelationships()); + if (relationships.size() != 2) { + return null; + } - return hasTwoRelationships && isNotHaveAttributes && isRelationshipsHasDependentPK() - && isTargetEntitiesDifferent(); + ManyToManyCandidateEntity candidateEntity = new ManyToManyCandidateEntity(joinEntity, relationships); + if (candidateEntity.isManyToMany()) { + return candidateEntity; + } + + return null; } - private void removeRelationshipsFromTargetEntities() { - getTargetEntity1().removeRelationship(getRelationship1().getReverseRelationship().getName()); - getTargetEntity2().removeRelationship(getRelationship2().getReverseRelationship().getName()); + private boolean isManyToMany() { + boolean isNotHaveAttributes = joinEntity.getAttributes().size() == 0; + + return isNotHaveAttributes && reverseRelationship1.isToDependentPK() && reverseRelationship2.isToDependentPK() + && !entity1.equals(entity2); } - private void addFlattenedRelationship(ObjEntity srcEntity, ObjEntity dstEntity, - DbRelationship... relationshipPath) { - ObjRelationship newRelationship = (ObjRelationship) NamedObjectFactory.createRelationship(srcEntity, dstEntity, - true); + private void addFlattenedRelationship(ObjectNameGenerator nameGenerator, ObjEntity srcEntity, ObjEntity dstEntity, + DbRelationship rel1, DbRelationship rel2) { + + ExportedKey key = new ExportedKey(rel1.getSourceEntity().getName(), + rel1.getSourceAttributes().iterator().next().getName(), + null, + rel2.getTargetEntity().getName(), + rel2.getTargetAttributes().iterator().next().getName(), + null); + + ObjRelationship newRelationship = new ObjRelationship(); + newRelationship.setName(DefaultUniqueNameGenerator.generate(NameCheckers.ObjRelationship, srcEntity, + nameGenerator.createDbRelationshipName(key, true))); newRelationship.setSourceEntity(srcEntity); newRelationship.setTargetEntity(dstEntity); - for (DbRelationship curRelationship : relationshipPath) { - newRelationship.addDbRelationship(curRelationship); - } + newRelationship.addDbRelationship(rel1); + newRelationship.addDbRelationship(rel2); srcEntity.addRelationship(newRelationship); } @@ -113,18 +112,15 @@ private void addFlattenedRelationship(ObjEntity srcEntity, ObjEntity dstEntity, /** * Method make direct relationships between 2 entities and remove relationships to * many to many entity + * + * @param nameGenerator */ - public void optimizeRelationships() { - removeRelationshipsFromTargetEntities(); - - DbRelationship dbRelationship1 = getRelationship1().getDbRelationships().get(0); - DbRelationship dbRelationship2 = getRelationship2().getDbRelationships().get(0); - - addFlattenedRelationship(getTargetEntity1(), getTargetEntity2(), dbRelationship1.getReverseRelationship(), - dbRelationship2); + public void optimizeRelationships(ObjectNameGenerator nameGenerator) { + entity1.removeRelationship(reverseRelationship1.getName()); + entity2.removeRelationship(reverseRelationship2.getName()); - addFlattenedRelationship(getTargetEntity2(), getTargetEntity1(), dbRelationship2.getReverseRelationship(), - dbRelationship1); + addFlattenedRelationship(nameGenerator, entity1, entity2, reverseRelationship1, dbRel2); + addFlattenedRelationship(nameGenerator, entity2, entity1, reverseRelationship2, dbRel1); } } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java index 908e718cf6..94ac84ac29 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbEntity.java @@ -154,12 +154,9 @@ public void encodeAsXML(XMLEncoder encoder) { * present. */ public String getFullyQualifiedName() { - - if (catalog != null) { - return (schema != null) ? catalog + '.' + schema + '.' + name : catalog + '.' + name; - } else { - return (schema != null) ? schema + '.' + name : name; - } + return (catalog != null ? catalog + '.' : "") + + (schema != null ? schema + '.' : "") + + name; } /** diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java index 8c8c2d415f..9aec8f8c81 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java @@ -19,16 +19,7 @@ package org.apache.cayenne.map; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; +import java.util.*; import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.configuration.ConfigurationNode; @@ -41,7 +32,7 @@ import org.apache.cayenne.map.event.EntityEvent; import org.apache.cayenne.map.event.ObjEntityListener; import org.apache.cayenne.util.CayenneMapEntry; -import org.apache.cayenne.util.NameConverter; +import org.apache.cayenne.map.naming.NameConverter; import org.apache.cayenne.util.Util; import org.apache.cayenne.util.XMLEncoder; import org.apache.commons.collections.Transformer; @@ -1115,6 +1106,14 @@ private PathComponentIterator createPathIterator(String path) { // here? } + public Set getCallbackMethods() { + Set res = new LinkedHashSet(); + for (CallbackDescriptor descriptor : getCallbackMap().getCallbacks()) { + res.addAll(descriptor.getCallbackMethods()); + } + return res; + } + final class DBPathConverter implements Transformer { // TODO: make it a public method - resolveDBPathComponents or diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNamingStrategy.java b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNameGenerator.java similarity index 92% rename from cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNamingStrategy.java rename to cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNameGenerator.java index 2b8d5bc590..b70045d5c6 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNamingStrategy.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNameGenerator.java @@ -21,7 +21,6 @@ import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.DbRelationship; -import org.apache.cayenne.util.NameConverter; /** * BasicNamingStrategy is an naming strategy that creates names in Cayenne's @@ -29,7 +28,7 @@ * * @since 3.0 */ -public class BasicNamingStrategy implements NamingStrategy { +public class BasicNameGenerator implements ObjectNameGenerator { public String createDbRelationshipName( ExportedKey key, boolean toMany) { diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/DefaultUniqueNameGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/DefaultUniqueNameGenerator.java new file mode 100644 index 0000000000..d3c38a208d --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/DefaultUniqueNameGenerator.java @@ -0,0 +1,104 @@ +/* + * **************************************************************** + * * 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.map.naming; + +import org.apache.cayenne.map.DataMap; + +/** + * @author Alex.Kolonitsky. + */ +public class DefaultUniqueNameGenerator implements UniqueNameGenerator { + + public static final String DEFAULT_PATTERN = "%s%d"; + + public final NameChecker nameChecker; + + public final String pattern; + + public static String generate(NameChecker checker) { + return generate(checker, DEFAULT_PATTERN, null, null); + } + + public static String generate(NameChecker checker, Object context) { + return generate(checker, DEFAULT_PATTERN, context, null); + } + + public static String generate(NameChecker checker, Object context, String baseName) { + return generate(checker, DEFAULT_PATTERN, context, baseName); + } + + public static String generate(NameChecker checker, String pattern, Object context, String baseName) { + DefaultUniqueNameGenerator generator; + if (checker == NameCheckers.Embeddable) { + generator = new DefaultUniqueNameGenerator(NameCheckers.Embeddable, pattern) { + @Override + public String generate(Object namingContext, String nameBase) { + String name = super.generate(namingContext, nameBase); + DataMap map = (DataMap) namingContext; + if (map.getDefaultPackage() != null) { + return map.getDefaultPackage() + "." + name; + } + return name; + } + }; + } else { + generator = new DefaultUniqueNameGenerator(checker, pattern); + } + + return generator.generate(context, baseName); + } + + + + public DefaultUniqueNameGenerator(NameChecker nameChecker, String pattern) { + this.nameChecker = nameChecker; + this.pattern = pattern; + } + + /** + * Creates a unique name for the new object and constructs this object. + */ + public String generate(Object namingContext) { + return generate(namingContext, nameChecker.baseName()); + } + + /** + * @since 1.0.5 + */ + public String generate(Object namingContext, String nameBase) { + return generate(pattern, namingContext, nameBase != null ? nameBase : nameChecker.baseName()); + } + + /** + * @since 1.0.5 + */ + private String generate(String pattern, Object namingContext, String nameBase) { + int c = 1; + String name = nameBase; + while (nameChecker.isNameInUse(namingContext, name)) { + name = String.format(pattern, nameBase, c++); + } + + return name; + } + +} diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameChecker.java b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameChecker.java new file mode 100644 index 0000000000..8ee5529404 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameChecker.java @@ -0,0 +1,25 @@ +package org.apache.cayenne.map.naming; + +/** + * + * @since 3.1 moved from project package + */ + +public interface NameChecker { + + + /** + * Returns a base default name, like "UntitledEntity", etc. + * + * */ + String baseName(); + + /** + * Checks if the name is already taken by another sibling in the same + * context. + * + */ + boolean isNameInUse(Object namingContext, String name); + + +} diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameCheckers.java b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameCheckers.java new file mode 100644 index 0000000000..afb49f6249 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameCheckers.java @@ -0,0 +1,196 @@ +/***************************************************************** + * 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.map.naming; + +import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.configuration.DataChannelDescriptor; +import org.apache.cayenne.map.*; +import org.apache.commons.lang.StringUtils; + + + +public enum NameCheckers implements NameChecker { + + DataChannelDescriptor("project") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + return false; + } + }, + + DataMap("datamap") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + // null context is a situation when DataMap is a + // top level object of the project + if (namingContext == null) { + return false; + } + + if (namingContext instanceof DataDomain) { + DataDomain domain = (DataDomain) namingContext; + return domain.getDataMap(name) != null; + } + + if (namingContext instanceof DataChannelDescriptor) { + DataChannelDescriptor domain = (DataChannelDescriptor) namingContext; + return domain.getDataMap(name) != null; + } + return false; + } + }, + + ObjEntity("ObjEntity") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + DataMap map = (DataMap) namingContext; + return map.getObjEntity(name) != null; + } + }, + + Embeddable("Embeddable") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + DataMap map = (DataMap) namingContext; + if (map.getDefaultPackage() != null) { + return map.getEmbeddable((map.getDefaultPackage() + "." + name)) != null; + } + return map.getEmbeddable(name) != null; + } + }, + + EmbeddableAttribute("untitledAttr") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + Embeddable emb = (Embeddable) namingContext; + return emb.getAttribute(name) != null; + } + }, + + DbEntity("db_entity") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + DataMap map = (DataMap) namingContext; + return map.getDbEntity(name) != null; + } + }, + + ProcedureParameter("UntitledProcedureParameter") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + + // it doesn't matter if we create a parameter with + // a duplicate name.. parameters are positional anyway.. + // still try to use unique names for visual consistency + Procedure procedure = (Procedure) namingContext; + for (final ProcedureParameter parameter : procedure.getCallParameters()) { + if (name.equals(parameter.getName())) { + return true; + } + } + + return false; + } + }, + + Procedure("procedure") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + DataMap map = (DataMap) namingContext; + return map.getProcedure(name) != null; + } + }, + + SelectQuery("query") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + DataMap map = (DataMap) namingContext; + return map.getQuery(name) != null; + } + }, + + ObjAttribute("untitledAttr") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + return ObjRelationship.isNameInUse(namingContext, name); + } + }, + + DbAttribute("untitledAttr") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + Entity ent = (Entity) namingContext; + return ent.getAttribute(name) != null || ent.getRelationship(name) != null; + } + }, + + DataNodeDescriptor("datanode") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + DataChannelDescriptor domain = (DataChannelDescriptor) namingContext; + for (org.apache.cayenne.configuration.DataNodeDescriptor dataNodeDescriptor : domain.getNodeDescriptors()) { + if (dataNodeDescriptor.getName().equals(name)) { + return true; + } + } + return false; + } + }, + + ObjRelationship("untitledRel") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + ObjEntity ent = (ObjEntity) namingContext; + return DbAttribute.isNameInUse(namingContext, name) + || ent.getCallbackMethods().contains("get" + StringUtils.capitalize(name)); + } + }, + + DbRelationship("untitledRel") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + return DbAttribute.isNameInUse(namingContext, name); + } + }, + + ObjCallbackMethod("ObjCallbackMethod") { + @Override + public boolean isNameInUse(Object namingContext, String name) { + ObjEntity ent = (ObjEntity) namingContext; + + return name.startsWith("get") && DbAttribute.isNameInUse(namingContext, StringUtils.uncapitalize(name.substring(3))) + || ent.getCallbackMethods().contains(name); + } + } + ; + + public final String baseName; + + NameCheckers(String baseName) { + this.baseName = baseName; + } + + @Override + public String baseName() { + return baseName; + } + + +} diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/NameConverter.java b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameConverter.java similarity index 99% rename from cayenne-server/src/main/java/org/apache/cayenne/util/NameConverter.java rename to cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameConverter.java index 7c83dadd6e..0183b16628 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/util/NameConverter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameConverter.java @@ -17,7 +17,7 @@ * under the License. ****************************************************************/ -package org.apache.cayenne.util; +package org.apache.cayenne.map.naming; import java.util.HashMap; import java.util.Map; diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NamingStrategy.java b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ObjectNameGenerator.java similarity index 95% rename from cayenne-server/src/main/java/org/apache/cayenne/map/naming/NamingStrategy.java rename to cayenne-server/src/main/java/org/apache/cayenne/map/naming/ObjectNameGenerator.java index cfb9ebb948..7bd317723f 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NamingStrategy.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ObjectNameGenerator.java @@ -28,7 +28,7 @@ * * @since 3.0 */ -public interface NamingStrategy { +public interface ObjectNameGenerator { /** * Creates new name for Obj Entity diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/UniqueNameGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/UniqueNameGenerator.java new file mode 100644 index 0000000000..50d49039a6 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/UniqueNameGenerator.java @@ -0,0 +1,34 @@ +/* + * **************************************************************** + * * 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.map.naming; + +/** + * @author Alex.Kolonitsky. + */ +public interface UniqueNameGenerator { + + + String generate(Object namingContext); + + String generate(Object namingContext, String nameBase); + +} diff --git a/cayenne-server/src/main/java/org/apache/cayenne/merge/CreateTableToModel.java b/cayenne-server/src/main/java/org/apache/cayenne/merge/CreateTableToModel.java index 9e6752df59..045f06d9c8 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/merge/CreateTableToModel.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/merge/CreateTableToModel.java @@ -21,7 +21,7 @@ import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.ObjEntity; -import org.apache.cayenne.util.NameConverter; +import org.apache.cayenne.map.naming.NameConverter; import org.apache.cayenne.util.Util; /** diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java b/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java index fe0795b94e..2cc0002152 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java @@ -36,8 +36,10 @@ import org.apache.cayenne.map.ObjAttribute; import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.map.ObjRelationship; -import org.apache.cayenne.map.naming.BasicNamingStrategy; -import org.apache.cayenne.map.naming.NamingStrategy; +import org.apache.cayenne.map.naming.BasicNameGenerator; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; +import org.apache.cayenne.map.naming.ObjectNameGenerator; /** * Implements methods for entity merging. @@ -65,7 +67,7 @@ public class EntityMergeSupport { /** * Strategy for choosing names for entities, attributes and relationships */ - protected NamingStrategy namingStrategy; + protected ObjectNameGenerator nameGenerator; /** * Listeners of merge process. @@ -73,18 +75,18 @@ public class EntityMergeSupport { protected List listeners; public EntityMergeSupport(DataMap map) { - this(map, new BasicNamingStrategy(), true); + this(map, new BasicNameGenerator(), true); } /** * @since 3.0 */ - public EntityMergeSupport(DataMap map, NamingStrategy namingStrategy, boolean removeMeaningfulPKs) { + public EntityMergeSupport(DataMap map, ObjectNameGenerator nameGenerator, boolean removeMeaningfulPKs) { this.map = map; this.removeMeaningfulFKs = true; this.listeners = new ArrayList(); this.removeMeaningfulPKs = removeMeaningfulPKs; - this.namingStrategy = namingStrategy; + this.nameGenerator = nameGenerator; /** * Adding a listener, so that all created ObjRelationships would have @@ -168,9 +170,9 @@ public boolean synchronizeWithDbEntity(ObjEntity entity) { // add missing attributes for (DbAttribute da : getAttributesToAdd(entity)) { - String attrName = namingStrategy.createObjAttributeName(da); + String attrName = nameGenerator.createObjAttributeName(da); // avoid duplicate names - attrName = NamedObjectFactory.createName(ObjAttribute.class, entity, attrName); + attrName = DefaultUniqueNameGenerator.generate(NameCheckers.ObjAttribute, entity, attrName); String type = TypesMapping.getJavaBySqlType(da.getType()); @@ -195,8 +197,8 @@ public boolean synchronizeWithDbEntity(ObjEntity entity) { for (Entity mappedTarget : map.getMappedEntities(targetEntity)) { // avoid duplicate names - String relationshipName = namingStrategy.createObjRelationshipName(dr); - relationshipName = NamedObjectFactory.createName(ObjRelationship.class, entity, relationshipName); + String relationshipName = nameGenerator.createObjRelationshipName(dr); + relationshipName = DefaultUniqueNameGenerator.generate(NameCheckers.ObjRelationship, entity, relationshipName); ObjRelationship or = new ObjRelationship(relationshipName); or.addDbRelationship(dr); @@ -406,15 +408,15 @@ protected void fireRelationshipAdded(ObjRelationship rel) { /** * Sets new naming strategy for reverse engineering */ - public void setNamingStrategy(NamingStrategy strategy) { - this.namingStrategy = strategy; + public void setNameGenerator(ObjectNameGenerator strategy) { + this.nameGenerator = strategy; } /** * @return naming strategy for reverse engineering */ - public NamingStrategy getNamingStrategy() { - return namingStrategy; + public ObjectNameGenerator getNameGenerator() { + return nameGenerator; } /** diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/NamedObjectFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/util/NamedObjectFactory.java deleted file mode 100644 index 4fd859dd6b..0000000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/util/NamedObjectFactory.java +++ /dev/null @@ -1,520 +0,0 @@ -/***************************************************************** - * 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.util; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.apache.cayenne.access.DataDomain; -import org.apache.cayenne.configuration.DataChannelDescriptor; -import org.apache.cayenne.configuration.DataNodeDescriptor; -import org.apache.cayenne.dba.TypesMapping; -import org.apache.cayenne.map.DataMap; -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.map.DbRelationship; -import org.apache.cayenne.map.Embeddable; -import org.apache.cayenne.map.EmbeddableAttribute; -import org.apache.cayenne.map.Entity; -import org.apache.cayenne.map.ObjAttribute; -import org.apache.cayenne.map.ObjEntity; -import org.apache.cayenne.map.ObjRelationship; -import org.apache.cayenne.map.Procedure; -import org.apache.cayenne.map.ProcedureParameter; -import org.apache.cayenne.map.Relationship; -import org.apache.cayenne.query.Query; -import org.apache.cayenne.query.SelectQuery; - -/** - * Factory class that generates various Cayenne objects with default names that - * are unique in their corresponding context. Supports creation of the following - * objects: - *
    - *
  • DataMap
  • - *
  • ObjEntity
  • - *
  • ObjAttribute
  • - *
  • ObjRelationship
  • - *
  • DbEntity
  • - *
  • DbAttribute
  • - *
  • DbRelationship
  • - *
  • DataNodeDescriptor
  • - *
  • DataDomain
  • - *
  • Query
  • - *
  • Procedure
  • - *
  • ProcedureParameter
  • - *
- * This is a helper class used mostly by GUI and database reengineering classes. - * - * @since 3.1 moved from project package - */ -// TODO andrus 03/10/2010: should we make that a pluggable DI strategy? -// TODO andrus 03/01/2011: move to Modeler? -public abstract class NamedObjectFactory { - - private static final Map, NamedObjectFactory> factories = new HashMap, NamedObjectFactory>(); - - static { - factories.put(DataMap.class, new DataMapFactory()); - factories.put(ObjEntity.class, new ObjEntityFactory()); - factories.put(DbEntity.class, new DbEntityFactory()); - factories.put(ObjAttribute.class, new ObjAttributeFactory()); - factories.put(DbAttribute.class, new DbAttributeFactory()); - factories.put(DataNodeDescriptor.class, new DataNodeDescriptorFactory()); - factories.put(DataChannelDescriptor.class, new DataChannelDescriptorFactory()); - factories.put(DbRelationship.class, new DbRelationshipFactory(null, false)); - factories.put(ObjRelationship.class, new ObjRelationshipFactory(null, false)); - factories.put(Procedure.class, new ProcedureFactory()); - factories.put(Query.class, new SelectQueryFactory()); - factories.put(ProcedureParameter.class, new ProcedureParameterFactory()); - factories.put(Embeddable.class, new EmbeddableFactory()); - factories.put(EmbeddableAttribute.class, new EmbeddableAttributeFactory()); - } - - public static String createName(Class objectClass, Object namingContext) { - return (factories.get(objectClass)).makeName(namingContext); - } - - /** - * @since 1.0.5 - */ - public static String createName(Class objectClass, Object namingContext, String nameBase) { - return (factories.get(objectClass)).makeName(namingContext, nameBase); - } - - /** - * Creates an object using an appropriate factory class. If no factory is - * found for the object, NullPointerException is thrown. - *

- * Note that newly created object is not added to the parent. This - * behavior can be changed later. - *

- */ - @SuppressWarnings("unchecked") - public static T createObject(Class objectClass, Object namingContext) { - return (T) factories.get(objectClass).makeObject(namingContext); - } - - /** - * @since 1.0.5 - * @deprecated since 3.2 unused, and generics spec makes no sense. - */ - @Deprecated - public static Object createObject(Class objectClass, Object namingContext, String nameBase) { - return (factories.get(objectClass)).makeObject(namingContext, nameBase); - } - - /** - * Creates a relationship using an appropriate factory class. If no factory - * is found for the object, NullPointerException is thrown. - *

- * Note that newly created object is not added to the parent. This - * behavior can be changed later. - *

- */ - public static Relationship createRelationship(Entity srcEnt, Entity targetEnt, boolean toMany) { - NamedObjectFactory factory = (srcEnt instanceof ObjEntity) ? new ObjRelationshipFactory(targetEnt, toMany) - : new DbRelationshipFactory(targetEnt, toMany); - return (Relationship) factory.makeObject(srcEnt); - } - - /** - * Creates a unique name for the new object and constructs this object. - */ - protected synchronized String makeName(Object namingContext) { - return makeName(namingContext, nameBase()); - } - - /** - * @since 1.0.5 - */ - protected synchronized String makeName(Object namingContext, String nameBase) { - int c = 1; - String name = nameBase; - while (isNameInUse(name, namingContext)) { - name = nameBase + c++; - } - - return name; - } - - /** - * Creates a unique name for the new object and constructs this object. - */ - protected Object makeObject(Object namingContext) { - return makeObject(namingContext, nameBase()); - } - - /** - * @since 1.0.5 - */ - protected Object makeObject(Object namingContext, String nameBase) { - return create(makeName(namingContext, nameBase), namingContext); - } - - /** Returns a base default name, like "UntitledEntity", etc. */ - protected abstract String nameBase(); - - /** Internal factory method. Invoked after the name is figured out. */ - protected abstract Object create(String name, Object namingContext); - - /** - * Checks if the name is already taken by another sibling in the same - * context. - */ - protected abstract boolean isNameInUse(String name, Object namingContext); - - static class DataChannelDescriptorFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "project"; - } - - @Override - protected Object create(String name, Object namingContext) { - DataChannelDescriptor dataChDes = new DataChannelDescriptor(); - dataChDes.setName(name); - return dataChDes; - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - return false; - } - } - - static class DataMapFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "datamap"; - } - - @Override - protected Object create(String name, Object namingContext) { - return new DataMap(name); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - // null context is a situation when DataMap is a - // top level object of the project - if (namingContext == null) { - return false; - } - - if (namingContext instanceof DataDomain) { - DataDomain domain = (DataDomain) namingContext; - return domain.getDataMap(name) != null; - } - - if (namingContext instanceof DataChannelDescriptor) { - DataChannelDescriptor domain = (DataChannelDescriptor) namingContext; - return domain.getDataMap(name) != null; - } - return false; - - } - } - - static class ObjEntityFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "ObjEntity"; - } - - @Override - protected Object create(String name, Object namingContext) { - return new ObjEntity(name); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - DataMap map = (DataMap) namingContext; - return map.getObjEntity(name) != null; - } - } - - static class EmbeddableFactory extends NamedObjectFactory { - - private String nameBase; - - public String getNameBase() { - return nameBase; - } - - public void setNameBase(String nameBase) { - this.nameBase = nameBase; - } - - @Override - protected String nameBase() { - if (getNameBase() == null) { - setNameBase("Embeddable"); - } - return getNameBase(); - - } - - @Override - protected Object create(String name, Object namingContext) { - DataMap map = (DataMap) namingContext; - if (map.getDefaultPackage() != null) { - return new Embeddable(map.getDefaultPackage() + "." + name); - } - return new Embeddable(name); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - DataMap map = (DataMap) namingContext; - if (map.getDefaultPackage() != null) { - return map.getEmbeddable((map.getDefaultPackage() + "." + name)) != null; - } - return map.getEmbeddable(name) != null; - } - } - - static class EmbeddableAttributeFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "untitledAttr"; - } - - @Override - protected Object create(String name, Object namingContext) { - return new EmbeddableAttribute(name); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - Embeddable emb = (Embeddable) namingContext; - return emb.getAttribute(name) != null; - } - } - - static class DbEntityFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "db_entity"; - } - - @Override - protected Object create(String name, Object namingContext) { - return new DbEntity(name); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - DataMap map = (DataMap) namingContext; - return map.getDbEntity(name) != null; - } - } - - static class ProcedureParameterFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "UntitledProcedureParameter"; - } - - @Override - protected Object create(String name, Object namingContext) { - return new ProcedureParameter(name); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - - // it doesn't matter if we create a parameter with - // a duplicate name.. parameters are positional anyway.. - // still try to use unique names for visual consistency - Procedure procedure = (Procedure) namingContext; - for (final ProcedureParameter parameter : procedure.getCallParameters()) { - if (name.equals(parameter.getName())) { - return true; - } - } - - return false; - } - } - - static class ProcedureFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "procedure"; - } - - @Override - protected Object create(String name, Object namingContext) { - return new Procedure(name); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - DataMap map = (DataMap) namingContext; - return map.getProcedure(name) != null; - } - } - - static class SelectQueryFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "query"; - } - - @Override - protected Object create(String name, Object namingContext) { - SelectQuery query = new SelectQuery(); - query.setName(name); - return query; - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - DataMap map = (DataMap) namingContext; - return map.getQuery(name) != null; - } - } - - static class ObjAttributeFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "untitledAttr"; - } - - @Override - protected Object create(String name, Object namingContext) { - return new ObjAttribute(name, null, (ObjEntity) namingContext); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - Entity ent = (Entity) namingContext; - return ent.getAttribute(name) != null || ent.getRelationship(name) != null; - } - } - - static class DbAttributeFactory extends ObjAttributeFactory { - - @Override - protected Object create(String name, Object namingContext) { - return new DbAttribute(name, TypesMapping.NOT_DEFINED, (DbEntity) namingContext); - } - } - - static class DataNodeDescriptorFactory extends NamedObjectFactory { - - @Override - protected String nameBase() { - return "datanode"; - } - - @Override - protected Object create(String name, Object namingContext) { - return new DataNodeDescriptor(name); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - DataChannelDescriptor domain = (DataChannelDescriptor) namingContext; - Iterator nodeIt = domain.getNodeDescriptors().iterator(); - while (nodeIt.hasNext()) { - if (nodeIt.next().getName().equals(name)) { - return true; - } - } - return false; - } - } - - static class ObjRelationshipFactory extends NamedObjectFactory { - - protected Entity target; - protected boolean toMany; - - public ObjRelationshipFactory(Entity target, boolean toMany) { - this.target = target; - this.toMany = toMany; - } - - @Override - protected Object create(String name, Object namingContext) { - return new ObjRelationship(name); - } - - @Override - protected boolean isNameInUse(String name, Object namingContext) { - Entity ent = (Entity) namingContext; - return ent.getRelationship(name) != null || ent.getAttribute(name) != null; - } - - /** - * Returns generated name for the ObjRelationships. For to-one case and - * entity name "xxxx" it generates name "toXxxx". For to-many case and - * entity name "Xxxx" it generates name "xxxxArray". - */ - @Override - protected String nameBase() { - if (target == null) { - return "untitledRel"; - } - - String name = target.getName(); - return (toMany) ? Character.toLowerCase(name.charAt(0)) + name.substring(1) + "Array" : "to" - + Character.toUpperCase(name.charAt(0)) + name.substring(1); - } - } - - static class DbRelationshipFactory extends ObjRelationshipFactory { - - public DbRelationshipFactory(Entity target, boolean toMany) { - super(target, toMany); - } - - @Override - protected Object create(String name, Object namingContext) { - return new DbRelationship(name); - } - - /** - * Returns generated name for the DbRelationships. For to-one case it - * generates name "TO_XXXX". For to-many case it generates name - * "XXXX_ARRAY". - */ - @Override - protected String nameBase() { - if (target == null) { - return "untitledRel"; - } - - String name = target.getName(); - return (toMany) ? name + "_ARRAY" : "TO_" + name; - } - } -} diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/ManyToManyCandidateEntityTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/ManyToManyCandidateEntityTest.java index d7c2600f03..eb9b6feed5 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/ManyToManyCandidateEntityTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/ManyToManyCandidateEntityTest.java @@ -38,6 +38,7 @@ import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.map.Relationship; +import org.apache.cayenne.map.naming.BasicNameGenerator; import org.apache.cayenne.resource.URLResource; import java.net.URL; @@ -76,19 +77,19 @@ public void configure(Binder binder) { public void testMatchingForManyToManyEntity() throws Exception { ObjEntity manyToManyEntity = map.getObjEntity("Table1Table2"); - assertEquals(true, new ManyToManyCandidateEntity(manyToManyEntity).isRepresentManyToManyTable()); + assertNotNull(ManyToManyCandidateEntity.build(manyToManyEntity)); } public void testMatchingForNotManyToManyEntity() throws Exception { ObjEntity entity = map.getObjEntity("Table1"); - assertEquals(false, new ManyToManyCandidateEntity(entity).isRepresentManyToManyTable()); + assertNull(ManyToManyCandidateEntity.build(entity)); } public void testOptimisationForManyToManyEntity() { ObjEntity manyToManyEntity = map.getObjEntity("Table1Table2"); - new ManyToManyCandidateEntity(manyToManyEntity).optimizeRelationships(); + ManyToManyCandidateEntity.build(manyToManyEntity).optimizeRelationships(new BasicNameGenerator()); ObjEntity table1Entity = map.getObjEntity("Table1"); ObjEntity table2Entity = map.getObjEntity("Table2"); diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/DataMapTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/DataMapTest.java index 0974f431c4..687db53376 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/map/DataMapTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/map/DataMapTest.java @@ -33,7 +33,6 @@ import org.apache.cayenne.query.AbstractQuery; import org.apache.cayenne.query.MockAbstractQuery; import org.apache.cayenne.query.Query; -import org.apache.cayenne.util.NamedObjectFactory; import org.apache.cayenne.util.Util; import org.apache.cayenne.util.XMLEncoder; import org.xml.sax.InputSource; @@ -313,21 +312,21 @@ public void testRemoveDbEntity() { DataMap map = new DataMap(); // create a twisty maze of intermingled relationships. - DbEntity e1 = NamedObjectFactory.createObject(DbEntity.class, map); + DbEntity e1 = new DbEntity(); e1.setName("e1"); - DbEntity e2 = NamedObjectFactory.createObject(DbEntity.class, map); + DbEntity e2 = new DbEntity(); e2.setName("e2"); - DbRelationship r1 = NamedObjectFactory.createObject(DbRelationship.class, e1); + DbRelationship r1 = new DbRelationship(); r1.setName("r1"); r1.setTargetEntity(e2); - DbRelationship r2 = NamedObjectFactory.createObject(DbRelationship.class, e2); + DbRelationship r2 = new DbRelationship(); r2.setName("r2"); r2.setTargetEntity(e1); - DbRelationship r3 = NamedObjectFactory.createObject(DbRelationship.class, e1); + DbRelationship r3 = new DbRelationship(); r3.setName("r3"); r3.setTargetEntity(e2); diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNamingStrategyTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNameGeneratorTest.java similarity index 89% rename from cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNamingStrategyTest.java rename to cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNameGeneratorTest.java index 424e18f5f6..e0bd5c0237 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNamingStrategyTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNameGeneratorTest.java @@ -23,12 +23,10 @@ import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.DbRelationship; -import org.apache.cayenne.map.naming.BasicNamingStrategy; -import org.apache.cayenne.map.naming.ExportedKey; -public class BasicNamingStrategyTest extends TestCase { +public class BasicNameGeneratorTest extends TestCase { public void testStrategy() throws Exception { - BasicNamingStrategy strategy = new BasicNamingStrategy(); + BasicNameGenerator strategy = new BasicNameGenerator(); ExportedKey key = new ExportedKey("ARTIST", "ARTIST_ID", null, "PAINTING", "ARTIST_ID", null); diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/naming/NameCheckersTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/naming/NameCheckersTest.java new file mode 100644 index 0000000000..e4b6739b77 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/map/naming/NameCheckersTest.java @@ -0,0 +1,175 @@ +package org.apache.cayenne.map.naming; + +import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.configuration.DataChannelDescriptor; +import org.apache.cayenne.configuration.DataNodeDescriptor; +import org.apache.cayenne.map.*; +import org.apache.cayenne.query.SelectQuery; +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class NameCheckersTest { + + @Test + public void testObjEntityAttributes() throws Exception { + NameCheckers maker = NameCheckers.ObjAttribute; + ObjEntity namingContainer = new ObjEntity(); + + String baseName = maker.baseName(); + String name = DefaultUniqueNameGenerator.generate(maker, namingContainer); + assertEquals(baseName, name); + namingContainer.addAttribute(new ObjAttribute(name)); + + name = DefaultUniqueNameGenerator.generate(maker, namingContainer); + assertEquals(baseName + "1", name); + namingContainer.addAttribute(new ObjAttribute(name)); + + name = DefaultUniqueNameGenerator.generate(maker, namingContainer); + assertEquals(baseName + "2", name); + namingContainer.addAttribute(new ObjAttribute(name)); + + name = DefaultUniqueNameGenerator.generate(maker, namingContainer); + assertEquals(baseName + "3", name); + namingContainer.addAttribute(new ObjAttribute(name)); + + maker = NameCheckers.ObjRelationship; + baseName = maker.baseName(); + name = DefaultUniqueNameGenerator.generate(maker, namingContainer); + assertEquals(baseName, name); + namingContainer.addRelationship(new ObjRelationship(name)); + + name = DefaultUniqueNameGenerator.generate(maker, namingContainer); + assertEquals(baseName + "1", name); + namingContainer.addRelationship(new ObjRelationship(name)); + + maker = NameCheckers.ObjCallbackMethod; + baseName = maker.baseName(); + name = DefaultUniqueNameGenerator.generate(maker, namingContainer); + assertEquals(baseName, name); + namingContainer.addRelationship(new ObjRelationship(name)); + } + + @Test + public void testEntity () { + DataMap map = new DataMap(); + + map.addDbEntity(new DbEntity("name")); + checkNameAndOther(map, NameCheckers.DbEntity, "name"); + + map.addObjEntity(new ObjEntity("name")); + checkNameAndOther(map, NameCheckers.ObjEntity, "name"); + + map.addProcedure(new Procedure("name")); + checkNameAndOther(map, NameCheckers.Procedure, "name"); + + SelectQuery query = new SelectQuery("name"); + query.setName("name"); + map.addQuery(query); + checkNameAndOther(map, NameCheckers.SelectQuery, "name"); + } + + @Test + public void testProject() throws Exception { + assertFalse(NameCheckers.DataChannelDescriptor.isNameInUse(null, null)); + } + + @Test + public void testDbEntity() throws Exception { + DbEntity dbEntity = new DbEntity(); + + dbEntity.addRelationship(new DbRelationship("name")); + checkNameAndOther(dbEntity, NameCheckers.DbRelationship, "name"); + } + + @Test + public void testProcedureAttr() throws Exception { + Procedure procedure = new Procedure(); + + procedure.addCallParameter(new ProcedureParameter("name")); + checkNameAndOther(procedure, NameCheckers.ProcedureParameter, "name"); + } + + @Test + public void testEmbeddableAttr() throws Exception { + Embeddable embeddable = new Embeddable(); + + embeddable.addAttribute(new EmbeddableAttribute("name")); + checkNameAndOther(embeddable, NameCheckers.EmbeddableAttribute, "name"); + } + + @Test + public void testDatanode() throws Exception { + DataChannelDescriptor descriptor = new DataChannelDescriptor(); + + descriptor.getDataMaps().add(new DataMap("name")); + checkNameAndOther(descriptor, NameCheckers.DataMap, "name"); + + descriptor.getNodeDescriptors().add(new DataNodeDescriptor("name")); + checkNameAndOther(descriptor, NameCheckers.DataNodeDescriptor, "name"); + } + + @Test + public void testDataMap() throws Exception { + DataDomain dataDomain = new DataDomain("name"); + + dataDomain.addDataMap(new DataMap("name")); + checkNameAndOther(dataDomain, NameCheckers.DataMap, "name"); + + assertFalse(NameCheckers.DataMap.isNameInUse(null, "name")); + assertFalse(NameCheckers.DataMap.isNameInUse(1, "name")); + } + + private void checkNameAndOther(Object namingContainer, NameCheckers maker, String newName) { + assertTrue(maker.isNameInUse(namingContainer, newName)); + assertEquals(newName + "1", DefaultUniqueNameGenerator.generate(maker,namingContainer, newName)); + assertEquals("other" + newName, DefaultUniqueNameGenerator.generate(maker,namingContainer, "other" + newName)); + } + + @Test + public void testOverlappingAttributeAndCallbackNames() throws Exception { + ObjEntity namingContainer = new ObjEntity(); + + namingContainer.addAttribute(new ObjAttribute("myName")); + Assert.assertEquals("getMyName1", DefaultUniqueNameGenerator.generate(NameCheckers.ObjCallbackMethod, namingContainer, "getMyName")); + + namingContainer.getCallbackMap().getPostAdd().addCallbackMethod("getSecondName"); + Assert.assertEquals("SecondName1", DefaultUniqueNameGenerator.generate(NameCheckers.ObjAttribute, namingContainer, "SecondName")); + Assert.assertEquals("secondName1", DefaultUniqueNameGenerator.generate(NameCheckers.ObjAttribute, namingContainer, "secondName")); + Assert.assertEquals("SecondName1", DefaultUniqueNameGenerator.generate(NameCheckers.ObjRelationship, namingContainer, "SecondName")); + Assert.assertEquals("secondName1", DefaultUniqueNameGenerator.generate(NameCheckers.ObjRelationship, namingContainer, "secondName")); + } + + @Test + public void testAttributeDifferentInFirstLetterCases() throws Exception { + ObjEntity namingContainer = new ObjEntity(); + + namingContainer.addAttribute(new ObjAttribute("myName")); + Assert.assertTrue(NameCheckers.ObjAttribute.isNameInUse(namingContainer, "myName")); + Assert.assertFalse(NameCheckers.ObjAttribute.isNameInUse(namingContainer, "MyName")); + + namingContainer.getCallbackMap().getPostAdd().addCallbackMethod("getSecondName"); + Assert.assertEquals("SecondName1", DefaultUniqueNameGenerator.generate(NameCheckers.ObjAttribute, namingContainer, "SecondName")); + Assert.assertEquals("secondName1", DefaultUniqueNameGenerator.generate(NameCheckers.ObjAttribute, namingContainer, "secondName")); + } + + @Test + public void testEmbeddable() { + DataMap map = new DataMap(); + + map.addEmbeddable(new Embeddable("name")); + Assert.assertTrue(NameCheckers.Embeddable.isNameInUse(map, "name")); + Assert.assertEquals("name1", DefaultUniqueNameGenerator.generate(NameCheckers.Embeddable, map, "name")); + Assert.assertFalse(NameCheckers.Embeddable.isNameInUse(map, "other-name")); + + map.setDefaultPackage("package"); + Assert.assertFalse(NameCheckers.Embeddable.isNameInUse(map, "name")); + Assert.assertEquals("package.name", DefaultUniqueNameGenerator.generate(NameCheckers.Embeddable, map, "name")); + map.addEmbeddable(new Embeddable("package.name")); + + Assert.assertTrue(NameCheckers.Embeddable.isNameInUse(map, "name")); + Assert.assertEquals("package.name1", DefaultUniqueNameGenerator.generate(NameCheckers.Embeddable, map, "name")); + Assert.assertFalse(NameCheckers.Embeddable.isNameInUse(map, "other-name")); + } +} \ No newline at end of file diff --git a/cayenne-server/src/test/java/org/apache/cayenne/util/NameConverterTest.java b/cayenne-server/src/test/java/org/apache/cayenne/util/NameConverterTest.java index 796f9004e9..bcb53d6561 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/util/NameConverterTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/util/NameConverterTest.java @@ -20,6 +20,7 @@ package org.apache.cayenne.util; import junit.framework.TestCase; +import org.apache.cayenne.map.naming.NameConverter; public class NameConverterTest extends TestCase { diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/gen/ClientDataMapArtifact.java b/cayenne-tools/src/main/java/org/apache/cayenne/gen/ClientDataMapArtifact.java index 602da17e93..129f2d3bc9 100644 --- a/cayenne-tools/src/main/java/org/apache/cayenne/gen/ClientDataMapArtifact.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/gen/ClientDataMapArtifact.java @@ -23,7 +23,7 @@ import org.apache.cayenne.map.DataMap; import org.apache.cayenne.query.Query; -import org.apache.cayenne.util.NameConverter; +import org.apache.cayenne.map.naming.NameConverter; import org.apache.cayenne.util.Util; public class ClientDataMapArtifact extends DataMapArtifact { diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java b/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java index 3db3916563..73a81d8e19 100644 --- a/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java @@ -28,7 +28,7 @@ import org.apache.cayenne.query.Query; import org.apache.cayenne.query.SQLTemplate; import org.apache.cayenne.query.SelectQuery; -import org.apache.cayenne.util.NameConverter; +import org.apache.cayenne.map.naming.NameConverter; import org.apache.velocity.VelocityContext; /** diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapUtils.java b/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapUtils.java index 6679b8b159..f10eaa34e4 100644 --- a/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapUtils.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapUtils.java @@ -34,7 +34,7 @@ import org.apache.cayenne.query.Query; import org.apache.cayenne.query.SelectQuery; import org.apache.cayenne.util.CayenneMapEntry; -import org.apache.cayenne.util.NameConverter; +import org.apache.cayenne.map.naming.NameConverter; import org.apache.commons.collections.set.ListOrderedSet; import java.util.Collection; diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/gen/EntityUtils.java b/cayenne-tools/src/main/java/org/apache/cayenne/gen/EntityUtils.java index a0662ea917..438b1f51de 100644 --- a/cayenne-tools/src/main/java/org/apache/cayenne/gen/EntityUtils.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/gen/EntityUtils.java @@ -68,12 +68,7 @@ public EntityUtils(DataMap dataMap, ObjEntity objEntity, String fqnBaseClass, St this.primaryDataMap = dataMap; this.objEntity = objEntity; - - this.callbackNames = new LinkedHashSet(); - for (CallbackDescriptor cb : objEntity.getCallbackMap().getCallbacks()) { - callbackNames.addAll(cb.getCallbackMethods()); - } - + this.callbackNames = objEntity.getCallbackMethods(); } EntityUtils(DataMap dataMap, ObjEntity objEntity, String baseClassName, String basePackageName, @@ -89,11 +84,7 @@ public EntityUtils(DataMap dataMap, ObjEntity objEntity, String fqnBaseClass, St this.primaryDataMap = dataMap; this.objEntity = objEntity; - - this.callbackNames = new LinkedHashSet(); - for (CallbackDescriptor cb : objEntity.getCallbackMap().getCallbacks()) { - callbackNames.addAll(cb.getCallbackMethods()); - } + this.callbackNames = objEntity.getCallbackMethods(); } /** @@ -124,10 +115,7 @@ public boolean isAbstract() { * Returns true if current ObjEntity is defined as abstract. */ public boolean isAbstract(ObjEntity anObjEntity) { - if (anObjEntity == null) - return false; - - return objEntity.isAbstract(); + return anObjEntity != null && anObjEntity.isAbstract(); } /** @@ -202,7 +190,7 @@ public boolean hasToOneRelationships(ObjEntity anObjEntity) { } for (Relationship r : anObjEntity.getRelationships()) { - if (false == r.isToMany()) { + if (!r.isToMany()) { return true; } } diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/gen/StringUtils.java b/cayenne-tools/src/main/java/org/apache/cayenne/gen/StringUtils.java index 0f2fe30ebe..bd5c4535b3 100644 --- a/cayenne-tools/src/main/java/org/apache/cayenne/gen/StringUtils.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/gen/StringUtils.java @@ -20,7 +20,7 @@ package org.apache.cayenne.gen; import org.apache.cayenne.project.validation.NameValidationHelper; -import org.apache.cayenne.util.NameConverter; +import org.apache.cayenne.map.naming.NameConverter; import org.apache.cayenne.util.Util; /** diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/map/naming/SmartNamingStrategy.java b/cayenne-tools/src/main/java/org/apache/cayenne/map/naming/SmartNameGenerator.java similarity index 63% rename from cayenne-tools/src/main/java/org/apache/cayenne/map/naming/SmartNamingStrategy.java rename to cayenne-tools/src/main/java/org/apache/cayenne/map/naming/SmartNameGenerator.java index 7dbf0260cc..450cd58c0c 100644 --- a/cayenne-tools/src/main/java/org/apache/cayenne/map/naming/SmartNamingStrategy.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/map/naming/SmartNameGenerator.java @@ -20,13 +20,13 @@ import java.util.Locale; -import org.apache.cayenne.map.naming.BasicNamingStrategy; -import org.apache.cayenne.map.naming.ExportedKey; -import org.apache.cayenne.util.NameConverter; +import org.apache.cayenne.map.DbAttribute; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.map.DbRelationship; import org.jvnet.inflector.Noun; /** - * SmartNamingStrategy is a new strategy for generating names of + * SmartNameGenerator is a new strategy for generating names of * entities, attributes etc. * * Advantages of this strategy are: @@ -37,52 +37,59 @@ * * @since 3.0 */ -public class SmartNamingStrategy extends BasicNamingStrategy { +public class SmartNameGenerator implements ObjectNameGenerator { + @Override - public String createDbRelationshipName( - ExportedKey key, - boolean toMany) { + public String createDbRelationshipName(ExportedKey key, boolean toMany) { String name; - - if (!toMany) { - String fkColName = key.getFKColumnName(); - - //trim "ID" in the end - if (fkColName.toUpperCase().endsWith("_ID") && fkColName.length() > 3) { - fkColName = fkColName.substring(0, fkColName.length() - 3); - } - else if (fkColName.toUpperCase().endsWith("ID") && fkColName.length() > 2) { - fkColName = fkColName.substring(0, fkColName.length() - 2); - } - else { - /** - * We don't want relationship to conflict with attribute, so we'd better return - * superior value with 'to' - */ - return super.createDbRelationshipName(key, toMany); - } - - name = fkColName; - } - else { + + if (toMany) { try { /** * by default we use english language rules here. - * uppercase is required for NameConverter to work properly + * uppercase is required for NameConverter to work properly */ name = Noun.pluralOf(key.getFKTableName().toLowerCase(), Locale.ENGLISH).toUpperCase(); - } - catch (Exception inflectorError) { + } 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 + * use superclass' behavior if something's gone wrong */ - return super.createDbRelationshipName(key, toMany); + return key.getFKTableName().toLowerCase(); + } + } else { + String fkColName = key.getFKColumnName(); + + //trim "ID" in the end + if (fkColName == null) { + name = key.getPKTableName(); + } else if (fkColName.toUpperCase().endsWith("_ID") && fkColName.length() > 3) { + name = fkColName.substring(0, fkColName.length() - 3); + } else if (fkColName.toUpperCase().endsWith("ID") && fkColName.length() > 2) { + name = fkColName.substring(0, fkColName.length() - 2); + } else { + /** + * We don't want relationship to conflict with attribute, so we'd better return + * superior value with 'to' + */ + name = key.getPKTableName(); } } return NameConverter.underscoredToJava(name, false); } + + public String createObjEntityName(DbEntity dbEntity) { + return NameConverter.underscoredToJava(dbEntity.getName(), true); + } + + public String createObjAttributeName(DbAttribute attr) { + return NameConverter.underscoredToJava(attr.getName(), false); + } + + public String createObjRelationshipName(DbRelationship dbRel) { + return NameConverter.underscoredToJava(dbRel.getName(), false); + } } diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java index f9b94e5708..c93f6b447f 100644 --- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbImporterTask.java @@ -23,7 +23,7 @@ import org.apache.cayenne.di.DIBootstrap; import org.apache.cayenne.di.Injector; -import org.apache.cayenne.map.naming.SmartNamingStrategy; +import org.apache.cayenne.map.naming.SmartNameGenerator; import org.apache.cayenne.tools.configuration.ToolsModule; import org.apache.cayenne.tools.dbimport.DbImportAction; import org.apache.cayenne.tools.dbimport.DbImportModule; @@ -53,7 +53,7 @@ public DbImporterTask() { parameters.setOverwrite(true); parameters.setImportProcedures(false); parameters.setUsePrimitives(true); - parameters.setNamingStrategy(SmartNamingStrategy.class.getName()); + parameters.setNamingStrategy(SmartNameGenerator.class.getName()); } @Override diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java index 1a20b6ab50..b377220f59 100644 --- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java @@ -40,7 +40,7 @@ import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.MapLoader; import org.apache.cayenne.map.ObjEntity; -import org.apache.cayenne.map.naming.NamingStrategy; +import org.apache.cayenne.map.naming.ObjectNameGenerator; import org.apache.cayenne.project.Project; import org.apache.cayenne.project.ProjectSaver; import org.apache.cayenne.resource.URLResource; @@ -168,7 +168,7 @@ public boolean includeTableName(String tableName) { @Override protected EntityMergeSupport createEntityMerger(DataMap map) { - EntityMergeSupport emSupport = new EntityMergeSupport(map, namingStrategy, true) { + EntityMergeSupport emSupport = new EntityMergeSupport(map, nameGenerator, true) { @Override protected boolean removePK(DbEntity dbEntity) { @@ -184,8 +184,8 @@ protected boolean removePK(DbEntity dbEntity) { // TODO: load via DI AdhocObjectFactory String namingStrategy = parameters.getNamingStrategy(); if (namingStrategy != null) { - NamingStrategy namingStrategyInst = (NamingStrategy) Class.forName(namingStrategy).newInstance(); - loader.setNamingStrategy(namingStrategyInst); + ObjectNameGenerator nameGeneratorInst = (ObjectNameGenerator) Class.forName(namingStrategy).newInstance(); + loader.setNameGenerator(nameGeneratorInst); } return loader; diff --git a/cayenne-tools/src/test/java/org/apache/cayenne/map/naming/SmartNamingStrategyTest.java b/cayenne-tools/src/test/java/org/apache/cayenne/map/naming/SmartNameGeneratorTest.java similarity index 93% rename from cayenne-tools/src/test/java/org/apache/cayenne/map/naming/SmartNamingStrategyTest.java rename to cayenne-tools/src/test/java/org/apache/cayenne/map/naming/SmartNameGeneratorTest.java index 14666e0f47..053ac8c9a7 100644 --- a/cayenne-tools/src/test/java/org/apache/cayenne/map/naming/SmartNamingStrategyTest.java +++ b/cayenne-tools/src/test/java/org/apache/cayenne/map/naming/SmartNameGeneratorTest.java @@ -23,11 +23,10 @@ import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.DbRelationship; -import org.apache.cayenne.map.naming.ExportedKey; -public class SmartNamingStrategyTest extends TestCase { +public class SmartNameGeneratorTest extends TestCase { public void testStrategy() throws Exception { - SmartNamingStrategy strategy = new SmartNamingStrategy(); + SmartNameGenerator strategy = new SmartNameGenerator(); ExportedKey key = new ExportedKey("ARTIST", "ARTIST_ID", null, "PAINTING", "ARTIST_ID", null); diff --git a/docs/docbook/cayenne-guide/src/docbkx/including-cayenne-in-project.xml b/docs/docbook/cayenne-guide/src/docbkx/including-cayenne-in-project.xml index b86edf8b8e..32ebe3133d 100644 --- a/docs/docbook/cayenne-guide/src/docbkx/including-cayenne-in-project.xml +++ b/docs/docbook/cayenne-guide/src/docbkx/including-cayenne-in-project.xml @@ -490,7 +490,7 @@ String The naming strategy used for mapping database names to object entity names. Default is - org.apache.cayenne.map.naming.SmartNamingStrategy. + org.apache.cayenne.map.naming.SmartNameGenerator. diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateAttributeAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateAttributeAction.java index 4b747fe6f3..1b8b939adb 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateAttributeAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateAttributeAction.java @@ -23,6 +23,7 @@ import org.apache.cayenne.configuration.ConfigurationNode; import org.apache.cayenne.configuration.DataChannelDescriptor; +import org.apache.cayenne.dba.TypesMapping; import org.apache.cayenne.map.Attribute; import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.DbAttribute; @@ -35,6 +36,8 @@ import org.apache.cayenne.map.event.AttributeEvent; import org.apache.cayenne.map.event.EmbeddableAttributeEvent; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.AttributeDisplayEvent; @@ -42,7 +45,6 @@ import org.apache.cayenne.modeler.undo.CreateAttributeUndoableEdit; import org.apache.cayenne.modeler.undo.CreateEmbAttributeUndoableEdit; import org.apache.cayenne.modeler.util.CayenneAction; -import org.apache.cayenne.util.NamedObjectFactory; /** */ @@ -74,8 +76,8 @@ public void performAction(ActionEvent e) { if (getProjectController().getCurrentEmbeddable() != null) { Embeddable embeddable = mediator.getCurrentEmbeddable(); - EmbeddableAttribute attr = (EmbeddableAttribute) NamedObjectFactory.createObject(EmbeddableAttribute.class, - embeddable); + EmbeddableAttribute attr = new EmbeddableAttribute(); + attr.setName(DefaultUniqueNameGenerator.generate(NameCheckers.EmbeddableAttribute, embeddable)); createEmbAttribute(embeddable, attr); @@ -87,7 +89,7 @@ public void performAction(ActionEvent e) { ObjEntity objEntity = mediator.getCurrentObjEntity(); - ObjAttribute attr = NamedObjectFactory.createObject(ObjAttribute.class, objEntity); + ObjAttribute attr = new ObjAttribute(DefaultUniqueNameGenerator.generate(NameCheckers.ObjAttribute, objEntity), null, objEntity); createObjAttribute(mediator.getCurrentDataMap(), objEntity, attr); @@ -97,7 +99,8 @@ public void performAction(ActionEvent e) { } else if (getProjectController().getCurrentDbEntity() != null) { DbEntity dbEntity = getProjectController().getCurrentDbEntity(); - DbAttribute attr = NamedObjectFactory.createObject(DbAttribute.class, dbEntity); + DbAttribute attr = new DbAttribute(DefaultUniqueNameGenerator.generate(NameCheckers.DbAttribute, dbEntity), + TypesMapping.NOT_DEFINED, dbEntity); createDbAttribute(mediator.getCurrentDataMap(), dbEntity, attr); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateCallbackMethodAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateCallbackMethodAction.java index b3cb1f41f0..7244bd8765 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateCallbackMethodAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateCallbackMethodAction.java @@ -23,12 +23,14 @@ import org.apache.cayenne.map.CallbackMap; import org.apache.cayenne.map.LifecycleEvent; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.editor.CallbackType; import org.apache.cayenne.modeler.event.CallbackMethodEvent; import org.apache.cayenne.modeler.undo.CreateCallbackMethodUndoableEdit; import org.apache.cayenne.modeler.util.CayenneAction; -import org.apache.cayenne.util.NameConverter; +import org.apache.cayenne.map.naming.NameConverter; /** * Action class for creating callback methods on ObjEntity @@ -76,26 +78,7 @@ public final void performAction(ActionEvent e) { // generate methodName String methodNamePrefix = toMethodName(callbackType.getType()); - String methodName; - // now that we're generating the method names based on the callback type, check to - // see if the - // raw prefix, no numbers, is taken. - if (!getCallbackMap() - .getCallbackDescriptor(callbackType.getType()) - .getCallbackMethods() - .contains(methodNamePrefix)) { - methodName = methodNamePrefix; - } - else { - int counter = 1; - do { - methodName = methodNamePrefix + counter; - counter++; - } while (getCallbackMap() - .getCallbackDescriptor(callbackType.getType()) - .getCallbackMethods() - .contains(methodName)); - } + String methodName = DefaultUniqueNameGenerator.generate(NameCheckers.ObjCallbackMethod, getProjectController().getCurrentObjEntity(), methodNamePrefix); createCallbackMethod(callbackType, methodName); application.getUndoManager().addEdit( diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateDataMapAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateDataMapAction.java index 9b0e446882..362a1e8c70 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateDataMapAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateDataMapAction.java @@ -25,12 +25,13 @@ import org.apache.cayenne.configuration.DataChannelDescriptor; import org.apache.cayenne.configuration.DataNodeDescriptor; import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.undo.CreateDataMapUndoableEdit; import org.apache.cayenne.modeler.util.CayenneAction; import org.apache.cayenne.resource.Resource; -import org.apache.cayenne.util.NamedObjectFactory; /** * Action that creates new DataMap in the project. @@ -63,9 +64,7 @@ public void performAction(ActionEvent e) { .getProject() .getRootNode(); - DataMap map = (DataMap) NamedObjectFactory.createObject( - DataMap.class, - currentDomain); + DataMap map = new DataMap(DefaultUniqueNameGenerator.generate(NameCheckers.DataMap, currentDomain)); // set configuration source for new dataMap Resource baseResource = currentDomain.getConfigurationSource(); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateDbEntityAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateDbEntityAction.java index 29094da675..9c11a2639f 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateDbEntityAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateDbEntityAction.java @@ -28,12 +28,13 @@ import org.apache.cayenne.map.Entity; import org.apache.cayenne.map.event.EntityEvent; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.EntityDisplayEvent; import org.apache.cayenne.modeler.undo.CreateDbEntityUndoableEdit; import org.apache.cayenne.modeler.util.CayenneAction; -import org.apache.cayenne.util.NamedObjectFactory; /** */ @@ -64,7 +65,7 @@ public void performAction(ActionEvent e) { ProjectController mediator = getProjectController(); DataMap map = mediator.getCurrentDataMap(); - DbEntity entity = (DbEntity) NamedObjectFactory.createObject(DbEntity.class, map); + DbEntity entity = new DbEntity(DefaultUniqueNameGenerator.generate(NameCheckers.DbEntity, map)); createEntity(map, entity); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateEmbeddableAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateEmbeddableAction.java index 631d57ab52..49bf0015af 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateEmbeddableAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateEmbeddableAction.java @@ -27,12 +27,13 @@ import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.map.event.EmbeddableEvent; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.EmbeddableDisplayEvent; import org.apache.cayenne.modeler.undo.CreateEmbeddableUndoableEdit; import org.apache.cayenne.modeler.util.CayenneAction; -import org.apache.cayenne.util.NamedObjectFactory; public class CreateEmbeddableAction extends CayenneAction { @@ -55,10 +56,7 @@ public void performAction(ActionEvent e) { DataMap dataMap = mediator.getCurrentDataMap(); - Embeddable embeddable = (Embeddable) NamedObjectFactory.createObject( - Embeddable.class, - mediator.getCurrentDataMap()); - + Embeddable embeddable = new Embeddable(DefaultUniqueNameGenerator.generate(NameCheckers.Embeddable, mediator.getCurrentDataMap())); createEmbeddable(dataMap, embeddable); application.getUndoManager().addEdit( diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateNodeAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateNodeAction.java index 0484d59036..75d79ea85c 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateNodeAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateNodeAction.java @@ -29,12 +29,13 @@ import org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory; import org.apache.cayenne.conn.DataSourceInfo; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.DataNodeDisplayEvent; import org.apache.cayenne.modeler.undo.CreateNodeUndoableEdit; import org.apache.cayenne.modeler.util.CayenneAction; -import org.apache.cayenne.util.NamedObjectFactory; /** */ @@ -47,7 +48,7 @@ public static String getActionName() { /** * Constructor for CreateNodeAction. * - * @param location + * @param application */ public CreateNodeAction(Application application) { super(getActionName(), application); @@ -82,11 +83,8 @@ public void createDataNode(DataNodeDescriptor node) { * Returns true if path contains a DataDomain object. */ public boolean enableForPath(ConfigurationNode object) { - if (object == null) { - return false; - } + return object != null && ((DataNodeDescriptor) object).getDataChannelDescriptor() != null; - return ((DataNodeDescriptor) object).getDataChannelDescriptor() != null; } /** @@ -114,11 +112,7 @@ public DataNodeDescriptor buildDataNode() { * A factory method that makes a new DataNode. */ DataNodeDescriptor buildDataNode(DataChannelDescriptor domain) { - String name = NamedObjectFactory.createName( - DataNodeDescriptor.class, - domain); - - DataNodeDescriptor node = new DataNodeDescriptor(name); + DataNodeDescriptor node = new DataNodeDescriptor(DefaultUniqueNameGenerator.generate(NameCheckers.DataNodeDescriptor, domain)); node.setDataChannelDescriptor(domain); return node; diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateObjEntityAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateObjEntityAction.java index c5e12a8942..8df37d8934 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateObjEntityAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateObjEntityAction.java @@ -28,6 +28,8 @@ import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.map.event.EntityEvent; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.EntityDisplayEvent; @@ -35,8 +37,7 @@ import org.apache.cayenne.modeler.util.CayenneAction; import org.apache.cayenne.util.DeleteRuleUpdater; import org.apache.cayenne.util.EntityMergeSupport; -import org.apache.cayenne.util.NameConverter; -import org.apache.cayenne.util.NamedObjectFactory; +import org.apache.cayenne.map.naming.NameConverter; /** */ @@ -70,9 +71,7 @@ protected void createObjEntity() { ProjectController mediator = getProjectController(); DataMap dataMap = mediator.getCurrentDataMap(); - ObjEntity entity = (ObjEntity) NamedObjectFactory.createObject( - ObjEntity.class, - mediator.getCurrentDataMap()); + ObjEntity entity = new ObjEntity(DefaultUniqueNameGenerator.generate(NameCheckers.ObjEntity, dataMap)); // init defaults entity.setSuperClassName(dataMap.getDefaultSuperclass()); @@ -82,9 +81,7 @@ protected void createObjEntity() { if (dbEntity != null) { entity.setDbEntity(dbEntity); String baseName = NameConverter.underscoredToJava(dbEntity.getName(), true); - String entityName = NamedObjectFactory.createName(ObjEntity.class, dbEntity - .getDataMap(), baseName); - entity.setName(entityName); + entity.setName(DefaultUniqueNameGenerator.generate(NameCheckers.ObjEntity, dbEntity.getDataMap(), baseName)); } String pkg = dataMap.getDefaultPackage(); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateProcedureAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateProcedureAction.java index 4ec3c065f4..2d0e6527b1 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateProcedureAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateProcedureAction.java @@ -27,12 +27,13 @@ import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.Procedure; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.ProcedureDisplayEvent; import org.apache.cayenne.modeler.undo.CreateProcedureUndoableEdit; import org.apache.cayenne.modeler.util.CayenneAction; -import org.apache.cayenne.util.NamedObjectFactory; /** * Action class to create a new stored procedure mapping. @@ -52,9 +53,7 @@ public void performAction(ActionEvent e) { ProjectController mediator = getProjectController(); DataMap map = mediator.getCurrentDataMap(); - Procedure procedure = (Procedure) NamedObjectFactory.createObject( - Procedure.class, - map); + Procedure procedure = new Procedure(DefaultUniqueNameGenerator.generate(NameCheckers.Procedure, map)); createProcedure(map, procedure); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateProcedureParameterAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateProcedureParameterAction.java index f70ac2f665..c4149215e8 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateProcedureParameterAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateProcedureParameterAction.java @@ -27,11 +27,12 @@ import org.apache.cayenne.map.Procedure; import org.apache.cayenne.map.ProcedureParameter; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.ProcedureParameterDisplayEvent; import org.apache.cayenne.modeler.util.CayenneAction; -import org.apache.cayenne.util.NamedObjectFactory; /** */ @@ -44,7 +45,6 @@ public static String getActionName() { /** * Constructor for CreateProcedureParameterAction. * - * @param name */ public CreateProcedureParameterAction(Application application) { super(getActionName(), application); @@ -66,9 +66,7 @@ public void performAction(ActionEvent e) { public void createProcedureParameter() { Procedure procedure = getProjectController().getCurrentProcedure(); - ProcedureParameter parameter = (ProcedureParameter) NamedObjectFactory - .createObject(ProcedureParameter.class, procedure); - + ProcedureParameter parameter = new ProcedureParameter(DefaultUniqueNameGenerator.generate(NameCheckers.ProcedureParameter, procedure)); procedure.addCallParameter(parameter); ProjectController mediator = getProjectController(); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateRelationshipAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateRelationshipAction.java index c8af7c7e03..0127a0131f 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateRelationshipAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/CreateRelationshipAction.java @@ -31,13 +31,14 @@ import org.apache.cayenne.map.Relationship; import org.apache.cayenne.map.event.MapEvent; import org.apache.cayenne.map.event.RelationshipEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.RelationshipDisplayEvent; import org.apache.cayenne.modeler.undo.CreateRelationshipUndoableEdit; import org.apache.cayenne.modeler.util.CayenneAction; import org.apache.cayenne.util.DeleteRuleUpdater; -import org.apache.cayenne.util.NamedObjectFactory; /** */ @@ -67,8 +68,7 @@ public void performAction(ActionEvent e) { ObjEntity objEnt = getProjectController().getCurrentObjEntity(); if (objEnt != null) { - ObjRelationship rel = (ObjRelationship) NamedObjectFactory.createObject(ObjRelationship.class, objEnt); - + ObjRelationship rel = new ObjRelationship(DefaultUniqueNameGenerator.generate(NameCheckers.ObjRelationship, objEnt)); createObjRelationship(objEnt, rel); application.getUndoManager().addEdit( @@ -77,8 +77,7 @@ public void performAction(ActionEvent e) { DbEntity dbEnt = getProjectController().getCurrentDbEntity(); if (dbEnt != null) { - DbRelationship rel = NamedObjectFactory.createObject(DbRelationship.class, dbEnt); - + DbRelationship rel = new DbRelationship(DefaultUniqueNameGenerator.generate(NameCheckers.DbRelationship, dbEnt)); createDbRelationship(dbEnt, rel); application.getUndoManager().addEdit( diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportDataMapAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportDataMapAction.java index c00db8a800..27d9f6d335 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportDataMapAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportDataMapAction.java @@ -32,12 +32,13 @@ import org.apache.cayenne.configuration.DataChannelDescriptor; import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.MapLoader; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.pref.FSPath; import org.apache.cayenne.modeler.util.CayenneAction; import org.apache.cayenne.modeler.util.FileFilters; import org.apache.cayenne.resource.Resource; -import org.apache.cayenne.util.NamedObjectFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xml.sax.InputSource; @@ -95,13 +96,10 @@ protected void importDataMap() { .getRootNode(); if (newMap.getName() != null) { - newMap.setName(NamedObjectFactory.createName( - DataMap.class, - domain, - newMap.getName())); + newMap.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DataMap, domain, newMap.getName())); } else { - newMap.setName(NamedObjectFactory.createName(DataMap.class, domain)); + newMap.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DataMap, domain)); } Resource baseResource = domain.getConfigurationSource(); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java index 22246f1e7f..27ad76e005 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ImportEOModelAction.java @@ -45,6 +45,8 @@ import org.apache.cayenne.map.Entity; import org.apache.cayenne.map.event.EntityEvent; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.dialog.ErrorDebugDialog; @@ -55,7 +57,6 @@ import org.apache.cayenne.modeler.util.CayenneAction; import org.apache.cayenne.modeler.util.FileFilters; import org.apache.cayenne.query.Query; -import org.apache.cayenne.util.NamedObjectFactory; import org.apache.cayenne.wocompat.EOModelProcessor; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.logging.Log; @@ -300,11 +301,8 @@ protected void addDataMap(DataMap map, DataMap currentMap) { } else { // fix DataMap name, as there maybe a map with the same name already - DataChannelDescriptor domain = (DataChannelDescriptor) mediator - .getProject() - .getRootNode(); - map.setName(NamedObjectFactory.createName(DataMap.class, domain, map - .getName())); + DataChannelDescriptor domain = (DataChannelDescriptor) mediator.getProject().getRootNode(); + map.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DataMap, domain, map.getName())); // side effect of this operation is that if a node was created, this DataMap // will be linked with it... diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/NewProjectAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/NewProjectAction.java index d06b983be7..6df35cf3c4 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/NewProjectAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/NewProjectAction.java @@ -27,11 +27,12 @@ import org.apache.cayenne.configuration.ConfigurationTree; import org.apache.cayenne.configuration.DataChannelDescriptor; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.CayenneModelerController; import org.apache.cayenne.modeler.event.DomainDisplayEvent; import org.apache.cayenne.project.Project; -import org.apache.cayenne.util.NamedObjectFactory; /** */ @@ -67,9 +68,7 @@ public void performAction(ActionEvent e) { DataChannelDescriptor domain = new DataChannelDescriptor(); - String name = NamedObjectFactory.createName(DataChannelDescriptor.class, domain); - - domain.setName(name); + domain.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DataChannelDescriptor, domain)); Project project = new Project( new ConfigurationTree(domain)); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java index c164a6d75a..6cdcedcd42 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java @@ -48,6 +48,8 @@ import org.apache.cayenne.map.Procedure; import org.apache.cayenne.map.ProcedureParameter; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.dialog.ErrorDebugDialog; @@ -67,7 +69,7 @@ */ public class PasteAction extends CayenneAction implements FlavorListener { - private static final String COPY_PREFIX = "Copy of "; + private static final String COPY_PATTERN = "Copy of %s (%d)"; public static String getActionName() { return "Paste"; @@ -171,9 +173,7 @@ public void paste( // paste DataMap to DataDomain or DataNode DataMap dataMap = ((DataMap) content); - dataMap - .setName(getFreeName(new DataMapNameChecker(domain), dataMap - .getName())); + dataMap.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DataMap, COPY_PATTERN, domain, dataMap.getName())); /** * Update all names in the new DataMap, so that they would not conflict with @@ -189,8 +189,7 @@ public void paste( for (DbEntity dbEntity : dataMap.getDbEntities()) { String oldName = dbEntity.getName(); - dbEntity.setName(getFreeName(new DbEntityNameChecker(domain), dbEntity - .getName())); + dbEntity.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DbEntity, COPY_PATTERN, domain, dbEntity.getName())); if (!oldName.equals(dbEntity.getName())) { renamedDbEntities.put(oldName, dbEntity.getName()); @@ -198,8 +197,7 @@ public void paste( } for (ObjEntity objEntity : dataMap.getObjEntities()) { String oldName = objEntity.getName(); - objEntity.setName(getFreeName(new ObjEntityNameChecker(domain), objEntity - .getName())); + objEntity.setName(DefaultUniqueNameGenerator.generate(NameCheckers.ObjEntity, COPY_PATTERN, domain, objEntity.getName())); if (!oldName.equals(objEntity.getName())) { renamedObjEntities.put(oldName, objEntity.getName()); @@ -208,9 +206,7 @@ public void paste( for (Embeddable embeddable : dataMap.getEmbeddables()) { String oldName = embeddable.getClassName(); - embeddable.setClassName(getFreeName( - new EmbeddableNameChecker(domain), - embeddable.getClassName())); + embeddable.setClassName(DefaultUniqueNameGenerator.generate(NameCheckers.Embeddable, COPY_PATTERN, domain, embeddable.getClassName())); if (!oldName.equals(embeddable.getClassName())) { renamedEmbeddables.put(oldName, embeddable.getClassName()); @@ -218,13 +214,10 @@ public void paste( } for (Procedure procedure : dataMap.getProcedures()) { - procedure.setName(getFreeName(new ProcedureNameChecker(domain), procedure - .getName())); + procedure.setName(DefaultUniqueNameGenerator.generate(NameCheckers.Procedure, COPY_PATTERN, domain, procedure.getName())); } for (Query query : dataMap.getQueries()) { - ((AbstractQuery) query).setName(getFreeName( - new QueryNameChecker(domain), - query.getName())); + ((AbstractQuery) query).setName(DefaultUniqueNameGenerator.generate(NameCheckers.SelectQuery, COPY_PATTERN, domain, query.getName())); } // if an entity was renamed, we rename all links to it too @@ -266,8 +259,7 @@ else if (where instanceof DataMap) { if (content instanceof DbEntity) { DbEntity dbEntity = (DbEntity) content; - dbEntity.setName(getFreeName(new DbEntityNameChecker(domain), dbEntity - .getName())); + dbEntity.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DbEntity, COPY_PATTERN, domain, dbEntity.getName())); dataMap.addDbEntity(dbEntity); CreateDbEntityAction.fireDbEntityEvent(this, mediator, dbEntity); @@ -275,8 +267,7 @@ else if (where instanceof DataMap) { else if (content instanceof ObjEntity) { // paste ObjEntity to DataMap ObjEntity objEntity = (ObjEntity) content; - objEntity.setName(getFreeName(new ObjEntityNameChecker(domain), objEntity - .getName())); + objEntity.setName(DefaultUniqueNameGenerator.generate(NameCheckers.ObjEntity, COPY_PATTERN, domain, objEntity.getName())); dataMap.addObjEntity(objEntity); CreateObjEntityAction.fireObjEntityEvent( @@ -288,9 +279,7 @@ else if (content instanceof ObjEntity) { else if (content instanceof Embeddable) { // paste Embeddable to DataMap Embeddable embeddable = (Embeddable) content; - embeddable.setClassName(getFreeName( - new EmbeddableNameChecker(domain), - embeddable.getClassName())); + embeddable.setClassName(DefaultUniqueNameGenerator.generate(NameCheckers.Embeddable, COPY_PATTERN, domain, embeddable.getClassName())); dataMap.addEmbeddable(embeddable); CreateEmbeddableAction.fireEmbeddableEvent( @@ -302,7 +291,7 @@ else if (content instanceof Embeddable) { else if (content instanceof EJBQLQuery) { EJBQLQuery query = (EJBQLQuery) content; - query.setName(getFreeName(new QueryNameChecker(domain), query.getName())); + query.setName(DefaultUniqueNameGenerator.generate(NameCheckers.SelectQuery, COPY_PATTERN, domain, query.getName())); query.setDataMap(dataMap); dataMap.addQuery(query); @@ -312,7 +301,7 @@ else if (content instanceof Query) { // paste Query to DataMap AbstractQuery query = (AbstractQuery) content; - query.setName(getFreeName(new QueryNameChecker(domain), query.getName())); + query.setName(DefaultUniqueNameGenerator.generate(NameCheckers.SelectQuery, COPY_PATTERN, domain, query.getName())); query.setDataMap(dataMap); dataMap.addQuery(query); @@ -321,8 +310,7 @@ else if (content instanceof Query) { else if (content instanceof Procedure) { // paste Procedure to DataMap Procedure procedure = (Procedure) content; - procedure.setName(getFreeName(new ProcedureNameChecker(domain), procedure - .getName())); + procedure.setName(DefaultUniqueNameGenerator.generate(NameCheckers.Procedure, COPY_PATTERN, domain, procedure.getName())); dataMap.addProcedure(procedure); CreateProcedureAction.fireProcedureEvent( @@ -335,18 +323,9 @@ else if (content instanceof Procedure) { else if (where instanceof DbEntity) { final DbEntity dbEntity = (DbEntity) where; - // attrs and rels must be unique in entity namespace - FreeNameChecker checker = new FreeNameChecker() { - - public boolean isNameFree(String name) { - return dbEntity.getAttribute(name) == null - && dbEntity.getRelationship(name) == null; - } - }; - if (content instanceof DbAttribute) { DbAttribute attr = (DbAttribute) content; - attr.setName(getFreeName(checker, attr.getName())); + attr.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DbAttribute, COPY_PATTERN, dbEntity, attr.getName())); dbEntity.addAttribute(attr); CreateAttributeAction.fireDbAttributeEvent(this, mediator, mediator @@ -354,7 +333,7 @@ public boolean isNameFree(String name) { } else if (content instanceof DbRelationship) { DbRelationship rel = (DbRelationship) content; - rel.setName(getFreeName(checker, rel.getName())); + rel.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DbRelationship, COPY_PATTERN, dbEntity, rel.getName())); dbEntity.addRelationship(rel); CreateRelationshipAction.fireDbRelationshipEvent( @@ -367,22 +346,10 @@ else if (content instanceof DbRelationship) { else if (where instanceof ObjEntity) { final ObjEntity objEntity = (ObjEntity) where; - // attrs and rels must be unique in entity namespace - FreeNameChecker checker = new FreeNameChecker() { - - public boolean isNameFree(String name) { - return objEntity.getAttribute(name) == null - && objEntity.getRelationship(name) == null - // uninitialized mediator.currentCallbackType should not affect a copying of rels or attrs - && (mediator.getCurrentCallbackType() == null ? true : - !objEntity.getCallbackMap().getCallbackDescriptor(mediator.getCurrentCallbackType().getType()) - .getCallbackMethods().contains(name)); - } - }; if (content instanceof ObjAttribute) { ObjAttribute attr = (ObjAttribute) content; - attr.setName(getFreeName(checker, attr.getName())); + attr.setName(DefaultUniqueNameGenerator.generate(NameCheckers.ObjAttribute, COPY_PATTERN, objEntity, attr.getName())); objEntity.addAttribute(attr); CreateAttributeAction.fireObjAttributeEvent(this, mediator, mediator @@ -390,7 +357,7 @@ public boolean isNameFree(String name) { } else if (content instanceof ObjRelationship) { ObjRelationship rel = (ObjRelationship) content; - rel.setName(getFreeName(checker, rel.getName())); + rel.setName(DefaultUniqueNameGenerator.generate(NameCheckers.ObjRelationship, COPY_PATTERN, objEntity, rel.getName())); objEntity.addRelationship(rel); CreateRelationshipAction.fireObjRelationshipEvent( @@ -400,8 +367,9 @@ else if (content instanceof ObjRelationship) { rel); } else if(content instanceof ObjCallbackMethod) { - ObjCallbackMethod method = (ObjCallbackMethod) content; - method.setName(getFreeName(checker, method.getName())); + ObjCallbackMethod method = (ObjCallbackMethod) content; + + method.setName(DefaultUniqueNameGenerator.generate(NameCheckers.ObjCallbackMethod, COPY_PATTERN, objEntity, method.getName())); objEntity.getCallbackMap().getCallbackDescriptor(mediator.getCurrentCallbackType().getType()).addCallbackMethod(method.getName()); @@ -418,17 +386,9 @@ else if(content instanceof ObjCallbackMethod) { else if (where instanceof Embeddable) { final Embeddable embeddable = (Embeddable) where; - // attrs and rels must be unique in entity namespace - FreeNameChecker checker = new FreeNameChecker() { - - public boolean isNameFree(String name) { - return embeddable.getAttribute(name) == null; - } - }; - if (content instanceof EmbeddableAttribute) { EmbeddableAttribute attr = (EmbeddableAttribute) content; - attr.setName(getFreeName(checker, attr.getName())); + attr.setName(DefaultUniqueNameGenerator.generate(NameCheckers.EmbeddableAttribute, COPY_PATTERN, embeddable, attr.getName())); embeddable.addAttribute(attr); CreateAttributeAction.fireEmbeddableAttributeEvent( @@ -447,19 +407,7 @@ else if (where instanceof Procedure) { if (content instanceof ProcedureParameter) { ProcedureParameter param = (ProcedureParameter) content; - param.setName(getFreeName(new FreeNameChecker() { - - public boolean isNameFree(String name) { - for (ProcedureParameter existingParam : procedure - .getCallParameters()) { - if (name.equals(existingParam.getName())) { - return false; - } - } - - return true; - } - }, param.getName())); + param.setName(DefaultUniqueNameGenerator.generate(NameCheckers.ProcedureParameter, COPY_PATTERN, procedure, param.getName())); procedure.addCallParameter(param); CreateProcedureParameterAction.fireProcedureParameterEvent( @@ -479,20 +427,6 @@ private void clearDataMapCache(DataMap dataMap) { } } - /** - * Finds avaliable name for an object - */ - private String getFreeName(FreeNameChecker checker, String defName) { - String name = defName; - - for (int i = 0; !checker.isNameFree(name); name = COPY_PREFIX - + defName - + (i == 0 ? "" : " (" + i + ")"), i++) - ; - - return name; - } - /** * Returns true if last object in the path contains a removable object. */ @@ -575,156 +509,4 @@ private boolean isTreeLeaf(Object content) { public void flavorsChanged(FlavorEvent e) { updateState(); } - - /** - * Interface for checking that specified name is free in superior DataMap, Entity etc. - * and therefore can be used for new object - */ - interface FreeNameChecker { - - boolean isNameFree(String name); - } - - /** - * FreeNameChecker implementation for choosing DataMap names - */ - class DataMapNameChecker implements FreeNameChecker { - - DataChannelDescriptor domain; - - public DataMapNameChecker(DataChannelDescriptor domain) { - this.domain = domain; - } - - public boolean isNameFree(String name) { - return domain.getDataMap(name) == null; - } - } - - /** - * FreeNameChecker implementation for choosing DbEntity names - */ - class DbEntityNameChecker implements FreeNameChecker { - - DataChannelDescriptor domain; - - public DbEntityNameChecker(DataChannelDescriptor domain) { - this.domain = domain; - } - - public boolean isNameFree(String name) { - /** - * Name mast be unique through all DataDomain, for EntityResolver to work - * correctlys - */ - for (DataMap map : domain.getDataMaps()) { - if (map.getDbEntity(name) != null) { - return false; - } - } - - return true; - } - } - - /** - * FreeNameChecker implementation for choosing ObjEntity names - */ - class ObjEntityNameChecker implements FreeNameChecker { - - DataChannelDescriptor domain; - - public ObjEntityNameChecker(DataChannelDescriptor domain) { - this.domain = domain; - } - - public boolean isNameFree(String name) { - /** - * Name mast be unique through all DataDomain, for EntityResolver to work - * correctly - */ - for (DataMap map : domain.getDataMaps()) { - if (map.getObjEntity(name) != null) { - return false; - } - } - - return true; - } - } - - class EmbeddableNameChecker implements FreeNameChecker { - - DataChannelDescriptor domain; - - public EmbeddableNameChecker(DataChannelDescriptor domain) { - this.domain = domain; - } - - public boolean isNameFree(String name) { - /** - * Name mast be unique through all DataDomain, for EntityResolver to work - * correctly - */ - for (DataMap map : domain.getDataMaps()) { - if (map.getEmbeddable(name) != null) { - return false; - } - } - - return true; - } - } - - /** - * FreeNameChecker implementation for choosing Procedure names - */ - class ProcedureNameChecker implements FreeNameChecker { - - DataChannelDescriptor domain; - - public ProcedureNameChecker(DataChannelDescriptor domain) { - this.domain = domain; - } - - public boolean isNameFree(String name) { - /** - * Name mast be unique through all DataDomain, for EntityResolver to work - * correctly - */ - for (DataMap map : domain.getDataMaps()) { - if (map.getNamespace().getProcedure(name) != null) { - return false; - } - } - - return true; - } - } - - /** - * FreeNameChecker implementation for choosing Query names - */ - class QueryNameChecker implements FreeNameChecker { - - DataChannelDescriptor domain; - - public QueryNameChecker(DataChannelDescriptor domain) { - this.domain = domain; - } - - public boolean isNameFree(String name) { - /** - * Name mast be unique through all DataDomain, for EntityResolver to work - * correctly - */ - for (DataMap map : domain.getDataMaps()) { - if (map.getNamespace().getQuery(name) != null) { - return false; - } - } - - return true; - } - } } diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java index bb8fa81c4b..3180e3c756 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java @@ -46,6 +46,8 @@ import org.apache.cayenne.map.Relationship; import org.apache.cayenne.map.event.MapEvent; import org.apache.cayenne.map.event.RelationshipEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.pref.TableColumnPreferences; import org.apache.cayenne.modeler.undo.RelationshipUndoableEdit; @@ -54,7 +56,6 @@ import org.apache.cayenne.modeler.util.ModelerUtil; import org.apache.cayenne.modeler.util.PanelFactory; import org.apache.cayenne.modeler.util.combo.AutoCompletion; -import org.apache.cayenne.util.NamedObjectFactory; import org.apache.cayenne.util.Util; import com.jgoodies.forms.builder.PanelBuilder; @@ -291,9 +292,7 @@ private void save() { } if (sourceEntityName == null) { - sourceEntityName = NamedObjectFactory.createName( - DbRelationship.class, - relationship.getSourceEntity()); + sourceEntityName = DefaultUniqueNameGenerator.generate(NameCheckers.DbRelationship, relationship.getSourceEntity()); } if (!validateName(relationship.getSourceEntity(), relationship, sourceEntityName)) { @@ -306,9 +305,7 @@ private void save() { } if (targetEntityName == null) { - targetEntityName = NamedObjectFactory.createName( - DbRelationship.class, - relationship.getTargetEntity()); + targetEntityName = DefaultUniqueNameGenerator.generate(NameCheckers.DbRelationship, relationship.getTargetEntity()); } // check if reverse name is valid diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java index addb9344c8..c9093ff508 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java @@ -29,7 +29,7 @@ import org.apache.cayenne.map.Entity; import org.apache.cayenne.map.event.MapEvent; import org.apache.cayenne.map.event.RelationshipEvent; -import org.apache.cayenne.map.naming.NamingStrategy; +import org.apache.cayenne.map.naming.ObjectNameGenerator; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ClassLoadingService; import org.apache.cayenne.modeler.ProjectController; @@ -37,7 +37,7 @@ import org.apache.cayenne.modeler.undo.CreateRelationshipUndoableEdit; import org.apache.cayenne.modeler.undo.InferRelationshipsUndoableEdit; import org.apache.cayenne.modeler.util.CayenneController; -import org.apache.cayenne.modeler.util.NamingStrategyPreferences; +import org.apache.cayenne.modeler.util.NameGeneratorPreferences; import org.apache.cayenne.swing.BindingBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -53,11 +53,11 @@ public class InferRelationshipsController extends InferRelationshipsControllerBa protected InferRelationshipsTabController entitySelector; - protected NamingStrategy strategy; + protected ObjectNameGenerator strategy; public InferRelationshipsController(CayenneController parent, DataMap dataMap) { super(parent, dataMap); - strategy = createNamingStrategy(NamingStrategyPreferences + strategy = createNamingStrategy(NameGeneratorPreferences .getInstance() .getLastUsedStrategies() .get(0)); @@ -66,13 +66,11 @@ public InferRelationshipsController(CayenneController parent, DataMap dataMap) { this.entitySelector = new InferRelationshipsTabController(this); } - public NamingStrategy createNamingStrategy(String strategyClass) { + public ObjectNameGenerator createNamingStrategy(String strategyClass) { try { - ClassLoadingService classLoader = Application - .getInstance() - .getClassLoadingService(); + ClassLoadingService classLoader = application.getClassLoadingService(); - return classLoader.loadClass(NamingStrategy.class, strategyClass).newInstance(); + return classLoader.loadClass(ObjectNameGenerator.class, strategyClass).newInstance(); } catch (Throwable th) { logObj.error("Error in " + getClass().getName(), th); @@ -147,11 +145,11 @@ public void strategyComboAction() { if (strategy == null) { return; } - NamingStrategyPreferences + NameGeneratorPreferences .getInstance() .addToLastUsedStrategies(strategyClass); view.getStrategyCombo().setModel( - new DefaultComboBoxModel(NamingStrategyPreferences + new DefaultComboBoxModel(NameGeneratorPreferences .getInstance() .getLastUsedStrategies())); @@ -168,7 +166,7 @@ public void strategyComboAction() { } - public NamingStrategy getNamingStrategy() { + public ObjectNameGenerator getNamingStrategy() { return strategy; } diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java index faa85d202c..aec9ee3aff 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java @@ -31,7 +31,7 @@ import org.apache.cayenne.map.DbJoin; import org.apache.cayenne.map.DbRelationship; import org.apache.cayenne.map.naming.ExportedKey; -import org.apache.cayenne.map.naming.NamingStrategy; +import org.apache.cayenne.map.naming.ObjectNameGenerator; import org.apache.cayenne.modeler.util.CayenneController; import org.apache.commons.collections.Predicate; @@ -46,7 +46,7 @@ public class InferRelationshipsControllerBase extends CayenneController { protected List entities; protected Set selectedEntities; protected int index = 0; - protected NamingStrategy strategy; + protected ObjectNameGenerator strategy; protected transient InferredRelationship currentEntity; protected transient Integer entityNumber; @@ -201,24 +201,21 @@ protected void createNames() { ExportedKey key = null; for (InferredRelationship myir : inferredRelationships) { if (myir.getJoinSource().isPrimaryKey()) { - key = getExportedKey(myir.getSource().getName(), myir - .getJoinSource() - .getName(), myir.getTarget().getName(), myir - .getJoinTarget() - .getName()); - } - else { - key = getExportedKey(myir.getTarget().getName(), myir - .getJoinTarget() - .getName(), myir.getSource().getName(), myir - .getJoinSource() - .getName()); + key = getExportedKey(myir.getSource().getName(), + myir.getJoinSource().getName(), + myir.getTarget().getName(), + myir.getJoinTarget().getName()); + } else { + key = getExportedKey(myir.getTarget().getName(), + myir.getJoinTarget().getName(), + myir.getSource().getName(), + myir.getJoinSource().getName()); } myir.setName(strategy.createDbRelationshipName(key, myir.isToMany())); } } - public ExportedKey getExportedKey( + protected ExportedKey getExportedKey( String pkTable, String pkColumn, String fkTable, @@ -310,7 +307,7 @@ public Component getView() { return null; } - public void setNamingStrategy(NamingStrategy namestr) { + public void setNamingStrategy(ObjectNameGenerator namestr) { strategy = namestr; } diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsDialog.java index d162e4ae5e..d468bd984f 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsDialog.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsDialog.java @@ -32,7 +32,7 @@ import javax.swing.JPanel; import org.apache.cayenne.modeler.Application; -import org.apache.cayenne.modeler.util.NamingStrategyPreferences; +import org.apache.cayenne.modeler.util.NameGeneratorPreferences; public class InferRelationshipsDialog extends JDialog { public static final int SELECT = 1; @@ -80,7 +80,7 @@ public InferRelationshipsDialog(Component entitySelectorPanel) { this.choice = CANCEL; strategyCombo.setModel(new DefaultComboBoxModel( - NamingStrategyPreferences.getInstance().getLastUsedStrategies())); + NameGeneratorPreferences.getInstance().getLastUsedStrategies())); setTitle("Infer Relationships"); } diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java index 00c3e1b475..e4aa68db36 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java @@ -42,13 +42,14 @@ import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.map.event.EntityEvent; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.DataMapDisplayEvent; import org.apache.cayenne.modeler.util.LongRunningTask; import org.apache.cayenne.resource.Resource; import org.apache.cayenne.util.DeleteRuleUpdater; -import org.apache.cayenne.util.NamedObjectFactory; import org.apache.cayenne.util.Util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -174,7 +175,7 @@ public void run() { this.procedureNamePattern = dialog.getProcedureNamePattern(); this.addedObjEntities = new ArrayList(); - this.loader.setNamingStrategy(dialog.getNamingStrategy()); + this.loader.setNameGenerator(dialog.getNamingStrategy()); // load DataMap... LongRunningTask loadDataMapTask = new LoadDataMapTask(Application.getFrame(), "Reengineering DB"); @@ -344,9 +345,8 @@ protected void execute() { DbLoaderHelper.this.existingMap = dataMap != null; if (!existingMap) { - dataMap = (DataMap) NamedObjectFactory.createObject(DataMap.class, null); - dataMap.setName(NamedObjectFactory.createName(DataMap.class, (DataChannelDescriptor) mediator - .getProject().getRootNode())); + dataMap = new DataMap(DefaultUniqueNameGenerator.generate(NameCheckers.DataMap)); + dataMap.setName(DefaultUniqueNameGenerator.generate(NameCheckers.DataMap, mediator.getProject().getRootNode())); dataMap.setDefaultSchema(schemaName); } diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderOptionsDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderOptionsDialog.java index 607b913e19..41902035e8 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderOptionsDialog.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderOptionsDialog.java @@ -39,11 +39,11 @@ import javax.swing.event.ChangeListener; import org.apache.cayenne.access.DbLoader; -import org.apache.cayenne.map.naming.NamingStrategy; +import org.apache.cayenne.map.naming.ObjectNameGenerator; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ClassLoadingService; import org.apache.cayenne.modeler.util.CayenneDialog; -import org.apache.cayenne.modeler.util.NamingStrategyPreferences; +import org.apache.cayenne.modeler.util.NameGeneratorPreferences; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -75,7 +75,7 @@ public class DbLoaderOptionsDialog extends CayenneDialog { */ protected JComboBox strategyCombo; - protected NamingStrategy strategy; + protected ObjectNameGenerator strategy; protected int choice; @@ -169,7 +169,7 @@ protected void initFromModel( this.procNamePatternField.setEnabled(shouldLoadProcedures); this.procedureLabel.setEnabled(shouldLoadProcedures); - Vector arr = NamingStrategyPreferences + Vector arr = NameGeneratorPreferences .getInstance() .getLastUsedStrategies(); strategyCombo.setModel(new DefaultComboBoxModel(arr)); @@ -206,13 +206,13 @@ private void processSelect() { String strategyClass = (String) strategyCombo.getSelectedItem(); this.strategy = classLoader - .loadClass(NamingStrategy.class, strategyClass) + .loadClass(ObjectNameGenerator.class, strategyClass) .newInstance(); /** * Be user-friendly and update preferences with specified strategy */ - NamingStrategyPreferences + NameGeneratorPreferences .getInstance() .addToLastUsedStrategies(strategyClass); } @@ -272,7 +272,7 @@ public String getProcedureNamePattern() { /** * Returns configured naming strategy */ - public NamingStrategy getNamingStrategy() { + public ObjectNameGenerator getNamingStrategy() { return strategy; } } diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java index ebbf73ea9c..4db235693d 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java @@ -43,16 +43,14 @@ import org.apache.cayenne.map.ObjRelationship; import org.apache.cayenne.map.Relationship; import org.apache.cayenne.map.event.RelationshipEvent; +import org.apache.cayenne.map.naming.ExportedKey; +import org.apache.cayenne.map.naming.ObjectNameGenerator; import org.apache.cayenne.modeler.Application; +import org.apache.cayenne.modeler.ClassLoadingService; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.dialog.ResolveDbRelationshipDialog; -import org.apache.cayenne.modeler.util.CayenneController; -import org.apache.cayenne.modeler.util.Comparators; -import org.apache.cayenne.modeler.util.EntityTreeFilter; -import org.apache.cayenne.modeler.util.EntityTreeModel; -import org.apache.cayenne.modeler.util.MultiColumnBrowser; +import org.apache.cayenne.modeler.util.*; import org.apache.cayenne.util.DeleteRuleUpdater; -import org.apache.cayenne.util.NamedObjectFactory; import org.apache.cayenne.util.Util; public class ObjRelationshipInfo extends CayenneController implements TreeSelectionListener { @@ -334,7 +332,7 @@ public MultiColumnBrowser getPathBrowser() { protected void createRelationship() { DbRelationship dbRel = getLastRelationship(); - DbEntity source = dbRel != null ? (DbEntity) dbRel.getTargetEntity() : null; + DbEntity source = dbRel != null ? dbRel.getTargetEntity() : null; DbRelationshipTarget targetModel = new DbRelationshipTarget(mediator, getStartEntity(), source); targetModel.startupAction(); @@ -343,8 +341,18 @@ protected void createRelationship() { return; } - DbRelationship dbRelationship = (DbRelationship) NamedObjectFactory.createRelationship(targetModel.getSource(), - targetModel.getTarget(), targetModel.isToMany()); + DbRelationship dbRelationship = new DbRelationship(); + dbRelationship.setName(createNamingStrategy(NameGeneratorPreferences + .getInstance() + .getLastUsedStrategies() + .get(0)).createDbRelationshipName( + new ExportedKey(targetModel.getSource().getName(), + null, + null, + targetModel.getTarget().getName(), + null, + null), + targetModel.isToMany())); // note: NamedObjectFactory doesn't set source or target, just the name dbRelationship.setSourceEntity(targetModel.getSource()); @@ -353,8 +361,7 @@ protected void createRelationship() { targetModel.getSource().addRelationship(dbRelationship); // TODO: creating relationship outside of ResolveDbRelationshipDialog - // confuses it - // to send incorrect event - CHANGE instead of ADD + // confuses it to send incorrect event - CHANGE instead of ADD ResolveDbRelationshipDialog dialog = new ResolveDbRelationshipDialog(dbRelationship); dialog.setVisible(true); @@ -384,6 +391,22 @@ protected void createRelationship() { dialog.dispose(); } + public ObjectNameGenerator createNamingStrategy(String strategyClass) { + try { + ClassLoadingService classLoader = application.getClassLoadingService(); + + return classLoader.loadClass(ObjectNameGenerator.class, strategyClass).newInstance(); + } + catch (Throwable th) { + JOptionPane.showMessageDialog( + view, + "Naming Strategy Initialization Error: " + th.getMessage(), + "Naming Strategy Initialization Error", + JOptionPane.ERROR_MESSAGE); + return null; + } + } + /** * Sets list of DB Relationships current ObjRelationship is mapped to */ diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/query/QueryType.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/query/QueryType.java index 14d9e3460f..1e192328f0 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/query/QueryType.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/query/QueryType.java @@ -28,6 +28,8 @@ import org.apache.cayenne.configuration.event.QueryEvent; import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.event.MapEvent; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.event.QueryDisplayEvent; import org.apache.cayenne.modeler.undo.CreateQueryUndoableEdit; @@ -38,7 +40,6 @@ import org.apache.cayenne.query.Query; import org.apache.cayenne.query.SQLTemplate; import org.apache.cayenne.query.SelectQuery; -import org.apache.cayenne.util.NamedObjectFactory; public class QueryType extends CayenneController{ @@ -140,7 +141,7 @@ public void createQuery() { } // update query... - String queryName = NamedObjectFactory.createName(Query.class, dataMap); + String queryName = DefaultUniqueNameGenerator.generate(NameCheckers.SelectQuery, dataMap); if (query instanceof EJBQLQuery) { ((EJBQLQuery) query).setName(queryName); ((EJBQLQuery) query).setDataMap(dataMap); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/CallbackType.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/CallbackType.java index 01776fe895..f0de775f1f 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/CallbackType.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/CallbackType.java @@ -21,7 +21,7 @@ import java.io.Serializable; import org.apache.cayenne.map.LifecycleEvent; -import org.apache.cayenne.util.NameConverter; +import org.apache.cayenne.map.naming.NameConverter; /** * Entity for callback type. Contains type and type name diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NamingStrategyPreferences.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NameGeneratorPreferences.java similarity index 82% rename from modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NamingStrategyPreferences.java rename to modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NameGeneratorPreferences.java index 0de47b273d..3af48594b7 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NamingStrategyPreferences.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NameGeneratorPreferences.java @@ -22,27 +22,29 @@ import java.util.Vector; import java.util.prefs.Preferences; +import org.apache.cayenne.map.naming.BasicNameGenerator; +import org.apache.cayenne.map.naming.SmartNameGenerator; import org.apache.cayenne.modeler.Application; /** * Helper class to store/read information about naming strategies have been used */ -public class NamingStrategyPreferences { +public class NameGeneratorPreferences { - private static final String STRATEGIES_PREFERENCE = "recent.strategies"; + private static final String STRATEGIES_PREFERENCE = "recent.name.generators"; /** * Naming strategies to appear in combobox by default */ private static final Vector PREDEFINED_STRATEGIES = new Vector(); static { - PREDEFINED_STRATEGIES.add("org.apache.cayenne.map.naming.BasicNamingStrategy"); - PREDEFINED_STRATEGIES.add("org.apache.cayenne.map.naming.SmartNamingStrategy"); - }; + PREDEFINED_STRATEGIES.add(BasicNameGenerator.class.getCanonicalName()); + PREDEFINED_STRATEGIES.add(SmartNameGenerator.class.getCanonicalName()); + } - static final NamingStrategyPreferences instance = new NamingStrategyPreferences(); + static final NameGeneratorPreferences instance = new NameGeneratorPreferences(); - public static NamingStrategyPreferences getInstance() { + public static NameGeneratorPreferences getInstance() { return instance; } diff --git a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java index 042b5c680a..3ee8ede747 100644 --- a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java +++ b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java @@ -39,9 +39,10 @@ import org.apache.cayenne.map.DbRelationship; import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.map.ObjRelationship; +import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator; +import org.apache.cayenne.map.naming.NameCheckers; import org.apache.cayenne.query.AbstractQuery; import org.apache.cayenne.query.Query; -import org.apache.cayenne.util.NamedObjectFactory; import org.apache.cayenne.wocompat.parser.Parser; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; @@ -627,8 +628,7 @@ protected void makeReverseDbRelationships(DbEntity dbEntity) { if (relationship.getReverseRelationship() == null) { DbRelationship reverse = relationship.createReverseRelationship(); - String name = NamedObjectFactory.createName(DbRelationship.class, reverse.getSourceEntity(), - relationship.getName() + "Reverse"); + String name = DefaultUniqueNameGenerator.generate(NameCheckers.DbRelationship, reverse.getSourceEntity(), relationship.getName() + "Reverse"); reverse.setName(name); relationship.getTargetEntity().addRelationship(reverse); } diff --git a/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java b/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java index b89d9c744a..be5e0955d2 100644 --- a/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java +++ b/plugins/maven-cayenne-plugin/src/main/java/org/apache/cayenne/tools/DbImporterMojo.java @@ -164,7 +164,7 @@ public class DbImporterMojo extends AbstractMojo { * The default is a basic naming strategy. * * @parameter expression="${cdbimport.namingStrategy}" - * default-value="org.apache.cayenne.map.naming.SmartNamingStrategy" + * default-value="org.apache.cayenne.map.naming.SmartNameGenerator" */ private String namingStrategy;