You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2013/04/09 12:51:02 UTC

svn commit: r1465962 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/api/ oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/ oak-core/src/main/java/org/...

Author: jukka
Date: Tue Apr  9 10:51:00 2013
New Revision: 1465962

URL: http://svn.apache.org/r1465962
Log:
OAK-764: Oak error codes

Removed:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidatorException.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/ConflictValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexHookUpdate.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadWriteNamespaceRegistry.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RegistrationEditor.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionHook.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreValidatorProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/FailingValidator.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidatorTest.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java
    jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java
    jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java
    jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/CommitFailedException.java Tue Apr  9 10:51:00 2013
@@ -16,56 +16,48 @@
  */
 package org.apache.jackrabbit.oak.api;
 
-import javax.jcr.RepositoryException;
-
 /**
- * Main exception thrown by methods defined on the {@code ContentSession} interface
- * indicating that committing a given set of changes failed.
+ * Main exception thrown by methods defined on the {@code ContentSession}
+ * interface indicating that committing a given set of changes failed.
  */
 public class CommitFailedException extends Exception {
-    public CommitFailedException() {
+
+    /** Serial version UID */
+    private static final long serialVersionUID = 2727602333350620918L;
+
+    private final String type;
+
+    private final int code;
+
+    public CommitFailedException(
+            String type, int code, String message, Throwable cause) {
+        super(String.format("Oak%s%04d: %s", type, code, message), cause);
+        this.type = type;
+        this.code = code;
+    }
+
+    public CommitFailedException(String type, int code, String message) {
+        this(type, code, message, null);
     }
 
-    public CommitFailedException(String message) {
-        super(message);
+    public boolean hasType(String type) {
+        return this.type.equals(type);
     }
 
-    public CommitFailedException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    public CommitFailedException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Rethrow this exception cast into a {@link RepositoryException}: if the cause
-     * for this exception already is a {@code RepositoryException}, this exception is
-     * wrapped into the actual type of the cause and rethrown. If creating an instance
-     * of the actual type of the cause fails, cause is simply re-thrown.
-     * If the cause for this exception is not a {@code RepositoryException} then  a
-     * new {@code RepositoryException} instance with this {@code CommitFailedException}
-     * is thrown.
-     * @throws RepositoryException
-     */
-    public void throwRepositoryException() throws RepositoryException {
-        Throwable cause = getCause();
-        if (cause instanceof RepositoryException) {
-            RepositoryException e;
-            try {
-                // Try to preserve all parts of the stack trace
-                e = (RepositoryException) cause.getClass().getConstructor().newInstance();
-                e.initCause(this);
-            }
-            catch (Exception ex) {
-                // Fall back to the initial cause on failure
-                e = (RepositoryException) cause;
-            }
-
-            throw e;
-        }
-        else {
-            throw new RepositoryException(this);
-        }
+    public boolean hasCode(int code) {
+        return this.code == code;
     }
+
+    public boolean hasTypeAndCode(String type, int code) {
+        return hasType(type) && hasCode(code);
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java Tue Apr  9 10:51:00 2013
@@ -172,7 +172,9 @@ class KernelNodeStoreBranch extends Abst
             }
         } catch (MicroKernelException e) {
             head = oldRoot;
-            throw new CommitFailedException(e);
+            throw new CommitFailedException(
+                    "Kernel", 1,
+                    "Failed to merge changes to the underlying MicroKernel", e);
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/ConflictValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/ConflictValidator.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/ConflictValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/commit/ConflictValidator.java Tue Apr  9 10:51:00 2013
@@ -16,8 +16,6 @@
  */
 package org.apache.jackrabbit.oak.plugins.commit;
 
-import javax.jcr.InvalidItemStateException;
-
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
@@ -35,6 +33,21 @@ import static org.apache.jackrabbit.oak.
  * @see AnnotatingConflictHandler
  */
 public class ConflictValidator extends DefaultValidator {
+
+    private final ConflictValidator parent;
+
+    private final String name;
+
+    public ConflictValidator() {
+        this.parent = null;
+        this.name = null;
+    }
+
+    private ConflictValidator(ConflictValidator parent, String name) {
+        this.parent = null;
+        this.name = name;
+    }
+
     @Override
     public void propertyAdded(PropertyState after) throws CommitFailedException {
         failOnMergeConflict(after);
@@ -48,27 +61,45 @@ public class ConflictValidator extends D
 
     @Override
     public Validator childNodeAdded(String name, NodeState after) {
-        return this;
+        return new ConflictValidator(this, name);
     }
 
     @Override
     public Validator childNodeChanged(String name, NodeState before, NodeState after) {
-        return this;
+        return new ConflictValidator(this, name);
     }
 
     @Override
     public Validator childNodeDeleted(String name, NodeState before) {
-        return this;
+        return null;
     }
 
-    private static void failOnMergeConflict(PropertyState property) throws CommitFailedException {
+    private void failOnMergeConflict(PropertyState property) throws CommitFailedException {
         if (JcrConstants.JCR_MIXINTYPES.equals(property.getName())) {
             assert property.isArray();
             for (String v : property.getValue(STRINGS)) {
                 if (NodeTypeConstants.MIX_REP_MERGE_CONFLICT.equals(v)) {
-                    throw new CommitFailedException(new InvalidItemStateException("Item has unresolved conflicts"));
+                    throw new CommitFailedException(
+                            "State", 1, "Unresolved conflicts in " + getPath());
                 }
             }
         }
     }
+
+    private String getPath() {
+        if (parent == null) {
+            return "/";
+        } else {
+            return parent.getPath(name);
+        }
+    }
+
+    private String getPath(String name) {
+        if (parent == null) {
+            return "/" + name;
+        } else {
+            return parent.getPath(this.name) + "/" + name;
+        }
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexHookUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexHookUpdate.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexHookUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexHookUpdate.java Tue Apr  9 10:51:00 2013
@@ -135,6 +135,7 @@ class Property2IndexHookUpdate {
             for (String key : modifiedKeys) {
                 if (store.count(state, Collections.singletonList(key), 2) > 1) {
                     throw new CommitFailedException(
+                            "Constraint", 30,
                             "Uniqueness constraint violated for key " + key);
                 }
             }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NameValidator.java Tue Apr  9 10:51:00 2013
@@ -44,7 +44,7 @@ class NameValidator extends DefaultValid
             String prefix = name.substring(0, colon);
             if (prefix.isEmpty() || !prefixes.contains(prefix)) {
                 throw new CommitFailedException(
-                        "Invalid namespace prefix: " + name);
+                        "Name", 1, "Invalid namespace prefix: " + name);
             }
         }
 
@@ -57,14 +57,16 @@ class NameValidator extends DefaultValid
                 i--;
             }
             if (local.charAt(i) != '[') {
-                throw new CommitFailedException("Invalid name index " + name);
+                throw new CommitFailedException(
+                        "Name", 2, "Invalid name index " + name);
             } else {
                 local = local.substring(0, i);
             }
         }
 
         if (!Namespaces.isValidLocalName(local)) {
-            throw new CommitFailedException("Invalid name: " + name);
+            throw new CommitFailedException(
+                    "Name", 3, "Invalid name: " + name);
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidator.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidator.java Tue Apr  9 10:51:00 2013
@@ -46,21 +46,25 @@ class NamespaceValidator extends Default
             return;
         }
         if (map.containsKey(prefix)) {
-            throw new NamespaceValidatorException(
-                    "Namespace mapping already registered", prefix);
+            throw new CommitFailedException(
+                    "Namespace", 1,
+                    "Namespace mapping already registered: " + prefix);
         } else if (Namespaces.isValidPrefix(prefix)) {
             if (after.isArray() || !STRING.equals(after.getType())) {
-                throw new NamespaceValidatorException(
-                        "Invalid namespace mapping", prefix);
+                throw new CommitFailedException(
+                        "Namespace", 2,
+                        "Invalid namespace mapping: " + prefix);
             } else if (prefix.toLowerCase(Locale.ENGLISH).startsWith("xml")) {
-                throw new NamespaceValidatorException(
-                        "XML prefixes are reserved", prefix);
+                throw new CommitFailedException(
+                        "Namespace", 3,
+                        "XML prefixes are reserved: " + prefix);
             } else if (map.containsValue(after.getValue(STRING))) {
                 throw modificationNotAllowed(prefix);
             }
         } else {
-            throw new NamespaceValidatorException(
-                    "Not a valid namespace prefix", prefix);
+            throw new CommitFailedException(
+                    "Namespace", 4,
+                    "Not a valid namespace prefix: " + prefix);
         }
     }
 
@@ -80,9 +84,10 @@ class NamespaceValidator extends Default
         }
     }
 
-    private static NamespaceValidatorException modificationNotAllowed(String prefix) {
-        return new NamespaceValidatorException(
-                "Namespace modification not allowed", prefix);
+    private static CommitFailedException modificationNotAllowed(String prefix) {
+        return new CommitFailedException(
+                "Namespace", 5,
+                "Namespace modification not allowed: " + prefix);
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadWriteNamespaceRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadWriteNamespaceRegistry.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadWriteNamespaceRegistry.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadWriteNamespaceRegistry.java Tue Apr  9 10:51:00 2013
@@ -97,12 +97,15 @@ public abstract class ReadWriteNamespace
             namespaces.setProperty(prefix, uri);
             root.commit();
             refresh();
-        } catch (NamespaceValidatorException e) {
-            throw e.getNamespaceException();
         } catch (CommitFailedException e) {
-            throw new RepositoryException(
+            String message =
                     "Failed to register namespace mapping from "
-                    + prefix + " to " + uri, e);
+                    + prefix + " to " + uri;
+            if (e.hasType("Namespace")) {
+                throw new NamespaceException(message, e);
+            } else {
+                throw new RepositoryException(message, e);
+            }
         }
     }
 
@@ -120,12 +123,13 @@ public abstract class ReadWriteNamespace
             namespaces.removeProperty(prefix);
             root.commit();
             refresh();
-        } catch (NamespaceValidatorException e) {
-            throw e.getNamespaceException();
         } catch (CommitFailedException e) {
-            throw new RepositoryException(
-                    "Failed to unregister namespace mapping for prefix "
-                    + prefix, e);
+            String message = "Failed to unregister namespace mapping for prefix " + prefix;
+            if (e.hasType("Namespace")) {
+                throw new NamespaceException(message, e);
+            } else {
+                throw new RepositoryException(message, e);
+            }
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RegistrationEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RegistrationEditor.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RegistrationEditor.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RegistrationEditor.java Tue Apr  9 10:51:00 2013
@@ -86,6 +86,7 @@ class RegistrationEditor extends Default
         if (nodeTypeName == null
                 || !name.equals(nodeTypeName.getValue(NAME))) {
             throw new CommitFailedException(
+                    "Constraint", 34,
                     "Unexpected " + JCR_NODETYPENAME + " in " + path);
         }
 
@@ -95,6 +96,7 @@ class RegistrationEditor extends Default
             for (String value : supertypes.getValue(NAMES)) {
                 if (!types.hasChildNode(value)) {
                     throw new CommitFailedException(
+                            "Constraint", 35,
                             "Missing supertype " + value + " in " + path);
                 }
             }
@@ -194,6 +196,7 @@ class RegistrationEditor extends Default
             for (String key : requiredTypes.getValue(NAMES)) {
                 if (!types.hasChildNode(key)) {
                     throw new CommitFailedException(
+                            "Constraint", 33,
                             "Unknown required primary type " + key);
                 } else if (!definitions.hasChildNode(key)) {
                     definitions.setNode(key, definition);
@@ -249,6 +252,7 @@ class RegistrationEditor extends Default
                 for (String superName : supertypes.getValue(NAMES)) {
                     if (removedTypes.contains(superName)) {
                         throw new CommitFailedException(
+                                "Constraint", 31,
                                 "Removed type " + superName
                                 + " is still referenced as a supertype of "
                                 + entry.getName());
@@ -267,6 +271,7 @@ class RegistrationEditor extends Default
                         for (String required : requiredTypes.getValue(NAMES)) {
                             if (removedTypes.contains(required)) {
                                 throw new CommitFailedException(
+                                        "Constraint", 32,
                                         "Removed type " + required
                                         + " is still referenced as a required "
                                         + " primary child node type in "

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java Tue Apr  9 10:51:00 2013
@@ -38,7 +38,6 @@ import java.util.Set;
 
 import javax.jcr.PropertyType;
 import javax.jcr.Value;
-import javax.jcr.nodetype.ConstraintViolationException;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
@@ -107,7 +106,7 @@ class TypeEditor extends DefaultEditor {
         if (parent != null
                 && parent.effective.getDefinition(nodeName, names) == null) {
             throw constraintViolation(
-                    "Incorrect node type of child node " + nodeName
+                    1, "Incorrect node type of child node " + nodeName
                     + " with types " + Joiner.on(", ").join(names));
         }
     }
@@ -121,13 +120,13 @@ class TypeEditor extends DefaultEditor {
         Set<String> missing = effective.findMissingMandatoryItems(after);
         if (!missing.isEmpty()) {
             throw constraintViolation(
-                    "Missing mandatory items " + Joiner.on(", ").join(missing));
+                    2, "Missing mandatory items " + Joiner.on(", ").join(missing));
         }
     }
 
-    private CommitFailedException constraintViolation(String message) {
+    private CommitFailedException constraintViolation(int code, String message) {
         return new CommitFailedException(
-                new ConstraintViolationException(getPath() + ": " + message));
+                "Constraint", code, getPath() + ": " + message);
     }
 
     @Override
@@ -135,7 +134,7 @@ class TypeEditor extends DefaultEditor {
         NodeState definition = effective.getDefinition(after);
         if (definition == null) {
             throw constraintViolation(
-                    "No matching property definition found for " + after);
+                    3, "No matching property definition found for " + after);
         }
         checkValueConstraints(definition, after);
     }
@@ -146,7 +145,7 @@ class TypeEditor extends DefaultEditor {
         NodeState definition = effective.getDefinition(after);
         if (definition == null) {
             throw constraintViolation(
-                    "No matching property definition found for " + after);
+                    4, "No matching property definition found for " + after);
         }
         checkValueConstraints(definition, after);
     }
@@ -222,7 +221,7 @@ class TypeEditor extends DefaultEditor {
                 }
             }
         }
-        throw constraintViolation("Value constraint violation in " + property);
+        throw constraintViolation(5, "Value constraint violation in " + property);
     }
 
     /**
@@ -248,13 +247,13 @@ class TypeEditor extends DefaultEditor {
             NodeState type = types.getChildNode(name);
             if (!type.exists()) {
                 throw constraintViolation(
-                        "Primary node type " + name + " does not exist");
+                        6, "Primary node type " + name + " does not exist");
             } else if (getBoolean(type, JCR_ISMIXIN)) {
                 throw constraintViolation(
-                        "Can not use mixin type " + name + " as primary");
+                        7, "Can not use mixin type " + name + " as primary");
             } else if (getBoolean(type, JCR_IS_ABSTRACT)) {
                 throw constraintViolation(
-                        "Can not use abstract type " + name + " as primary");
+                        8, "Can not use abstract type " + name + " as primary");
             }
 
             list.add(type);
@@ -268,13 +267,13 @@ class TypeEditor extends DefaultEditor {
                     NodeState type = types.getChildNode(name);
                     if (!type.exists()) {
                         throw constraintViolation(
-                                "Mixin node type " + name + " does not exist");
+                                9, "Mixin node type " + name + " does not exist");
                     } else if (!getBoolean(type, JCR_ISMIXIN)) {
                         throw constraintViolation(
-                                "Can not use primary type " + name + " as mixin");
+                                10, "Can not use primary type " + name + " as mixin");
                     } else if (getBoolean(type, JCR_IS_ABSTRACT)) {
                         throw constraintViolation(
-                                "Can not use abstract type " + name + " as mixin");
+                                11, "Can not use abstract type " + name + " as mixin");
                     }
 
                     list.add(type);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java Tue Apr  9 10:51:00 2013
@@ -107,10 +107,11 @@ class SegmentNodeStoreBranch extends Abs
                         backoff *= 2;
                     } catch (InterruptedException e) {
                         throw new CommitFailedException(
-                                "Commit was interrupted", e);
+                                "Segment", 1, "Commit was interrupted", e);
                     }
                 } else {
                     throw new CommitFailedException(
+                            "Segment", 2,
                             "System overloaded, try again later");
                 }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionHook.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionHook.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionHook.java Tue Apr  9 10:51:00 2013
@@ -59,7 +59,8 @@ public class VersionHook implements Comm
             after.compareAgainstBaseState(before,
                     new VersionDiff(null, vMgr, builder));
         } catch (UncheckedRepositoryException e) {
-            throw new CommitFailedException(e.getCause());
+            throw new CommitFailedException(
+                    "Version", 1, "Versioning failure", e.getCause());
         }
         return builder.getNodeState();
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java Tue Apr  9 10:51:00 2013
@@ -133,7 +133,7 @@ class AccessControlValidator extends Def
 
     private static void checkIsAccessControlEntry(Tree tree) throws CommitFailedException {
         if (!isAccessControlEntry(tree)) {
-            fail("Access control entry node expected.");
+            throw accessViolation(2, "Access control entry node expected.");
         }
     }
 
@@ -147,22 +147,22 @@ class AccessControlValidator extends Def
                 POLICY_NODE_NAMES :
                 Collections.singleton(REP_POLICY);
         if (!validPolicyNames.contains(policyNode.getName())) {
-            fail("Invalid policy name " + policyNode.getName());
+            throw accessViolation(3, "Invalid policy name " + policyNode.getName());
         }
 
         if (!policyNode.hasProperty(TreeImpl.OAK_CHILD_ORDER)) {
-            fail("Invalid policy node: Order of children is not stable.");
+            throw accessViolation(4, "Invalid policy node: Order of children is not stable.");
         }
     }
 
     private void checkValidAccessControlledNode(Tree accessControlledTree, String requiredMixin) throws CommitFailedException {
         if (AC_NODETYPE_NAMES.contains(TreeUtil.getPrimaryTypeName(accessControlledTree))) {
-            fail("Access control policy within access control content (" + accessControlledTree.getPath() + ')');
+            throw accessViolation(5, "Access control policy within access control content (" + accessControlledTree.getPath() + ')');
         }
 
         String msg = "Isolated policy node. Parent is not of type " + requiredMixin;
         if (!ntMgr.isNodeType(accessControlledTree, requiredMixin)) {
-            fail(msg);
+            throw accessViolation(6, msg);
         }
 
         if (MIX_REP_REPO_ACCESS_CONTROLLABLE.equals(requiredMixin)) {
@@ -173,7 +173,7 @@ class AccessControlValidator extends Def
     private void checkValidAccessControlEntry(Tree aceNode) throws CommitFailedException {
         Tree parent = aceNode.getParent();
         if (parent == null || !NT_REP_ACL.equals(TreeUtil.getPrimaryTypeName(parent))) {
-            fail("Isolated access control entry at " + aceNode.getPath());
+            throw accessViolation(7, "Isolated access control entry at " + aceNode.getPath());
         }
         checkValidPrincipal(TreeUtil.getString(aceNode, REP_PRINCIPAL_NAME));
         checkValidPrivileges(TreeUtil.getStrings(aceNode, REP_PRIVILEGES));
@@ -182,7 +182,7 @@ class AccessControlValidator extends Def
 
     private void checkValidPrincipal(String principalName) throws CommitFailedException {
         if (principalName == null || principalName.isEmpty()) {
-            fail("Missing principal name.");
+            throw accessViolation(8, "Missing principal name.");
         }
         // validity of principal is only a JCR specific contract and will not be
         // enforced on the oak level.
@@ -190,16 +190,16 @@ class AccessControlValidator extends Def
 
     private void checkValidPrivileges(String[] privilegeNames) throws CommitFailedException {
         if (privilegeNames == null || privilegeNames.length == 0) {
-            fail("Missing privileges.");
+            throw accessViolation(9, "Missing privileges.");
         }
         for (String privilegeName : privilegeNames) {
             if (privilegeName == null || !privileges.containsKey(privilegeName)) {
-                fail("Invalid privilege " + privilegeName);
+                throw accessViolation(10, "Invalid privilege " + privilegeName);
             }
 
             Privilege privilege = privileges.get(privilegeName);
             if (privilege.isAbstract()) {
-                fail("Abstract privilege " + privilegeName);
+                throw accessViolation(11, "Abstract privilege " + privilegeName);
             }
         }
     }
@@ -216,7 +216,8 @@ class AccessControlValidator extends Def
         try {
             restrictionProvider.validateRestrictions(path, aceTree);
         } catch (AccessControlException e) {
-            throw new CommitFailedException(e);
+            throw new CommitFailedException(
+                    "Access", 1, "Access control violation", e);
         }
     }
 
@@ -230,11 +231,11 @@ class AccessControlValidator extends Def
 
     private static void checkValidRepoAccessControlled(Tree accessControlledTree) throws CommitFailedException {
         if (!accessControlledTree.isRoot()) {
-            fail("Only root can store repository level policies.");
+            throw accessViolation(12, "Only root can store repository level policies.");
         }
     }
 
-    private static void fail(String msg) throws CommitFailedException {
-        throw new CommitFailedException(new AccessControlException(msg));
+    private static CommitFailedException accessViolation(int code, String message) {
+        return new CommitFailedException("Access", code, message);
     }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreValidatorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreValidatorProvider.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreValidatorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreValidatorProvider.java Tue Apr  9 10:51:00 2013
@@ -34,7 +34,8 @@ public class PermissionStoreValidatorPro
     @Nonnull
     @Override
     public Validator getRootValidator(NodeState before, NodeState after) {
-        FailingValidator validator = new FailingValidator("Attempt to modify permission store.");
+        FailingValidator validator = new FailingValidator(
+                "Constraint", 41, "Attempt to modify permission store.");
         return new SubtreeValidator(validator, JCR_SYSTEM, REP_PERMISSION_STORE);
     }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidator.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidator.java Tue Apr  9 10:51:00 2013
@@ -102,7 +102,9 @@ class PermissionValidator extends Defaul
         if (isVersionstorageTree(child)) {
             child = getVersionHistoryTree(child);
             if (child == null) {
-                throw new CommitFailedException("New version storage node without version history: cannot verify permissions.");
+                throw new CommitFailedException(
+                        "Access", 21,
+                        "New version storage node without version history: cannot verify permissions.");
             }
         }
         return checkPermissions(child, false, Permissions.ADD_NODE);
@@ -124,7 +126,9 @@ class PermissionValidator extends Defaul
         Tree child = checkNotNull(parentBefore.getChild(name));
         if (isVersionstorageTree(child)) {
             // TODO: check again
-            throw new CommitFailedException("Attempt to remove versionstorage node: Fail to verify delete permission.");
+            throw new CommitFailedException(
+                    "Access", 22,
+                    "Attempt to remove versionstorage node: Fail to verify delete permission.");
         }
         return checkPermissions(child, true, Permissions.REMOVE_NODE);
     }
@@ -139,12 +143,12 @@ class PermissionValidator extends Defaul
         long toTest = getPermission(tree, defaultPermission);
         if (Permissions.isRepositoryPermission(toTest)) {
             if (!permissionProvider.isGranted(toTest)) {
-                throw new CommitFailedException(new AccessDeniedException());
+                throw new CommitFailedException("Access", 0, "Access denied");
             }
             return null; // no need for further validation down the subtree
         } else {
             if (!permissionProvider.isGranted(tree, null, toTest)) {
-                throw new CommitFailedException(new AccessDeniedException());
+                throw new CommitFailedException("Access", 0, "Access denied");
             }
             if (noTraverse(toTest)) {
                 return null;
@@ -161,7 +165,7 @@ class PermissionValidator extends Defaul
         if (!NodeStateUtils.isHidden((property.getName()))) {
             long toTest = getPermission(parent, property, defaultPermission);
             if (!permissionProvider.isGranted(parent, property, toTest)) {
-                throw new CommitFailedException(new AccessDeniedException());
+                throw new CommitFailedException("Access", 0, "Access denied");
             }
         }
     }
@@ -243,7 +247,7 @@ class PermissionValidator extends Defaul
                 versionHistory = getVersionHistoryTree(child);
             } else {
                 // TODO:
-                throw new CommitFailedException("unexpected node");
+                throw new CommitFailedException("Misc", 0, "unexpected node");
             }
         }
         return versionHistory;

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java Tue Apr  9 10:51:00 2013
@@ -20,6 +20,8 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
+
+import javax.jcr.AccessDeniedException;
 import javax.jcr.RepositoryException;
 
 import com.google.common.collect.ImmutableMap;
@@ -115,9 +117,8 @@ class PrivilegeDefinitionWriter implemen
             root.commit();
 
         } catch (CommitFailedException e) {
-            Throwable t = e.getCause();
-            if (t instanceof RepositoryException) {
-                throw (RepositoryException) t;
+            if (e.hasType("Access")) {
+                throw new AccessDeniedException(e);
             } else {
                 throw new RepositoryException(e);
             }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java Tue Apr  9 10:51:00 2013
@@ -20,7 +20,6 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import javax.annotation.Nonnull;
-import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
@@ -62,13 +61,17 @@ class PrivilegeValidator extends Default
         if (REP_NEXT.equals(before.getName())) {
             validateNext(PrivilegeBits.getInstance(getPrivilegesTree(rootBefore).getProperty(REP_NEXT)));
         } else {
-            throw new CommitFailedException("Attempt to modify existing privilege definition.");
+            throw new CommitFailedException(
+                    "Constraint", 45,
+                    "Attempt to modify existing privilege definition.");
         }
     }
 
     @Override
     public void propertyDeleted(PropertyState before) throws CommitFailedException {
-        throw new CommitFailedException("Attempt to modify existing privilege definition.");
+        throw new CommitFailedException(
+                "Constraint", 46,
+                "Attempt to modify existing privilege definition.");
     }
 
     @Override
@@ -84,13 +87,13 @@ class PrivilegeValidator extends Default
         // name may not contain reserved namespace prefix
         if (NamespaceConstants.RESERVED_PREFIXES.contains(Text.getNamespacePrefix(name))) {
             String msg = "Failed to register custom privilege: Definition uses reserved namespace: " + name;
-            throw new CommitFailedException(new RepositoryException(msg));
+            throw new CommitFailedException("Privilege", 1, msg);
         }
 
         // primary node type name must be rep:privilege
         Tree tree = new ImmutableTree(ImmutableTree.ParentProvider.UNSUPPORTED, name, after);
         if (!NT_REP_PRIVILEGE.equals(TreeUtil.getPrimaryTypeName(tree))) {
-            throw new CommitFailedException("Privilege definition must have primary node type set to rep:privilege");
+            throw new CommitFailedException("Privilege", 2, "Privilege definition must have primary node type set to rep:privilege");
         }
 
         // additional validation of the definition
@@ -102,19 +105,24 @@ class PrivilegeValidator extends Default
 
     @Override
     public Validator childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException {
-        throw new CommitFailedException("Attempt to modify existing privilege definition " + name);
+        throw new CommitFailedException(
+                "Constraint", 41,
+                "Attempt to modify existing privilege definition " + name);
     }
 
     @Override
     public Validator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
-        throw new CommitFailedException("Attempt to un-register privilege " + name);
+        throw new CommitFailedException(
+                "Constraint", 42,
+                "Attempt to un-register privilege " + name);
     }
 
     //------------------------------------------------------------< private >---
     private void validateNext(PrivilegeBits bits) throws CommitFailedException {
         PrivilegeBits next = PrivilegeBits.getInstance(getPrivilegesTree(rootAfter).getProperty(REP_NEXT));
         if (!next.equals(bits.nextBits())) {
-            throw new CommitFailedException("Next bits not updated.");
+            throw new CommitFailedException(
+                    "Constraint", 43, "Next bits not updated");
         }
     }
 
@@ -122,7 +130,8 @@ class PrivilegeValidator extends Default
     private Tree getPrivilegesTree(Root root) throws CommitFailedException {
         Tree privilegesTree = root.getTree(PRIVILEGES_PATH);
         if (privilegesTree == null) {
-            throw new CommitFailedException("Privilege store not initialized.");
+            throw new CommitFailedException(
+                    "Constraint", 44, "Privilege store not initialized.");
         }
         return privilegesTree;
     }
@@ -144,7 +153,8 @@ class PrivilegeValidator extends Default
     private void validateDefinition(Tree definitionTree) throws CommitFailedException {
         PrivilegeBits newBits = PrivilegeBits.getInstance(definitionTree);
         if (newBits.isEmpty()) {
-            throw new CommitFailedException("PrivilegeBits are missing.");
+            throw new CommitFailedException(
+                    "Constraint", 48, "PrivilegeBits are missing.");
         }
 
         Set<String> privNames = bitsProvider.getPrivilegeNames(newBits);
@@ -154,7 +164,8 @@ class PrivilegeValidator extends Default
         // non-aggregate privilege
         if (declaredNames.isEmpty()) {
             if (!privNames.isEmpty()) {
-                throw new CommitFailedException("PrivilegeBits already in used.");
+                throw new CommitFailedException(
+                        "Constraint", 49, "PrivilegeBits already in used.");
             }
             validateNext(newBits);
             return;
@@ -162,7 +173,8 @@ class PrivilegeValidator extends Default
 
         // aggregation of a single privilege
         if (declaredNames.size() == 1) {
-            throw new CommitFailedException("Singular aggregation is equivalent to existing privilege.");
+            throw new CommitFailedException(
+                    "Constraint", 50, "Singular aggregation is equivalent to existing privilege.");
         }
 
         // aggregation of >1 privileges
@@ -170,13 +182,14 @@ class PrivilegeValidator extends Default
         for (String aggrName : declaredNames) {
             // aggregated privilege not registered
             if (!definitions.containsKey(aggrName)) {
-                throw new CommitFailedException("Declared aggregate '" + aggrName + "' is not a registered privilege.");
+                throw new CommitFailedException(
+                        "Constraint", 51, "Declared aggregate '" + aggrName + "' is not a registered privilege.");
             }
 
             // check for circular aggregation
             if (isCircularAggregation(definition.getName(), aggrName, definitions)) {
                 String msg = "Detected circular aggregation within custom privilege caused by " + aggrName;
-                throw new CommitFailedException(msg);
+                throw new CommitFailedException("Constraint", 52, msg);
             }
         }
 
@@ -190,13 +203,15 @@ class PrivilegeValidator extends Default
             // test for exact same aggregation or aggregation with the same net effect
             if (declaredNames.equals(existingDeclared) || aggregateNames.equals(resolveAggregates(existingDeclared, definitions))) {
                 String msg = "Custom aggregate privilege '" + definition.getName() + "' is already covered by '" + existing.getName() + '\'';
-                throw new CommitFailedException(msg);
+                throw new CommitFailedException("Constraint", 53, msg);
             }
         }
 
         PrivilegeBits aggrBits = bitsProvider.getBits(declaredNames.toArray(new String[declaredNames.size()]));
         if (!newBits.equals(aggrBits)) {
-            throw new CommitFailedException("Invalid privilege bits for aggregated privilege definition.");
+            throw new CommitFailedException(
+                    "Constraint", 53,
+                    "Invalid privilege bits for aggregated privilege definition.");
         }
     }
 
@@ -228,7 +243,9 @@ class PrivilegeValidator extends Default
         for (String name : declared) {
             PrivilegeDefinition d = definitions.get(name);
             if (d == null) {
-                throw new CommitFailedException("Invalid declared aggregate name " + name + ": Unknown privilege.");
+                throw new CommitFailedException(
+                        "Constraint", 47,
+                        "Invalid declared aggregate name " + name + ": Unknown privilege.");
             }
 
             Set<String> names = d.getDeclaredAggregateNames();

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java Tue Apr  9 10:51:00 2013
@@ -18,7 +18,6 @@ package org.apache.jackrabbit.oak.securi
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import javax.jcr.nodetype.ConstraintViolationException;
 
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -70,12 +69,12 @@ class UserValidator extends DefaultValid
         String name = after.getName();
         if (REP_DISABLED.equals(name) && isAdminUser(parentAfter)) {
             String msg = "Admin user cannot be disabled.";
-            fail(msg);
+            throw constraintViolation(20, msg);
         }
 
         if (JcrConstants.JCR_UUID.equals(name) && !isValidUUID(parentAfter, after.getValue(Type.STRING))) {
             String msg = "Invalid jcr:uuid for authorizable " + parentAfter.getName();
-            fail(msg);
+            throw constraintViolation(21, msg);
         }
 
         if (REP_MEMBERS.equals(name)) {
@@ -92,18 +91,18 @@ class UserValidator extends DefaultValid
         String name = before.getName();
         if (REP_PRINCIPAL_NAME.equals(name) || REP_AUTHORIZABLE_ID.equals(name)) {
             String msg = "Authorizable property " + name + " may not be altered after user/group creation.";
-            fail(msg);
+            throw constraintViolation(22, msg);
         } else if (JcrConstants.JCR_UUID.equals(name)) {
             checkNotNull(parentAfter);
             if (!isValidUUID(parentAfter, after.getValue(Type.STRING))) {
                 String msg = "Invalid jcr:uuid for authorizable " + parentAfter.getName();
-                fail(msg);
+                throw constraintViolation(23, msg);
             }
         }
 
         if (isUser(parentBefore) && REP_PASSWORD.equals(name) && PasswordUtility.isPlainTextPassword(after.getValue(Type.STRING))) {
             String msg = "Password may not be plain text.";
-            fail(msg);
+            throw constraintViolation(24, msg);
         }
 
         if (REP_MEMBERS.equals(name)) {
@@ -121,7 +120,7 @@ class UserValidator extends DefaultValid
         String name = before.getName();
         if (REP_PASSWORD.equals(name) || REP_PRINCIPAL_NAME.equals(name) || REP_AUTHORIZABLE_ID.equals(name)) {
             String msg = "Authorizable property " + name + " may not be removed.";
-            fail(msg);
+            throw constraintViolation(25, msg);
         }
     }
 
@@ -136,7 +135,7 @@ class UserValidator extends DefaultValid
             // assert rep:principalName is present (that should actually by covered
             // by node type validator)
             if (TreeUtil.getString(tree, REP_PRINCIPAL_NAME) == null) {
-                fail("Mandatory property rep:principalName missing.");
+                throw constraintViolation(26, "Mandatory property rep:principalName missing.");
             }
         }
         return new UserValidator(null, tree, provider);
@@ -153,7 +152,7 @@ class UserValidator extends DefaultValid
         Tree node = parentBefore.getChild(name);
         if (isAdminUser(node)) {
             String msg = "The admin user cannot be removed.";
-            fail(msg);
+            throw constraintViolation(27, msg);
         }
         return null;
     }
@@ -193,20 +192,20 @@ class UserValidator extends DefaultValid
     private static void assertHierarchy(@Nonnull Tree tree, @Nonnull String pathConstraint) throws CommitFailedException {
         if (!Text.isDescendant(pathConstraint, tree.getPath())) {
             String msg = "Attempt to create user/group outside of configured scope " + pathConstraint;
-            fail(msg);
+            throw constraintViolation(28, msg);
         }
         Tree parent = tree.getParent();
         while (parent != null && !parent.isRoot()) {
             if (!NT_REP_AUTHORIZABLE_FOLDER.equals(TreeUtil.getPrimaryTypeName(parent))) {
                 String msg = "Cannot create user/group: Intermediate folders must be of type rep:AuthorizableFolder.";
-                fail(msg);
+                throw constraintViolation(29, msg);
             }
             parent = parent.getParent();
         }
     }
 
-    private static void fail(@Nonnull String msg) throws CommitFailedException {
-        Exception e = new ConstraintViolationException(msg);
-        throw new CommitFailedException(e);
+    private static CommitFailedException constraintViolation(
+            int code, @Nonnull String message) {
+        return new CommitFailedException("Constraint", code, message);
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/FailingValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/FailingValidator.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/FailingValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/FailingValidator.java Tue Apr  9 10:51:00 2013
@@ -28,63 +28,69 @@ import org.apache.jackrabbit.oak.spi.sta
  */
 public class FailingValidator implements Validator {
 
+    private final String type;
+
+    private final int code;
+
     private final String message;
 
     public FailingValidator() {
-        this("All changes are rejected");
+        this("Misc", 0, "All changes are rejected");
     }
 
-    public FailingValidator(String message) {
+    public FailingValidator(String type, int code, String message) {
+        this.type = type;
+        this.code = code;
         this.message = message;
     }
 
     @Override
     public void enter(NodeState before, NodeState after)
             throws CommitFailedException {
-        throw new CommitFailedException(message);
+        throw new CommitFailedException(type, code, message);
     }
 
     @Override
     public void leave(NodeState before, NodeState after)
             throws CommitFailedException {
-        throw new CommitFailedException(message);
+        throw new CommitFailedException(type, code, message);
     }
 
     @Override
     public void propertyAdded(PropertyState after)
             throws CommitFailedException {
-        throw new CommitFailedException(message);
+        throw new CommitFailedException(type, code, message);
     }
 
     @Override
     public void propertyChanged(PropertyState before, PropertyState after)
             throws CommitFailedException {
-        throw new CommitFailedException(message);
+        throw new CommitFailedException(type, code, message);
     }
 
     @Override
     public void propertyDeleted(PropertyState before)
             throws CommitFailedException {
-        throw new CommitFailedException(message);
+        throw new CommitFailedException(type, code, message);
     }
 
     @Override
     public Validator childNodeAdded(String name, NodeState after)
             throws CommitFailedException {
-        throw new CommitFailedException(message);
+        throw new CommitFailedException(type, code, message);
     }
 
     @Override
     public Validator childNodeChanged(
             String name, NodeState before, NodeState after)
             throws CommitFailedException {
-        throw new CommitFailedException(message);
+        throw new CommitFailedException(type, code, message);
     }
 
     @Override
     public Validator childNodeDeleted(String name, NodeState before)
             throws CommitFailedException {
-        throw new CommitFailedException(message);
+        throw new CommitFailedException(type, code, message);
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java Tue Apr  9 10:51:00 2013
@@ -106,8 +106,8 @@ public class AccessControlValidatorTest 
             fail("Policy node with child node ordering");
         } catch (CommitFailedException e) {
             // success
-            assertTrue(e.getCause() instanceof AccessControlException);
-            assertEquals("Invalid policy node: Order of children is not stable.", e.getCause().getMessage());
+            assertTrue(e.hasType("Access"));
+            assertEquals("OakAccess0004: Invalid policy node: Order of children is not stable.", e.getMessage());
         }
     }
 
@@ -121,7 +121,7 @@ public class AccessControlValidatorTest 
             fail("Only the root node can be made RepoAccessControllable.");
         } catch (CommitFailedException e) {
             // success
-            assertTrue(e.getCause() instanceof AccessControlException);
+            assertTrue(e.hasType("Access"));
         }
     }
 
@@ -135,7 +135,7 @@ public class AccessControlValidatorTest 
             fail("Attempt to add repo-policy with rep:AccessControllable node.");
         } catch (CommitFailedException e) {
             // success
-            assertTrue(e.getCause() instanceof AccessControlException);
+            assertTrue(e.hasType("Access"));
         } finally {
             policy.getTree().remove();
         }
@@ -154,7 +154,7 @@ public class AccessControlValidatorTest 
                 fail("Adding an ACL below access control content should fail");
             } catch (CommitFailedException e) {
                 // success
-                assertTrue(e.getCause() instanceof AccessControlException);
+                assertTrue(e.hasType("Access"));
             } finally {
                 policy.getTree().remove();
             }
