From 88b1e95d137d6bd637d03ac248a4bb5d4b322dad Mon Sep 17 00:00:00 2001 From: alexkolonitsky Date: Thu, 14 Aug 2014 14:03:29 +0300 Subject: [PATCH 1/2] Name generation refactoring: 1) Make Smart and Base naming strategies independent in order to make behavior of Smart strategy consistent in all cases 2) Rename NamingStrategy to NameGenerator 3) Split NamedObjectFactory into 3.1) NameChecker which responsible for checking is name available in naming context i.e. EntityAttribute name within Entity 3.2) UniqueNameGenerator which in charge of returning unique name within passed naming context 4) refactor copy/past action in order to use introduced mechanism for name generation 5) move all classes responsible for name generation and checking into "naming" package --- .gitignore | 2 + .../org/apache/cayenne/access/DbLoader.java | 36 +- .../access/ManyToManyCandidateEntity.java | 122 ++-- .../java/org/apache/cayenne/map/DbEntity.java | 9 +- .../org/apache/cayenne/map/ObjEntity.java | 21 +- ...gStrategy.java => BasicNameGenerator.java} | 103 ++-- .../naming/DefaultUniqueNameGenerator.java | 104 ++++ .../cayenne/map/naming/NameChecker.java | 25 + .../cayenne/map/naming/NameCheckers.java | 196 +++++++ .../{util => map/naming}/NameConverter.java | 2 +- ...Strategy.java => ObjectNameGenerator.java} | 104 ++-- .../map/naming/UniqueNameGenerator.java | 34 ++ .../cayenne/merge/CreateTableToModel.java | 2 +- .../cayenne/util/EntityMergeSupport.java | 30 +- .../cayenne/util/NamedObjectFactory.java | 520 ------------------ .../access/ManyToManyCandidateEntityTest.java | 7 +- .../org/apache/cayenne/map/DataMapTest.java | 11 +- ...yTest.java => BasicNameGeneratorTest.java} | 102 ++-- .../cayenne/map/naming/NameCheckersTest.java | 175 ++++++ .../cayenne/util/NameConverterTest.java | 1 + .../cayenne/gen/ClientDataMapArtifact.java | 2 +- .../apache/cayenne/gen/DataMapArtifact.java | 2 +- .../org/apache/cayenne/gen/DataMapUtils.java | 2 +- .../org/apache/cayenne/gen/EntityUtils.java | 20 +- .../org/apache/cayenne/gen/StringUtils.java | 2 +- ...gStrategy.java => SmartNameGenerator.java} | 77 +-- .../apache/cayenne/tools/DbImporterTask.java | 4 +- .../tools/dbimport/DbImportAction.java | 8 +- ...yTest.java => SmartNameGeneratorTest.java} | 5 +- .../docbkx/including-cayenne-in-project.xml | 2 +- .../modeler/action/CreateAttributeAction.java | 13 +- .../action/CreateCallbackMethodAction.java | 25 +- .../modeler/action/CreateDataMapAction.java | 7 +- .../modeler/action/CreateDbEntityAction.java | 5 +- .../action/CreateEmbeddableAction.java | 8 +- .../modeler/action/CreateNodeAction.java | 16 +- .../modeler/action/CreateObjEntityAction.java | 13 +- .../modeler/action/CreateProcedureAction.java | 7 +- .../CreateProcedureParameterAction.java | 8 +- .../action/CreateRelationshipAction.java | 9 +- .../modeler/action/ImportDataMapAction.java | 10 +- .../modeler/action/ImportEOModelAction.java | 10 +- .../modeler/action/NewProjectAction.java | 7 +- .../cayenne/modeler/action/PasteAction.java | 266 +-------- .../dialog/ResolveDbRelationshipDialog.java | 11 +- .../InferRelationshipsController.java | 22 +- .../InferRelationshipsControllerBase.java | 29 +- .../InferRelationshipsDialog.java | 4 +- .../modeler/dialog/db/DbLoaderHelper.java | 10 +- .../dialog/db/DbLoaderOptionsDialog.java | 14 +- .../dialog/objentity/ObjRelationshipInfo.java | 45 +- .../modeler/dialog/query/QueryType.java | 5 +- .../cayenne/modeler/editor/CallbackType.java | 2 +- ...ces.java => NameGeneratorPreferences.java} | 184 ++++--- .../cayenne/wocompat/EOModelProcessor.java | 6 +- .../apache/cayenne/tools/DbImporterMojo.java | 2 +- 56 files changed, 1118 insertions(+), 1350 deletions(-) rename cayenne-server/src/main/java/org/apache/cayenne/map/naming/{BasicNamingStrategy.java => BasicNameGenerator.java} (92%) create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/map/naming/DefaultUniqueNameGenerator.java create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameChecker.java create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameCheckers.java rename cayenne-server/src/main/java/org/apache/cayenne/{util => map/naming}/NameConverter.java (99%) rename cayenne-server/src/main/java/org/apache/cayenne/map/naming/{NamingStrategy.java => ObjectNameGenerator.java} (95%) create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/map/naming/UniqueNameGenerator.java delete mode 100644 cayenne-server/src/main/java/org/apache/cayenne/util/NamedObjectFactory.java rename cayenne-server/src/test/java/org/apache/cayenne/map/naming/{BasicNamingStrategyTest.java => BasicNameGeneratorTest.java} (89%) create mode 100644 cayenne-server/src/test/java/org/apache/cayenne/map/naming/NameCheckersTest.java rename cayenne-tools/src/main/java/org/apache/cayenne/map/naming/{SmartNamingStrategy.java => SmartNameGenerator.java} (63%) rename cayenne-tools/src/test/java/org/apache/cayenne/map/naming/{SmartNamingStrategyTest.java => SmartNameGeneratorTest.java} (93%) rename modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/{NamingStrategyPreferences.java => NameGeneratorPreferences.java} (84%) 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..a8f569f660 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 @@ -1,52 +1,51 @@ -/***************************************************************** - * 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.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 - * old-fashioned manner, i.e. the same way Cayenne did before 3.0 - * - * @since 3.0 - */ -public class BasicNamingStrategy implements NamingStrategy { - public String createDbRelationshipName( - ExportedKey key, - boolean toMany) { - - String uglyName = (toMany) ? key.getFKTableName() + "_ARRAY" : "to_" + key.getPKTableName(); - return NameConverter.underscoredToJava(uglyName, 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); - } -} +/***************************************************************** + * 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.DbAttribute; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.map.DbRelationship; + +/** + * BasicNamingStrategy is an naming strategy that creates names in Cayenne's + * old-fashioned manner, i.e. the same way Cayenne did before 3.0 + * + * @since 3.0 + */ +public class BasicNameGenerator implements ObjectNameGenerator { + public String createDbRelationshipName( + ExportedKey key, + boolean toMany) { + + String uglyName = (toMany) ? key.getFKTableName() + "_ARRAY" : "to_" + key.getPKTableName(); + return NameConverter.underscoredToJava(uglyName, 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-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..c7b5e148b0 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 @@ -1,52 +1,52 @@ -/***************************************************************** - * 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.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.map.DbRelationship; - -/** - * NamingStrategy is a strategy for creating names for entities, attributes, relationships - * during reverse engineering. - * - * @since 3.0 - */ -public interface NamingStrategy { - - /** - * Creates new name for Obj Entity - */ - String createObjEntityName(DbEntity entity); - - /** - * Creates new name for Obj Attribute - */ - String createObjAttributeName(DbAttribute attr); - - /** - * Creates new name for Db Relationship - */ - String createDbRelationshipName(ExportedKey key, boolean toMany); - - /** - * Creates new name for Obj Relationship - */ - String createObjRelationshipName(DbRelationship dbRel); -} +/***************************************************************** + * 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.DbAttribute; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.map.DbRelationship; + +/** + * NamingStrategy is a strategy for creating names for entities, attributes, relationships + * during reverse engineering. + * + * @since 3.0 + */ +public interface ObjectNameGenerator { + + /** + * Creates new name for Obj Entity + */ + String createObjEntityName(DbEntity entity); + + /** + * Creates new name for Obj Attribute + */ + String createObjAttributeName(DbAttribute attr); + + /** + * Creates new name for Db Relationship + */ + String createDbRelationshipName(ExportedKey key, boolean toMany); + + /** + * Creates new name for Obj Relationship + */ + String createObjRelationshipName(DbRelationship dbRel); +} 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..11612799fa 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 @@ -1,52 +1,50 @@ -/***************************************************************** - * 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 junit.framework.TestCase; - -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 void testStrategy() throws Exception { - BasicNamingStrategy strategy = new BasicNamingStrategy(); - - ExportedKey key = new ExportedKey("ARTIST", "ARTIST_ID", null, - "PAINTING", "ARTIST_ID", null); - assertEquals(strategy.createDbRelationshipName(key, false), "toArtist"); - assertEquals(strategy.createDbRelationshipName(key, true), "paintingArray"); - - key = new ExportedKey("PERSON", "PERSON_ID", null, - "PERSON", "MOTHER_ID", null); - assertEquals(strategy.createDbRelationshipName(key, false), "toPerson"); - assertEquals(strategy.createDbRelationshipName(key, true), "personArray"); - - assertEquals(strategy.createObjEntityName(new DbEntity("ARTIST")), "Artist"); - assertEquals(strategy.createObjEntityName(new DbEntity("ARTIST_WORK")), "ArtistWork"); - - assertEquals(strategy.createObjAttributeName(new DbAttribute("NAME")), "name"); - assertEquals(strategy.createObjAttributeName(new DbAttribute("ARTIST_NAME")), "artistName"); - - assertEquals(strategy.createObjRelationshipName(new DbRelationship("toArtist")), "toArtist"); - assertEquals(strategy.createObjRelationshipName(new DbRelationship("paintingArray")), "paintingArray"); - } -} +/***************************************************************** + * 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 junit.framework.TestCase; + +import org.apache.cayenne.map.DbAttribute; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.map.DbRelationship; + +public class BasicNameGeneratorTest extends TestCase { + public void testStrategy() throws Exception { + BasicNameGenerator strategy = new BasicNameGenerator(); + + ExportedKey key = new ExportedKey("ARTIST", "ARTIST_ID", null, + "PAINTING", "ARTIST_ID", null); + assertEquals(strategy.createDbRelationshipName(key, false), "toArtist"); + assertEquals(strategy.createDbRelationshipName(key, true), "paintingArray"); + + key = new ExportedKey("PERSON", "PERSON_ID", null, + "PERSON", "MOTHER_ID", null); + assertEquals(strategy.createDbRelationshipName(key, false), "toPerson"); + assertEquals(strategy.createDbRelationshipName(key, true), "personArray"); + + assertEquals(strategy.createObjEntityName(new DbEntity("ARTIST")), "Artist"); + assertEquals(strategy.createObjEntityName(new DbEntity("ARTIST_WORK")), "ArtistWork"); + + assertEquals(strategy.createObjAttributeName(new DbAttribute("NAME")), "name"); + assertEquals(strategy.createObjAttributeName(new DbAttribute("ARTIST_NAME")), "artistName"); + + assertEquals(strategy.createObjRelationshipName(new DbRelationship("toArtist")), "toArtist"); + assertEquals(strategy.createObjRelationshipName(new DbRelationship("paintingArray")), "paintingArray"); + } +} 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 84% 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..817331f7c0 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 @@ -1,91 +1,93 @@ -/***************************************************************** - * 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.modeler.util; - -import java.util.Arrays; -import java.util.Vector; -import java.util.prefs.Preferences; - -import org.apache.cayenne.modeler.Application; - -/** - * Helper class to store/read information about naming strategies have been used - */ -public class NamingStrategyPreferences { - - private static final String STRATEGIES_PREFERENCE = "recent.strategies"; - - /** - * 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"); - }; - - static final NamingStrategyPreferences instance = new NamingStrategyPreferences(); - - public static NamingStrategyPreferences getInstance() { - return instance; - } - - Preferences getPreference() { - return Application.getInstance().getMainPreferenceForProject(); - } - - /** - * @return last used strategies, PREDEFINED_STRATEGIES by default - */ - public Vector getLastUsedStrategies() { - - String prop = null; - - if (getPreference() != null) { - prop = getPreference().get(STRATEGIES_PREFERENCE, null); - } - - if (prop == null) { - return PREDEFINED_STRATEGIES; - } - - return new Vector(Arrays.asList(prop.split(","))); - } - - /** - * Adds strategy to history - */ - public void addToLastUsedStrategies(String strategy) { - Vector strategies = getLastUsedStrategies(); - - // move to top - strategies.remove(strategy); - strategies.add(0, strategy); - - StringBuilder res = new StringBuilder(); - for (String str : strategies) { - res.append(str).append(","); - } - if (strategies.size() > 0) { - res.deleteCharAt(res.length() - 1); - } - - getPreference().put(STRATEGIES_PREFERENCE, res.toString()); - } -} +/***************************************************************** + * 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.modeler.util; + +import java.util.Arrays; +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 NameGeneratorPreferences { + + 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(BasicNameGenerator.class.getCanonicalName()); + PREDEFINED_STRATEGIES.add(SmartNameGenerator.class.getCanonicalName()); + } + + static final NameGeneratorPreferences instance = new NameGeneratorPreferences(); + + public static NameGeneratorPreferences getInstance() { + return instance; + } + + Preferences getPreference() { + return Application.getInstance().getMainPreferenceForProject(); + } + + /** + * @return last used strategies, PREDEFINED_STRATEGIES by default + */ + public Vector getLastUsedStrategies() { + + String prop = null; + + if (getPreference() != null) { + prop = getPreference().get(STRATEGIES_PREFERENCE, null); + } + + if (prop == null) { + return PREDEFINED_STRATEGIES; + } + + return new Vector(Arrays.asList(prop.split(","))); + } + + /** + * Adds strategy to history + */ + public void addToLastUsedStrategies(String strategy) { + Vector strategies = getLastUsedStrategies(); + + // move to top + strategies.remove(strategy); + strategies.add(0, strategy); + + StringBuilder res = new StringBuilder(); + for (String str : strategies) { + res.append(str).append(","); + } + if (strategies.size() > 0) { + res.deleteCharAt(res.length() - 1); + } + + getPreference().put(STRATEGIES_PREFERENCE, res.toString()); + } +} 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; From d3dcbe01f8b30d325936133e32124d4280623735 Mon Sep 17 00:00:00 2001 From: alexkolonitsky Date: Thu, 14 Aug 2014 15:55:09 +0300 Subject: [PATCH 2/2] 1) Make Smart and Base naming strategies independent in order to make behavior of Smart strategy consistent in all cases 2) Rename NamingStrategy to NameGenerator 3) Split NamedObjectFactory into 3.1) NameChecker which responsible for checking is name available in naming context i.e. EntityAttribute name within Entity 3.2) UniqueNameGenerator which in charge of returning unique name within passed naming context 4) refactor copy/past action in order to use introduced mechanism for name generation 5) move all classes responsible for name generation and checking into "naming" package --- .../map/naming/BasicNameGenerator.java | 102 +++++----- .../map/naming/ObjectNameGenerator.java | 104 +++++----- .../map/naming/BasicNameGeneratorTest.java | 100 +++++----- .../util/NameGeneratorPreferences.java | 186 +++++++++--------- 4 files changed, 246 insertions(+), 246 deletions(-) diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNameGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNameGenerator.java index a8f569f660..b70045d5c6 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNameGenerator.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/BasicNameGenerator.java @@ -1,51 +1,51 @@ -/***************************************************************** - * 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.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.map.DbRelationship; - -/** - * BasicNamingStrategy is an naming strategy that creates names in Cayenne's - * old-fashioned manner, i.e. the same way Cayenne did before 3.0 - * - * @since 3.0 - */ -public class BasicNameGenerator implements ObjectNameGenerator { - public String createDbRelationshipName( - ExportedKey key, - boolean toMany) { - - String uglyName = (toMany) ? key.getFKTableName() + "_ARRAY" : "to_" + key.getPKTableName(); - return NameConverter.underscoredToJava(uglyName, 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); - } -} +/***************************************************************** + * 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.DbAttribute; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.map.DbRelationship; + +/** + * BasicNamingStrategy is an naming strategy that creates names in Cayenne's + * old-fashioned manner, i.e. the same way Cayenne did before 3.0 + * + * @since 3.0 + */ +public class BasicNameGenerator implements ObjectNameGenerator { + public String createDbRelationshipName( + ExportedKey key, + boolean toMany) { + + String uglyName = (toMany) ? key.getFKTableName() + "_ARRAY" : "to_" + key.getPKTableName(); + return NameConverter.underscoredToJava(uglyName, 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-server/src/main/java/org/apache/cayenne/map/naming/ObjectNameGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ObjectNameGenerator.java index c7b5e148b0..7bd317723f 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ObjectNameGenerator.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ObjectNameGenerator.java @@ -1,52 +1,52 @@ -/***************************************************************** - * 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.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.map.DbRelationship; - -/** - * NamingStrategy is a strategy for creating names for entities, attributes, relationships - * during reverse engineering. - * - * @since 3.0 - */ -public interface ObjectNameGenerator { - - /** - * Creates new name for Obj Entity - */ - String createObjEntityName(DbEntity entity); - - /** - * Creates new name for Obj Attribute - */ - String createObjAttributeName(DbAttribute attr); - - /** - * Creates new name for Db Relationship - */ - String createDbRelationshipName(ExportedKey key, boolean toMany); - - /** - * Creates new name for Obj Relationship - */ - String createObjRelationshipName(DbRelationship dbRel); -} +/***************************************************************** + * 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.DbAttribute; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.map.DbRelationship; + +/** + * NamingStrategy is a strategy for creating names for entities, attributes, relationships + * during reverse engineering. + * + * @since 3.0 + */ +public interface ObjectNameGenerator { + + /** + * Creates new name for Obj Entity + */ + String createObjEntityName(DbEntity entity); + + /** + * Creates new name for Obj Attribute + */ + String createObjAttributeName(DbAttribute attr); + + /** + * Creates new name for Db Relationship + */ + String createDbRelationshipName(ExportedKey key, boolean toMany); + + /** + * Creates new name for Obj Relationship + */ + String createObjRelationshipName(DbRelationship dbRel); +} diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNameGeneratorTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNameGeneratorTest.java index 11612799fa..e0bd5c0237 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNameGeneratorTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/map/naming/BasicNameGeneratorTest.java @@ -1,50 +1,50 @@ -/***************************************************************** - * 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 junit.framework.TestCase; - -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.map.DbRelationship; - -public class BasicNameGeneratorTest extends TestCase { - public void testStrategy() throws Exception { - BasicNameGenerator strategy = new BasicNameGenerator(); - - ExportedKey key = new ExportedKey("ARTIST", "ARTIST_ID", null, - "PAINTING", "ARTIST_ID", null); - assertEquals(strategy.createDbRelationshipName(key, false), "toArtist"); - assertEquals(strategy.createDbRelationshipName(key, true), "paintingArray"); - - key = new ExportedKey("PERSON", "PERSON_ID", null, - "PERSON", "MOTHER_ID", null); - assertEquals(strategy.createDbRelationshipName(key, false), "toPerson"); - assertEquals(strategy.createDbRelationshipName(key, true), "personArray"); - - assertEquals(strategy.createObjEntityName(new DbEntity("ARTIST")), "Artist"); - assertEquals(strategy.createObjEntityName(new DbEntity("ARTIST_WORK")), "ArtistWork"); - - assertEquals(strategy.createObjAttributeName(new DbAttribute("NAME")), "name"); - assertEquals(strategy.createObjAttributeName(new DbAttribute("ARTIST_NAME")), "artistName"); - - assertEquals(strategy.createObjRelationshipName(new DbRelationship("toArtist")), "toArtist"); - assertEquals(strategy.createObjRelationshipName(new DbRelationship("paintingArray")), "paintingArray"); - } -} +/***************************************************************** + * 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 junit.framework.TestCase; + +import org.apache.cayenne.map.DbAttribute; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.map.DbRelationship; + +public class BasicNameGeneratorTest extends TestCase { + public void testStrategy() throws Exception { + BasicNameGenerator strategy = new BasicNameGenerator(); + + ExportedKey key = new ExportedKey("ARTIST", "ARTIST_ID", null, + "PAINTING", "ARTIST_ID", null); + assertEquals(strategy.createDbRelationshipName(key, false), "toArtist"); + assertEquals(strategy.createDbRelationshipName(key, true), "paintingArray"); + + key = new ExportedKey("PERSON", "PERSON_ID", null, + "PERSON", "MOTHER_ID", null); + assertEquals(strategy.createDbRelationshipName(key, false), "toPerson"); + assertEquals(strategy.createDbRelationshipName(key, true), "personArray"); + + assertEquals(strategy.createObjEntityName(new DbEntity("ARTIST")), "Artist"); + assertEquals(strategy.createObjEntityName(new DbEntity("ARTIST_WORK")), "ArtistWork"); + + assertEquals(strategy.createObjAttributeName(new DbAttribute("NAME")), "name"); + assertEquals(strategy.createObjAttributeName(new DbAttribute("ARTIST_NAME")), "artistName"); + + assertEquals(strategy.createObjRelationshipName(new DbRelationship("toArtist")), "toArtist"); + assertEquals(strategy.createObjRelationshipName(new DbRelationship("paintingArray")), "paintingArray"); + } +} diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NameGeneratorPreferences.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NameGeneratorPreferences.java index 817331f7c0..3af48594b7 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NameGeneratorPreferences.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/NameGeneratorPreferences.java @@ -1,93 +1,93 @@ -/***************************************************************** - * 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.modeler.util; - -import java.util.Arrays; -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 NameGeneratorPreferences { - - 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(BasicNameGenerator.class.getCanonicalName()); - PREDEFINED_STRATEGIES.add(SmartNameGenerator.class.getCanonicalName()); - } - - static final NameGeneratorPreferences instance = new NameGeneratorPreferences(); - - public static NameGeneratorPreferences getInstance() { - return instance; - } - - Preferences getPreference() { - return Application.getInstance().getMainPreferenceForProject(); - } - - /** - * @return last used strategies, PREDEFINED_STRATEGIES by default - */ - public Vector getLastUsedStrategies() { - - String prop = null; - - if (getPreference() != null) { - prop = getPreference().get(STRATEGIES_PREFERENCE, null); - } - - if (prop == null) { - return PREDEFINED_STRATEGIES; - } - - return new Vector(Arrays.asList(prop.split(","))); - } - - /** - * Adds strategy to history - */ - public void addToLastUsedStrategies(String strategy) { - Vector strategies = getLastUsedStrategies(); - - // move to top - strategies.remove(strategy); - strategies.add(0, strategy); - - StringBuilder res = new StringBuilder(); - for (String str : strategies) { - res.append(str).append(","); - } - if (strategies.size() > 0) { - res.deleteCharAt(res.length() - 1); - } - - getPreference().put(STRATEGIES_PREFERENCE, res.toString()); - } -} +/***************************************************************** + * 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.modeler.util; + +import java.util.Arrays; +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 NameGeneratorPreferences { + + 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(BasicNameGenerator.class.getCanonicalName()); + PREDEFINED_STRATEGIES.add(SmartNameGenerator.class.getCanonicalName()); + } + + static final NameGeneratorPreferences instance = new NameGeneratorPreferences(); + + public static NameGeneratorPreferences getInstance() { + return instance; + } + + Preferences getPreference() { + return Application.getInstance().getMainPreferenceForProject(); + } + + /** + * @return last used strategies, PREDEFINED_STRATEGIES by default + */ + public Vector getLastUsedStrategies() { + + String prop = null; + + if (getPreference() != null) { + prop = getPreference().get(STRATEGIES_PREFERENCE, null); + } + + if (prop == null) { + return PREDEFINED_STRATEGIES; + } + + return new Vector(Arrays.asList(prop.split(","))); + } + + /** + * Adds strategy to history + */ + public void addToLastUsedStrategies(String strategy) { + Vector strategies = getLastUsedStrategies(); + + // move to top + strategies.remove(strategy); + strategies.add(0, strategy); + + StringBuilder res = new StringBuilder(); + for (String str : strategies) { + res.append(str).append(","); + } + if (strategies.size() > 0) { + res.deleteCharAt(res.length() - 1); + } + + getPreference().put(STRATEGIES_PREFERENCE, res.toString()); + } +}