JCRVLT-817 check only once for protected properties (#384)
* JCRVLT-817 check only once for protected properties
diff --git a/vault-core/.DS_Store b/vault-core/.DS_Store
new file mode 100644
index 0000000..9cad092
--- /dev/null
+++ b/vault-core/.DS_Store
Binary files differ
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java
index ad742dd..3ca72a3 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java
@@ -34,6 +34,7 @@
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
+import java.util.stream.Collectors;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.Item;
@@ -1078,11 +1079,10 @@
}
}
EffectiveNodeType effectiveNodeType = EffectiveNodeType.ofNode(node);
- // logging for uncovered protected properties
- logIgnoredProtectedProperties(effectiveNodeType, node.getPath(), ni.getProperties(), PROTECTED_PROPERTIES_CONSIDERED_FOR_UPDATED_NODES);
+ Collection<DocViewProperty2> unprotectedProperties = removeProtectedProperties(ni.getProperties(), effectiveNodeType, node.getPath(), PROTECTED_PROPERTIES_CONSIDERED_FOR_UPDATED_NODES);
// add/modify properties contained in package
- if (setUnprotectedProperties(effectiveNodeType, node, ni, importMode == ImportMode.REPLACE|| importMode == ImportMode.UPDATE || importMode == ImportMode.UPDATE_PROPERTIES, vs)) {
+ if (setProperties(node, ni,unprotectedProperties, importMode == ImportMode.REPLACE|| importMode == ImportMode.UPDATE || importMode == ImportMode.UPDATE_PROPERTIES, vs)) {
updatedNode = node;
}
}
@@ -1181,9 +1181,8 @@
Node node = getNodeByIdOrName(parentNode, ni, importUuidBehavior == ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
EffectiveNodeType effectiveNodeType = EffectiveNodeType.ofNode(node);
- // logging for uncovered protected properties
- logIgnoredProtectedProperties(effectiveNodeType, node.getPath(), ni.getProperties(), PROTECTED_PROPERTIES_CONSIDERED_FOR_NEW_NODES);
- setUnprotectedProperties(effectiveNodeType, node, ni, true, null);
+ Collection<DocViewProperty2> unprotectedProperties = removeProtectedProperties(ni.getProperties(), effectiveNodeType, node.getPath(), PROTECTED_PROPERTIES_CONSIDERED_FOR_NEW_NODES);
+ setProperties(node, ni, unprotectedProperties, true, null);
// remove mix referenceable if it was temporarily added
if (addMixRef) {
node.removeMixin(JcrConstants.MIX_REFERENCEABLE);
@@ -1211,20 +1210,36 @@
}
}
- private void logIgnoredProtectedProperties(EffectiveNodeType effectiveNodeType, String nodePath, Collection<DocViewProperty2> properties, Set<Name> importedProtectedProperties) {
- // logging for protected properties which are not considered during import
- properties.stream()
- .filter(p -> p.getStringValue().isPresent()
- && !importedProtectedProperties.contains(p.getName()))
- .forEach(p -> {
- try {
- if (isPropertyProtected(effectiveNodeType, p)) {
- log.warn("Ignore protected property '{}' on node '{}'", npResolver.getJCRName(p.getName()), nodePath);
+ /**
+ * filter the provided properties for non-protected properties, and all protected are removed.
+ * Any removed protected property is logged unless its name is contained in the importedProtectedProperties parameter.
+ *
+ * @param properties all properties
+ * @param effectiveNodeType the effective nodetype of the node to which the properties are supposed to be added
+ * @param nodePath the path of the node
+ * @param importedProtectedProperties a list of names of protected properties, which are not supposed to logged
+ * @return a non-null collection of non-protected properties
+ */
+ private @NotNull Collection<DocViewProperty2> removeProtectedProperties(@NotNull Collection<DocViewProperty2> properties, @NotNull EffectiveNodeType effectiveNodeType,
+ @NotNull String nodePath, @NotNull Set<Name> importedProtectedProperties) {
+ return properties.stream()
+ .filter(p -> {
+ try {
+ if (isPropertyProtected(effectiveNodeType, p)) {
+ // remove all protected properties
+ if (p.getStringValue().isPresent() && !importedProtectedProperties.contains(p.getName())) {
+ // log only those properties, which are not protected by the JCR standard because of special meaning
+ log.warn("Ignore protected property '{}' on node '{}'", npResolver.getJCRName(p.getName()), nodePath);
+ }
+ return false;
+ } else {
+ return true; // pass on non-protected properties
+ }
+ } catch (RepositoryException e) {
+ throw new IllegalStateException("Error retrieving protected status of properties", e);
}
- } catch (RepositoryException e) {
- throw new IllegalStateException("Error retrieving protected status of properties", e);
- }
- });
+ })
+ .collect(Collectors.toList());
}
/**
@@ -1269,7 +1284,19 @@
return node;
}
- private boolean setUnprotectedProperties(@NotNull EffectiveNodeType effectiveNodeType, @NotNull Node node, @NotNull DocViewNode2 ni, boolean overwriteExistingProperties, @Nullable VersioningState vs) throws RepositoryException {
+ /**
+ * Set all provided properties to the node.
+ * There is no check or special handling if the properties are protected or not, so only invoke it with non-protected properties.
+ *
+ * @param node the node to set the properties to
+ * @param ni the DocViewNode to persist
+ * @param unprotectedProperties the (unprotected) properties to set on the given node
+ * @param overwriteExistingProperties
+ * @param vs
+ * @return
+ * @throws RepositoryException
+ */
+ private boolean setProperties(@NotNull Node node, @NotNull DocViewNode2 ni, @NotNull Collection<DocViewProperty2> unprotectedProperties, boolean overwriteExistingProperties, @Nullable VersioningState vs) throws RepositoryException {
boolean isAtomicCounter = false;
for (String mixin : ni.getMixinTypes()) {
if ("mix:atomicCounter".equals(mixin)) {
@@ -1279,9 +1306,9 @@
boolean modified = false;
// add properties
- for (DocViewProperty2 prop : ni.getProperties()) {
+ for (DocViewProperty2 prop : unprotectedProperties) {
String name = npResolver.getJCRName(prop.getName());
- if (prop != null && !isPropertyProtected(effectiveNodeType, prop) && (overwriteExistingProperties || !node.hasProperty(name)) && wspFilter.includesProperty(node.getPath() + "/" + name)) {
+ if (prop != null && (overwriteExistingProperties || !node.hasProperty(name)) && wspFilter.includesProperty(node.getPath() + "/" + name)) {
// check if property is allowed
try {
modified |= prop.apply(node);