@@ -174,7 +174,7 @@ public class AccessControlValidatorTest 
                 fail("Adding an ACL below access control content should fail");
             } catch (CommitFailedException e) {
                 // success
-                assertTrue(e.getCause() instanceof AccessControlException);
+                assertTrue(e.hasType("Access"));
             } finally {
                 policy.getTree().remove();
             }
@@ -194,7 +194,7 @@ public class AccessControlValidatorTest 
                 fail("Adding an ACE below an ACE or restriction should fail");
             } catch (CommitFailedException e) {
                 // success
-                assertTrue(e.getCause() instanceof AccessControlException);
+                assertTrue(e.hasType("Access"));
             } finally {
                 entry.getTree().remove();
             }
@@ -214,7 +214,7 @@ public class AccessControlValidatorTest 
                 fail("Adding an ACE below an ACE or restriction should fail");
             } catch (CommitFailedException e) {
                 // success
-                assertTrue(e.getCause() instanceof AccessControlException);
+                assertTrue(e.hasType("Access"));
             } finally {
                 entry.getTree().remove();
             }
@@ -233,7 +233,7 @@ public class AccessControlValidatorTest 
                 fail("Writing an isolated ACL without the parent being rep:AccessControllable should fail.");
             } catch (CommitFailedException e) {
                 // success
-                assertTrue(e.getCause() instanceof AccessControlException);
+                assertTrue(e.hasType("Access"));
             } finally {
                 // revert pending changes that cannot be saved.
                 policy.getTree().remove();
@@ -254,7 +254,7 @@ public class AccessControlValidatorTest 
                 fail("Writing an isolated ACE should fail.");
             } catch (CommitFailedException e) {
                 // success
-                assertTrue(e.getCause() instanceof AccessControlException);
+                assertTrue(e.hasType("Access"));
             } finally {
                 // revert pending changes that cannot be saved.
                 ace.getTree().remove();
@@ -271,7 +271,7 @@ public class AccessControlValidatorTest 
             fail("Writing an isolated Restriction should fail.");
         } catch (CommitFailedException e) {
             // success
-            assertTrue(e.getCause() instanceof AccessControlException);
+            assertTrue(e.hasType("Access"));
         } finally {
             // revert pending changes that cannot be saved.
             restriction.getTree().remove();
@@ -289,7 +289,7 @@ public class AccessControlValidatorTest 
             fail("Creating an ACE with invalid privilege should fail.");
         } catch (CommitFailedException e) {
             // success
-            assertTrue(e.getCause() instanceof AccessControlException);
+            assertTrue(e.hasType("Access"));
         }
     }
 
