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 2012/06/01 10:13:31 UTC
svn commit: r1345006 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/name/
main/java/org/apache/jackrabbit/oak/plugins/type/
main/java/org/apache/jackrabbit/oak/spi/commit/
test/java/org/apache/jackrabbit/oak/spi/co...
Author: jukka
Date: Fri Jun 1 08:13:30 2012
New Revision: 1345006
URL: http://svn.apache.org/viewvc?rev=1345006&view=rev
Log:
OAK-125: Improved namespace registry
Add a validator for the /jcr:system/jcr:namespaces tree.
Restore the Validator return value in childNodeDeleted as it makes NamespaceValidator easier to write.
Added some utility classes and tests for the validator infrastructure.
Added:
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/NamespaceValidatorProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/DefaultValidator.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/FailingValidator.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidator.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/commit/
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidatorTest.java
Modified:
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/type/TypeValidator.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CompositeValidator.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/ValidatingCommitHook.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/Validator.java
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=1345006&r1=1345005&r2=1345006&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 Fri Jun 1 08:13:30 2012
@@ -102,8 +102,8 @@ class NameValidator implements Validator
}
@Override
- public void childNodeDeleted(String name, NodeState before) {
- // do nothing
+ public Validator childNodeDeleted(String name, NodeState before) {
+ return null;
}
}
Added: 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=1345006&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidator.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidator.java Fri Jun 1 08:13:30 2012
@@ -0,0 +1,72 @@
+/*
+ * 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.jackrabbit.oak.plugins.name;
+
+import java.util.Map;
+
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.commit.DefaultValidator;
+
+class NamespaceValidator extends DefaultValidator {
+
+ private final Map<String, String> map;
+
+ public NamespaceValidator(Map<String, String> map) {
+ this.map = map;
+ }
+
+ //-----------------------------------------------------< NodeValidator >--
+
+ @Override
+ public void propertyAdded(PropertyState after)
+ throws CommitFailedException {
+ String prefix = after.getName();
+ if (map.containsKey(prefix)) {
+ throw new CommitFailedException(
+ "Namespace mapping already registered: " + prefix);
+ } else if (Namespaces.isValidPrefix(prefix)) {
+ if (after.isArray()
+ || after.getValue().getType() != PropertyType.STRING) {
+ throw new CommitFailedException(
+ "Invalid namespace mapping: " + prefix);
+ }
+
+ }
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after)
+ throws CommitFailedException {
+ if (map.containsKey(after.getName())) {
+ throw new CommitFailedException(
+ "Namespace modification not allowed: " + after.getName());
+ }
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before)
+ throws CommitFailedException {
+ if (map.containsKey(before.getName())) {
+ throw new CommitFailedException(
+ "Namespace removal not allowed: " + before.getName());
+ }
+ }
+
+}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidatorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidatorProvider.java?rev=1345006&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidatorProvider.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceValidatorProvider.java Fri Jun 1 08:13:30 2012
@@ -0,0 +1,45 @@
+/*
+ * 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.jackrabbit.oak.plugins.name;
+
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.spi.commit.SubtreeValidator;
+import org.apache.jackrabbit.oak.spi.commit.Validator;
+import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Validator service that checks that all node and property names as well
+ * as any name values are syntactically valid and that any namespace prefixes
+ * are properly registered.
+ */
+@Component
+@Service(ValidatorProvider.class)
+public class NamespaceValidatorProvider implements ValidatorProvider {
+
+ @Override
+ public Validator getRootValidator(NodeState before, NodeState after) {
+ Map<String, String> map = Namespaces.getNamespaceMap(before);
+ Validator validator =
+ new NamespaceValidator(map);
+ return new SubtreeValidator(validator, "jcr:system", "jcr:namespaces");
+ }
+
+}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidator.java?rev=1345006&r1=1345005&r2=1345006&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidator.java Fri Jun 1 08:13:30 2012
@@ -91,8 +91,9 @@ class TypeValidator implements Validator
}
@Override
- public void childNodeDeleted(String name, NodeState before) {
+ public Validator childNodeDeleted(String name, NodeState before) {
// TODO: validate removed child node
+ return null;
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CompositeValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CompositeValidator.java?rev=1345006&r1=1345005&r2=1345006&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CompositeValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CompositeValidator.java Fri Jun 1 08:13:30 2012
@@ -44,7 +44,6 @@ public class CompositeValidator implemen
@Override
public void propertyChanged(PropertyState before, PropertyState after)
throws CommitFailedException {
-
for (Validator validator : validators) {
validator.propertyChanged(before, after);
}
@@ -61,26 +60,48 @@ public class CompositeValidator implemen
public Validator childNodeAdded(String name, NodeState after) throws CommitFailedException {
List<Validator> childValidators = new ArrayList<Validator>(validators.size());
for (Validator validator : validators) {
- childValidators.add(
- validator.childNodeAdded(name, after));
+ Validator child = validator.childNodeAdded(name, after);
+ if (child != null) {
+ childValidators.add(child);
+ }
+ }
+ if (!childValidators.isEmpty()) {
+ return new CompositeValidator(childValidators);
+ } else {
+ return null;
}
- return new CompositeValidator(childValidators);
}
@Override
public Validator childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException {
List<Validator> childValidators = new ArrayList<Validator>(validators.size());
for (Validator validator : validators) {
- childValidators.add(
- validator.childNodeChanged(name, before, after));
+ Validator child = validator.childNodeChanged(name, before, after);
+ if (child != null) {
+ childValidators.add(child);
+ }
+ }
+ if (!childValidators.isEmpty()) {
+ return new CompositeValidator(childValidators);
+ } else {
+ return null;
}
- return new CompositeValidator(childValidators);
}
@Override
- public void childNodeDeleted(String name, NodeState before) throws CommitFailedException {
+ public Validator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
+ List<Validator> childValidators = new ArrayList<Validator>(validators.size());
for (Validator validator : validators) {
- validator.childNodeDeleted(name, before);
+ Validator child = validator.childNodeDeleted(name, before);
+ if (child != null) {
+ childValidators.add(child);
+ }
+ }
+ if (!childValidators.isEmpty()) {
+ return new CompositeValidator(childValidators);
+ } else {
+ return null;
}
}
+
}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/DefaultValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/DefaultValidator.java?rev=1345006&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/DefaultValidator.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/DefaultValidator.java Fri Jun 1 08:13:30 2012
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.spi.commit;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Validator that does nothing by default and doesn't recurse into subtrees.
+ * Useful as a sentinel or as a base class for more complex validators.
+ *
+ * @since Oak 0.3
+ */
+public class DefaultValidator implements Validator {
+
+ @Override
+ public void propertyAdded(PropertyState after)
+ throws CommitFailedException {
+ // do nothing
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after)
+ throws CommitFailedException {
+ // do nothing
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before)
+ throws CommitFailedException {
+ // do nothing
+ }
+
+ @Override
+ public Validator childNodeAdded(String name, NodeState after)
+ throws CommitFailedException {
+ return null;
+ }
+
+ @Override
+ public Validator childNodeChanged(
+ String name, NodeState before, NodeState after)
+ throws CommitFailedException {
+ return null;
+ }
+
+ @Override
+ public Validator childNodeDeleted(String name, NodeState before)
+ throws CommitFailedException {
+ return null;
+ }
+
+}
Added: 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=1345006&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/FailingValidator.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/FailingValidator.java Fri Jun 1 08:13:30 2012
@@ -0,0 +1,78 @@
+/*
+ * 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.jackrabbit.oak.spi.commit;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Validator that rejects all changes. Useful as a sentinel or as
+ * a tool for testing composite validators.
+ *
+ * @since Oak 0.3
+ */
+public class FailingValidator implements Validator {
+
+ private final String message;
+
+ public FailingValidator() {
+ this("All changes are rejected");
+ }
+
+ public FailingValidator(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public void propertyAdded(PropertyState after)
+ throws CommitFailedException {
+ throw new CommitFailedException(message);
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after)
+ throws CommitFailedException {
+ throw new CommitFailedException(message);
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before)
+ throws CommitFailedException {
+ throw new CommitFailedException(message);
+ }
+
+ @Override
+ public Validator childNodeAdded(String name, NodeState after)
+ throws CommitFailedException {
+ throw new CommitFailedException(message);
+ }
+
+ @Override
+ public Validator childNodeChanged(
+ String name, NodeState before, NodeState after)
+ throws CommitFailedException {
+ throw new CommitFailedException(message);
+ }
+
+ @Override
+ public Validator childNodeDeleted(String name, NodeState before)
+ throws CommitFailedException {
+ throw new CommitFailedException(message);
+ }
+
+}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidator.java?rev=1345006&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidator.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidator.java Fri Jun 1 08:13:30 2012
@@ -0,0 +1,77 @@
+/*
+ * 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.jackrabbit.oak.spi.commit;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Validator that detects changes to a specified subtree and delegates the
+ * validation of such changes to another given validator.
+ *
+ * @since Oak 0.3
+ */
+public class SubtreeValidator extends DefaultValidator {
+
+ private final Validator validator;
+
+ private final String head;
+
+ private final List<String> tail;
+
+ public SubtreeValidator(Validator validator, String... path) {
+ this(validator, Arrays.asList(path));
+ }
+
+ private SubtreeValidator(Validator validator, List<String> path) {
+ assert validator != null;
+ assert path != null && !path.isEmpty();
+ this.validator = validator;
+ this.head = path.get(0);
+ this.tail = path.subList(1, path.size());
+ }
+
+ @Override
+ public Validator childNodeAdded(String name, NodeState after) {
+ return descend(name);
+ }
+
+ @Override
+ public Validator childNodeChanged(
+ String name, NodeState before, NodeState after) {
+ return descend(name);
+ }
+
+ @Override
+ public Validator childNodeDeleted(String name, NodeState before) {
+ return descend(name);
+ }
+
+ private Validator descend(String name) {
+ if (!head.equals(name)) {
+ return null;
+ } else if (tail.isEmpty()) {
+ return validator;
+ } else {
+ return new SubtreeValidator(validator, tail);
+ }
+ }
+
+}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/ValidatingCommitHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/ValidatingCommitHook.java?rev=1345006&r1=1345005&r2=1345006&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/ValidatingCommitHook.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/ValidatingCommitHook.java Fri Jun 1 08:13:30 2012
@@ -16,9 +16,10 @@
*/
package org.apache.jackrabbit.oak.spi.commit;
+import static org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState.EMPTY_NODE;
+
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
@@ -29,6 +30,7 @@ import org.apache.jackrabbit.oak.spi.sta
* passed to the class' constructor.
*/
public class ValidatingCommitHook implements CommitHook {
+
private final ValidatorProvider validatorProvider;
/**
@@ -41,11 +43,11 @@ public class ValidatingCommitHook implem
}
@Override
- public NodeState beforeCommit(NodeStore store, NodeState before, NodeState after)
+ public NodeState beforeCommit(
+ NodeStore store, NodeState before, NodeState after)
throws CommitFailedException {
-
- Validator rootValidator = validatorProvider.getRootValidator(before, after);
- validate(store, before, after, rootValidator);
+ Validator validator = validatorProvider.getRootValidator(before, after);
+ new ValidatorDiff(validator, store).validate(validator, before, after);
return after;
}
@@ -56,112 +58,121 @@ public class ValidatingCommitHook implem
//------------------------------------------------------------< private >---
- private static void validate(final NodeStore store, NodeState before, NodeState after,
- final Validator validator) throws CommitFailedException {
+ private static class ValidatorDiff implements NodeStateDiff {
+
+ private final Validator validator;
+
+ private final NodeStore store;
- /*
+ /**
* Checked exceptions don't compose. So we need to hack around.
* See http://markmail.org/message/ak67n5k7mr3vqylm and
* http://markmail.org/message/bhocbruikljpuhu6
*/
- final CommitFailedException[] exception = {null};
+ private CommitFailedException exception = null;
- store.compare(before, after, new NodeStateDiff() {
- @Override
- public void propertyAdded(PropertyState after) {
- if (exception[0] == null) {
- try {
- validator.propertyAdded(after);
- }
- catch (CommitFailedException e) {
- exception[0] = e;
- }
- }
+ private ValidatorDiff(Validator validator, NodeStore store) {
+ this.validator = validator;
+ this.store = store;
+ }
+
+ /**
+ * Validates the given subtree by diffing and recursing through it.
+ *
+ * @param validator validator for the root of the subtree
+ * @param before state of the original subtree
+ * @param after state of the modified subtree
+ * @throws CommitFailedException if validation failed
+ */
+ public void validate(
+ Validator validator, NodeState before, NodeState after)
+ throws CommitFailedException {
+ ValidatorDiff diff = new ValidatorDiff(validator, store);
+ store.compare(before, after, diff);
+ if (exception != null) {
+ throw exception;
}
+ }
- @Override
- public void propertyChanged(PropertyState before, PropertyState after) {
- if (exception[0] == null) {
- try {
- validator.propertyChanged(before, after);
- }
- catch (CommitFailedException e) {
- exception[0] = e;
- }
+ //-------------------------------------------------< NodeStateDiff >--
+
+ @Override
+ public void propertyAdded(PropertyState after) {
+ if (exception == null) {
+ try {
+ validator.propertyAdded(after);
+ } catch (CommitFailedException e) {
+ exception = e;
}
}
+ }
- @Override
- public void propertyDeleted(PropertyState before) {
- if (exception[0] == null) {
- try {
- validator.propertyDeleted(before);
- }
- catch (CommitFailedException e) {
- exception[0] = e;
- }
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after) {
+ if (exception == null) {
+ try {
+ validator.propertyChanged(before, after);
+ } catch (CommitFailedException e) {
+ exception = e;
}
}
+ }
- @Override
- public void childNodeAdded(String name, NodeState after) {
- if (exception[0] == null) {
- try {
- Validator childValidator = validator.childNodeAdded(name, after);
- if (childValidator != null) {
- validate(after, validator);
- }
- }
- catch (CommitFailedException e) {
- exception[0] = e;
- }
+ @Override
+ public void propertyDeleted(PropertyState before) {
+ if (exception == null) {
+ try {
+ validator.propertyDeleted(before);
+ } catch (CommitFailedException e) {
+ exception = e;
}
}
+ }
- @Override
- public void childNodeChanged(String name, NodeState before, NodeState after) {
- if (exception[0] == null) {
- try {
- Validator childValidator = validator.childNodeChanged(name, before, after);
- if (childValidator != null) {
- validate(store, before, after, childValidator);
- }
- }
- catch (CommitFailedException e) {
- exception[0] = e;
+ @Override
+ public void childNodeAdded(String name, NodeState after) {
+ if (exception == null) {
+ try {
+ Validator v = validator.childNodeAdded(name, after);
+ if (v != null) {
+ validate(v, EMPTY_NODE, after);
}
+ } catch (CommitFailedException e) {
+ exception = e;
}
}
+ }
- @Override
- public void childNodeDeleted(String name, NodeState before) {
- if (exception[0] == null) {
- try {
- validator.childNodeDeleted(name, before);
- }
- catch (CommitFailedException e) {
- exception[0] = e;
+ @Override
+ public void childNodeChanged(
+ String name, NodeState before, NodeState after) {
+ if (exception == null) {
+ try {
+ Validator v =
+ validator.childNodeChanged(name, before, after);
+ if (v != null) {
+ validate(v, before, after);
}
+ } catch (CommitFailedException e) {
+ exception = e;
}
}
- });
-
- if (exception[0] != null) {
- throw new CommitFailedException(exception[0]);
}
- }
-
- private static void validate(NodeState nodeState, Validator validator)
- throws CommitFailedException {
- for (PropertyState property : nodeState.getProperties()) {
- validator.propertyAdded(property);
+ @Override
+ public void childNodeDeleted(String name, NodeState before) {
+ if (exception == null) {
+ try {
+ Validator v = validator.childNodeDeleted(name, before);
+ if (v != null) {
+ validate(v, before, EMPTY_NODE);
+ }
+ } catch (CommitFailedException e) {
+ exception = e;
+ }
+ }
}
- for (ChildNodeEntry child : nodeState.getChildNodeEntries()) {
- Validator childValidator = validator.childNodeAdded(
- child.getName(), child.getNodeState());
- validate(child.getNodeState(), childValidator);
- }
}
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/Validator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/Validator.java?rev=1345006&r1=1345005&r2=1345006&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/Validator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/Validator.java Fri Jun 1 08:13:30 2012
@@ -82,9 +82,12 @@ public interface Validator {
/**
* Validate a deleted node
* @param before the original node
+ * @return a {@code Validator} for the removed subtree or
+ * {@code null} if validation should not decent into the subtree
* @throws CommitFailedException if validation fails.
*/
- void childNodeDeleted(String name, NodeState before)
+ @CheckForNull
+ Validator childNodeDeleted(String name, NodeState before)
throws CommitFailedException;
}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidatorTest.java?rev=1345006&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidatorTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/commit/SubtreeValidatorTest.java Fri Jun 1 08:13:30 2012
@@ -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.jackrabbit.oak.spi.commit;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState.EMPTY_NODE;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.junit.Test;
+
+public class SubtreeValidatorTest {
+
+
+ @Test
+ public void testSubtreeValidator() throws CommitFailedException {
+ Validator delegate = new FailingValidator();
+ Validator validator = new SubtreeValidator(delegate, "one", "two");
+
+ assertNull(validator.childNodeAdded("zero", EMPTY_NODE));
+ assertNull(validator.childNodeChanged("two", EMPTY_NODE, EMPTY_NODE));
+ assertNull(validator.childNodeDeleted("foo", EMPTY_NODE));
+
+ assertNotNull(validator.childNodeAdded("one", EMPTY_NODE));
+ assertNotNull(validator.childNodeChanged("one", EMPTY_NODE, EMPTY_NODE));
+ assertNotNull(validator.childNodeDeleted("one", EMPTY_NODE));
+
+ // Descend to the subtree
+ validator = validator.childNodeChanged("one", EMPTY_NODE, EMPTY_NODE);
+ assertNull(validator.childNodeAdded("zero", EMPTY_NODE));
+ assertNull(validator.childNodeChanged("one", EMPTY_NODE, EMPTY_NODE));
+ assertNull(validator.childNodeDeleted("foo", EMPTY_NODE));
+
+ assertEquals(delegate, validator.childNodeAdded("two", EMPTY_NODE));
+ assertEquals(delegate, validator.childNodeChanged("two", EMPTY_NODE, EMPTY_NODE));
+ assertEquals(delegate, validator.childNodeDeleted("two", EMPTY_NODE));
+ }
+
+}