SLING-11449: Use latest improvements of Oak 1.44.0 (#28)
diff --git a/pom.xml b/pom.xml
index fd803b0..f717752 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,9 +44,8 @@
<properties>
<site.jira.version.id>12314286</site.jira.version.id>
<site.javadoc.exclude>**.internal.**</site.javadoc.exclude>
- <!-- aok 1.10.0 was first version compatible with Jackrabbit API 2.18 (https://issues.apache.org/jira/browse/OAK-7943) -->
- <!-- aok 1.42.0 first version to include JackrabbitSession.getParentOrNull in oak-jackrabbit-api (https://issues.apache.org/jira/browse/SLING-10011) -->
- <oak.version>1.42.0</oak.version>
+ <!-- oak 1.44.0 first version to include JackrabbitNode.getPropertyOrNull in oak-jackrabbit-api (https://issues.apache.org/jira/browse/SLING-11449) -->
+ <oak.version>1.44.0</oak.version>
<jackrabbit.version>2.18.0</jackrabbit.version><!-- required for direct binary access, https://issues.apache.org/jira/browse/JCR-4335 -->
<project.build.outputTimestamp>1</project.build.outputTimestamp>
</properties>
diff --git a/src/main/java/org/apache/sling/jcr/resource/internal/JcrModifiableValueMap.java b/src/main/java/org/apache/sling/jcr/resource/internal/JcrModifiableValueMap.java
index 5ec28f3..87b2477 100644
--- a/src/main/java/org/apache/sling/jcr/resource/internal/JcrModifiableValueMap.java
+++ b/src/main/java/org/apache/sling/jcr/resource/internal/JcrModifiableValueMap.java
@@ -22,6 +22,7 @@
import java.util.Map;
import javax.jcr.Node;
+import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
@@ -104,8 +105,9 @@
final Object oldValue = this.valueCache.remove(key);
try {
final String name = escapeKeyName(key);
- if (node.hasProperty(name)) {
- node.getProperty(name).remove();
+ Property property = NodeUtil.getPropertyOrNull(node, name);
+ if (property != null) {
+ property.remove();
}
} catch (final RepositoryException re) {
throw new IllegalArgumentException("Property '" + key + "' can't be removed from node '" + getPath() + "'.", re);
diff --git a/src/main/java/org/apache/sling/jcr/resource/internal/JcrValueMap.java b/src/main/java/org/apache/sling/jcr/resource/internal/JcrValueMap.java
index 4d5fc4d..ba9abc9 100644
--- a/src/main/java/org/apache/sling/jcr/resource/internal/JcrValueMap.java
+++ b/src/main/java/org/apache/sling/jcr/resource/internal/JcrValueMap.java
@@ -26,7 +26,6 @@
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
-
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
@@ -279,8 +278,9 @@
// encoding
final String path = ISO9075.encodePath(name);
try {
- if (node.hasProperty(path)) {
- return new JcrPropertyMapCacheEntry(node.getProperty(path));
+ Property property = NodeUtil.getPropertyOrNull(node, path);
+ if (property != null) {
+ return new JcrPropertyMapCacheEntry(property);
}
} catch (final RepositoryException re) {
throw new IllegalArgumentException(re);
@@ -304,8 +304,9 @@
}
final String newPath = sb.toString();
try {
- if (node.hasProperty(newPath)) {
- return new JcrPropertyMapCacheEntry(node.getProperty(newPath));
+ Property property = NodeUtil.getPropertyOrNull(node,newPath);
+ if (property != null) {
+ return new JcrPropertyMapCacheEntry(property);
}
} catch (final RepositoryException re) {
throw new IllegalArgumentException(re);
@@ -322,9 +323,9 @@
try {
final String key = escapeKeyName(name);
- if (node.hasProperty(key)) {
- final Property prop = node.getProperty(key);
- return cacheProperty(prop);
+ Property property = NodeUtil.getPropertyOrNull(node,key);
+ if (property != null) {
+ return cacheProperty(property);
}
} catch (final RepositoryException re) {
throw new IllegalArgumentException(re);
@@ -334,9 +335,9 @@
// for compatibility with older versions we use the (wrong) ISO9075 path
// encoding
final String oldKey = ISO9075.encodePath(name);
- if (node.hasProperty(oldKey)) {
- final Property prop = node.getProperty(oldKey);
- return cacheProperty(prop);
+ Property property = NodeUtil.getPropertyOrNull(node,oldKey);
+ if (property != null) {
+ return cacheProperty(property);
}
} catch (final RepositoryException re) {
// we ignore this
diff --git a/src/main/java/org/apache/sling/jcr/resource/internal/NodeUtil.java b/src/main/java/org/apache/sling/jcr/resource/internal/NodeUtil.java
index f315416..81eb7f0 100644
--- a/src/main/java/org/apache/sling/jcr/resource/internal/NodeUtil.java
+++ b/src/main/java/org/apache/sling/jcr/resource/internal/NodeUtil.java
@@ -36,6 +36,7 @@
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;
+import org.apache.jackrabbit.api.JackrabbitNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -90,8 +91,9 @@
: node.isNodeType(NT_LINKED_FILE) ? node.getProperty(JCR_CONTENT).getNode() : node;
Property data;
// if the node has a jcr:data property, use that property
- if (content.hasProperty(JCR_DATA)) {
- data = content.getProperty(JCR_DATA);
+ final Property property = getPropertyOrNull(content,JCR_DATA);
+ if (property != null) {
+ data = property;
} else {
// otherwise try to follow default item trail
Item item = content.getPrimaryItem();
@@ -102,4 +104,42 @@
}
return data;
}
+
+ /**
+ * Return a named property from a node.
+ *
+ * In case a recent Oak JCR version is present, it switches to an optimized
+ * version which just does one lookup of the property. This is not possible
+ * with plain JCR.
+ *
+ * @param node the node
+ * @param propertyName the property to check for
+ * @return the property if it exists, null otherwise
+ * @throws RepositoryException in case of a problem
+ */
+ public static @Nullable Property getPropertyOrNull (@NotNull Node node, @NotNull String propertyName) throws RepositoryException {
+ if (node instanceof JackrabbitNode) {
+ JackrabbitNode jnode = (JackrabbitNode) node;
+ return jnode.getPropertyOrNull(propertyName);
+ } else {
+ if (node.hasProperty(propertyName)) {
+ return node.getProperty(propertyName);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public static @Nullable Node getNodeOrNull (@NotNull Node node, @NotNull String childNode) throws RepositoryException {
+ if (node instanceof JackrabbitNode) {
+ JackrabbitNode jnode = (JackrabbitNode) node;
+ return jnode.getNodeOrNull(childNode);
+ } else {
+ if (node.hasNode(childNode)) {
+ return node.getNode(childNode);
+ } else {
+ return null;
+ }
+ }
+ }
}
diff --git a/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java b/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java
index d91ef82..d81cd8e 100644
--- a/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java
+++ b/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java
@@ -33,6 +33,7 @@
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.jcr.resource.api.JcrResourceConstants;
+import org.apache.sling.jcr.resource.internal.NodeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@@ -119,15 +120,17 @@
protected String getResourceTypeForNode(final @NotNull Node node) throws RepositoryException {
String result = null;
- if (node.hasProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY)) {
- result = node.getProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY).getString();
+ Property property = NodeUtil.getPropertyOrNull(node, JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY);
+ if (property != null) {
+ result = property.getString();
}
if (result == null || result.length() == 0) {
// Do not load the relatively expensive NodeType object unless necessary. See OAK-2441 for the reason why it
// cannot only use getProperty here.
- if (node.hasProperty(Property.JCR_PRIMARY_TYPE)) {
- result = node.getProperty(Property.JCR_PRIMARY_TYPE).getString();
+ property = NodeUtil.getPropertyOrNull(node, Property.JCR_PRIMARY_TYPE);
+ if (property != null) {
+ result = property.getString();
} else {
result = node.getPrimaryNodeType().getName();
}
diff --git a/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceFactory.java b/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceFactory.java
index f77d644..b2d97f5 100644
--- a/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceFactory.java
+++ b/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceFactory.java
@@ -35,6 +35,7 @@
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.jcr.resource.internal.HelperData;
+import org.apache.sling.jcr.resource.internal.NodeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@@ -142,15 +143,18 @@
private static @Nullable Item getSubitem(@NotNull Node node, @NotNull String relPath) {
try {
- if (relPath.length() == 0) { // not using isEmpty() due to 1.5 compatibility
+ if (relPath.isEmpty()) {
return node;
- } else if (node.hasNode(relPath)) {
- return node.getNode(relPath);
- } else if (node.hasProperty(relPath)) {
- return node.getProperty(relPath);
- } else {
- return null;
}
+ Node childNode = NodeUtil.getNodeOrNull(node, relPath);
+ if (childNode != null) {
+ return childNode;
+ }
+ Property property = NodeUtil.getPropertyOrNull(node, relPath);
+ if (property != null) {
+ return property;
+ }
+ return null;
} catch (RepositoryException e) {
log.debug("getSubitem: Can't get subitem {} of {}: {}", relPath, node, e.toString());
return null;
@@ -162,11 +166,11 @@
final VersionHistory history = versionManager.getVersionHistory(node.getPath());
if (history.hasVersionLabel(versionSpecifier)) {
return history.getVersionByLabel(versionSpecifier).getFrozenNode();
- } else if (history.hasNode(versionSpecifier)) {
- return history.getVersion(versionSpecifier).getFrozenNode();
- } else {
- return null;
}
+ if (history.hasNode(versionSpecifier)) {
+ return history.getVersion(versionSpecifier).getFrozenNode();
+ }
+ return null;
}
private static boolean isVersionable(@NotNull Item item) throws RepositoryException {
diff --git a/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java b/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
index f5628bc..dba7f67 100644
--- a/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
+++ b/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
@@ -107,8 +107,9 @@
// Yes, this isn't how you're supposed to compare Strings, but this is intentional.
if (resourceSuperType == UNSET_RESOURCE_SUPER_TYPE) {
try {
- if (getNode().hasProperty(JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY)) {
- resourceSuperType = getNode().getProperty(JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY).getValue().getString();
+ Property property = NodeUtil.getPropertyOrNull(getNode(), JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY);
+ if (property != null) {
+ resourceSuperType = property.getValue().getString();
}
} catch (RepositoryException re) {
// we ignore this
diff --git a/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java b/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
index 7440ddd..0ad1e08 100644
--- a/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
+++ b/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceMetadata.java
@@ -39,6 +39,7 @@
import javax.jcr.ValueFormatException;
import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.jcr.resource.internal.NodeUtil;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -108,8 +109,9 @@
String contentType = null;
final Node targetNode = promoteNode();
try {
- if (targetNode.hasProperty(JCR_MIMETYPE)) {
- contentType = targetNode.getProperty(JCR_MIMETYPE).getString();
+ Property property = NodeUtil.getPropertyOrNull(targetNode, JCR_MIMETYPE);
+ if (property != null) {
+ contentType = property.getString();
}
} catch (final RepositoryException re) {
report(re);
@@ -121,8 +123,9 @@
String characterEncoding = null;
final Node targetNode = promoteNode();
try {
- if (targetNode.hasProperty(JCR_ENCODING)) {
- characterEncoding = targetNode.getProperty(JCR_ENCODING).getString();
+ Property property = NodeUtil.getPropertyOrNull(targetNode, JCR_ENCODING);
+ if (property != null) {
+ characterEncoding = property.getString();
}
} catch (final RepositoryException re) {
report(re);
@@ -133,9 +136,9 @@
long modificationTime = -1;
final Node targetNode = promoteNode();
try {
- if (targetNode.hasProperty(JCR_LAST_MODIFIED)) {
+ Property prop = NodeUtil.getPropertyOrNull(targetNode, JCR_LAST_MODIFIED);
+ if (prop != null) {
// We don't check node type, so JCR_LASTMODIFIED might not be a long
- final Property prop = targetNode.getProperty(JCR_LAST_MODIFIED);
try {
modificationTime = prop.getLong();
} catch (final ValueFormatException vfe) {
@@ -153,8 +156,8 @@
final Node targetNode = promoteNode();
try {
// if the node has a jcr:data property, use that property
- if (targetNode.hasProperty(JCR_DATA)) {
- final Property prop = targetNode.getProperty(JCR_DATA);
+ Property prop = NodeUtil.getPropertyOrNull(targetNode, JCR_DATA);
+ if (prop != null) {
contentLength = JcrItemResource.getContentLength(prop);
} else {
// otherwise try to follow default item trail
@@ -186,13 +189,15 @@
if (name == null) {
return null;
}
- if (node.hasProperty(name)) {
- return node.getProperty(name);
- } else if (node.hasNode(name)) {
- return node.getNode(name);
- } else {
- return null;
+ Property property = NodeUtil.getPropertyOrNull(node, name);
+ if (property != null) {
+ return property;
}
+ Node childNode = NodeUtil.getNodeOrNull(node, name);
+ if (childNode != null) {
+ return childNode;
+ }
+ return null;
}
private void populate() {