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/09/30 18:05:01 UTC
[5/5] cayenne git commit: CAY-2116 Split schema synchronization code
in a separate module
CAY-2116 Split schema synchronization code in a separate module
* more refactoring
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/ad944755
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/ad944755
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/ad944755
Branch: refs/heads/master
Commit: ad9447556dd5e12b5e7f94a517bab1df7f50a5d3
Parents: 2df9f66
Author: Andrus Adamchik <an...@objectstyle.com>
Authored: Fri Sep 30 20:45:47 2016 +0300
Committer: Andrus Adamchik <an...@objectstyle.com>
Committed: Fri Sep 30 20:58:07 2016 +0300
----------------------------------------------------------------------
.../dbsync/merge/CreateTableToModel.java | 24 +-
.../dbsync/merge/EntityMergeSupport.java | 8 +-
.../dbsync/naming/DuplicateNameResolver.java | 68 ++++++
.../cayenne/dbsync/naming/NameChecker.java | 36 +++
.../cayenne/dbsync/naming/NameCheckers.java | 223 +++++++++++++++++++
.../cayenne/dbsync/reverse/db/DbLoader.java | 8 +-
.../reverse/db/ManyToManyCandidateEntity.java | 6 +-
.../naming/DefaultObjectNameGenerator.java | 11 +-
.../naming/LegacyObjectNameGenerator.java | 16 +-
.../dbsync/reverse/naming/NameConverter.java | 154 -------------
.../cayenne/dbsync/naming/NameCheckersTest.java | 204 +++++++++++++++++
.../reverse/naming/NameConverterTest.java | 115 ----------
.../java/org/apache/cayenne/map/ObjEntity.java | 2 +-
.../apache/cayenne/map/naming/NameChecker.java | 36 ---
.../apache/cayenne/map/naming/NameCheckers.java | 221 ------------------
.../cayenne/map/naming/UniqueNameGenerator.java | 91 --------
.../main/java/org/apache/cayenne/util/Util.java | 126 +++++++++--
.../cayenne/map/naming/NameCheckersTest.java | 204 -----------------
.../java/org/apache/cayenne/util/UtilTest.java | 38 ++++
.../cayenne/gen/ClientDataMapArtifact.java | 3 +-
.../org/apache/cayenne/gen/DataMapArtifact.java | 4 +-
.../org/apache/cayenne/gen/DataMapUtils.java | 30 +--
.../org/apache/cayenne/gen/StringUtils.java | 23 +-
.../org/apache/cayenne/gen/StringUtilsTest.java | 49 ++++
.../modeler/action/CreateAttributeAction.java | 10 +-
.../action/CreateCallbackMethodAction.java | 15 +-
.../modeler/action/CreateDataMapAction.java | 6 +-
.../modeler/action/CreateDbEntityAction.java | 6 +-
.../modeler/action/CreateEmbeddableAction.java | 6 +-
.../modeler/action/CreateNodeAction.java | 6 +-
.../modeler/action/CreateObjEntityAction.java | 12 +-
.../modeler/action/CreateProcedureAction.java | 6 +-
.../action/CreateProcedureParameterAction.java | 6 +-
.../action/CreateRelationshipAction.java | 8 +-
.../modeler/action/ImportDataMapAction.java | 8 +-
.../modeler/action/ImportEOModelAction.java | 6 +-
.../modeler/action/NewProjectAction.java | 6 +-
.../cayenne/modeler/action/PasteAction.java | 40 ++--
.../action/ReverseEngineeringAction.java | 8 +-
.../dialog/ResolveDbRelationshipDialog.java | 8 +-
.../modeler/dialog/db/DbLoaderHelper.java | 10 +-
.../cayenne/modeler/dialog/query/QueryType.java | 6 +-
.../cayenne/modeler/editor/CallbackType.java | 32 +--
modeler/cayenne-wocompat/pom.xml | 6 +
.../cayenne/wocompat/EOModelProcessor.java | 39 ++--
45 files changed, 933 insertions(+), 1017 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/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 0997e9b..436a1f5 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,21 +19,22 @@
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.reverse.naming.DefaultObjectNameGenerator;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.dbsync.reverse.naming.NameConverter;
/**
* A {@link MergerToken} to add a {@link DbEntity} to a {@link DataMap}
- *
*/
public class CreateTableToModel extends AbstractToModelToken.Entity {
/**
* className if {@link ObjEntity} should be generated with a
- * special class name.
- * Setting this to <code>null</code>, because by default class name should be generated
+ * special class name.
+ * Setting this to <code>null</code>, because by default class name should be generated
*/
private String objEntityClassName = null; //CayenneDataObject.class.getName();
@@ -53,11 +54,18 @@ public class CreateTableToModel extends AbstractToModelToken.Entity {
}
public void execute(MergerContext mergerContext) {
+ DbEntity dbEntity = getEntity();
+
DataMap map = mergerContext.getDataMap();
- map.addDbEntity(getEntity());
+ map.addDbEntity(dbEntity);
// create a ObjEntity
- String objEntityName = NameConverter.underscoredToJava(getEntity().getName(), true);
+
+ // TODO: proper name generator must be injected
+
+ String objEntityName = new DefaultObjectNameGenerator().createObjEntityName(dbEntity);
+ objEntityName = DuplicateNameResolver.resolve(NameCheckers.objEntity, dbEntity.getDataMap(), objEntityName);
+
// 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;
@@ -77,12 +85,12 @@ public class CreateTableToModel extends AbstractToModelToken.Entity {
objEntity.setClassName(className);
objEntity.setSuperClassName(map.getDefaultSuperclass());
-
+
if (map.isClientSupported()) {
objEntity.setClientClassName(map.getNameWithDefaultClientPackage(objEntity.getName()));
objEntity.setClientSuperClassName(map.getDefaultClientSuperclass());
}
-
+
map.addObjEntity(objEntity);
// presumably there are no other ObjEntities pointing to this DbEntity, so syncing just this one...
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/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 7db68af..e055883 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
@@ -29,9 +29,9 @@ 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.naming.UniqueNameGenerator;
+import org.apache.cayenne.dbsync.naming.DuplicateNameResolver;
import org.apache.cayenne.dbsync.reverse.naming.LegacyObjectNameGenerator;
-import org.apache.cayenne.map.naming.NameCheckers;
+import org.apache.cayenne.dbsync.naming.NameCheckers;
import org.apache.cayenne.dbsync.reverse.naming.ObjectNameGenerator;
import org.apache.cayenne.util.DeleteRuleUpdater;
import org.apache.cayenne.util.EntityMergeListener;
@@ -205,7 +205,7 @@ public class EntityMergeSupport {
private boolean createObjRelationship(ObjEntity entity, DbRelationship dr, String targetEntityName) {
String relationshipName = nameGenerator.createObjRelationshipName(dr);
- relationshipName = UniqueNameGenerator.generate(NameCheckers.objRelationship, entity, relationshipName);
+ relationshipName = DuplicateNameResolver.resolve(NameCheckers.objRelationship, entity, relationshipName);
ObjRelationship or = new ObjRelationship(relationshipName);
or.addDbRelationship(dr);
@@ -279,7 +279,7 @@ public class EntityMergeSupport {
}
private void addMissingAttribute(ObjEntity entity, DbAttribute da) {
- String attrName = UniqueNameGenerator.generate(NameCheckers.objAttribute, entity,
+ String attrName = DuplicateNameResolver.resolve(NameCheckers.objAttribute, entity,
nameGenerator.createObjAttributeName(da));
String type = TypesMapping.getJavaBySqlType(da.getType());
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/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
new file mode 100644
index 0000000..3f55d8f
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/DuplicateNameResolver.java
@@ -0,0 +1,68 @@
+/*****************************************************************
+ * 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/ad944755/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
new file mode 100644
index 0000000..ade1ec5
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameChecker.java
@@ -0,0 +1,36 @@
+/*****************************************************************
+ * 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/ad944755/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
new file mode 100644
index 0000000..fca1734
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/naming/NameCheckers.java
@@ -0,0 +1,223 @@
+/*****************************************************************
+ * 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/ad944755/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 5f233cd..44b9fb3 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
@@ -34,9 +34,9 @@ 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.map.naming.UniqueNameGenerator;
+import org.apache.cayenne.dbsync.naming.DuplicateNameResolver;
import org.apache.cayenne.dbsync.reverse.naming.LegacyObjectNameGenerator;
-import org.apache.cayenne.map.naming.NameCheckers;
+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;
@@ -133,7 +133,7 @@ public class DbLoader {
continue;
}
- String objEntityName = UniqueNameGenerator.generate(NameCheckers.objEntity, map,
+ String objEntityName = DuplicateNameResolver.resolve(NameCheckers.objEntity, map,
nameGenerator.createObjEntityName(dbEntity));
ObjEntity objEntity = new ObjEntity(objEntityName);
@@ -439,7 +439,7 @@ public class DbLoader {
private String generateName(DbEntity entity, ExportedKey key, boolean toMany) {
String forwardPreferredName = nameGenerator.createDbRelationshipName(key, toMany);
- return UniqueNameGenerator.generate(NameCheckers.dbRelationship, entity, forwardPreferredName);
+ return DuplicateNameResolver.resolve(NameCheckers.dbRelationship, entity, forwardPreferredName);
}
private void fireObjEntitiesAddedEvents(Collection<ObjEntity> loadedObjEntities) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/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 06c7d82..85af6a4 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
@@ -21,8 +21,8 @@ package org.apache.cayenne.dbsync.reverse.db;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.map.naming.UniqueNameGenerator;
-import org.apache.cayenne.map.naming.NameCheckers;
+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,7 +113,7 @@ class ManyToManyCandidateEntity {
(short) 1);
ObjRelationship newRelationship = new ObjRelationship();
- newRelationship.setName(UniqueNameGenerator.generate(NameCheckers.objRelationship, srcEntity,
+ newRelationship.setName(DuplicateNameResolver.resolve(NameCheckers.objRelationship, srcEntity,
nameGenerator.createDbRelationshipName(key, true)));
newRelationship.setSourceEntity(srcEntity);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/DefaultObjectNameGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/DefaultObjectNameGenerator.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/DefaultObjectNameGenerator.java
index d299338..a2d2264 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/DefaultObjectNameGenerator.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/DefaultObjectNameGenerator.java
@@ -18,10 +18,11 @@
****************************************************************/
package org.apache.cayenne.dbsync.reverse.naming;
+import org.apache.cayenne.dbsync.reverse.db.ExportedKey;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.dbsync.reverse.db.ExportedKey;
+import org.apache.cayenne.util.Util;
import org.jvnet.inflector.Noun;
import java.util.Locale;
@@ -73,21 +74,21 @@ public class DefaultObjectNameGenerator implements ObjectNameGenerator {
}
}
- return NameConverter.underscoredToJava(name, false);
+ return Util.underscoredToJava(name, false);
}
@Override
public String createObjEntityName(DbEntity dbEntity) {
- return NameConverter.underscoredToJava(dbEntity.getName(), true);
+ return Util.underscoredToJava(dbEntity.getName(), true);
}
@Override
public String createObjAttributeName(DbAttribute attr) {
- return NameConverter.underscoredToJava(attr.getName(), false);
+ return Util.underscoredToJava(attr.getName(), false);
}
@Override
public String createObjRelationshipName(DbRelationship dbRel) {
- return NameConverter.underscoredToJava(dbRel.getName(), false);
+ return Util.underscoredToJava(dbRel.getName(), false);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/LegacyObjectNameGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/LegacyObjectNameGenerator.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/LegacyObjectNameGenerator.java
index 16f7f7a..1c52a6e 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/LegacyObjectNameGenerator.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/LegacyObjectNameGenerator.java
@@ -18,35 +18,37 @@
****************************************************************/
package org.apache.cayenne.dbsync.reverse.naming;
+import org.apache.cayenne.dbsync.reverse.db.ExportedKey;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.dbsync.reverse.db.ExportedKey;
+import org.apache.cayenne.util.Util;
/**
* 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 4.0
*/
public class LegacyObjectNameGenerator implements ObjectNameGenerator {
+
public String createDbRelationshipName(
ExportedKey key,
boolean toMany) {
-
+
String uglyName = (toMany) ? key.getFKTableName() + "_ARRAY" : "to_" + key.getPKTableName();
- return NameConverter.underscoredToJava(uglyName, false);
+ return Util.underscoredToJava(uglyName, false);
}
public String createObjEntityName(DbEntity dbEntity) {
- return NameConverter.underscoredToJava(dbEntity.getName(), true);
+ return Util.underscoredToJava(dbEntity.getName(), true);
}
public String createObjAttributeName(DbAttribute attr) {
- return NameConverter.underscoredToJava(attr.getName(), false);
+ return Util.underscoredToJava(attr.getName(), false);
}
public String createObjRelationshipName(DbRelationship dbRel) {
- return NameConverter.underscoredToJava(dbRel.getName(), false);
+ return Util.underscoredToJava(dbRel.getName(), false);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/NameConverter.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/NameConverter.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/NameConverter.java
deleted file mode 100644
index 63c4dcb..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/naming/NameConverter.java
+++ /dev/null
@@ -1,154 +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.reverse.naming;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/**
- * Utility class to convert from different naming styles to Java convention. For example
- * names like "ABCD_EFG" can be converted to "abcdEfg".
- */
-// TODO: deprecate
-public class NameConverter {
-
- private static final Map<String, String> SPECIAL_CHAR_TO_JAVA_MAPPING = new HashMap<>();
-
- static {
- SPECIAL_CHAR_TO_JAVA_MAPPING.put("#", "pound");
- }
-
- /**
- * Converts a String name to a String following java convention for the static final
- * variables. E.g. "abcXyz" will be converted to "ABC_XYZ".
- */
- // TODO: move to the only user....
- public static String javaToUnderscored(String name) {
- if (name == null) {
- return null;
- }
-
- // clear of non-java chars. While the method name implies that a passed identifier
- // is pure Java, it is used to build pk columns names and such, so extra safety
- // check is a good idea
- name = specialCharsToJava(name);
-
- char charArray[] = name.toCharArray();
- StringBuilder buffer = new StringBuilder();
-
- for (int i = 0; i < charArray.length; i++) {
- if ((Character.isUpperCase(charArray[i])) && (i != 0)) {
-
- char prevChar = charArray[i - 1];
- if ((Character.isLowerCase(prevChar))) {
- buffer.append("_");
- }
- }
-
- buffer.append(Character.toUpperCase(charArray[i]));
- }
-
- return buffer.toString();
- }
-
- /**
- * Converts names like "ABCD_EFG_123" to Java-style names like "abcdEfg123". If
- * <code>capitalize</code> is true, returned name is capitalized (for instance if
- * this is a class name).
- *
- * @since 1.2
- */
- // TODO: migrate users to ObjectNameGenerator
- public static String underscoredToJava(String name, boolean capitalize) {
- StringTokenizer st = new StringTokenizer(name, "_");
- StringBuilder buf = new StringBuilder();
-
- boolean first = true;
- while (st.hasMoreTokens()) {
- String token = st.nextToken();
-
- // clear of non-java chars
- token = specialCharsToJava(token);
-
- int len = token.length();
- if (len == 0) {
- continue;
- }
-
- // sniff mixed case vs. single case styles
- boolean hasLowerCase = false;
- boolean hasUpperCase = false;
- for (int i = 0; i < len && !(hasUpperCase && hasLowerCase); i++) {
- if (Character.isUpperCase(token.charAt(i))) {
- hasUpperCase = true;
- } else if (Character.isLowerCase(token.charAt(i))) {
- hasLowerCase = true;
- }
- }
-
- // if mixed case, preserve it, if all upper, convert to lower
- if (hasUpperCase && !hasLowerCase) {
- token = token.toLowerCase();
- }
-
- if (first) {
- // apply explicit capitalization rules, if this is the first token
- first = false;
- if (capitalize) {
- buf.append(Character.toUpperCase(token.charAt(0)));
- } else {
- buf.append(Character.toLowerCase(token.charAt(0)));
- }
- } else {
- buf.append(Character.toUpperCase(token.charAt(0)));
- }
-
- if (len > 1) {
- buf.append(token.substring(1, len));
- }
- }
- return buf.toString();
- }
-
- /**
- * Replaces special chars with human-readable and Java-id-compatible symbols.
- */
- static String specialCharsToJava(String string) {
- int len = string.length();
- if (len == 0) {
- return string;
- }
-
- StringBuilder buffer = new StringBuilder(len);
- for (int i = 0; i < len; i++) {
-
- char c = string.charAt(i);
- if (Character.isJavaIdentifierPart(c)) {
- buffer.append(c);
- } else {
- Object word = SPECIAL_CHAR_TO_JAVA_MAPPING.get(String.valueOf(c));
- buffer.append(word != null ? word : "_");
- }
- }
-
- return buffer.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/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
new file mode 100644
index 0000000..8131160
--- /dev/null
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/naming/NameCheckersTest.java
@@ -0,0 +1,204 @@
+/*****************************************************************
+ * 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/ad944755/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/naming/NameConverterTest.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/naming/NameConverterTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/naming/NameConverterTest.java
deleted file mode 100644
index 1c52f6e..0000000
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/naming/NameConverterTest.java
+++ /dev/null
@@ -1,115 +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.reverse.naming;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class NameConverterTest {
-
- @Test
- public void testUnderscoredToJava1() throws Exception {
- String expected = "ClassNameIdentifier";
- assertEquals(expected, NameConverter.underscoredToJava(
- "_CLASS_NAME_IDENTIFIER_",
- true));
- }
-
- @Test
- public void testUnderscoredToJava2() throws Exception {
- String expected = "propNameIdentifier123";
- assertEquals(expected, NameConverter.underscoredToJava(
- "_prop_name_Identifier_123",
- false));
- }
-
- @Test
- public void testUnderscoredToJava3() throws Exception {
- String expected = "lastName";
- assertEquals(expected, NameConverter.underscoredToJava("lastName", false));
- }
-
- @Test
- public void testUnderscoredToJava4() throws Exception {
- String expected = "lastName";
- assertEquals(expected, NameConverter.underscoredToJava("LastName", false));
- }
-
- @Test
- public void testUnderscoredToJava5() throws Exception {
- String expected = "LastName";
- assertEquals(expected, NameConverter.underscoredToJava("LastName", true));
- }
-
- @Test
- public void testUnderscoredToJavaSpecialChars() throws Exception {
- assertEquals("ABCpoundXyz", NameConverter.underscoredToJava("ABC#_XYZ", true));
- }
-
- @Test
- public void testJavaToUnderscored1() throws Exception {
- String expected = "LAST_NAME";
- assertEquals(expected, NameConverter.javaToUnderscored("LastName"));
- }
-
- @Test
- public void testJavaToUnderscored2() throws Exception {
- String expected = "A_CLASS";
- assertEquals(expected, NameConverter.javaToUnderscored("aClass"));
- }
-
- @Test
- public void testJavaToUnderscored3() throws Exception {
- String expected = "VAR_A";
- assertEquals(expected, NameConverter.javaToUnderscored("varA"));
- }
-
- @Test
- public void testJavaToUnderscored4() throws Exception {
- String expected = "LAST_NAME";
- assertEquals(expected, NameConverter.javaToUnderscored("LAST_NAME"));
- }
-
- @Test
- public void testJavaToUnderscored5() throws Exception {
- String expected = "ABC_A";
- assertEquals(expected, NameConverter.javaToUnderscored("abc_A"));
- }
-
- @Test
- public void testJavaToUnderscored6() throws Exception {
- String expected = "A123";
- assertEquals(expected, NameConverter.javaToUnderscored("a123"));
- }
-
- @Test
- public void testJavaToUnderscored7() throws Exception {
- String expected = "AB_CDEF";
- assertEquals(expected, NameConverter.javaToUnderscored("abCDEF"));
- }
-
- @Test
- public void testJavaToUnderscored8() throws Exception {
- String expected = "AB_CE";
- assertEquals(expected, NameConverter.javaToUnderscored("abCe"));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-server/src/main/java/org/apache/cayenne/map/ObjEntity.java
----------------------------------------------------------------------
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 de79a6a..81a66ee 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
@@ -677,7 +677,7 @@ public class ObjEntity extends Entity implements ObjEntityListener, Configuratio
// create synthetic attribute
if (attribute == null) {
- attribute = new SyntheticPKObjAttribute(pk.getName());
+ attribute = new SyntheticPKObjAttribute(Util.underscoredToJava(pk.getName(), false));
attribute.setDbAttributePath(pk.getName());
attribute.setType(TypesMapping.getJavaBySqlType(pk.getType()));
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameChecker.java
----------------------------------------------------------------------
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
deleted file mode 100644
index 68fdfd3..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/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.map.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/ad944755/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameCheckers.java
----------------------------------------------------------------------
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
deleted file mode 100644
index 67639d6..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/NameCheckers.java
+++ /dev/null
@@ -1,221 +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.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;
-
-/**
- * @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);
- }
- };
-
- public 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/ad944755/cayenne-server/src/main/java/org/apache/cayenne/map/naming/UniqueNameGenerator.java
----------------------------------------------------------------------
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
deleted file mode 100644
index 2fe6801..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/UniqueNameGenerator.java
+++ /dev/null
@@ -1,91 +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.naming;
-
-import org.apache.cayenne.map.DataMap;
-
-/**
- * @since 4.0
- */
-public class UniqueNameGenerator {
-
- public static final String DEFAULT_PATTERN = "%s%d";
-
- private final NameChecker nameChecker;
-
- private final String pattern;
-
- public UniqueNameGenerator(NameChecker nameChecker, String pattern) {
- this.nameChecker = nameChecker;
- this.pattern = 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) {
- UniqueNameGenerator generator;
- if (checker == NameCheckers.embeddable) {
- generator = new UniqueNameGenerator(NameCheckers.embeddable, pattern) {
- @Override
- public String generate(Object namingContext, String nameBase) {
- return ((DataMap) namingContext).getNameWithDefaultPackage(super.generate(namingContext, nameBase));
- }
- };
- } else {
- generator = new UniqueNameGenerator(checker, pattern);
- }
-
- return generator.generate(context, baseName);
- }
-
- /**
- * Creates a unique name for the new object and constructs this object.
- */
- String generate(Object namingContext) {
- return generate(namingContext, nameChecker.baseName());
- }
-
- 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;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java b/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
index e0f5571..14e5eab 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/Util.java
@@ -19,6 +19,23 @@
package org.apache.cayenne.util;
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.di.AdhocObjectFactory;
+import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
+import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
+import org.apache.cayenne.reflect.ArcProperty;
+import org.apache.cayenne.reflect.AttributeProperty;
+import org.apache.cayenne.reflect.PropertyVisitor;
+import org.apache.cayenne.reflect.ToManyProperty;
+import org.apache.cayenne.reflect.ToOneProperty;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -42,31 +59,19 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.StringTokenizer;
import java.util.regex.Pattern;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.di.AdhocObjectFactory;
-import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
-import org.apache.cayenne.di.spi.DefaultClassLoaderManager;
-import org.apache.cayenne.reflect.ArcProperty;
-import org.apache.cayenne.reflect.AttributeProperty;
-import org.apache.cayenne.reflect.PropertyVisitor;
-import org.apache.cayenne.reflect.ToManyProperty;
-import org.apache.cayenne.reflect.ToOneProperty;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-
/**
* Contains various unorganized static utility methods used across Cayenne.
*/
public class Util {
+ private static final Map<String, String> SPECIAL_CHAR_TO_JAVA_MAPPING = new HashMap<>();
+ static {
+ SPECIAL_CHAR_TO_JAVA_MAPPING.put("#", "pound");
+ }
+
@Deprecated
private static DefaultAdhocObjectFactory objectFactory;
@@ -508,6 +513,91 @@ public class Util {
return objectFactory.getJavaClass(className);
}
+ /**
+ * Converts names like "ABCD_EFG_123" to Java-style names like "abcdEfg123". If
+ * <code>capitalize</code> is true, returned name is capitalized (for instance if
+ * this is a class name).
+ *
+ * @since 4.0
+ */
+ // TODO: trace direct users and switch over to ObjectNameGenerator
+ public static String underscoredToJava(String name, boolean capitalize) {
+ StringTokenizer st = new StringTokenizer(name, "_");
+ StringBuilder buf = new StringBuilder();
+
+ boolean first = true;
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+
+ // clear of non-java chars
+ token = specialCharsToJava(token);
+
+ int len = token.length();
+ if (len == 0) {
+ continue;
+ }
+
+ // sniff mixed case vs. single case styles
+ boolean hasLowerCase = false;
+ boolean hasUpperCase = false;
+ for (int i = 0; i < len && !(hasUpperCase && hasLowerCase); i++) {
+ if (Character.isUpperCase(token.charAt(i))) {
+ hasUpperCase = true;
+ } else if (Character.isLowerCase(token.charAt(i))) {
+ hasLowerCase = true;
+ }
+ }
+
+ // if mixed case, preserve it, if all upper, convert to lower
+ if (hasUpperCase && !hasLowerCase) {
+ token = token.toLowerCase();
+ }
+
+ if (first) {
+ // apply explicit capitalization rules, if this is the first token
+ first = false;
+ if (capitalize) {
+ buf.append(Character.toUpperCase(token.charAt(0)));
+ } else {
+ buf.append(Character.toLowerCase(token.charAt(0)));
+ }
+ } else {
+ buf.append(Character.toUpperCase(token.charAt(0)));
+ }
+
+ if (len > 1) {
+ buf.append(token.substring(1, len));
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Replaces special chars with human-readable and Java-id-compatible symbols.
+ *
+ * @since 4.0
+ */
+ public static String specialCharsToJava(String string) {
+ int len = string.length();
+ if (len == 0) {
+ return string;
+ }
+
+ StringBuilder buffer = new StringBuilder(len);
+ for (int i = 0; i < len; i++) {
+
+ char c = string.charAt(i);
+ if (Character.isJavaIdentifierPart(c)) {
+ buffer.append(c);
+ } else {
+ Object word = SPECIAL_CHAR_TO_JAVA_MAPPING.get(String.valueOf(c));
+ buffer.append(word != null ? word : "_");
+ }
+ }
+
+ return buffer.toString();
+ }
+
static void setReverse(final Persistent sourceObject, String propertyName, final Persistent targetObject) {
ArcProperty property = (ArcProperty) Cayenne.getClassDescriptor(sourceObject).getProperty(propertyName);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-server/src/test/java/org/apache/cayenne/map/naming/NameCheckersTest.java
----------------------------------------------------------------------
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
deleted file mode 100644
index e3e6628..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/map/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.map.naming;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-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;
-
-public class NameCheckersTest {
-
- @Test
- public void testObjEntityAttributes() throws Exception {
- NameCheckers maker = NameCheckers.objAttribute;
- ObjEntity namingContainer = new ObjEntity();
-
- String baseName = maker.baseName();
- String name = UniqueNameGenerator.generate(maker, namingContainer);
- assertEquals(baseName, name);
- namingContainer.addAttribute(new ObjAttribute(name));
-
- name = UniqueNameGenerator.generate(maker, namingContainer);
- assertEquals(baseName + "1", name);
- namingContainer.addAttribute(new ObjAttribute(name));
-
- name = UniqueNameGenerator.generate(maker, namingContainer);
- assertEquals(baseName + "2", name);
- namingContainer.addAttribute(new ObjAttribute(name));
-
- name = UniqueNameGenerator.generate(maker, namingContainer);
- assertEquals(baseName + "3", name);
- namingContainer.addAttribute(new ObjAttribute(name));
-
- maker = NameCheckers.objRelationship;
- baseName = maker.baseName();
- name = UniqueNameGenerator.generate(maker, namingContainer);
- assertEquals(baseName, name);
- namingContainer.addRelationship(new ObjRelationship(name));
-
- name = UniqueNameGenerator.generate(maker, namingContainer);
- assertEquals(baseName + "1", name);
- namingContainer.addRelationship(new ObjRelationship(name));
-
- maker = NameCheckers.objCallbackMethod;
- baseName = maker.baseName();
- name = UniqueNameGenerator.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");
-
- 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", UniqueNameGenerator.generate(maker,namingContainer, newName));
- assertEquals("other" + newName, UniqueNameGenerator.generate(maker,namingContainer, "other" + newName));
- }
-
- @Test
- public void testOverlappingAttributeAndCallbackNames() throws Exception {
- ObjEntity namingContainer = new ObjEntity();
-
- namingContainer.addAttribute(new ObjAttribute("myName"));
- Assert.assertEquals("getMyName1", UniqueNameGenerator.generate(NameCheckers.objCallbackMethod, namingContainer, "getMyName"));
-
- namingContainer.getCallbackMap().getPostAdd().addCallbackMethod("getSecondName");
- Assert.assertEquals("SecondName1", UniqueNameGenerator.generate(NameCheckers.objAttribute, namingContainer, "SecondName"));
- Assert.assertEquals("secondName1", UniqueNameGenerator.generate(NameCheckers.objAttribute, namingContainer, "secondName"));
- Assert.assertEquals("SecondName1", UniqueNameGenerator.generate(NameCheckers.objRelationship, namingContainer, "SecondName"));
- Assert.assertEquals("secondName1", UniqueNameGenerator.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", UniqueNameGenerator.generate(NameCheckers.objAttribute, namingContainer, "SecondName"));
- Assert.assertEquals("secondName1", UniqueNameGenerator.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", UniqueNameGenerator.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", UniqueNameGenerator.generate(NameCheckers.embeddable, map, "name"));
- map.addEmbeddable(new Embeddable("package.name"));
-
- Assert.assertTrue(NameCheckers.embeddable.isNameInUse(map, "name"));
- Assert.assertEquals("package.name1", UniqueNameGenerator.generate(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/ad944755/cayenne-server/src/test/java/org/apache/cayenne/util/UtilTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/util/UtilTest.java b/cayenne-server/src/test/java/org/apache/cayenne/util/UtilTest.java
index 2db6987..eab7371 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/util/UtilTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/util/UtilTest.java
@@ -295,4 +295,42 @@ public class UtilTest {
assertEquals("1...78", Util.prettyTrim("12345678", 6));
}
+ @Test
+ public void testUnderscoredToJava1() throws Exception {
+ String expected = "ClassNameIdentifier";
+ assertEquals(expected, Util.underscoredToJava(
+ "_CLASS_NAME_IDENTIFIER_",
+ true));
+ }
+
+ @Test
+ public void testUnderscoredToJava2() throws Exception {
+ String expected = "propNameIdentifier123";
+ assertEquals(expected, Util.underscoredToJava(
+ "_prop_name_Identifier_123",
+ false));
+ }
+
+ @Test
+ public void testUnderscoredToJava3() throws Exception {
+ String expected = "lastName";
+ assertEquals(expected, Util.underscoredToJava("lastName", false));
+ }
+
+ @Test
+ public void testUnderscoredToJava4() throws Exception {
+ String expected = "lastName";
+ assertEquals(expected, Util.underscoredToJava("LastName", false));
+ }
+
+ @Test
+ public void testUnderscoredToJava5() throws Exception {
+ String expected = "LastName";
+ assertEquals(expected, Util.underscoredToJava("LastName", true));
+ }
+
+ @Test
+ public void testUnderscoredToJavaSpecialChars() throws Exception {
+ assertEquals("ABCpoundXyz", Util.underscoredToJava("ABC#_XYZ", true));
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-tools/src/main/java/org/apache/cayenne/gen/ClientDataMapArtifact.java
----------------------------------------------------------------------
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 d99a577..a9d1dfe 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
@@ -19,7 +19,6 @@
package org.apache.cayenne.gen;
-import org.apache.cayenne.dbsync.reverse.naming.NameConverter;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.QueryDescriptor;
import org.apache.cayenne.util.Util;
@@ -46,6 +45,6 @@ public class ClientDataMapArtifact extends DataMapArtifact {
clientPrefix = "Client_";
}
- return dataMap.getNameWithDefaultClientPackage(NameConverter.underscoredToJava(clientPrefix + dataMap.getName(), true));
+ return dataMap.getNameWithDefaultClientPackage(Util.underscoredToJava(clientPrefix + dataMap.getName(), true));
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapArtifact.java
----------------------------------------------------------------------
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 e01d002..8e60495 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
@@ -19,9 +19,9 @@
package org.apache.cayenne.gen;
-import org.apache.cayenne.dbsync.reverse.naming.NameConverter;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.QueryDescriptor;
+import org.apache.cayenne.util.Util;
import org.apache.velocity.VelocityContext;
import java.util.Collection;
@@ -58,7 +58,7 @@ public class DataMapArtifact implements Artifact {
}
public String getQualifiedClassName() {
- return dataMap.getNameWithDefaultPackage(NameConverter.underscoredToJava(dataMap.getName(), true));
+ return dataMap.getNameWithDefaultPackage(Util.underscoredToJava(dataMap.getName(), true));
}
public Object getObject() {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-tools/src/main/java/org/apache/cayenne/gen/DataMapUtils.java
----------------------------------------------------------------------
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 9d5c75a..a0013cc 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
@@ -19,17 +19,6 @@
package org.apache.cayenne.gen;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionException;
import org.apache.cayenne.exp.ExpressionParameter;
@@ -42,11 +31,22 @@ import org.apache.cayenne.map.ObjRelationship;
import org.apache.cayenne.map.PathComponent;
import org.apache.cayenne.map.QueryDescriptor;
import org.apache.cayenne.map.SelectQueryDescriptor;
-import org.apache.cayenne.dbsync.reverse.naming.NameConverter;
import org.apache.cayenne.query.Ordering;
import org.apache.cayenne.util.CayenneMapEntry;
+import org.apache.cayenne.util.Util;
import org.apache.commons.collections.set.ListOrderedSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
/**
* Attributes and Methods for working with Queries.
*
@@ -64,7 +64,7 @@ public class DataMapUtils {
* @return Method name that perform query.
*/
public String getQueryMethodName(QueryDescriptor query) {
- return NameConverter.underscoredToJava(query.getName(), true);
+ return Util.underscoredToJava(query.getName(), true);
}
/**
@@ -136,7 +136,7 @@ public class DataMapUtils {
Matcher matcher = pattern.matcher(qualifierString);
while (matcher.find()) {
String name = matcher.group();
- result.add(NameConverter.underscoredToJava(name.substring(1), false));
+ result.add(Util.underscoredToJava(name.substring(1), false));
}
return result;
@@ -209,7 +209,7 @@ public class DataMapUtils {
}
for (String name : names) {
- types.put(NameConverter.underscoredToJava(name, false), typeName);
+ types.put(Util.underscoredToJava(name, false), typeName);
}
return types;
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ad944755/cayenne-tools/src/main/java/org/apache/cayenne/gen/StringUtils.java
----------------------------------------------------------------------
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 34ccfb3..5473142 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,6 @@
package org.apache.cayenne.gen;
import org.apache.cayenne.project.validation.NameValidationHelper;
-import org.apache.cayenne.dbsync.reverse.naming.NameConverter;
import org.apache.cayenne.util.Util;
/**
@@ -112,7 +111,27 @@ public class StringUtils {
if (name == null || name.length() == 0)
return name;
- return NameConverter.javaToUnderscored(name);
+ // clear of non-java chars. While the method name implies that a passed identifier
+ // is pure Java, it is used to build pk columns names and such, so extra safety
+ // check is a good idea
+ name = Util.specialCharsToJava(name);
+
+ char charArray[] = name.toCharArray();
+ StringBuilder buffer = new StringBuilder();
+
+ for (int i = 0; i < charArray.length; i++) {
+ if ((Character.isUpperCase(charArray[i])) && (i != 0)) {
+
+ char prevChar = charArray[i - 1];
+ if ((Character.isLowerCase(prevChar))) {
+ buffer.append("_");
+ }
+ }
+
+ buffer.append(Character.toUpperCase(charArray[i]));
+ }
+
+ return buffer.toString();
}
/**