@@ -305,7 +305,7 @@ public class AccessControlValidatorTest 
             fail("Creating an ACE with an abstract privilege should fail.");
         } catch (CommitFailedException e) {
             // success
-            assertTrue(e.getCause() instanceof AccessControlException);
+            assertTrue(e.hasType("Access"));
         }
     }
 
@@ -318,7 +318,7 @@ public class AccessControlValidatorTest 
             fail("Creating an unsupported restriction should fail.");
         } catch (CommitFailedException e) {
             // success
-            assertTrue(e.getCause() instanceof AccessControlException);
+            assertTrue(e.hasType("Access"));
         }
     }
 
@@ -331,7 +331,7 @@ public class AccessControlValidatorTest 
             fail("Creating restriction with invalid type should fail.");
         } catch (CommitFailedException e) {
             // success
-            assertTrue(e.getCause() instanceof AccessControlException);
+            assertTrue(e.hasType("Access"));
         }
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidatorTest.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidatorTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidatorTest.java Tue Apr  9 10:51:00 2013
@@ -65,7 +65,7 @@ public class PrivilegeValidatorTest exte
             fail("Missing privilege bits property must be detected.");
         } catch (CommitFailedException e) {
             // success
-            assertEquals("PrivilegeBits are missing.", e.getMessage());
+            assertEquals("OakConstraint0048: PrivilegeBits are missing.", e.getMessage());
         } finally {
             root.refresh();
         }
