SLING-8116 - ValueMap - implement default methods using OSGI Converter
* fixed performance issues for ValueMapDecorator#get(java.lang.String, java.lang.Class<T>):
the ObjectConverter should not be called for converting to superclasses of the stored values
* made sure default implementations (default methods or wrappers) obey the conventions from
SLING-6609, where clients could call ValueMap#get(java.lang.String, T) with a null 2nd
parameter
diff --git a/src/main/java/org/apache/sling/api/resource/ValueMap.java b/src/main/java/org/apache/sling/api/resource/ValueMap.java
index cf39837..a2ce95e 100644
--- a/src/main/java/org/apache/sling/api/resource/ValueMap.java
+++ b/src/main/java/org/apache/sling/api/resource/ValueMap.java
@@ -49,8 +49,8 @@
/**
* Empty immutable value map.
*/
- final ValueMap EMPTY = new ValueMapDecorator(
- Collections.<String, Object> emptyMap());
+ ValueMap EMPTY = new ValueMapDecorator(
+ Collections.emptyMap());
/**
* Get a named property and convert it into the given type.
@@ -69,7 +69,7 @@
default <T> T get(@NotNull String name, @NotNull Class<T> type) {
Object value = get(name);
if (value == null) {
- return (T)null;
+ return null;
}
if (type.isAssignableFrom(value.getClass())) {
return (T)value;
@@ -100,9 +100,12 @@
@SuppressWarnings("unchecked")
@NotNull
default <T> T get(@NotNull String name, @NotNull T defaultValue) {
+ if (defaultValue == null) {
+ return (T) get(name);
+ }
T value = (T)get(name, defaultValue.getClass());
if (value == null) {
- return (T)defaultValue;
+ return defaultValue;
}
return value;
}
diff --git a/src/main/java/org/apache/sling/api/wrappers/CompositeValueMap.java b/src/main/java/org/apache/sling/api/wrappers/CompositeValueMap.java
index 92197b5..cee8cca 100644
--- a/src/main/java/org/apache/sling/api/wrappers/CompositeValueMap.java
+++ b/src/main/java/org/apache/sling/api/wrappers/CompositeValueMap.java
@@ -93,7 +93,7 @@
public <T> T get(@NotNull String name, @NotNull Class<T> type) {
Object value = get(name);
if (value == null) {
- return (T)null;
+ return null;
}
if (type.isAssignableFrom(value.getClass())) {
return (T)value;
@@ -106,10 +106,13 @@
*/
@SuppressWarnings("unchecked")
@NotNull
- public <T> T get(@NotNull String name, T defaultValue) {
+ public <T> T get(@NotNull String name, @NotNull T defaultValue) {
+ if (defaultValue == null) {
+ return (T) get(name);
+ }
T value = (T)get(name, defaultValue.getClass());
if (value == null) {
- return (T)defaultValue;
+ return defaultValue;
}
return value;
}
diff --git a/src/main/java/org/apache/sling/api/wrappers/DeepReadValueMapDecorator.java b/src/main/java/org/apache/sling/api/wrappers/DeepReadValueMapDecorator.java
index 9d241b0..eff451f 100644
--- a/src/main/java/org/apache/sling/api/wrappers/DeepReadValueMapDecorator.java
+++ b/src/main/java/org/apache/sling/api/wrappers/DeepReadValueMapDecorator.java
@@ -21,6 +21,7 @@
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
+import org.jetbrains.annotations.NotNull;
/**
* A value map wrapper which implements deep reading of properties
@@ -69,15 +70,16 @@
* @see org.apache.sling.api.resource.ValueMap#get(java.lang.String, java.lang.Class)
*/
@Override
- public <T> T get(final String name, final Class<T> type) {
+ public <T> T get(@NotNull final String name, @NotNull final Class<T> type) {
return this.getValueMap(name).get(this.getPropertyName(name), type);
}
/**
* @see org.apache.sling.api.resource.ValueMap#get(java.lang.String, java.lang.Object)
*/
+ @NotNull
@Override
- public <T> T get(final String name, T defaultValue) {
+ public <T> T get(@NotNull final String name, @NotNull T defaultValue) {
return this.getValueMap(name).get(this.getPropertyName(name), defaultValue);
}
diff --git a/src/main/java/org/apache/sling/api/wrappers/ValueMapDecorator.java b/src/main/java/org/apache/sling/api/wrappers/ValueMapDecorator.java
index 18e3cf3..d96e0d3 100644
--- a/src/main/java/org/apache/sling/api/wrappers/ValueMapDecorator.java
+++ b/src/main/java/org/apache/sling/api/wrappers/ValueMapDecorator.java
@@ -24,6 +24,7 @@
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.impl.ObjectConverter;
+import org.jetbrains.annotations.NotNull;
/**
* <code>ValueMapDecorator</code> decorates another {@link Map}
@@ -48,26 +49,37 @@
/**
* {@inheritDoc}
*/
- public <T> T get(String name, Class<T> type) {
+ public <T> T get(@NotNull String name, @NotNull Class<T> type) {
if (base instanceof ValueMap) {
// shortcut if decorated map is ValueMap
return ((ValueMap)base).get(name, type);
}
+ Object value = get(name);
+ if (value == null) {
+ return null;
+ }
+ if (type.isAssignableFrom(value.getClass())) {
+ return (T)value;
+ }
return ObjectConverter.convert(get(name), type);
}
/**
* {@inheritDoc}
*/
+ @NotNull
@SuppressWarnings("unchecked")
- public <T> T get(String name, T defaultValue) {
+ public <T> T get(@NotNull String name, @NotNull T defaultValue) {
if (base instanceof ValueMap) {
// shortcut if decorated map is ValueMap
return ((ValueMap)base).get(name, defaultValue);
}
- T value = (T)get(name, defaultValue.getClass());
+ if (defaultValue == null) {
+ return (T) get(name);
+ }
+ T value = (T) get(name, defaultValue.getClass());
if (value == null) {
- return (T)defaultValue;
+ return defaultValue;
}
return value;
}
@@ -178,4 +190,4 @@
}
-}
\ No newline at end of file
+}