You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by mg...@apache.org on 2013/06/13 22:15:38 UTC

svn commit: r1492843 - /cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ObjEntityValidator.java

Author: mgentry
Date: Thu Jun 13 20:15:37 2013
New Revision: 1492843

URL: http://svn.apache.org/r1492843
Log:
More fixes for CAY-1813: Missing ObjEntity Attribute Validation with Duplicate DbEntity Columns.  Fixes an NPE on Embeddables and adds better duplicate detection/messages.

Modified:
    cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ObjEntityValidator.java

Modified: cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ObjEntityValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ObjEntityValidator.java?rev=1492843&r1=1492842&r2=1492843&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ObjEntityValidator.java (original)
+++ cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ObjEntityValidator.java Thu Jun 13 20:15:37 2013
@@ -19,13 +19,16 @@
 
 package org.apache.cayenne.project.validator;
 
-import java.util.HashSet;
-import java.util.Set;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.EmbeddedAttribute;
 import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
 import org.apache.cayenne.project.ProjectPath;
 import org.apache.cayenne.util.Util;
 
@@ -47,6 +50,7 @@ public class ObjEntityValidator extends 
         validateClassName(ent, path, validator);
         validateSuperClassName(ent, path, validator);
         validateAttributes(ent, path, validator);
+        validateRelationships(ent, path, validator);
 
         // validate DbEntity presence
         if (ent.getDbEntity() == null && !ent.isAbstract()) {
@@ -112,23 +116,104 @@ public class ObjEntityValidator extends 
         }
     }
 
-
     private void validateAttributes(ObjEntity entity, ProjectPath path, Validator validator) {
-        Set<String> dbAttributeNames = new HashSet<String>();
+        // Map of dbAttributeName:objAttributeName.
+        Map<String,String> dbAttributes = new HashMap<String,String>();
 
         for (ObjAttribute attribute : entity.getAttributes()) {
-            String dbAttributeName = attribute.getDbAttribute().getName();
+            DbAttribute dbAttribute = attribute.getDbAttribute();
+
+            /*
+             * When a dbAttributeName has not been encountered, the
+             * dbAttributeName is added to the map along with the
+             * objAttributeName. This is the original occurrence.
+             *
+             * When a duplicate dbAttributeName is encountered, check to see if
+             * the objAttributeName is NOT null (indicating the first time the
+             * duplicate is encountered) and warn about the original
+             * dbAttributeName (which is a duplication of the current one) and
+             * set the original objAttributeName to null (indicating it has been
+             * processed), then warn about the duplicate, too.
+             */
+
+            // Embleddables do not have DB Attributes.
+            if (attribute instanceof EmbeddedAttribute) {
+                if (dbAttribute != null)
+                    validator.registerWarning("Embeddable (" + attribute.getName() + ") cannot have a DbAttribute mapping", path);
+            }
+            else if (dbAttribute == null) {
+                validator.registerWarning("Attribute (" + attribute.getName() + ") must have a DbAttribute mapping", path);
+            }
+            else {
+                String dbAttributeName = dbAttribute.getName();
+
+                if (Util.isEmptyString(dbAttributeName) == false) {
+                    // Be sure to add the original duplicate if not already processed:
+                    if (dbAttributes.containsKey(dbAttributeName)) {
+                        if (dbAttributes.get(dbAttributeName) != null) {
+                            addAttributeWarning(validator, entity.getName(), dbAttributes.get(dbAttributeName), dbAttributeName, path);
+                            dbAttributes.put(dbAttributeName, null);
+                        }
 
-            if (Util.isEmptyString(dbAttributeName) == false) {
-                if (dbAttributeNames.contains(dbAttributeName)) {
-                    validator.registerWarning("ObjEntity contains duplicate DbAttribute mappings (" + dbAttributeName + ")", path);
+                        // Add the current duplicate:
+                        addAttributeWarning(validator, entity.getName(), attribute.getName(), dbAttributeName, path);
+                    }
+                    else {
+                        // Add the original (not duplicated):
+                        dbAttributes.put(dbAttributeName, attribute.getName());
+                    }
                 }
+            }
+        }
+    }
+
+    private void validateRelationships(ObjEntity entity, ProjectPath path, Validator validator) {
+        // Map of relationshipPath:relationshipName.
+        Map<String,String> dbRelationshipPaths = new HashMap<String,String>();
+
+        for (ObjRelationship relationship : entity.getRelationships()) {
+            String dbRelationshipPath = relationship.getTargetEntityName() + "." + relationship.getDbRelationshipPath();
+
+            /*
+             * When a relationshipPath has not been encountered, the
+             * relationshipPath is added to the map along with the
+             * relationshipName. This is the original occurrence.
+             *
+             * When a duplicate relationshipPath is encountered, check to see if
+             * the relationshipName is NOT null (indicating the first time the
+             * duplicate is encountered) and warn about the original
+             * relationshipPath (which is a duplication of the current one) and
+             * set the original relationshipName to null (indicating it has been
+             * processed), then warn about the duplicate, too.
+             */
+
+            if (Util.isEmptyString(dbRelationshipPath) == false) {
+                if (dbRelationshipPaths.containsKey(dbRelationshipPath)) {
+                    // Be sure to add the original duplicate if not already processed:
+                    if (dbRelationshipPaths.get(dbRelationshipPath) != null) {
+                        addRelationshipWarning(validator, entity.getName(), dbRelationshipPaths.get(dbRelationshipPath), dbRelationshipPath, path);
+                        dbRelationshipPaths.put(dbRelationshipPath, null);
+                    }
 
-                dbAttributeNames.add(dbAttributeName);
+                    // Add the current duplicate:
+                    addRelationshipWarning(validator, entity.getName(), relationship.getName(), dbRelationshipPath, path);
+                }
+                else {
+                    // Add the original (not duplicated):
+                    dbRelationshipPaths.put(dbRelationshipPath, relationship.getName());
+                }
             }
         }
     }
 
+    private void addAttributeWarning(Validator validator, String entityName, String objAttributeName, String dbAttributeName, ProjectPath path) {
+        validator.registerWarning("ObjEntity " + entityName + " contains duplicate DbRelationship mappings (" + objAttributeName + " -> " + dbAttributeName + ")", path);
+    }
+
+    private void addRelationshipWarning(Validator validator, String entityName, String relationshipName, String relationshipPath, ProjectPath path) {
+        validator.registerWarning("ObjEntity " + entityName + " contains duplicate DbRelationship mappings (" + relationshipName + " -> " + relationshipPath + ")", path);
+    }
+
     protected void validateName(ObjEntity entity, ProjectPath path, Validator validator) {
         String name = entity.getName();