@@ -80,7 +80,7 @@ public class PrivilegeValidatorTest exte
             fail("Conflicting privilege bits property must be detected.");
         } catch (CommitFailedException e) {
             // success
-            assertEquals("PrivilegeBits already in used.", e.getMessage());
+            assertEquals("OakConstraint0049: PrivilegeBits already in used.", e.getMessage());
         } finally {
             root.refresh();
         }
@@ -98,7 +98,7 @@ public class PrivilegeValidatorTest exte
             fail("Privilege bits don't match the aggregation.");
         } catch (CommitFailedException e) {
             // success
-            assertEquals("Invalid privilege bits for aggregated privilege definition.", e.getMessage());
+            assertEquals("OakConstraint0053: Invalid privilege bits for aggregated privilege definition.", e.getMessage());
         } finally {
             root.refresh();
         }
@@ -116,7 +116,7 @@ public class PrivilegeValidatorTest exte
             fail("Outdated rep:next property must be detected.");
         } catch (CommitFailedException e) {
             // success
-            assertEquals("Next bits not updated.", e.getMessage());
+            assertEquals("OakConstraint0043: Next bits not updated", e.getMessage());
         } finally {
             root.refresh();
         }
@@ -130,7 +130,7 @@ public class PrivilegeValidatorTest exte
             fail("Outdated rep:next property must be detected.");
         } catch (CommitFailedException e) {
             // success
-            assertEquals("Next bits not updated.", e.getMessage());
+            assertEquals("OakConstraint0043: Next bits not updated", e.getMessage());
         } finally {
             root.refresh();
         }
