You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2016/10/02 18:31:32 UTC
[3/3] cayenne git commit: CAY-2116 Split schema synchronization code
in a separate module
CAY-2116 Split schema synchronization code in a separate module
Refactoring: Sane name builder API
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/38e4e7fd
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/38e4e7fd
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/38e4e7fd
Branch: refs/heads/master
Commit: 38e4e7fda64c3793f3fd4fe6c0ca8dc29211e1f5
Parents: 827056e
Author: Andrus Adamchik <an...@objectstyle.com>
Authored: Sun Oct 2 16:04:12 2016 +0300
Committer: Andrus Adamchik <an...@objectstyle.com>
Committed: Sun Oct 2 21:27:04 2016 +0300
----------------------------------------------------------------------
.../dbsync/merge/CreateTableToModel.java | 22 +-
.../dbsync/merge/DropRelationshipToDb.java | 2 +-
.../dbsync/merge/EntityMergeSupport.java | 20 +-
.../dbsync/naming/CallbackNameBuilder.java | 74 +++++
.../dbsync/naming/DeduplicationVisitor.java | 277 +++++++++++++++++++
.../dbsync/naming/DefaultBaseNameVisitor.java | 122 ++++++++
.../dbsync/naming/DuplicateNameResolver.java | 68 -----
.../cayenne/dbsync/naming/NameBuilder.java | 84 ++++++
.../cayenne/dbsync/naming/NameChecker.java | 36 ---
.../cayenne/dbsync/naming/NameCheckers.java | 223 ---------------
.../apache/cayenne/dbsync/naming/NameUtil.java | 65 +++++
.../dbsync/naming/NormalizationVisitor.java | 123 ++++++++
.../cayenne/dbsync/reverse/db/DbLoader.java | 47 ++--
.../reverse/db/DbRelationshipDetected.java | 53 ++++
.../reverse/db/ManyToManyCandidateEntity.java | 11 +-
.../cayenne/dbsync/naming/NameBuilderTest.java | 272 ++++++++++++++++++
.../cayenne/dbsync/naming/NameCheckersTest.java | 204 --------------
.../apache/cayenne/map/CallbackDescriptor.java | 2 +-
.../cayenne/map/DbRelationshipDetected.java | 48 ----
.../modeler/action/CreateAttributeAction.java | 106 +++----
.../action/CreateCallbackMethodAction.java | 47 ++--
.../modeler/action/CreateDataMapAction.java | 13 +-
.../modeler/action/CreateDbEntityAction.java | 116 ++++----
.../modeler/action/CreateEmbeddableAction.java | 13 +-
.../modeler/action/CreateNodeAction.java | 148 +++++-----
.../modeler/action/CreateObjEntityAction.java | 65 ++---
.../modeler/action/CreateProcedureAction.java | 89 +++---
.../action/CreateProcedureParameterAction.java | 102 +++----
.../action/CreateRelationshipAction.java | 217 ++++++++-------
.../modeler/action/ImportDataMapAction.java | 139 +++++-----
.../modeler/action/ImportEOModelAction.java | 38 +--
.../modeler/action/NewProjectAction.java | 27 +-
.../cayenne/modeler/action/PasteAction.java | 189 ++++++++-----
.../action/ReverseEngineeringAction.java | 24 +-
.../dialog/ResolveDbRelationshipDialog.java | 127 +++------
.../modeler/dialog/db/DbLoaderHelper.java | 43 ++-
.../cayenne/modeler/dialog/query/QueryType.java | 19 +-
.../cayenne/wocompat/EOModelProcessor.java | 11 +-
38 files changed, 1887 insertions(+), 1399 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToModel.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToModel.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToModel.java
index a8483b9..ba93d2c 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToModel.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToModel.java
@@ -19,8 +19,7 @@
package org.apache.cayenne.dbsync.merge;
import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
-import org.apache.cayenne.dbsync.naming.DuplicateNameResolver;
-import org.apache.cayenne.dbsync.naming.NameCheckers;
+import org.apache.cayenne.dbsync.naming.NameBuilder;
import org.apache.cayenne.dbsync.reverse.naming.DefaultObjectNameGenerator;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbEntity;
@@ -62,26 +61,21 @@ public class CreateTableToModel extends AbstractToModelToken.Entity {
// create a ObjEntity
- // TODO: proper name generator must be injected
+ // TODO: name generator must be injected...
+ // TODO: should we use DbEntity name as a basis instead of generic name like "ObjEntity1"?
+ String baseName = new DefaultObjectNameGenerator().createObjEntityName(dbEntity);
- String objEntityName = new DefaultObjectNameGenerator().createObjEntityName(dbEntity);
- objEntityName = DuplicateNameResolver.resolve(NameCheckers.objEntity, dbEntity.getDataMap(), objEntityName);
+ ObjEntity objEntity = new ObjEntity();
- // this loop will terminate even if no valid name is found
- // to prevent loader from looping forever (though such case is very unlikely)
- String baseName = objEntityName;
- for (int i = 1; i < 1000 && map.getObjEntity(objEntityName) != null; i++) {
- objEntityName = baseName + i;
- }
-
- ObjEntity objEntity = new ObjEntity(objEntityName);
+ String name = NameBuilder.builder(objEntity, dbEntity.getDataMap()).baseName(baseName).name();
+ objEntity.setName(name);
objEntity.setDbEntity(getEntity());
// try to find a class name for the ObjEntity
String className = objEntityClassName;
if (className == null) {
// we should generate a className based on the objEntityName
- className = map.getNameWithDefaultPackage(objEntityName);
+ className = map.getNameWithDefaultPackage(name);
}
objEntity.setClassName(className);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DropRelationshipToDb.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DropRelationshipToDb.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DropRelationshipToDb.java
index 3c7dd82..1579b25 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DropRelationshipToDb.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DropRelationshipToDb.java
@@ -23,7 +23,7 @@ import org.apache.cayenne.dba.QuotingStrategy;
import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.DbRelationshipDetected;
+import org.apache.cayenne.dbsync.reverse.db.DbRelationshipDetected;
import java.util.Collections;
import java.util.List;
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EntityMergeSupport.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EntityMergeSupport.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EntityMergeSupport.java
index c7fc8de..e3692b0 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EntityMergeSupport.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EntityMergeSupport.java
@@ -20,8 +20,7 @@
package org.apache.cayenne.dbsync.merge;
import org.apache.cayenne.dba.TypesMapping;
-import org.apache.cayenne.dbsync.naming.DuplicateNameResolver;
-import org.apache.cayenne.dbsync.naming.NameCheckers;
+import org.apache.cayenne.dbsync.naming.NameBuilder;
import org.apache.cayenne.dbsync.reverse.naming.ObjectNameGenerator;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbAttribute;
@@ -199,10 +198,11 @@ public class EntityMergeSupport {
}
private boolean createObjRelationship(ObjEntity entity, DbRelationship dr, String targetEntityName) {
- String relationshipName = nameGenerator.createObjRelationshipName(dr);
- relationshipName = DuplicateNameResolver.resolve(NameCheckers.objRelationship, entity, relationshipName);
+ ObjRelationship or = new ObjRelationship();
+ or.setName(NameBuilder.builder(or, entity)
+ .baseName(nameGenerator.createObjRelationshipName(dr))
+ .name());
- ObjRelationship or = new ObjRelationship(relationshipName);
or.addDbRelationship(dr);
Map<String, ObjEntity> objEntities = entity.getDataMap().getSubclassesForObjEntity(entity);
@@ -274,8 +274,11 @@ public class EntityMergeSupport {
}
private void addMissingAttribute(ObjEntity entity, DbAttribute da) {
- String attrName = DuplicateNameResolver.resolve(NameCheckers.objAttribute, entity,
- nameGenerator.createObjAttributeName(da));
+ ObjAttribute oa = new ObjAttribute();
+ oa.setName(NameBuilder.builder(oa, entity)
+ .baseName(nameGenerator.createObjAttributeName(da))
+ .name());
+ oa.setEntity(entity);
String type = TypesMapping.getJavaBySqlType(da.getType());
if (usePrimitives) {
@@ -284,8 +287,7 @@ public class EntityMergeSupport {
type = primitive;
}
}
-
- ObjAttribute oa = new ObjAttribute(attrName, type, entity);
+ oa.setType(type);
oa.setDbAttributePath(da.getName());
entity.addAttribute(oa);
fireAttributeAdded(oa);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/CallbackNameBuilder.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/CallbackNameBuilder.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/CallbackNameBuilder.java
new file mode 100644
index 0000000..655841c
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/CallbackNameBuilder.java
@@ -0,0 +1,74 @@
+/*
+ * 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.dbsync.naming;
+
+import org.apache.cayenne.configuration.ConfigurationNode;
+import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
+import org.apache.cayenne.map.ObjEntity;
+
+/**
+ * @since 4.0
+ */
+// TODO: fold CallbackMethod to org.apache.cayenne.map package and make it a ConfigurationNode
+// then we can get rid off this fork...
+class CallbackNameBuilder extends NameBuilder {
+
+ public CallbackNameBuilder() {
+ super(new CallbackNode());
+ }
+
+ @Override
+ public String name() {
+ String baseName = this.baseName != null
+ ? this.baseName
+ : "onEvent";
+
+ return new DeduplicationVisitor(namingContext, baseName, dupesPattern).resolve(new DeduplicationVisitor.Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+
+ ObjEntity entity = (ObjEntity) namingContext;
+
+ if (entity.getCallbackMethods().contains(name)) {
+ return true;
+ }
+
+ if (name.startsWith("get")) {
+ String conflictingProperty = NameUtil.uncapitalize(name.substring(3));
+
+ // check if either attribute or relationship name matches...
+ if (entity.getAttribute(conflictingProperty) != null
+ || entity.getRelationship(conflictingProperty) != null) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ });
+ }
+
+ static class CallbackNode implements ConfigurationNode {
+
+ @Override
+ public <T> T acceptVisitor(ConfigurationNodeVisitor<T> visitor) {
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DeduplicationVisitor.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DeduplicationVisitor.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DeduplicationVisitor.java
new file mode 100644
index 0000000..f809fd3
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DeduplicationVisitor.java
@@ -0,0 +1,277 @@
+/*
+ * 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.dbsync.naming;
+
+import org.apache.cayenne.configuration.ConfigurationNode;
+import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.dbimport.ReverseEngineering;
+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.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.QueryDescriptor;
+
+import java.util.Objects;
+
+/**
+ * @since 4.0
+ */
+// TODO: swap inner classes for lambdas when we are on java 8
+class DeduplicationVisitor implements ConfigurationNodeVisitor<String> {
+
+ private ConfigurationNode namingContext;
+ private String baseName;
+ private String dupesPattern;
+
+ DeduplicationVisitor(ConfigurationNode context, String baseName, String dupesPattern) {
+ this.namingContext = context;
+ this.baseName = Objects.requireNonNull(baseName);
+ this.dupesPattern = Objects.requireNonNull(dupesPattern);
+ }
+
+ @Override
+ public String visitDataChannelDescriptor(DataChannelDescriptor channelDescriptor) {
+ // DataChannelDescriptor is top-level. No context or naming conflicts are expected...
+ return baseName;
+ }
+
+ @Override
+ public String visitDataNodeDescriptor(DataNodeDescriptor nodeDescriptor) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+
+ DataChannelDescriptor dataChannelDescriptor = (DataChannelDescriptor) namingContext;
+ for (DataNodeDescriptor dataNodeDescriptor : dataChannelDescriptor.getNodeDescriptors()) {
+ if (dataNodeDescriptor.getName().equals(name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ });
+ }
+
+ @Override
+ public String visitDataMap(DataMap dataMap) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(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 DataChannelDescriptor) {
+ DataChannelDescriptor domain = (DataChannelDescriptor) namingContext;
+ return domain.getDataMap(name) != null;
+ }
+ return false;
+ }
+ });
+ }
+
+ @Override
+ public String visitObjEntity(ObjEntity entity) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+ DataMap map = (DataMap) namingContext;
+ return map.getObjEntity(name) != null;
+ }
+ });
+ }
+
+ @Override
+ public String visitDbEntity(DbEntity entity) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+ DataMap map = (DataMap) namingContext;
+ return map.getDbEntity(name) != null;
+ }
+ });
+ }
+
+ @Override
+ public String visitEmbeddable(Embeddable embeddable) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+ DataMap map = (DataMap) namingContext;
+ return map.getEmbeddable(map.getNameWithDefaultPackage(name)) != null;
+ }
+ });
+ }
+
+ @Override
+ public String visitEmbeddableAttribute(EmbeddableAttribute attribute) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+ Embeddable emb = (Embeddable) namingContext;
+ return emb.getAttribute(name) != null;
+ }
+ });
+ }
+
+ @Override
+ public String visitObjAttribute(ObjAttribute attribute) {
+ return resolveObjEntityProperty();
+ }
+
+ @Override
+ public String visitDbAttribute(DbAttribute attribute) {
+ return resolveDbEntityProperty();
+ }
+
+ @Override
+ public String visitObjRelationship(ObjRelationship relationship) {
+ return resolveObjEntityProperty();
+ }
+
+ @Override
+ public String visitDbRelationship(DbRelationship relationship) {
+ return resolveDbEntityProperty();
+ }
+
+ @Override
+ public String visitProcedure(Procedure procedure) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+ DataMap map = (DataMap) namingContext;
+ return map.getProcedure(name) != null;
+ }
+ });
+ }
+
+ @Override
+ public String visitProcedureParameter(ProcedureParameter parameter) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(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 (ProcedureParameter parameter : procedure.getCallParameters()) {
+ if (name.equals(parameter.getName())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ });
+ }
+
+ @Override
+ public String visitQuery(QueryDescriptor query) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+ DataMap map = (DataMap) namingContext;
+ return map.getQueryDescriptor(name) != null;
+ }
+ });
+ }
+
+ @Override
+ public String visitReverseEngineering(ReverseEngineering reverseEngineering) {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+
+ if (namingContext == null) {
+ return false;
+ }
+
+ DataChannelDescriptor dataChannelDescriptor = (DataChannelDescriptor) namingContext;
+ for (DataMap dataMap : dataChannelDescriptor.getDataMaps()) {
+ if (dataMap != null && dataMap.getReverseEngineering() != null &&
+ dataMap.getReverseEngineering().getName() != null
+ && dataMap.getReverseEngineering().getName().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+ }
+
+ String resolve(Predicate nameChecker) {
+ int c = 1;
+ String name = baseName;
+ while (nameChecker.isNameInUse(name)) {
+ name = String.format(dupesPattern, baseName, c++);
+ }
+
+ return name;
+ }
+
+ private String resolveDbEntityProperty() {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+
+ DbEntity entity = (DbEntity) namingContext;
+
+ // check if either attribute or relationship name matches...
+ return entity.getAttribute(name) != null || entity.getRelationship(name) != null;
+ }
+ });
+ }
+
+ private String resolveObjEntityProperty() {
+ return resolve(new Predicate() {
+ @Override
+ public boolean isNameInUse(String name) {
+
+ ObjEntity entity = (ObjEntity) namingContext;
+
+ // check if either attribute or relationship name matches...
+ if (entity.getAttribute(name) != null || entity.getRelationship(name) != null) {
+ return true;
+ }
+
+ // check if there's a callback method that shadows attribute getter (unlikely, but still)
+ String conflictingCallback = "get" + NameUtil.capitalize(name);
+ return entity.getCallbackMethods().contains(conflictingCallback);
+ }
+ });
+ }
+
+ interface Predicate {
+ boolean isNameInUse(String name);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DefaultBaseNameVisitor.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DefaultBaseNameVisitor.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DefaultBaseNameVisitor.java
new file mode 100644
index 0000000..ecc17f0
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DefaultBaseNameVisitor.java
@@ -0,0 +1,122 @@
+/*
+ * 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.dbsync.naming;
+
+import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.dbimport.ReverseEngineering;
+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.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.QueryDescriptor;
+
+/**
+ * @since 4.0
+ */
+class DefaultBaseNameVisitor implements ConfigurationNodeVisitor<String> {
+
+ static final DefaultBaseNameVisitor INSTANCE = new DefaultBaseNameVisitor();
+
+ private DefaultBaseNameVisitor() {
+ }
+
+ @Override
+ public String visitDataChannelDescriptor(DataChannelDescriptor channelDescriptor) {
+ return "project";
+ }
+
+ @Override
+ public String visitDataNodeDescriptor(DataNodeDescriptor nodeDescriptor) {
+ return "datanode";
+ }
+
+ @Override
+ public String visitDataMap(DataMap dataMap) {
+ return "datamap";
+ }
+
+ @Override
+ public String visitObjEntity(ObjEntity entity) {
+ return "ObjEntity";
+ }
+
+ @Override
+ public String visitDbEntity(DbEntity entity) {
+ return "db_entity";
+ }
+
+ @Override
+ public String visitEmbeddable(Embeddable embeddable) {
+ return "Embeddable";
+ }
+
+ @Override
+ public String visitEmbeddableAttribute(EmbeddableAttribute attribute) {
+ return "untitledAttr";
+ }
+
+ @Override
+ public String visitObjAttribute(ObjAttribute attribute) {
+ return "untitledAttr";
+ }
+
+ @Override
+ public String visitDbAttribute(DbAttribute attribute) {
+ return "untitledAttr";
+ }
+
+ @Override
+ public String visitObjRelationship(ObjRelationship relationship) {
+ return "untitledRel";
+ }
+
+ @Override
+ public String visitDbRelationship(DbRelationship relationship) {
+ return "untitledRel";
+ }
+
+ @Override
+ public String visitProcedure(Procedure procedure) {
+ return "procedure";
+ }
+
+ @Override
+ public String visitProcedureParameter(ProcedureParameter parameter) {
+ return "UntitledProcedureParameter";
+ }
+
+ @Override
+ public String visitQuery(QueryDescriptor query) {
+ return "query";
+ }
+
+ @Override
+ public String visitReverseEngineering(ReverseEngineering reverseEngineering) {
+ return "reverseEngineering";
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DuplicateNameResolver.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DuplicateNameResolver.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DuplicateNameResolver.java
deleted file mode 100644
index 3f55d8f..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DuplicateNameResolver.java
+++ /dev/null
@@ -1,68 +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.dbsync.naming;
-
-import org.apache.cayenne.map.DataMap;
-
-/**
- * A generator of unique names for the various model objects.
- *
- * @since 4.0
- */
-public class DuplicateNameResolver {
-
- private static final String DEFAULT_PATTERN = "%s%d";
-
- public static String resolve(NameChecker checker) {
- return resolve(checker, DEFAULT_PATTERN, null, null);
- }
-
- public static String resolve(NameChecker checker, Object context) {
- return resolve(checker, DEFAULT_PATTERN, context, null);
- }
-
- public static String resolve(NameChecker checker, Object context, String baseName) {
- return resolve(checker, DEFAULT_PATTERN, context, baseName);
- }
-
- public static String resolve(NameChecker nameChecker, String pattern, Object context, String baseName) {
-
- if (baseName == null) {
- baseName = nameChecker.baseName();
- }
-
- String resolved = doResolve(nameChecker, pattern, context, baseName);
-
- // TODO ugly hack with cast... something more OO is in order
- return (nameChecker == NameCheckers.embeddable)
- ? ((DataMap) context).getNameWithDefaultPackage(resolved) : resolved;
- }
-
-
- private static String doResolve(NameChecker nameChecker, String pattern, Object namingContext, String baseName) {
- int c = 1;
- String name = baseName;
- while (nameChecker.isNameInUse(namingContext, name)) {
- name = String.format(pattern, baseName, c++);
- }
-
- return name;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameBuilder.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameBuilder.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameBuilder.java
new file mode 100644
index 0000000..c791cbc
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameBuilder.java
@@ -0,0 +1,84 @@
+/*
+ * 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.dbsync.naming;
+
+import org.apache.cayenne.configuration.ConfigurationNode;
+import org.apache.cayenne.map.ObjEntity;
+
+import java.util.Objects;
+
+/**
+ * A
+ *
+ * @since 4.0
+ */
+public class NameBuilder {
+
+ protected ConfigurationNode nodeToName;
+ protected ConfigurationNode namingContext;
+ protected String dupesPattern;
+ protected String baseName;
+
+ protected NameBuilder(ConfigurationNode nodeToName) {
+ this.nodeToName = Objects.requireNonNull(nodeToName);
+ this.dupesPattern = "%s%d";
+ }
+
+ public static NameBuilder builder(ConfigurationNode node) {
+ return new NameBuilder(node);
+ }
+
+ public static NameBuilder builder(ConfigurationNode node, ConfigurationNode namingContext) {
+ return new NameBuilder(node).in(namingContext);
+ }
+
+ /**
+ * A special builder starter for callback methods. Eventually callback methods will be made into ConfigurationNodes,
+ * and we can use regular {@link #builder(ConfigurationNode)} methods to name them.
+ */
+ // TODO: fold CallbackMethod to org.apache.cayenne.map package and make it a ConfigurationNode
+ // then we can use normal API for it... for now have to keep a special one-off method...
+ public static NameBuilder builderForCallbackMethod(ObjEntity namingContext) {
+ return new CallbackNameBuilder().in(namingContext);
+ }
+
+ public NameBuilder in(ConfigurationNode namingContext) {
+ this.namingContext = Objects.requireNonNull(namingContext);
+ return this;
+ }
+
+ public NameBuilder dupesPattern(String dupesPattern) {
+ this.dupesPattern = Objects.requireNonNull(dupesPattern);
+ return this;
+ }
+
+ public NameBuilder baseName(String baseName) {
+ this.baseName = baseName;
+ return this;
+ }
+
+ public String name() {
+ String baseName = this.baseName != null && this.baseName.length() > 0
+ ? this.baseName
+ : nodeToName.acceptVisitor(DefaultBaseNameVisitor.INSTANCE);
+
+ String normalizedBaseName = nodeToName.acceptVisitor(new NormalizationVisitor(baseName));
+ return nodeToName.acceptVisitor(new DeduplicationVisitor(namingContext, normalizedBaseName, dupesPattern));
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameChecker.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameChecker.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameChecker.java
deleted file mode 100644
index ade1ec5..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameChecker.java
+++ /dev/null
@@ -1,36 +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.dbsync.naming;
-
-/**
- * @since 4.0
- */
-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);
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameCheckers.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameCheckers.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameCheckers.java
deleted file mode 100644
index fca1734..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameCheckers.java
+++ /dev/null
@@ -1,223 +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.dbsync.naming;
-
-import org.apache.cayenne.access.DataDomain;
-import org.apache.cayenne.configuration.DataChannelDescriptor;
-import org.apache.cayenne.configuration.DataNodeDescriptor;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.Embeddable;
-import org.apache.cayenne.map.Entity;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.Procedure;
-import org.apache.cayenne.map.ProcedureParameter;
-import org.apache.commons.lang.StringUtils;
-
-/**
- * A set of default {@link NameChecker} objects for the known model objects.
- *
- * @since 4.0
- */
-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;
- }
- },
-
- reverseEngineering("reverseEngineering") {
- @Override
- public boolean isNameInUse(Object namingContext, String name) {
- if (namingContext == null) {
- return false;
- }
-
- for (DataMap dataMap : ((DataChannelDescriptor) namingContext).getDataMaps()) {
- if (dataMap != null && dataMap.getReverseEngineering() != null &&
- dataMap.getReverseEngineering().getName() != null && dataMap.getReverseEngineering().getName().equals(name)) {
- return true;
- }
- }
- 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;
- return map.getEmbeddable(map.getNameWithDefaultPackage(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;
- }
- },
-
- query("query") {
- @Override
- public boolean isNameInUse(Object namingContext, String name) {
- DataMap map = (DataMap) namingContext;
- return map.getQueryDescriptor(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 (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);
- }
- };
-
- private final String baseName;
-
- NameCheckers(String baseName) {
- this.baseName = baseName;
- }
-
- @Override
- public String baseName() {
- return baseName;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameUtil.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameUtil.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameUtil.java
new file mode 100644
index 0000000..fb47bcb
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameUtil.java
@@ -0,0 +1,65 @@
+/*
+ * 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.dbsync.naming;
+
+/**
+ * @since 4.0
+ */
+final class NameUtil {
+ static String uncapitalize(String string) {
+ int len;
+ if (string == null || (len = string.length()) == 0) {
+ return string;
+ }
+
+ final char firstChar = string.charAt(0);
+ final char newChar = Character.toLowerCase(firstChar);
+ if (firstChar == newChar) {
+ // already capitalized
+ return string;
+ }
+
+ char[] newChars = new char[len];
+ newChars[0] = newChar;
+ string.getChars(1, len, newChars, 1);
+
+ return String.valueOf(newChars);
+ }
+
+ static String capitalize(String string) {
+ int len;
+ if (string == null || (len = string.length()) == 0) {
+ return string;
+ }
+
+ final char firstChar = string.charAt(0);
+ final char newChar = Character.toTitleCase(firstChar);
+ if (firstChar == newChar) {
+ // already capitalized
+ return string;
+ }
+
+ char[] newChars = new char[len];
+ newChars[0] = newChar;
+ string.getChars(1, len, newChars, 1);
+
+ return String.valueOf(newChars);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NormalizationVisitor.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NormalizationVisitor.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NormalizationVisitor.java
new file mode 100644
index 0000000..75d941d
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NormalizationVisitor.java
@@ -0,0 +1,123 @@
+/*
+ * 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.dbsync.naming;
+
+import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.dbimport.ReverseEngineering;
+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.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.QueryDescriptor;
+
+/**
+ * @since 4.0
+ */
+class NormalizationVisitor implements ConfigurationNodeVisitor<String> {
+
+ private String baseName;
+
+ public NormalizationVisitor(String baseName) {
+ this.baseName = baseName;
+ }
+
+ @Override
+ public String visitDataChannelDescriptor(DataChannelDescriptor channelDescriptor) {
+ return baseName;
+ }
+
+ @Override
+ public String visitDataNodeDescriptor(DataNodeDescriptor nodeDescriptor) {
+ return baseName;
+ }
+
+ @Override
+ public String visitDataMap(DataMap dataMap) {
+ return baseName;
+ }
+
+ @Override
+ public String visitObjEntity(ObjEntity entity) {
+ return NameUtil.capitalize(baseName);
+ }
+
+ @Override
+ public String visitDbEntity(DbEntity entity) {
+ return baseName;
+ }
+
+ @Override
+ public String visitEmbeddable(Embeddable embeddable) {
+ return NameUtil.capitalize(baseName);
+ }
+
+ @Override
+ public String visitEmbeddableAttribute(EmbeddableAttribute attribute) {
+ return NameUtil.uncapitalize(baseName);
+ }
+
+ @Override
+ public String visitObjAttribute(ObjAttribute attribute) {
+ return NameUtil.uncapitalize(baseName);
+ }
+
+ @Override
+ public String visitDbAttribute(DbAttribute attribute) {
+ return baseName;
+ }
+
+ @Override
+ public String visitObjRelationship(ObjRelationship relationship) {
+ return NameUtil.uncapitalize(baseName);
+ }
+
+ @Override
+ public String visitDbRelationship(DbRelationship relationship) {
+ return NameUtil.uncapitalize(baseName);
+ }
+
+ @Override
+ public String visitProcedure(Procedure procedure) {
+ return baseName;
+ }
+
+ @Override
+ public String visitProcedureParameter(ProcedureParameter parameter) {
+ return baseName;
+ }
+
+ @Override
+ public String visitQuery(QueryDescriptor query) {
+ return baseName;
+ }
+
+ @Override
+ public String visitReverseEngineering(ReverseEngineering reverseEngineering) {
+ return baseName;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/DbLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/DbLoader.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/DbLoader.java
index 44b9fb3..ecdfa70 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/DbLoader.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/DbLoader.java
@@ -21,23 +21,21 @@ package org.apache.cayenne.dbsync.reverse.db;
import org.apache.cayenne.dba.DbAdapter;
import org.apache.cayenne.dba.TypesMapping;
import org.apache.cayenne.dbsync.merge.EntityMergeSupport;
+import org.apache.cayenne.dbsync.naming.NameBuilder;
import org.apache.cayenne.dbsync.reverse.filters.CatalogFilter;
import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
import org.apache.cayenne.dbsync.reverse.filters.SchemaFilter;
import org.apache.cayenne.dbsync.reverse.filters.TableFilter;
+import org.apache.cayenne.dbsync.reverse.naming.LegacyObjectNameGenerator;
+import org.apache.cayenne.dbsync.reverse.naming.ObjectNameGenerator;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbJoin;
import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.DbRelationshipDetected;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.Procedure;
import org.apache.cayenne.map.ProcedureParameter;
-import org.apache.cayenne.dbsync.naming.DuplicateNameResolver;
-import org.apache.cayenne.dbsync.reverse.naming.LegacyObjectNameGenerator;
-import org.apache.cayenne.dbsync.naming.NameCheckers;
-import org.apache.cayenne.dbsync.reverse.naming.ObjectNameGenerator;
import org.apache.cayenne.util.EqualsBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -133,10 +131,12 @@ public class DbLoader {
continue;
}
- String objEntityName = DuplicateNameResolver.resolve(NameCheckers.objEntity, map,
- nameGenerator.createObjEntityName(dbEntity));
+ ObjEntity objEntity = new ObjEntity();
+ objEntity.setName(NameBuilder
+ .builder(objEntity, map)
+ .baseName(nameGenerator.createObjEntityName(dbEntity))
+ .name());
- ObjEntity objEntity = new ObjEntity(objEntityName);
objEntity.setDbEntity(dbEntity);
objEntity.setClassName(config.getGenericClassName() != null ? config.getGenericClassName() : map
.getNameWithDefaultPackage(objEntity.getName()));
@@ -315,13 +315,26 @@ public class DbLoader {
}
// forwardRelationship is a reference from table with primary key
- DbRelationship forwardRelationship = new DbRelationship(generateName(pkEntity, key, true));
+ DbRelationship forwardRelationship = new DbRelationship();
+ forwardRelationship.setName(NameBuilder
+ .builder(forwardRelationship, pkEntity)
+ .baseName(nameGenerator.createDbRelationshipName(key, true))
+ .name());
+
forwardRelationship.setSourceEntity(pkEntity);
forwardRelationship.setTargetEntityName(fkEntity);
// forwardRelationship is a reference from table with foreign key,
// it is what exactly we load from db
- DbRelationshipDetected reverseRelationship = new DbRelationshipDetected(generateName(fkEntity, key, false));
+
+ // TODO: dirty and non-transparent... using DbRelationshipDetected for the benefit of the merge package.
+ // This info is available from joins....
+ DbRelationshipDetected reverseRelationship = new DbRelationshipDetected();
+ reverseRelationship.setName(NameBuilder
+ .builder(reverseRelationship, fkEntity)
+ .baseName(nameGenerator.createDbRelationshipName(key, false))
+ .name());
+
reverseRelationship.setFkName(key.getFKName());
reverseRelationship.setSourceEntity(fkEntity);
reverseRelationship.setTargetEntityName(pkEntity);
@@ -336,7 +349,12 @@ public class DbLoader {
&& fkEntity.getPrimaryKeys().size() == forwardRelationship.getJoins().size();
forwardRelationship.setToMany(!isOneToOne);
- forwardRelationship.setName(generateName(pkEntity, key, !isOneToOne));
+
+ // TODO: can we avoid resetting the name twice? Do we need a placeholder name above?
+ forwardRelationship.setName(NameBuilder
+ .builder(forwardRelationship, pkEntity)
+ .baseName(nameGenerator.createDbRelationshipName(key, !isOneToOne))
+ .name());
if (delegate.dbRelationshipLoaded(fkEntity, reverseRelationship)) {
fkEntity.addRelationship(reverseRelationship);
@@ -358,7 +376,7 @@ public class DbLoader {
}
private void createAndAppendJoins(Set<ExportedKey> exportedKeys, DbEntity pkEntity, DbEntity fkEntity,
- DbRelationship forwardRelationship, DbRelationshipDetected reverseRelationship) {
+ DbRelationship forwardRelationship, DbRelationship reverseRelationship) {
for (ExportedKey exportedKey : exportedKeys) {
// Create and append joins
String pkName = exportedKey.getPKColumnName();
@@ -437,11 +455,6 @@ public class DbLoader {
LOGGER.info("Skip relation: '" + key + "' because table '" + tableName + "' not found");
}
- private String generateName(DbEntity entity, ExportedKey key, boolean toMany) {
- String forwardPreferredName = nameGenerator.createDbRelationshipName(key, toMany);
- return DuplicateNameResolver.resolve(NameCheckers.dbRelationship, entity, forwardPreferredName);
- }
-
private void fireObjEntitiesAddedEvents(Collection<ObjEntity> loadedObjEntities) {
for (ObjEntity curEntity : loadedObjEntities) {
// notify delegate
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/DbRelationshipDetected.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/DbRelationshipDetected.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/DbRelationshipDetected.java
new file mode 100644
index 0000000..dfad14f
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/DbRelationshipDetected.java
@@ -0,0 +1,53 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.dbsync.reverse.db;
+
+
+import org.apache.cayenne.map.DbRelationship;
+
+/**
+ * A subclass of {@link DbRelationship} to hold some extra runtime information.
+ */
+// TODO: dirty ... can we lookup fkName via joins?
+public class DbRelationshipDetected extends DbRelationship {
+
+ private String fkName;
+
+ public DbRelationshipDetected(String uniqueRelName) {
+ super(uniqueRelName);
+ }
+
+ public DbRelationshipDetected() {
+ }
+
+ /**
+ * Get the name of the underlying foreign key. Typically FK_NAME from jdbc metadata.
+ */
+ public String getFkName() {
+ return fkName;
+ }
+
+ /**
+ * Set the name of the underlying foreign key. Typically FK_NAME from jdbc metadata.
+ */
+ public void setFkName(String fkName) {
+ this.fkName = fkName;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/ManyToManyCandidateEntity.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/ManyToManyCandidateEntity.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/ManyToManyCandidateEntity.java
index 85af6a4..7f2f815 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/ManyToManyCandidateEntity.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/db/ManyToManyCandidateEntity.java
@@ -18,12 +18,11 @@
****************************************************************/
package org.apache.cayenne.dbsync.reverse.db;
+import org.apache.cayenne.dbsync.naming.NameBuilder;
+import org.apache.cayenne.dbsync.reverse.naming.ObjectNameGenerator;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.dbsync.naming.DuplicateNameResolver;
-import org.apache.cayenne.dbsync.naming.NameCheckers;
-import org.apache.cayenne.dbsync.reverse.naming.ObjectNameGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -113,8 +112,10 @@ class ManyToManyCandidateEntity {
(short) 1);
ObjRelationship newRelationship = new ObjRelationship();
- newRelationship.setName(DuplicateNameResolver.resolve(NameCheckers.objRelationship, srcEntity,
- nameGenerator.createDbRelationshipName(key, true)));
+ newRelationship.setName(NameBuilder
+ .builder(newRelationship, srcEntity)
+ .baseName(nameGenerator.createDbRelationshipName(key, true))
+ .name());
newRelationship.setSourceEntity(srcEntity);
newRelationship.setTargetEntityName(dstEntity);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/NameBuilderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/NameBuilderTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/NameBuilderTest.java
new file mode 100644
index 0000000..8aa21c3
--- /dev/null
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/NameBuilderTest.java
@@ -0,0 +1,272 @@
+/*****************************************************************
+ * 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.dbsync.naming;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataNodeDescriptor;
+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.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.QueryDescriptor;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class NameBuilderTest {
+
+ @Test
+ public void testName_Root() {
+ assertEquals("project", NameBuilder.builder(new DataChannelDescriptor()).name());
+ }
+
+ @Test
+ public void testName_DataChannelDescriptorContext() throws Exception {
+ DataChannelDescriptor descriptor = new DataChannelDescriptor();
+
+ DataMap m0 = new DataMap();
+ m0.setName(NameBuilder.builder(m0).in(descriptor).name());
+ assertEquals("datamap", m0.getName());
+ descriptor.getDataMaps().add(m0);
+
+ DataMap m1 = new DataMap();
+ m1.setName(NameBuilder.builder(m1).in(descriptor).name());
+ assertEquals("datamap1", m1.getName());
+ descriptor.getDataMaps().add(m1);
+
+ DataNodeDescriptor nd0 = new DataNodeDescriptor();
+ nd0.setName(NameBuilder.builder(nd0).in(descriptor).name());
+ assertEquals("datanode", nd0.getName());
+ descriptor.getNodeDescriptors().add(nd0);
+
+ DataNodeDescriptor nd1 = new DataNodeDescriptor();
+ nd1.setName(NameBuilder.builder(nd1).in(descriptor).name());
+ assertEquals("datanode1", nd1.getName());
+ descriptor.getNodeDescriptors().add(nd1);
+ }
+
+
+ @Test
+ public void testName_DataMapContext() {
+ DataMap map = new DataMap();
+ map.setDefaultPackage("com.foo");
+
+ DbEntity de0 = new DbEntity();
+ de0.setName(NameBuilder.builder(de0).in(map).name());
+ assertEquals("db_entity", de0.getName());
+ map.addDbEntity(de0);
+
+ DbEntity de1 = new DbEntity();
+ de1.setName(NameBuilder.builder(de1).in(map).name());
+ assertEquals("db_entity1", de1.getName());
+ map.addDbEntity(de1);
+
+ ObjEntity oe0 = new ObjEntity();
+ oe0.setName(NameBuilder.builder(oe0).in(map).name());
+ assertEquals("ObjEntity", oe0.getName());
+ map.addObjEntity(oe0);
+
+ ObjEntity oe1 = new ObjEntity();
+ oe1.setName(NameBuilder.builder(oe1).in(map).name());
+ assertEquals("ObjEntity1", oe1.getName());
+ map.addObjEntity(oe1);
+
+ ObjEntity oe2 = new ObjEntity();
+ oe2.setName(NameBuilder.builder(oe0).in(map).baseName("db_entity").name());
+ assertEquals("Should not conflict with similarly named DbEntity", "Db_entity", oe2.getName());
+ map.addObjEntity(oe2);
+
+ Procedure p0 = new Procedure();
+ p0.setName(NameBuilder.builder(p0).in(map).name());
+ assertEquals("procedure", p0.getName());
+ map.addProcedure(p0);
+
+ Procedure p1 = new Procedure();
+ p1.setName(NameBuilder.builder(p1).in(map).name());
+ assertEquals("procedure1", p1.getName());
+ map.addProcedure(p1);
+
+ Procedure p2 = new Procedure();
+ p2.setName(NameBuilder.builder(p1).in(map).baseName("db_enity").name());
+ assertEquals("Should not conflict with similarly named DbEntity", "db_enity", p2.getName());
+ map.addProcedure(p2);
+
+ QueryDescriptor q0 = QueryDescriptor.selectQueryDescriptor();
+ q0.setName(NameBuilder.builder(q0).in(map).name());
+ assertEquals("query", q0.getName());
+ map.addQueryDescriptor(q0);
+
+ QueryDescriptor q1 = QueryDescriptor.ejbqlQueryDescriptor();
+ q1.setName(NameBuilder.builder(q1).in(map).name());
+ assertEquals("query1", q1.getName());
+ map.addQueryDescriptor(q1);
+
+ Embeddable e0 = new Embeddable();
+ e0.setClassName("com.foo." + NameBuilder.builder(e0).in(map).name());
+ assertEquals("com.foo.Embeddable", e0.getClassName());
+ map.addEmbeddable(e0);
+
+ Embeddable e1 = new Embeddable();
+ e1.setClassName("com.foo." + NameBuilder.builder(e1).in(map).name());
+ assertEquals("com.foo.Embeddable1", e1.getClassName());
+ map.addEmbeddable(e1);
+ }
+
+ @Test
+ public void testName_ObjEntityContext() {
+
+ ObjEntity entity = new ObjEntity();
+
+ entity.getCallbackMap().getPostAdd().addCallbackMethod("getMe");
+
+ ObjAttribute a0 = new ObjAttribute();
+ String na0 = NameBuilder.builder(a0).in(entity).name();
+ assertEquals("untitledAttr", na0);
+ a0.setName(na0);
+ entity.addAttribute(a0);
+
+ ObjAttribute a1 = new ObjAttribute();
+ String na1 = NameBuilder.builder(a1).in(entity).name();
+ assertEquals("untitledAttr1", na1);
+ a1.setName(na1);
+ entity.addAttribute(a1);
+
+ ObjAttribute a2 = new ObjAttribute();
+ String na2 = NameBuilder.builder(a2).in(entity).baseName("me").name();
+ assertEquals("Conflict with callback method was not detected", "me1", na2);
+ a2.setName(na2);
+ entity.addAttribute(a2);
+
+ ObjRelationship r0 = new ObjRelationship();
+ String nr0 = NameBuilder.builder(r0).in(entity).name();
+ assertEquals("untitledRel", nr0);
+ r0.setName(nr0);
+ entity.addRelationship(r0);
+
+ ObjRelationship r1 = new ObjRelationship();
+ String nr1 = NameBuilder.builder(r1).in(entity).name();
+ assertEquals("untitledRel1", nr1);
+ r1.setName(nr1);
+ entity.addRelationship(r1);
+ }
+
+ @Test
+ public void testName_DbEntityContext() {
+ DbEntity entity = new DbEntity();
+
+ DbAttribute a0 = new DbAttribute();
+ String na0 = NameBuilder.builder(a0).in(entity).name();
+ assertEquals("untitledAttr", na0);
+ a0.setName(na0);
+ entity.addAttribute(a0);
+
+ DbAttribute a1 = new DbAttribute();
+ String na1 = NameBuilder.builder(a1).in(entity).name();
+ assertEquals("untitledAttr1", na1);
+ a1.setName(na1);
+ entity.addAttribute(a1);
+
+ DbRelationship r0 = new DbRelationship();
+ String nr0 = NameBuilder.builder(r0).in(entity).name();
+ assertEquals("untitledRel", nr0);
+ r0.setName(nr0);
+ entity.addRelationship(r0);
+
+ DbRelationship r1 = new DbRelationship();
+ String nr1 = NameBuilder.builder(r1).in(entity).name();
+ assertEquals("untitledRel1", nr1);
+ r1.setName(nr1);
+ entity.addRelationship(r1);
+ }
+
+ @Test
+ public void testName_ProcedureContext() {
+ Procedure procedure = new Procedure();
+
+ ProcedureParameter p0 = new ProcedureParameter();
+ p0.setName(NameBuilder.builder(p0).in(procedure).name());
+ assertEquals("UntitledProcedureParameter", p0.getName());
+ procedure.addCallParameter(p0);
+
+ ProcedureParameter p1 = new ProcedureParameter();
+ p1.setName(NameBuilder.builder(p1).in(procedure).name());
+ assertEquals("UntitledProcedureParameter1", p1.getName());
+ procedure.addCallParameter(p1);
+ }
+
+ @Test
+ public void testName_EmbeddableContext() {
+ Embeddable embeddable = new Embeddable();
+
+ EmbeddableAttribute ea0 = new EmbeddableAttribute();
+ ea0.setName(NameBuilder.builder(ea0).in(embeddable).name());
+ assertEquals("untitledAttr", ea0.getName());
+ embeddable.addAttribute(ea0);
+
+ EmbeddableAttribute ea1 = new EmbeddableAttribute();
+ ea1.setName(NameBuilder.builder(ea1).in(embeddable).name());
+ assertEquals("untitledAttr1", ea1.getName());
+ embeddable.addAttribute(ea1);
+ }
+
+ @Test
+ public void testName_UncapitalizeAttributeNames() throws Exception {
+
+ ObjEntity entity = new ObjEntity();
+
+ ObjAttribute a0 = new ObjAttribute();
+ String na0 = NameBuilder.builder(a0).in(entity).baseName("myName").name();
+ assertEquals("myName", na0);
+ a0.setName(na0);
+ entity.addAttribute(a0);
+
+ ObjAttribute a1 = new ObjAttribute();
+ String na1 = NameBuilder.builder(a1).in(entity).baseName("MyName").name();
+ assertEquals("myName1", na1);
+ a1.setName(na1);
+ entity.addAttribute(a1);
+ }
+
+ @Test
+ public void testName_Callbacks_ObjEntityContext() {
+
+ ObjEntity entity = new ObjEntity();
+
+ String c0 = NameBuilder.builderForCallbackMethod(entity).name();
+ assertEquals("onEvent", c0);
+ entity.getCallbackMap().getPostAdd().addCallbackMethod(c0);
+
+ String c1 = NameBuilder.builderForCallbackMethod(entity).name();
+ assertEquals("onEvent1", c1);
+ entity.getCallbackMap().getPostAdd().addCallbackMethod(c1);
+
+ entity.addAttribute(new ObjAttribute("untitledAttr"));
+
+ String c3 = NameBuilder.builderForCallbackMethod(entity).baseName("getUntitledAttr").name();
+ assertEquals("getUntitledAttr1", c3);
+ entity.getCallbackMap().getPostAdd().addCallbackMethod(c3);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/NameCheckersTest.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/NameCheckersTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/NameCheckersTest.java
deleted file mode 100644
index 8131160..0000000
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/NameCheckersTest.java
+++ /dev/null
@@ -1,204 +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.dbsync.naming;
-
-import org.apache.cayenne.access.DataDomain;
-import org.apache.cayenne.configuration.DataChannelDescriptor;
-import org.apache.cayenne.configuration.DataNodeDescriptor;
-import org.apache.cayenne.map.DataMap;
-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.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.QueryDescriptor;
-import org.junit.Assert;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class NameCheckersTest {
-
- @Test
- public void testObjEntityAttributes() throws Exception {
- NameCheckers maker = NameCheckers.objAttribute;
- ObjEntity namingContainer = new ObjEntity();
-
- String baseName = maker.baseName();
- String name = DuplicateNameResolver.resolve(maker, namingContainer);
- assertEquals(baseName, name);
- namingContainer.addAttribute(new ObjAttribute(name));
-
- name = DuplicateNameResolver.resolve(maker, namingContainer);
- assertEquals(baseName + "1", name);
- namingContainer.addAttribute(new ObjAttribute(name));
-
- name = DuplicateNameResolver.resolve(maker, namingContainer);
- assertEquals(baseName + "2", name);
- namingContainer.addAttribute(new ObjAttribute(name));
-
- name = DuplicateNameResolver.resolve(maker, namingContainer);
- assertEquals(baseName + "3", name);
- namingContainer.addAttribute(new ObjAttribute(name));
-
- maker = NameCheckers.objRelationship;
- baseName = maker.baseName();
- name = DuplicateNameResolver.resolve(maker, namingContainer);
- assertEquals(baseName, name);
- namingContainer.addRelationship(new ObjRelationship(name));
-
- name = DuplicateNameResolver.resolve(maker, namingContainer);
- assertEquals(baseName + "1", name);
- namingContainer.addRelationship(new ObjRelationship(name));
-
- maker = NameCheckers.objCallbackMethod;
- baseName = maker.baseName();
- name = DuplicateNameResolver.resolve(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");
-
- QueryDescriptor query = QueryDescriptor.selectQueryDescriptor();
- query.setName("name");
- map.addQueryDescriptor(query);
- checkNameAndOther(map, NameCheckers.query, "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", DuplicateNameResolver.resolve(maker,namingContainer, newName));
- assertEquals("other" + newName, DuplicateNameResolver.resolve(maker,namingContainer, "other" + newName));
- }
-
- @Test
- public void testOverlappingAttributeAndCallbackNames() throws Exception {
- ObjEntity namingContainer = new ObjEntity();
-
- namingContainer.addAttribute(new ObjAttribute("myName"));
- assertEquals("getMyName1", DuplicateNameResolver.resolve(NameCheckers.objCallbackMethod, namingContainer, "getMyName"));
-
- namingContainer.getCallbackMap().getPostAdd().addCallbackMethod("getSecondName");
- assertEquals("SecondName1", DuplicateNameResolver.resolve(NameCheckers.objAttribute, namingContainer, "SecondName"));
- assertEquals("secondName1", DuplicateNameResolver.resolve(NameCheckers.objAttribute, namingContainer, "secondName"));
- assertEquals("SecondName1", DuplicateNameResolver.resolve(NameCheckers.objRelationship, namingContainer, "SecondName"));
- assertEquals("secondName1", DuplicateNameResolver.resolve(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");
- assertEquals("SecondName1", DuplicateNameResolver.resolve(NameCheckers.objAttribute, namingContainer, "SecondName"));
- assertEquals("secondName1", DuplicateNameResolver.resolve(NameCheckers.objAttribute, namingContainer, "secondName"));
- }
-
- @Test
- public void testEmbeddable() {
- DataMap map = new DataMap();
-
- map.addEmbeddable(new Embeddable("name"));
- Assert.assertTrue(NameCheckers.embeddable.isNameInUse(map, "name"));
- assertEquals("name1", DuplicateNameResolver.resolve(NameCheckers.embeddable, map, "name"));
- Assert.assertFalse(NameCheckers.embeddable.isNameInUse(map, "other-name"));
-
- map.setDefaultPackage("package");
- Assert.assertFalse(NameCheckers.embeddable.isNameInUse(map, "name"));
- assertEquals("package.name", DuplicateNameResolver.resolve(NameCheckers.embeddable, map, "name"));
- map.addEmbeddable(new Embeddable("package.name"));
-
- Assert.assertTrue(NameCheckers.embeddable.isNameInUse(map, "name"));
- assertEquals("package.name1", DuplicateNameResolver.resolve(NameCheckers.embeddable, map, "name"));
- Assert.assertFalse(NameCheckers.embeddable.isNameInUse(map, "other-name"));
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-server/src/main/java/org/apache/cayenne/map/CallbackDescriptor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/CallbackDescriptor.java b/cayenne-server/src/main/java/org/apache/cayenne/map/CallbackDescriptor.java
index d76f38c..c1a75f1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/CallbackDescriptor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/CallbackDescriptor.java
@@ -74,7 +74,7 @@ public class CallbackDescriptor implements Serializable {
}
/**
- * moves specified callback method to the specified position
+ * Moves specified callback method to the specified position
*
* @param callbackMethod callbacm method name (should exist)
* @param destinationIndex destinationi index (should be valid)
http://git-wip-us.apache.org/repos/asf/cayenne/blob/38e4e7fd/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationshipDetected.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationshipDetected.java b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationshipDetected.java
deleted file mode 100644
index 8a610e3..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationshipDetected.java
+++ /dev/null
@@ -1,48 +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.map;
-
-
-/**
- * A subclass of {@link DbRelationship} to hold some extra runtime information.
- *
- */
-public class DbRelationshipDetected extends DbRelationship {
-
- private String fkName;
-
- public DbRelationshipDetected(String uniqueRelName) {
- super(uniqueRelName);
- }
-
- /**
- * Set the name of the underlying foreign key. Typically FK_NAME from jdbc metadata.
- */
- public void setFkName(String fkName) {
- this.fkName = fkName;
- }
-
- /**
- * Get the name of the underlying foreign key. Typically FK_NAME from jdbc metadata.
- */
- public String getFkName() {
- return fkName;
- }
-
-}