You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by ol...@apache.org on 2010/02/02 14:08:18 UTC

svn commit: r905616 [6/6] - in /cayenne/main/trunk/framework: cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/event/ cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/ cayenne-jdk1.5-unpublished/src/main/java/org/apach...

Added: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/DbEntityValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/DbEntityValidator.java?rev=905616&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/DbEntityValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/DbEntityValidator.java Tue Feb  2 13:06:56 2010
@@ -0,0 +1,106 @@
+/*****************************************************************
+ *   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.project2.validate;
+
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.util.Util;
+
+
+public class DbEntityValidator  implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        DbEntity ent = (DbEntity) object;
+        ProjectPath path = new ProjectPath(new Object[]{});
+        validateName(ent, path, validator);
+        validateAttributes(ent, path, validator);
+        validatePK(ent, path, validator);
+    }
+
+    /**
+     * Validates the presence of the primary key. A warning is given only if the parent
+     * map also conatins an ObjEntity mapped to this entity, since unmapped primary key
+     * is ok if working with data rows.
+     */
+    protected void validatePK(
+        DbEntity ent,
+        ProjectPath path,
+        ConfigurationValidationVisitor validator) {
+        if (ent.getAttributes().size() > 0
+            && ent.getPrimaryKeys().size() == 0) {
+            DataMap map = ent.getDataMap();
+            if (map != null && map.getMappedEntities(ent).size() > 0) {
+                // there is an objentity, so complain about no pk
+                validator.registerWarning(
+                    "DbEntity \""
+                        + ent.getName()
+                        + "\" has no primary key attributes defined.",
+                    path);
+            }
+        }
+    }
+
+    /**
+     * Tables must have columns.
+     */
+    protected void validateAttributes(
+        DbEntity ent,
+        ProjectPath path,
+        ConfigurationValidationVisitor validator) {
+        if (ent.getAttributes().size() == 0) {
+            // complain about missing attributes
+            validator.registerWarning(
+                "DbEntity \"" + ent.getName() + "\" has no attributes defined.",
+                path);
+        }
+    }
+
+    protected void validateName(
+        DbEntity ent,
+        ProjectPath path,
+        ConfigurationValidationVisitor validator) {
+        String name = ent.getName();
+
+        // Must have name
+        if (Util.isEmptyString(name)) {
+            validator.registerError("Unnamed DbEntity.", path);
+            return;
+        }
+
+        DataMap map = (DataMap) path.getObjectParent();
+        if (map == null) {
+            return;
+        }
+
+        // check for duplicate names in the parent context
+        for (final DbEntity otherEnt : map.getDbEntities()) {
+            if (otherEnt == ent) {
+                continue;
+            }
+
+            if (name.equals(otherEnt.getName())) {
+                validator.registerError(
+                        "Duplicate DbEntity name: " + name + ".",
+                        path);
+                break;
+            }
+        }
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/DbRelationshipValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/DbRelationshipValidator.java?rev=905616&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/DbRelationshipValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/DbRelationshipValidator.java Tue Feb  2 13:06:56 2010
@@ -0,0 +1,101 @@
+/*****************************************************************
+ *   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.project2.validate;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.project.validator.MappingNamesHelper;
+import org.apache.cayenne.util.Util;
+
+public class DbRelationshipValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        DbRelationship rel = (DbRelationship) object;
+
+        ProjectPath path = new ProjectPath(new Object[] {
+                (DataChannelDescriptor) validator.getProject().getRootNode(),
+                rel.getTargetEntity().getDataMap(), rel.getTargetEntity(), rel
+        });
+
+        if (rel.getTargetEntity() == null) {
+            validator.registerWarning("DbRelationship "
+                    + dbRelationshipIdentifier(rel)
+                    + " has no target entity.", path);
+        }
+        else if (rel.getJoins().size() == 0) {
+            validator.registerWarning("DbRelationship "
+                    + dbRelationshipIdentifier(rel)
+                    + " has no joins.", path);
+        }
+        else {
+            // validate joins
+            for (final DbJoin join : rel.getJoins()) {
+                if (join.getSource() == null && join.getTarget() == null) {
+                    validator
+                            .registerWarning(
+                                    "DbRelationship "
+                                            + dbRelationshipIdentifier(rel)
+                                            + " join has no source and target attributes selected.",
+                                    path);
+                }
+                else if (join.getSource() == null) {
+                    validator.registerWarning("DbRelationship "
+                            + dbRelationshipIdentifier(rel)
+                            + " join has no source attribute selected.", path);
+                }
+                else if (join.getTarget() == null) {
+                    validator.registerWarning("DbRelationship "
+                            + dbRelationshipIdentifier(rel)
+                            + " join has no target attribute selected.", path);
+                }
+            }
+        }
+
+        if (Util.isEmptyString(rel.getName())) {
+            validator.registerError("Unnamed DbRelationship.", path);
+        }
+        // check if there are attributes having the same name
+        else if (rel.getSourceEntity().getAttribute(rel.getName()) != null) {
+            validator.registerError("DbRelationship "
+                    + dbRelationshipIdentifier(rel)
+                    + " has the same name as one of DbAttributes", path);
+        }
+        else {
+            MappingNamesHelper helper = MappingNamesHelper.getInstance();
+            String invalidChars = helper.invalidCharsInDbPathComponent(rel.getName());
+
+            if (invalidChars != null) {
+                validator.registerWarning("DbRelationship "
+                        + dbRelationshipIdentifier(rel)
+                        + " name contains invalid characters: "
+                        + invalidChars, path);
+            }
+        }
+    }
+
+    public String dbRelationshipIdentifier(DbRelationship rel) {
+        if (null == rel.getSourceEntity()) {
+            return "<[null source entity]." + rel.getName() + ">";
+        }
+        return "<" + rel.getSourceEntity().getName() + "." + rel.getName() + ">";
+    }
+
+}

Copied: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EJBQLQueryValidator.java (from r905298, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/EJBQLQueryValidator.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EJBQLQueryValidator.java?p2=cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EJBQLQueryValidator.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/EJBQLQueryValidator.java&r1=905298&r2=905616&rev=905616&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/EJBQLQueryValidator.java (original)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EJBQLQueryValidator.java Tue Feb  2 13:06:56 2010
@@ -16,43 +16,47 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-package org.apache.cayenne.project.validator;
+package org.apache.cayenne.project2.validate;
 
 import java.lang.reflect.Field;
 
 import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.ejbql.EJBQLException;
-
+import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.project.ProjectPath;
 import org.apache.cayenne.query.EJBQLQuery;
 
-public class EJBQLQueryValidator extends TreeNodeValidator {
+public class EJBQLQueryValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        EJBQLQuery query = (EJBQLQuery) object;
 
-    // private DataDomain dd;
-    @Override
-    public void validateObject(ProjectPath treeNodePath, Validator validator) {
-        EJBQLQuery query = (EJBQLQuery) treeNodePath.getObject();
-        PositionException message = validateEJBQL(query, treeNodePath
-                .firstInstanceOf(DataDomain.class));
+        ProjectPath path = new ProjectPath(new Object[] {
+                (DataChannelDescriptor) validator.getProject().getRootNode(),
+                query.getDataMap(), query
+        });
+
+        PositionException message = validateEJBQL(query, new EntityResolver(
+                ((DataChannelDescriptor) validator.getProject().getRootNode())
+                        .getDataMaps()));
 
         if (message != null) {
             validator.registerWarning(
                     "EJBQL query " + query.getName() + " has error.",
-                    treeNodePath);
+                    path);
         }
     }
 
-    public PositionException validateEJBQL(EJBQLQuery query, DataDomain dd) {
-
+    public PositionException validateEJBQL(EJBQLQuery query, EntityResolver er) {
         if (query.getEjbqlStatement() != null) {
             PositionException message = null;
 
             EJBQLQuery queryTemp = new EJBQLQuery();
             queryTemp.setEjbqlStatement(query.getEjbqlStatement());
-            
+
             try {
-                queryTemp.getExpression(dd.getEntityResolver());
+                queryTemp.getExpression(er);
             }
             catch (CayenneRuntimeException e) {
                 message = new PositionException();
@@ -66,31 +70,37 @@
                         EJBQLException ejbqlException = (EJBQLException) e;
                         Throwable cause = ejbqlException.getCause();
 
-                        try {
-                            Field tokenField = cause.getClass().getField("currentToken");
-
-                            Object token = tokenField.get(cause);
-                            Field nextTokenField = token.getClass().getField("next");
-                            Object nextToken = nextTokenField.get(token);
-                            Field beginColumnField = nextToken.getClass().getField(
-                                    "beginColumn");
-                            Field beginLineField = nextToken.getClass().getField(
-                                    "beginLine");
-                            Field endColumnField = nextToken.getClass().getField(
-                                    "endColumn");
-                            Field endLineField = nextToken.getClass().getField("endLine");
-                            Field imageField = nextToken.getClass().getField("image");
-
-                            message.setBeginColumn((Integer) beginColumnField
-                                    .get(nextToken));
-                            message.setBeginLine((Integer) beginLineField.get(nextToken));
-                            message.setEndColumn((Integer) endColumnField.get(nextToken));
-                            message.setEndLine((Integer) endLineField.get(nextToken));
-                            message.setImage((String) imageField.get(nextToken));
-                            message.setLength(message.getImage().length());
-                        }
-                        catch (Exception e1) {
-                            throw new CayenneRuntimeException(e1);
+                        if (cause != null) {
+                            try {
+                                Field tokenField = cause.getClass().getField(
+                                        "currentToken");
+
+                                Object token = tokenField.get(cause);
+                                Field nextTokenField = token.getClass().getField("next");
+                                Object nextToken = nextTokenField.get(token);
+                                Field beginColumnField = nextToken.getClass().getField(
+                                        "beginColumn");
+                                Field beginLineField = nextToken.getClass().getField(
+                                        "beginLine");
+                                Field endColumnField = nextToken.getClass().getField(
+                                        "endColumn");
+                                Field endLineField = nextToken.getClass().getField(
+                                        "endLine");
+                                Field imageField = nextToken.getClass().getField("image");
+
+                                message.setBeginColumn((Integer) beginColumnField
+                                        .get(nextToken));
+                                message.setBeginLine((Integer) beginLineField
+                                        .get(nextToken));
+                                message.setEndColumn((Integer) endColumnField
+                                        .get(nextToken));
+                                message.setEndLine((Integer) endLineField.get(nextToken));
+                                message.setImage((String) imageField.get(nextToken));
+                                message.setLength(message.getImage().length());
+                            }
+                            catch (Exception e1) {
+                                throw new CayenneRuntimeException(e1);
+                            }
                         }
 
                     }
@@ -112,7 +122,6 @@
         else {
             return null;
         }
-
     }
 
     public class PositionException {

Added: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EmbeddableAttributeValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EmbeddableAttributeValidator.java?rev=905616&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EmbeddableAttributeValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EmbeddableAttributeValidator.java Tue Feb  2 13:06:56 2010
@@ -0,0 +1,54 @@
+/*****************************************************************
+ *   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.project2.validate;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.map.EmbeddableAttribute;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.util.Util;
+
+public class EmbeddableAttributeValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+
+        EmbeddableAttribute emAttribute = (EmbeddableAttribute) object;
+
+        ProjectPath path = new ProjectPath(new Object[] {
+                (DataChannelDescriptor) validator.getProject().getRootNode(),
+                emAttribute.getEmbeddable().getDataMap(),
+                emAttribute.getEmbeddable(), emAttribute
+        });
+
+        // Must have name
+        if (Util.isEmptyString(emAttribute.getName())) {
+            validator.registerError("Unnamed ObjAttribute.", path);
+        }
+
+        // skip validation of inherited attributes
+        if (path.getObjectParent() != null
+                && path.getObjectParent() != emAttribute.getEmbeddable()) {
+            return;
+        }
+
+        // all attributes must have type
+        if (Util.isEmptyString(emAttribute.getType())) {
+            validator.registerWarning("EmbeddableAttribute has no type.", path);
+        }
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EmbeddableValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EmbeddableValidator.java?rev=905616&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EmbeddableValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/EmbeddableValidator.java Tue Feb  2 13:06:56 2010
@@ -0,0 +1,90 @@
+/*****************************************************************
+ *   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.project2.validate;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.util.Util;
+
+public class EmbeddableValidator implements Validator {
+
+    public void validate(
+            Object object,
+            ConfigurationValidationVisitor configurationValidationVisitor) {
+        Embeddable emb = (Embeddable) object;
+        ProjectPath path = new ProjectPath();
+        validateName(emb, path, configurationValidationVisitor);
+    }
+
+    protected void validateName(
+            Embeddable emb,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
+        String name = emb.getClassName();
+
+        // Must have name
+        if (Util.isEmptyString(name)) {
+            validator.registerError("Unnamed Embeddable.", path);
+            return;
+        }
+
+        DataMap map = emb.getDataMap();
+        if (map == null) {
+            return;
+        }
+
+        // check for duplicate names in the parent context
+        for (Embeddable otherEmb : map.getEmbeddables()) {
+            if (otherEmb == emb) {
+                continue;
+            }
+
+            if (name.equals(otherEmb.getClassName())) {
+                validator.registerError("Duplicate Embeddable name: " + name + ".", path);
+                break;
+            }
+        }
+
+        // check for dupliucates in other DataMaps
+        DataChannelDescriptor domain = (DataChannelDescriptor) validator
+                .getProject()
+                .getRootNode();
+        if (domain != null) {
+            for (DataMap nextMap : domain.getDataMaps()) {
+                if (nextMap == map) {
+                    continue;
+                }
+
+                Embeddable conflictingEmbeddable = nextMap.getEmbeddable(name);
+                if (conflictingEmbeddable != null) {
+
+                    validator
+                            .registerWarning(
+                                    "Duplicate Embeddable name in another DataMap: "
+                                            + name
+                                            + ".",
+                                    path);
+                    break;
+                }
+            }
+        }
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjAttributeValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjAttributeValidator.java?rev=905616&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjAttributeValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjAttributeValidator.java Tue Feb  2 13:06:56 2010
@@ -0,0 +1,130 @@
+/*****************************************************************
+ *   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.project2.validate;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
+import org.apache.cayenne.map.EmbeddedAttribute;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.project.validator.MappingNamesHelper;
+import org.apache.cayenne.util.Util;
+
+public class ObjAttributeValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        ObjAttribute attribute = (ObjAttribute) object;
+
+        ProjectPath path = new ProjectPath(new Object[] {
+                validator.getProject().getRootNode(), attribute.getEntity().getDataMap(),
+                attribute.getEntity(), attribute
+        });
+
+        // Must have name
+        if (Util.isEmptyString(attribute.getName())) {
+            validator.registerError("Unnamed ObjAttribute.", path);
+        }
+        else {
+            MappingNamesHelper helper = MappingNamesHelper.getInstance();
+            String invalidChars = helper.invalidCharsInObjPathComponent(attribute
+                    .getName());
+
+            if (invalidChars != null) {
+                validator.registerWarning(
+                        "ObjAttribute name contains invalid characters: " + invalidChars,
+                        path);
+            }
+            else if (helper.invalidDataObjectProperty(attribute.getName())) {
+                validator.registerWarning("ObjAttribute name is invalid: "
+                        + attribute.getName(), path);
+            }
+        }
+
+        // all attributes must have type
+        if (Util.isEmptyString(attribute.getType())) {
+            validator.registerWarning("ObjAttribute has no type.", path);
+        }
+
+        if (attribute.getEntity() instanceof ObjEntity
+                && ((ObjEntity) attribute.getEntity()).isAbstract()) {
+            // nothing, abstract entity does not have to define a dbAttribute
+        }
+        else if (attribute instanceof EmbeddedAttribute) {
+            Map<String, String> attrOverrides = ((EmbeddedAttribute) attribute)
+                    .getAttributeOverrides();
+            Embeddable emb = ((EmbeddedAttribute) attribute).getEmbeddable();
+            if (emb == null && ((EmbeddedAttribute) attribute).getType() != null) {
+                validator.registerWarning(
+                        "EmbeddedAttribute has incorrect Embeddable.",
+                        path);
+            }
+            else if (emb == null && ((EmbeddedAttribute) attribute).getType() == null) {
+                validator.registerWarning("EmbeddedAttribute has no Embeddable.", path);
+            }
+
+            if (emb != null) {
+                Collection<EmbeddableAttribute> embAttributes = emb.getAttributes();
+
+                Iterator<EmbeddableAttribute> it = embAttributes.iterator();
+                while (it.hasNext()) {
+                    EmbeddableAttribute embAttr = (EmbeddableAttribute) it.next();
+                    String dbAttributeName;
+                    if (attrOverrides.size() > 0
+                            && attrOverrides.containsKey(embAttr.getName())) {
+                        dbAttributeName = attrOverrides.get(embAttr.getName());
+                    }
+                    else {
+                        dbAttributeName = embAttr.getDbAttributeName();
+                    }
+
+                    if (dbAttributeName == "" || dbAttributeName == null) {
+                        validator.registerWarning(
+                                "EmbeddedAttribute has no DbAttribute mapping.",
+                                path);
+                    }
+                    else if (((ObjEntity) attribute.getEntity())
+                            .getDbEntity()
+                            .getAttribute(dbAttributeName) == null) {
+                        validator.registerWarning(
+                                "EmbeddedAttribute has incorrect DbAttribute mapping.",
+                                path);
+                    }
+                }
+            }
+
+        }
+        else if (attribute.getDbAttribute() == null) {
+            validator.registerWarning("ObjAttribute has no DbAttribute mapping.", path);
+        }
+        // can't support generated meaningful attributes for now; besides they don't make
+        // sense.
+        else if (attribute.getDbAttribute().isPrimaryKey()
+                && attribute.getDbAttribute().isGenerated()) {
+            validator.registerWarning("ObjAttribute is mapped to a generated PK: "
+                    + attribute.getDbAttributeName(), path);
+        }
+
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjEntityValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjEntityValidator.java?rev=905616&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjEntityValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjEntityValidator.java Tue Feb  2 13:06:56 2010
@@ -0,0 +1,165 @@
+/*****************************************************************
+ *   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.project2.validate;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.project.validator.MappingNamesHelper;
+import org.apache.cayenne.util.Util;
+
+public class ObjEntityValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        ObjEntity ent = (ObjEntity) object;
+
+        ProjectPath path = new ProjectPath(new Object[] {
+                (DataChannelDescriptor) validator.getProject().getRootNode(),
+                ent.getDataMap(), ent
+        });
+
+        validateName(ent, path, validator);
+        validateClassName(ent, path, validator);
+        validateSuperClassName(ent, path, validator);
+
+        // validate DbEntity presence
+        if (ent.getDbEntity() == null && !ent.isAbstract()) {
+            validator.registerWarning("ObjEntity has no DbEntity mapping.", path);
+        }
+    }
+
+    private void validateClassName(
+            ObjEntity ent,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
+        String className = ent.getClassName();
+
+        // if mapped to default class, ignore...
+        if (Util.isEmptyString(className)) {
+            return;
+        }
+
+        MappingNamesHelper helper = MappingNamesHelper.getInstance();
+        String invalidChars = helper.invalidCharsInJavaClassName(className);
+
+        if (invalidChars != null) {
+            validator.registerWarning(
+                    "ObjEntity Java class contains invalid characters: " + invalidChars,
+                    path);
+        }
+        else if (helper.invalidDataObjectClass(className)) {
+            validator.registerWarning(
+                    "ObjEntity Java class is invalid: " + className,
+                    path);
+        }
+        else if (className.indexOf('.') < 0) {
+            validator.registerWarning(
+                    "Placing Java class in default package is discouraged: " + className,
+                    path);
+        }
+    }
+
+    private void validateSuperClassName(
+            ObjEntity ent,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
+        String superClassName = ent.getSuperClassName();
+
+        if (Util.isEmptyString(superClassName)) {
+            return; // null is Ok
+        }
+
+        MappingNamesHelper helper = MappingNamesHelper.getInstance();
+        String invalidChars = helper.invalidCharsInJavaClassName(superClassName);
+
+        if (invalidChars != null) {
+            validator.registerWarning(
+                    "ObjEntity Java superclass contains invalid characters: "
+                            + invalidChars,
+                    path);
+        }
+        else if (helper.invalidDataObjectClass(superClassName)) {
+            validator.registerWarning("ObjEntity Java superclass is invalid: "
+                    + superClassName, path);
+        }
+
+        DataMap map = ent.getDataMap();
+        if (map == null) {
+            return;
+        }
+    }
+
+    protected void validateName(
+            ObjEntity entity,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
+        String name = entity.getName();
+
+        // Must have name
+        if (Util.isEmptyString(name)) {
+            validator.registerError("Unnamed ObjEntity.", path);
+            return;
+        }
+
+        DataMap map = entity.getDataMap();
+        if (map == null) {
+            return;
+        }
+
+        // check for duplicate names in the parent context
+        for (ObjEntity otherEnt : map.getObjEntities()) {
+            if (otherEnt == entity) {
+                continue;
+            }
+
+            if (name.equals(otherEnt.getName())) {
+                validator.registerError("Duplicate ObjEntity name: " + name + ".", path);
+                break;
+            }
+        }
+
+        // check for dupliucates in other DataMaps
+        DataChannelDescriptor domain = (DataChannelDescriptor) validator
+                .getProject()
+                .getRootNode();
+        if (domain != null) {
+            for (DataMap nextMap : domain.getDataMaps()) {
+                if (nextMap == map) {
+                    continue;
+                }
+
+                ObjEntity conflictingEntity = nextMap.getObjEntity(name);
+                if (conflictingEntity != null) {
+
+                    if (!Util.nullSafeEquals(conflictingEntity.getClassName(), entity
+                            .getClassName())) {
+                        validator.registerWarning(
+                                "Duplicate ObjEntity name in another DataMap: "
+                                        + name
+                                        + ".",
+                                path);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjRelationshipValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjRelationshipValidator.java?rev=905616&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjRelationshipValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ObjRelationshipValidator.java Tue Feb  2 13:06:56 2010
@@ -0,0 +1,139 @@
+/*****************************************************************
+ *   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.project2.validate;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.DeleteRule;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.project.validator.MappingNamesHelper;
+import org.apache.cayenne.util.Util;
+
+public class ObjRelationshipValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        ObjRelationship rel = (ObjRelationship) object;
+
+        ProjectPath path = new ProjectPath(new Object[]{(DataChannelDescriptor)validator.getProject().getRootNode(),
+                rel.getSourceEntity().getDataMap(), 
+                rel.getSourceEntity(), rel});
+        
+        if (Util.isEmptyString(rel.getName())) {
+            validator.registerError("Unnamed ObjRelationship.", path);
+        }
+        // check if there are attributes having the same name
+        else if (rel.getSourceEntity().getAttribute(rel.getName()) != null) {
+            validator.registerWarning("ObjRelationship "
+                    + objRelationshipIdentifier(rel)
+                    + " has the same name as one of ObjAttributes", path);
+        }
+        else {
+            MappingNamesHelper helper = MappingNamesHelper.getInstance();
+            String invalidChars = helper.invalidCharsInObjPathComponent(rel.getName());
+
+            if (invalidChars != null) {
+                validator.registerWarning("ObjRelationship "
+                        + objRelationshipIdentifier(rel)
+                        + " name contains invalid characters: "
+                        + invalidChars, path);
+            }
+            else if (helper.invalidDataObjectProperty(rel.getName())) {
+                validator.registerWarning("ObjRelationship "
+                        + objRelationshipIdentifier(rel)
+                        + " name is invalid.", path);
+            }
+        }
+
+        if (rel.getTargetEntity() == null) {
+            validator.registerWarning("ObjRelationship "
+                    + objRelationshipIdentifier(rel)
+                    + " has no target entity.", path);
+        }
+        else {
+            // check for missing DbRelationship mappings
+            List<DbRelationship> dbRels = rel.getDbRelationships();
+            if (dbRels.size() == 0) {
+                validator.registerWarning("ObjRelationship "
+                        + objRelationshipIdentifier(rel)
+                        + " has no DbRelationship mapping.", path);
+            }
+            else {
+                DbEntity expectedSrc = ((ObjEntity) rel.getSourceEntity()).getDbEntity();
+                DbEntity expectedTarget = ((ObjEntity) rel.getTargetEntity())
+                        .getDbEntity();
+
+                if ((dbRels.get(0)).getSourceEntity() != expectedSrc
+                        || (dbRels.get(dbRels.size() - 1))
+                                .getTargetEntity() != expectedTarget) {
+                    validator.registerWarning("ObjRelationship "
+                            + objRelationshipIdentifier(rel)
+                            + " has incomplete DbRelationship mapping.", path);
+                }
+            }
+        }
+
+        // Disallow a Nullify delete rule where the relationship is toMany and the
+        // foreign key attributes are mandatory.
+        if (rel.isToMany()
+                && !rel.isFlattened()
+                && (rel.getDeleteRule() == DeleteRule.NULLIFY)) {
+            ObjRelationship inverse = rel.getReverseRelationship();
+            if (inverse != null) {
+                DbRelationship firstRel = inverse
+                        .getDbRelationships()
+                        .get(0);
+                Iterator<DbJoin> attributePairIterator = firstRel.getJoins().iterator();
+                // by default, the relation will be check for mandatory.
+                boolean check = true;
+                while (attributePairIterator.hasNext()) {
+                    DbJoin pair = attributePairIterator.next();
+                    if (!pair.getSource().isMandatory()) {
+                        // a field of the fk can be nullable, cancel the check.
+                        check = false;
+                        break;
+                    }
+                }
+                
+                if (check) {
+                    validator
+                            .registerWarning(
+                                    "ObjRelationship "
+                                            + objRelationshipIdentifier(rel)
+                                            + " has a Nullify delete rule and a mandatory reverse relationship ",
+                                    path);
+                }
+            }
+        }
+    }
+
+    public String objRelationshipIdentifier(ObjRelationship rel) {
+        if (null == rel.getSourceEntity()) {
+            return "<[null source entity]." + rel.getName() + ">";
+        }
+        return "<" + rel.getSourceEntity().getName() + "." + rel.getName() + ">";
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureParameterValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureParameterValidator.java?rev=905616&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureParameterValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureParameterValidator.java Tue Feb  2 13:06:56 2010
@@ -0,0 +1,66 @@
+/*****************************************************************
+ *   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.project2.validate;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.dba.TypesMapping;
+import org.apache.cayenne.map.ProcedureParameter;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.util.Util;
+
+public class ProcedureParameterValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+
+        ProcedureParameter parameter = (ProcedureParameter) object;
+
+        ProjectPath path = new ProjectPath(new Object[] {
+                (DataChannelDescriptor) validator.getProject().getRootNode(),
+                parameter.getProcedure().getDataMap(), parameter.getProcedure(),
+                parameter
+        });
+
+        // Must have name
+        if (Util.isEmptyString(parameter.getName())) {
+            validator.registerError("Unnamed ProcedureParameter.", path);
+        }
+
+        // all attributes must have type
+        if (parameter.getType() == TypesMapping.NOT_DEFINED) {
+            validator.registerWarning("ProcedureParameter has no type.", path);
+        }
+
+        // VARCHAR and CHAR attributes must have max length
+        if (parameter.getMaxLength() < 0
+                && (parameter.getType() == java.sql.Types.VARCHAR || parameter.getType() == java.sql.Types.CHAR)) {
+
+            validator.registerWarning(
+                    "Character procedure parameter doesn't have max length.",
+                    path);
+        }
+
+        // all attributes must have type
+        if (parameter.getDirection() <= 0) {
+            validator.registerWarning(
+                    "ProcedureParameter has no direction.",
+                    path);
+        }
+    }
+
+}

Copied: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureQueryValidator.java (from r905298, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ProcedureQueryValidator.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureQueryValidator.java?p2=cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureQueryValidator.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ProcedureQueryValidator.java&r1=905298&r2=905616&rev=905616&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/ProcedureQueryValidator.java (original)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureQueryValidator.java Tue Feb  2 13:06:56 2010
@@ -16,11 +16,9 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
+package org.apache.cayenne.project2.validate;
 
-package org.apache.cayenne.project.validator;
-
-import java.util.Iterator;
-
+import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.Procedure;
 import org.apache.cayenne.project.ProjectPath;
@@ -28,25 +26,24 @@
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.util.Util;
 
-/**
- * Validator for ProcedureQueries.
- * 
- * @since 1.1
- */
-public class ProcedureQueryValidator extends TreeNodeValidator {
-
-    @Override
-    public void validateObject(ProjectPath treeNodePath, Validator validator) {
-        ProcedureQuery query = (ProcedureQuery) treeNodePath.getObject();
+public class ProcedureQueryValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        ProcedureQuery query = (ProcedureQuery) object;
 
-        validateName(query, treeNodePath, validator);
-        validateRoot(query, treeNodePath, validator);
+        ProjectPath path = new ProjectPath(new Object[] {
+                (DataChannelDescriptor) validator.getProject().getRootNode(),
+                query.getDataMap(), query
+        });
+
+        validateName(query, path, validator);
+        validateRoot(query, path, validator);
     }
 
-    protected void validateRoot(
+    private void validateRoot(
             ProcedureQuery query,
             ProjectPath path,
-            Validator validator) {
+            ConfigurationValidationVisitor validator) {
         DataMap map = path.firstInstanceOf(DataMap.class);
         Object root = query.getRoot();
 
@@ -74,7 +71,10 @@
         }
     }
 
-    protected void validateName(Query query, ProjectPath path, Validator validator) {
+    private void validateName(
+            ProcedureQuery query,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
         String name = query.getName();
 
         // Must have name

Added: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureValidator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureValidator.java?rev=905616&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureValidator.java (added)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/ProcedureValidator.java Tue Feb  2 13:06:56 2010
@@ -0,0 +1,81 @@
+/*****************************************************************
+ *   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.project2.validate;
+
+import java.util.List;
+
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.Procedure;
+import org.apache.cayenne.map.ProcedureParameter;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.util.Util;
+
+public class ProcedureValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        Procedure procedure = (Procedure) object;
+
+        ProjectPath path = new ProjectPath(new Object[] {
+                (DataChannelValidator) validator.getProject().getRootNode(),
+                procedure.getDataMap(), procedure
+        });
+
+        validateName(procedure, path, validator);
+
+        // check that return value is present
+        if (procedure.isReturningValue()) {
+            List<ProcedureParameter> parameters = procedure.getCallParameters();
+            if (parameters.size() == 0) {
+                validator.registerWarning(
+                        "Procedure returns a value, but has no parameters.",
+                        path);
+            }
+        }
+    }
+
+    protected void validateName(
+            Procedure procedure,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
+        String name = procedure.getName();
+
+        // Must have name
+        if (Util.isEmptyString(name)) {
+            validator.registerError("Unnamed Procedure.", path);
+            return;
+        }
+
+        DataMap map = (DataMap) path.getObjectParent();
+        if (map == null) {
+            return;
+        }
+
+        // check for duplicate names in the parent context
+        for (final Procedure otherProcedure : map.getProcedures()) {
+            if (otherProcedure == procedure) {
+                continue;
+            }
+
+            if (name.equals(otherProcedure.getName())) {
+                validator.registerError("Duplicate Procedure name: " + name + ".", path);
+                break;
+            }
+        }
+    }
+}

Copied: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/SQLTemplateValidator.java (from r905298, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/SQLTemplateValidator.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/SQLTemplateValidator.java?p2=cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/SQLTemplateValidator.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/SQLTemplateValidator.java&r1=905298&r2=905616&rev=905616&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/SQLTemplateValidator.java (original)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/SQLTemplateValidator.java Tue Feb  2 13:06:56 2010
@@ -16,38 +16,35 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
+package org.apache.cayenne.project2.validate;
 
-package org.apache.cayenne.project.validator;
-
-import java.util.Iterator;
-
+import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.project.ProjectPath;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLTemplate;
 import org.apache.cayenne.util.Util;
 
-/**
- * Validator for SQLTemplate queries.
- * 
- * @since 1.1
- */
-public class SQLTemplateValidator extends TreeNodeValidator {
-
-    @Override
-    public void validateObject(ProjectPath treeNodePath, Validator validator) {
-        SQLTemplate query = (SQLTemplate) treeNodePath.getObject();
-
-        validateName(query, treeNodePath, validator);
-        validateRoot(query, treeNodePath, validator);
-        validateDefaultSQL(query, treeNodePath, validator);
+public class SQLTemplateValidator implements Validator {
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        SQLTemplate query = (SQLTemplate) object;
+
+        ProjectPath path = new ProjectPath(new Object[] {
+                (DataChannelDescriptor) validator.getProject().getRootNode(),
+                query.getDataMap(), query
+        });
+
+        validateName(query, path, validator);
+        validateRoot(query, path, validator);
+        validateDefaultSQL(query, path, validator);
     }
 
-    protected void validateDefaultSQL(
+    private void validateDefaultSQL(
             SQLTemplate query,
             ProjectPath path,
-            Validator validator) {
-
+            ConfigurationValidationVisitor validator) {
+        
         if (Util.isEmptyString(query.getDefaultTemplate())) {
             // see if there is at least one adapter-specific template...
 
@@ -61,14 +58,20 @@
         }
     }
 
-    protected void validateRoot(SQLTemplate query, ProjectPath path, Validator validator) {
+    private void validateRoot(
+            SQLTemplate query,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
         DataMap map = path.firstInstanceOf(DataMap.class);
         if (query.getRoot() == null && map != null) {
             validator.registerWarning("Query has no root", path);
         }
     }
 
-    protected void validateName(Query query, ProjectPath path, Validator validator) {
+    private void validateName(
+            SQLTemplate query,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
         String name = query.getName();
 
         // Must have name

Copied: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/SelectQueryValidator.java (from r905298, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/SelectQueryValidator.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/SelectQueryValidator.java?p2=cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/SelectQueryValidator.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/SelectQueryValidator.java&r1=905298&r2=905616&rev=905616&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/validator/SelectQueryValidator.java (original)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/SelectQueryValidator.java Tue Feb  2 13:06:56 2010
@@ -16,15 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-
-package org.apache.cayenne.project.validator;
-
-import java.util.Iterator;
+package org.apache.cayenne.project2.validate;
 
 import org.apache.cayenne.access.QueryEngine;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionException;
-import org.apache.cayenne.exp.TraversalHelper;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.Entity;
 import org.apache.cayenne.project.ProjectPath;
@@ -34,43 +30,67 @@
 import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.util.Util;
 
-/**
- * Validator for SelectQueries.
- * 
- * @since 1.1
- */
-public class SelectQueryValidator extends TreeNodeValidator {
-
-    @Override
-    public void validateObject(ProjectPath treeNodePath, Validator validator) {
-        SelectQuery query = (SelectQuery) treeNodePath.getObject();
 
-        validateName(query, treeNodePath, validator);
+public class SelectQueryValidator  implements Validator{
+
+    public void validate(Object object, ConfigurationValidationVisitor validator) {
+        SelectQuery query = (SelectQuery) object;
+        
+        ProjectPath path = new ProjectPath(new Object[] {
+                (DataChannelDescriptor) validator.getProject().getRootNode(),
+                query.getDataMap(), query
+        });
+
+        validateName(query, path, validator);
 
         // Resolve root to Entity for further validation
-        Entity root = validateRoot(query, treeNodePath, validator);
+        Entity root = validateRoot(query, path, validator);
 
         // validate path-based parts
         if (root != null) {
-            validateQualifier(root, query.getQualifier(), treeNodePath, validator);
+            validateQualifier(root, query.getQualifier(), path, validator);
 
             for (final Ordering ordering : query.getOrderings()) {
                 validateOrdering(
                         root,
                         ordering,
-                        treeNodePath,
+                        path,
                         validator);
             }
 
             if (query.getPrefetchTree() != null) {
                 for (final PrefetchTreeNode prefetchTreeNode : query.getPrefetchTree().nonPhantomNodes()) {
-                    validatePrefetch(root, prefetchTreeNode.getPath(), treeNodePath, validator);
+                    validatePrefetch(root, prefetchTreeNode.getPath(), path, validator);
                 }
             }
         }
     }
 
-    protected Entity validateRoot(SelectQuery query, ProjectPath path, Validator validator) {
+    private void validatePrefetch(
+            Entity root,
+            String path,
+            ProjectPath path2,
+            ConfigurationValidationVisitor validator) {
+    }
+
+    private void validateOrdering(
+            Entity root,
+            Ordering ordering,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
+    }
+
+    private void validateQualifier(
+            Entity root,
+            Expression qualifier,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
+    }
+
+    private Entity validateRoot(
+            SelectQuery query,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
         DataMap map = path.firstInstanceOf(DataMap.class);
         if (query.getRoot() == null && map != null) {
             validator.registerWarning("Query has no root", path);
@@ -109,7 +129,10 @@
         return null;
     }
 
-    protected void validateName(Query query, ProjectPath path, Validator validator) {
+    private void validateName(
+            SelectQuery query,
+            ProjectPath path,
+            ConfigurationValidationVisitor validator) {
         String name = query.getName();
 
         // Must have name
@@ -137,94 +160,4 @@
         }
     }
 
-    protected void validateQualifier(
-            Entity entity,
-            Expression qualifier,
-            ProjectPath path,
-            Validator validator) {
-
-        try {
-            testExpression(entity, qualifier);
-        }
-        catch (ExpressionException e) {
-            validator.registerWarning(buildValidationMessage(
-                    e,
-                    "Invalid path in qualifier"), path);
-        }
-    }
-
-    protected void validateOrdering(
-            Entity entity,
-            Ordering ordering,
-            ProjectPath path,
-            Validator validator) {
-
-        if (ordering == null) {
-            return;
-        }
-
-        try {
-            testExpression(entity, ordering.getSortSpec());
-        }
-        catch (ExpressionException e) {
-            validator
-                    .registerWarning(buildValidationMessage(e, "Invalid ordering"), path);
-        }
-    }
-
-    protected void validatePrefetch(
-            Entity entity,
-            String prefetch,
-            ProjectPath path,
-            Validator validator) {
-
-        if (prefetch == null) {
-            return;
-        }
-
-        try {
-            testExpression(entity, Expression.fromString(prefetch));
-        }
-        catch (ExpressionException e) {
-            validator
-                    .registerWarning(buildValidationMessage(e, "Invalid prefetch"), path);
-        }
-    }
-
-    private void testExpression(Entity rootEntity, Expression exp)
-            throws ExpressionException {
-
-        if (exp != null) {
-            exp.traverse(new EntityExpressionValidator(rootEntity));
-        }
-    }
-
-    private String buildValidationMessage(ExpressionException e, String prefix) {
-        StringBuilder buffer = new StringBuilder(prefix);
-        if (e.getExpressionString() != null) {
-            buffer.append(": '").append(e.getExpressionString()).append("'");
-        }
-
-        buffer.append(".");
-        return buffer.toString();
-    }
-
-    final class EntityExpressionValidator extends TraversalHelper {
-
-        Entity rootEntity;
-
-        EntityExpressionValidator(Entity rootEntity) {
-            this.rootEntity = rootEntity;
-        }
-
-        @Override
-        public void startNode(Expression node, Expression parentNode) {
-            // check if path nodes are compatibe with root entity
-            if (node.getType() == Expression.OBJ_PATH
-                    || node.getType() == Expression.DB_PATH) {
-                // this will throw an exception if the path is invalid
-                node.evaluate(rootEntity);
-            }
-        }
-    }
 }

Copied: cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/Validator.java (from r905298, cayenne/main/trunk/framework/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/event/DomainDisplayEventTest.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/Validator.java?p2=cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/Validator.java&p1=cayenne/main/trunk/framework/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/event/DomainDisplayEventTest.java&r1=905298&r2=905616&rev=905616&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/test/java/org/apache/cayenne/modeler/event/DomainDisplayEventTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-project-unpublished/src/main/java/org/apache/cayenne/project2/validate/Validator.java Tue Feb  2 13:06:56 2010
@@ -16,22 +16,9 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
+package org.apache.cayenne.project2.validate;
 
-package org.apache.cayenne.modeler.event;
-
-import junit.framework.TestCase;
-
-import org.apache.cayenne.access.DataDomain;
-
-/**
- */
-public class DomainDisplayEventTest extends TestCase {
-
-	public void testDomain() throws Exception {
-		DataDomain d = new DataDomain("abc");
-		DomainDisplayEvent e = new DomainDisplayEvent(new Object(), d);
-		assertSame(d, e.getDomain());
-	}
 
+public interface Validator {
+    public void validate(Object object, ConfigurationValidationVisitor configurationValidationVisitor);
 }
-