@@ -147,7 +147,7 @@ public class PrivilegeValidatorTest exte
             fail("Aggregation of a single privilege is invalid.");
         } catch (CommitFailedException e) {
             // success
-            assertEquals("Singular aggregation is equivalent to existing privilege.", e.getMessage());
+            assertEquals("OakConstraint0050: Singular aggregation is equivalent to existing privilege.", e.getMessage());
         } finally {
             root.refresh();
         }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java Tue Apr  9 10:51:00 2013
@@ -22,9 +22,16 @@ import java.io.IOException;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
 import javax.jcr.ItemExistsException;
 import javax.jcr.PathNotFoundException;
+import javax.jcr.ReferentialIntegrityException;
 import javax.jcr.RepositoryException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.version.VersionException;
 
 import org.apache.jackrabbit.oak.api.AuthInfo;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -186,7 +193,7 @@ public class SessionDelegate {
         try {
             root.commit();
         } catch (CommitFailedException e) {
-            e.throwRepositoryException();
+            throw newRepositoryException(e);
         }
     }
 
@@ -235,9 +242,8 @@ public class SessionDelegate {
             Root currentRoot = contentSession.getLatestRoot();
             currentRoot.copy(srcPath, destPath);
             currentRoot.commit();
-        }
-        catch (CommitFailedException e) {
-            e.throwRepositoryException();
+        } catch (CommitFailedException e) {
+            throw newRepositoryException(e);
         }
     }
 
@@ -278,7 +284,7 @@ public class SessionDelegate {
                 moveRoot.commit();
             }
         } catch (CommitFailedException e) {
-            e.throwRepositoryException();
+            throw newRepositoryException(e);
         }
     }
 
@@ -309,4 +315,35 @@ public class SessionDelegate {
     private Tree getTree(String path) {
         return root.getTree(path);
     }
+
+    /**
+     * Wraps the given {@link CommitFailedException} instance using the
+     * appropriate {@link RepositoryException} subclass based on the
+     * {@link CommitFailedException#getType() type} of the given exception.
+     *
+     * @param exception typed commit failure exception
+     * @return matching repository exception
+     */
+    private static RepositoryException newRepositoryException(
+            CommitFailedException exception) {
+        checkNotNull(exception);
+        if (exception.hasType("Constraint")) {
+            return new ConstraintViolationException(exception);
+        } else if (exception.hasType("Type")) {
+            return new NoSuchNodeTypeException(exception);
+        } else if (exception.hasType("Access")) {
+            return new AccessDeniedException(exception);
+        } else if (exception.hasType("Integrity")) {
+            return new ReferentialIntegrityException(exception);
+        } else if (exception.hasType("State")) {
+            return new InvalidItemStateException(exception);
+        } else if (exception.hasType("Version")) {
+            return new VersionException(exception);
+        } else if (exception.hasType("Lock")) {
+            return new LockException(exception);
+        } else {
+            return new RepositoryException(exception);
+        }
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java Tue Apr  9 10:51:00 2013
@@ -144,6 +144,7 @@ class LuceneIndexUpdate implements Close
         } catch (IOException e) {
             e.printStackTrace();
             throw new CommitFailedException(
+                    "Lucene", 1,
                     "Failed to update the full text search index", e);
         } finally {
             remove.clear();

Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHook.java Tue Apr  9 10:51:00 2013
@@ -45,7 +45,7 @@ public class SolrCommitHook implements C
             return after;
         } catch (IOException e) {
             throw new CommitFailedException(
-                    "Failed to update the Solr index", e);
+                    "Solr", 1, "Failed to update the Solr index", e);
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHook.java Tue Apr  9 10:51:00 2013
@@ -230,7 +230,7 @@ public class SolrIndexHook implements In
             } catch (Exception e1) {
                 log.warn("An error occurred while rollback-ing too {}", e);
             }
-            throw new CommitFailedException(e);
+            throw new CommitFailedException("Solr", 1, "Index failure", e);
         }
     }
 
@@ -242,7 +242,7 @@ public class SolrIndexHook implements In
             solrInputDocuments.addAll(docsFromState(getPath(), state));
             apply();
         } catch (IOException e) {
-            throw new CommitFailedException(e);
+            throw new CommitFailedException("Solr", 2, "Re-index failure", e);
         }
         return null;
     }

Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java?rev=1465962&r1=1465961&r2=1465962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexUpdate.java Tue Apr  9 10:51:00 2013
@@ -102,10 +102,10 @@ public class SolrIndexUpdate implements 
             OakSolrUtils.commitByPolicy(solrServer,  configuration.getCommitPolicy());
         } catch (IOException e) {
             throw new CommitFailedException(
-                    "Failed to update the full text search index", e);
+                    "Solr", 2, "Failed to update the full text search index", e);
         } catch (SolrServerException e) {
             throw new CommitFailedException(
-                    "Failed to update the full text search index", e);
+                    "Solr", 3, "Failed to update the full text search index", e);
         } finally {
             remove.clear();
             insert.clear();