You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2016/02/15 11:49:30 UTC
svn commit: r1730493 - in
/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource:
./ internal/ internal/helper/ internal/helper/jcr/
Author: cziegeler
Date: Mon Feb 15 10:49:29 2016
New Revision: 1730493
URL: http://svn.apache.org/viewvc?rev=1730493&view=rev
Log:
SLING-5513 : Deprecate JcrResourceUtil - add deprecation warnings
Added:
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrResourceUtil.java (with props)
Modified:
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrValueMap.java
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/BasicQueryLanguageProvider.java
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java?rev=1730493&r1=1730492&r2=1730493&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java Mon Feb 15 10:49:29 2016
@@ -31,6 +31,7 @@ import org.apache.sling.api.resource.Per
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.jcr.resource.internal.NodeUtil;
import org.apache.sling.jcr.resource.internal.helper.JcrPropertyMapCacheEntry;
+import org.slf4j.LoggerFactory;
/**
* This implementation of the value map allows to change
@@ -44,6 +45,8 @@ public final class JcrModifiableProperty
extends JcrPropertyMap
implements PersistableValueMap {
+ private static volatile boolean LOG_DEPRECATED = true;
+
/** Set of removed and changed properties. */
private Set<String> changedProperties;
@@ -53,6 +56,10 @@ public final class JcrModifiableProperty
*/
public JcrModifiablePropertyMap(final Node node) {
super(node);
+ if ( LOG_DEPRECATED ) {
+ LOG_DEPRECATED = false;
+ LoggerFactory.getLogger(this.getClass()).warn("DEPRECATION WARNING: JcrModifiablePropertyMap is deprecated. Please switch to resource API.");
+ }
}
/**
@@ -63,6 +70,10 @@ public final class JcrModifiableProperty
*/
public JcrModifiablePropertyMap(final Node node, final ClassLoader dynamicCL) {
super(node, dynamicCL);
+ if ( LOG_DEPRECATED ) {
+ LOG_DEPRECATED = false;
+ LoggerFactory.getLogger(this.getClass()).warn("DEPRECATION WARNING: JcrModifiablePropertyMap is deprecated. Please switch to resource API.");
+ }
}
// ---------- Map
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java?rev=1730493&r1=1730492&r2=1730493&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java Mon Feb 15 10:49:29 2016
@@ -37,6 +37,7 @@ import org.apache.jackrabbit.util.ISO907
import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.resource.internal.helper.JcrPropertyMapCacheEntry;
+import org.slf4j.LoggerFactory;
/**
* An implementation of the value map based on a JCR node.
@@ -48,6 +49,8 @@ import org.apache.sling.jcr.resource.int
public class JcrPropertyMap
implements ValueMap {
+ private static volatile boolean LOG_DEPRECATED = true;
+
/** The underlying node. */
private final Node node;
@@ -85,6 +88,10 @@ public class JcrPropertyMap
this.valueCache = new LinkedHashMap<String, Object>();
this.fullyRead = false;
this.dynamicClassLoader = dynamicCL;
+ if ( LOG_DEPRECATED ) {
+ LOG_DEPRECATED = false;
+ LoggerFactory.getLogger(this.getClass()).warn("DEPRECATION WARNING: JcrPropertyMap is deprecated. Please switch to resource API.");
+ }
}
protected ClassLoader getDynamicClassLoader() {
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java?rev=1730493&r1=1730492&r2=1730493&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java Mon Feb 15 10:49:29 2016
@@ -39,6 +39,7 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.jcr.resource.internal.helper.LazyInputStream;
+import org.slf4j.LoggerFactory;
/**
* The <code>JcrResourceUtil</code> class provides helper methods used
@@ -49,6 +50,17 @@ import org.apache.sling.jcr.resource.int
@Deprecated
public class JcrResourceUtil {
+ private static volatile boolean LOG_DEPRECATED_QUERY = true;
+ private static volatile boolean LOG_DEPRECATED_TO_JAVA_OBJECT_1 = true;
+ private static volatile boolean LOG_DEPRECATED_TO_JAVA_OBJECT_2 = true;
+ private static volatile boolean LOG_DEPRECATED_CREATE_VALUE = true;
+ private static volatile boolean LOG_DEPRECATED_SET_PROPERTY = true;
+ private static volatile boolean LOG_DEPRECATED_CREATE_PATH_1 = true;
+ private static volatile boolean LOG_DEPRECATED_CREATE_PATH_2 = true;
+ private static volatile boolean LOG_DEPRECATED_GET_RST_1 = true;
+ private static volatile boolean LOG_DEPRECATED_GET_RST_2 = true;
+ private static volatile boolean LOG_DEPRECATED_RT_TO_PATH = true;
+
/**
* Helper method to execute a JCR query.
*
@@ -60,6 +72,10 @@ public class JcrResourceUtil {
*/
public static QueryResult query(Session session, String query,
String language) throws RepositoryException {
+ if ( LOG_DEPRECATED_QUERY ) {
+ LOG_DEPRECATED_QUERY = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.query is deprecated. Please use the resource resolver.");
+ }
QueryManager qManager = session.getWorkspace().getQueryManager();
Query q = qManager.createQuery(query, language);
return q.execute();
@@ -73,6 +89,10 @@ public class JcrResourceUtil {
* @throws RepositoryException if the value cannot be converted
*/
public static Object toJavaObject(Value value) throws RepositoryException {
+ if ( LOG_DEPRECATED_TO_JAVA_OBJECT_1 ) {
+ LOG_DEPRECATED_TO_JAVA_OBJECT_1 = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.toJavaObject(Value) is deprecated. Please use the resource resolver API.");
+ }
switch (value.getType()) {
case PropertyType.DECIMAL:
return value.getDecimal();
@@ -107,6 +127,10 @@ public class JcrResourceUtil {
*/
public static Object toJavaObject(Property property)
throws RepositoryException {
+ if ( LOG_DEPRECATED_TO_JAVA_OBJECT_2 ) {
+ LOG_DEPRECATED_TO_JAVA_OBJECT_2 = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.toJavaObject(Property) is deprecated. Please use the resource resolver API.");
+ }
// multi-value property: return an array of values
if (property.isMultiple()) {
Value[] values = property.getValues();
@@ -153,6 +177,10 @@ public class JcrResourceUtil {
*/
public static Value createValue(final Object value, final Session session)
throws RepositoryException {
+ if ( LOG_DEPRECATED_CREATE_VALUE ) {
+ LOG_DEPRECATED_CREATE_VALUE = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.createValue is deprecated. Please use the resource resolver API.");
+ }
Value val;
ValueFactory fac = session.getValueFactory();
if(value instanceof Calendar) {
@@ -194,6 +222,10 @@ public class JcrResourceUtil {
final String propertyName,
final Object propertyValue)
throws RepositoryException {
+ if ( LOG_DEPRECATED_SET_PROPERTY ) {
+ LOG_DEPRECATED_SET_PROPERTY = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.setProperty is deprecated. Please use the resource resolver API.");
+ }
if ( propertyValue == null ) {
node.setProperty(propertyName, (String)null);
} else if ( propertyValue.getClass().isArray() ) {
@@ -220,6 +252,10 @@ public class JcrResourceUtil {
*/
@Deprecated
public static String resourceTypeToPath(String type) {
+ if ( LOG_DEPRECATED_RT_TO_PATH ) {
+ LOG_DEPRECATED_RT_TO_PATH = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.resourceTypeToPath is deprecated. Please use the resource resolver API.");
+ }
return type.replaceAll("\\:", "/");
}
@@ -249,6 +285,10 @@ public class JcrResourceUtil {
@Deprecated
public static String getResourceSuperType(
ResourceResolver resourceResolver, String resourceType) {
+ if ( LOG_DEPRECATED_GET_RST_1) {
+ LOG_DEPRECATED_GET_RST_1 = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.getResourceSuperType(String) is deprecated. Please use the resource resolver API.");
+ }
return ResourceUtil.getResourceSuperType(resourceResolver, resourceType);
}
@@ -273,6 +313,10 @@ public class JcrResourceUtil {
@SuppressWarnings("deprecation")
@Deprecated
public static String getResourceSuperType(Resource resource) {
+ if ( LOG_DEPRECATED_GET_RST_2) {
+ LOG_DEPRECATED_GET_RST_2 = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.getResourceSuperType(Resource) is deprecated. Please use the resource resolver API.");
+ }
String resourceSuperType = resource.getResourceSuperType();
if ( resourceSuperType == null ) {
final ResourceResolver resolver = resource.getResourceResolver();
@@ -305,6 +349,10 @@ public class JcrResourceUtil {
Session session,
boolean autoSave)
throws RepositoryException {
+ if ( LOG_DEPRECATED_CREATE_PATH_1 ) {
+ LOG_DEPRECATED_CREATE_PATH_1 = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.createPath(String, ...) is deprecated. Please use the resource resolver API.");
+ }
if (path == null || path.length() == 0 || "/".equals(path)) {
return session.getRootNode();
}
@@ -357,6 +405,10 @@ public class JcrResourceUtil {
String nodeType,
boolean autoSave)
throws RepositoryException {
+ if ( LOG_DEPRECATED_CREATE_PATH_2 ) {
+ LOG_DEPRECATED_CREATE_PATH_2 = false;
+ LoggerFactory.getLogger(JcrResourceUtil.class).warn("DEPRECATION WARNING: JcrResourceUtil.createPath(Node,...) is deprecated. Please use the resource resolver API.");
+ }
if (relativePath == null || relativePath.length() == 0 || "/".equals(relativePath)) {
return parentNode;
}
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java?rev=1730493&r1=1730492&r2=1730493&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java Mon Feb 15 10:49:29 2016
@@ -23,6 +23,7 @@ import java.util.Map;
import javax.jcr.Session;
+import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
@@ -37,6 +38,7 @@ import org.apache.sling.commons.classloa
import org.apache.sling.jcr.resource.JcrResourceConstants;
import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
import org.osgi.framework.Constants;
+import org.slf4j.LoggerFactory;
/**
* The <code>JcrResourceResolverFactoryImpl</code> is the
@@ -63,6 +65,11 @@ public class JcrResourceResolverFactoryI
@Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC)
private volatile DynamicClassLoaderManager dynamicClassLoaderManager;
+ @Activate
+ protected void activate() {
+ LoggerFactory.getLogger(this.getClass()).warn("DEPRECATION WARNING: JcrResourceResolverFactory is deprecated. Please use ResourceResolverFactory instead.");
+ }
+
/**
* Get the dynamic class loader if available.
*
@@ -79,6 +86,7 @@ public class JcrResourceResolverFactoryI
/**
* @see org.apache.sling.jcr.resource.JcrResourceResolverFactory#getResourceResolver(javax.jcr.Session)
*/
+ @Override
public ResourceResolver getResourceResolver(final Session session) {
final Map<String, Object> authInfo = new HashMap<String, Object>(1);
authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, session);
@@ -94,6 +102,7 @@ public class JcrResourceResolverFactoryI
/**
* @see org.apache.sling.api.resource.ResourceResolverFactory#getServiceResourceResolver(Map)
*/
+ @Override
public ResourceResolver getServiceResourceResolver(Map<String, Object> authenticationInfo) throws LoginException {
return delegatee.getServiceResourceResolver(authenticationInfo);
}
@@ -101,6 +110,7 @@ public class JcrResourceResolverFactoryI
/**
* @see org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)
*/
+ @Override
public ResourceResolver getAdministrativeResourceResolver(
final Map<String, Object> authenticationInfo) throws LoginException {
return delegatee.getAdministrativeResourceResolver(authenticationInfo);
@@ -109,6 +119,7 @@ public class JcrResourceResolverFactoryI
/**
* @see org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)
*/
+ @Override
public ResourceResolver getResourceResolver(final Map<String, Object> arg0)
throws LoginException {
return delegatee.getResourceResolver(arg0);
@@ -117,6 +128,7 @@ public class JcrResourceResolverFactoryI
/**
* @see org.apache.sling.api.resource.ResourceResolverFactory#getThreadResourceResolver()
*/
+ @Override
public ResourceResolver getThreadResourceResolver() {
return delegatee.getThreadResourceResolver();
}
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrValueMap.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrValueMap.java?rev=1730493&r1=1730492&r2=1730493&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrValueMap.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrValueMap.java Mon Feb 15 10:49:29 2016
@@ -18,28 +18,459 @@
*/
package org.apache.sling.jcr.resource.internal;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
+import javax.jcr.Value;
-import org.apache.sling.jcr.resource.JcrPropertyMap;
+import org.apache.jackrabbit.util.ISO9075;
+import org.apache.jackrabbit.util.Text;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.jcr.resource.internal.helper.JcrPropertyMapCacheEntry;
-@SuppressWarnings("deprecation")
-public class JcrValueMap extends JcrPropertyMap {
+public class JcrValueMap implements ValueMap {
private final HelperData helper;
+ /** The underlying node. */
+ private final Node node;
+
+ /** A cache for the properties. */
+ final Map<String, JcrPropertyMapCacheEntry> cache;
+
+ /** A cache for the values. */
+ final Map<String, Object> valueCache;
+
+ /** Has the node been read completely? */
+ boolean fullyRead;
+
+ /**
+ * Create a new JCR property map based on a node.
+ * @param node The underlying node.
+ */
public JcrValueMap(final Node node, final HelperData helper) {
- super(node, null);
+ this.node = node;
+ this.cache = new LinkedHashMap<String, JcrPropertyMapCacheEntry>();
+ this.valueCache = new LinkedHashMap<String, Object>();
+ this.fullyRead = false;
this.helper = helper;
}
+ /**
+ * Get the node.
+ *
+ * @return the node
+ */
+ protected Node getNode() {
+ return node;
+ }
+
+ // ---------- ValueMap
+
+ String checkKey(final String key) {
+ if ( key == null ) {
+ throw new NullPointerException("Key must not be null.");
+ }
+ if ( key.startsWith("./") ) {
+ return key.substring(2);
+ }
+ return key;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ValueMap#get(java.lang.String, java.lang.Class)
+ */
@Override
- protected String[] getNamespacePrefixes() throws RepositoryException {
- return this.helper.getNamespacePrefixes(this.getNode().getSession());
+ @SuppressWarnings("unchecked")
+ public <T> T get(final String aKey, final Class<T> type) {
+ final String key = checkKey(aKey);
+ if (type == null) {
+ return (T) get(key);
+ }
+
+ final JcrPropertyMapCacheEntry entry = this.read(key);
+ if ( entry == null ) {
+ return null;
+ }
+ return entry.convertToType(type, this.node, this.getDynamicClassLoader());
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ValueMap#get(java.lang.String, java.lang.Object)
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T> T get(final String aKey,final T defaultValue) {
+ final String key = checkKey(aKey);
+ if (defaultValue == null) {
+ return (T) get(key);
+ }
+
+ // special handling in case the default value implements one
+ // of the interface types supported by the convertToType method
+ Class<T> type = (Class<T>) normalizeClass(defaultValue.getClass());
+
+ T value = get(key, type);
+ if (value == null) {
+ value = defaultValue;
+ }
+
+ return value;
+ }
+
+ // ---------- Map
+
+ /**
+ * @see java.util.Map#get(java.lang.Object)
+ */
+ @Override
+ public Object get(final Object aKey) {
+ final String key = checkKey(aKey.toString());
+ final JcrPropertyMapCacheEntry entry = this.read(key);
+ final Object value = (entry == null ? null : entry.getPropertyValueOrNull());
+ return value;
+ }
+
+ /**
+ * @see java.util.Map#containsKey(java.lang.Object)
+ */
+ @Override
+ public boolean containsKey(final Object key) {
+ return get(key) != null;
+ }
+
+ /**
+ * @see java.util.Map#containsValue(java.lang.Object)
+ */
+ @Override
+ public boolean containsValue(final Object value) {
+ readFully();
+ return valueCache.containsValue(value);
+ }
+
+ /**
+ * @see java.util.Map#isEmpty()
+ */
+ @Override
+ public boolean isEmpty() {
+ return size() == 0;
+ }
+
+ /**
+ * @see java.util.Map#size()
+ */
+ @Override
+ public int size() {
+ readFully();
+ return cache.size();
+ }
+
+ /**
+ * @see java.util.Map#entrySet()
+ */
+ @Override
+ public Set<java.util.Map.Entry<String, Object>> entrySet() {
+ readFully();
+ final Map<String, Object> sourceMap;
+ if (cache.size() == valueCache.size()) {
+ sourceMap = valueCache;
+ } else {
+ sourceMap = transformEntries(cache);
+ }
+ return Collections.unmodifiableSet(sourceMap.entrySet());
+ }
+
+ /**
+ * @see java.util.Map#keySet()
+ */
+ @Override
+ public Set<String> keySet() {
+ readFully();
+ return cache.keySet();
+ }
+
+ /**
+ * @see java.util.Map#values()
+ */
+ @Override
+ public Collection<Object> values() {
+ readFully();
+ final Map<String, Object> sourceMap;
+ if (cache.size() == valueCache.size()) {
+ sourceMap = valueCache;
+ } else {
+ sourceMap = transformEntries(cache);
+ }
+ return Collections.unmodifiableCollection(sourceMap.values());
}
+ /**
+ * Return the path of the current node.
+ *
+ * @return the path
+ * @throws IllegalStateException If a repository exception occurs
+ * @deprecated
+ */
+ @Deprecated
+ public String getPath() {
+ try {
+ return node.getPath();
+ } catch (final RepositoryException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ // ---------- Helpers to access the node's property ------------------------
+
+ /**
+ * Put a single property into the cache
+ * @param prop
+ * @return the cached property
+ * @throws IllegalArgumentException if a repository exception occurs
+ */
+ private JcrPropertyMapCacheEntry cacheProperty(final Property prop) {
+ try {
+ // calculate the key
+ final String name = prop.getName();
+ String key = null;
+ if ( name.indexOf("_x") != -1 ) {
+ // for compatibility with older versions we use the (wrong)
+ // ISO9075 path encoding
+ key = ISO9075.decode(name);
+ if ( key.equals(name) ) {
+ key = null;
+ }
+ }
+ if ( key == null ) {
+ key = Text.unescapeIllegalJcrChars(name);
+ }
+ JcrPropertyMapCacheEntry entry = cache.get(key);
+ if ( entry == null ) {
+ entry = new JcrPropertyMapCacheEntry(prop);
+ cache.put(key, entry);
+
+ final Object defaultValue = entry.getPropertyValue();
+ if (defaultValue != null) {
+ valueCache.put(key, entry.getPropertyValue());
+ }
+ }
+ return entry;
+ } catch (final RepositoryException re) {
+ throw new IllegalArgumentException(re);
+ }
+ }
+
+ /**
+ * Read a single property.
+ * @throws IllegalArgumentException if a repository exception occurs
+ */
+ JcrPropertyMapCacheEntry read(final String name) {
+ // check for empty key
+ if ( name.length() == 0 ) {
+ return null;
+ }
+ // if the name is a path, we should handle this differently
+ if ( name.indexOf('/') != -1 ) {
+ // first a compatibility check with the old (wrong) ISO9075
+ // encoding
+ final String path = ISO9075.encodePath(name);
+ try {
+ if ( node.hasProperty(path) ) {
+ return new JcrPropertyMapCacheEntry(node.getProperty(path));
+ }
+ } catch (final RepositoryException re) {
+ throw new IllegalArgumentException(re);
+ }
+ // now we do a proper segment by segment encoding
+ final StringBuilder sb = new StringBuilder();
+ int pos = 0;
+ int lastPos = -1;
+ while ( pos < name.length() ) {
+ if ( name.charAt(pos) == '/' ) {
+ if ( lastPos + 1 < pos ) {
+ sb.append(Text.escapeIllegalJcrChars(name.substring(lastPos + 1, pos)));
+ }
+ sb.append('/');
+ lastPos = pos;
+ }
+ pos++;
+ }
+ if ( lastPos + 1 < pos ) {
+ sb.append(Text.escapeIllegalJcrChars(name.substring(lastPos + 1)));
+ }
+ final String newPath = sb.toString();
+ try {
+ if ( node.hasProperty(newPath) ) {
+ return new JcrPropertyMapCacheEntry(node.getProperty(newPath));
+ }
+ } catch (final RepositoryException re) {
+ throw new IllegalArgumentException(re);
+ }
+
+ return null;
+ }
+
+ // check cache
+ JcrPropertyMapCacheEntry cachedValued = cache.get(name);
+ if ( fullyRead || cachedValued != null ) {
+ return cachedValued;
+ }
+
+ final String key;
+ try {
+ key = escapeKeyName(name);
+ if (node.hasProperty(key)) {
+ final Property prop = node.getProperty(key);
+ return cacheProperty(prop);
+ }
+ } catch (final RepositoryException re) {
+ throw new IllegalArgumentException(re);
+ }
+
+ try {
+ // for compatibility with older versions we use the (wrong) ISO9075 path
+ // encoding
+ final String oldKey = ISO9075.encodePath(name);
+ if (!oldKey.equals(key) && node.hasProperty(oldKey)) {
+ final Property prop = node.getProperty(oldKey);
+ return cacheProperty(prop);
+ }
+ } catch (final RepositoryException re) {
+ // we ignore this
+ }
+
+ // property not found
+ return null;
+ }
+
+ /**
+ * Handles key name escaping by taking into consideration if it contains a
+ * registered prefix
+ *
+ * @param key the key to escape
+ * @return escaped key name
+ * @throws RepositoryException if the repository's namespaced prefixes cannot be retrieved
+ */
+ protected String escapeKeyName(final String key) throws RepositoryException {
+ final int indexOfPrefix = key.indexOf(':');
+ // check if colon is neither the first nor the last character
+ if (indexOfPrefix > 0 && key.length() > indexOfPrefix + 1) {
+ final String prefix = key.substring(0, indexOfPrefix);
+ for (final String existingPrefix : getNamespacePrefixes()) {
+ if (existingPrefix.equals(prefix)) {
+ return prefix
+ + ":"
+ + Text.escapeIllegalJcrChars(key
+ .substring(indexOfPrefix + 1));
+ }
+ }
+ }
+ return Text.escapeIllegalJcrChars(key);
+ }
+
+ /**
+ * Read all properties.
+ * @throws IllegalArgumentException if a repository exception occurs
+ */
+ void readFully() {
+ if (!fullyRead) {
+ try {
+ final PropertyIterator pi = node.getProperties();
+ while (pi.hasNext()) {
+ final Property prop = pi.nextProperty();
+ this.cacheProperty(prop);
+ }
+ fullyRead = true;
+ } catch (final RepositoryException re) {
+ throw new IllegalArgumentException(re);
+ }
+ }
+ }
+
+ // ---------- Unsupported Modification methods
+
@Override
- protected ClassLoader getDynamicClassLoader() {
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object put(String key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void putAll(Map<? extends String, ? extends Object> t) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ // ---------- Implementation helper
+
+ private Class<?> normalizeClass(Class<?> type) {
+ if (Calendar.class.isAssignableFrom(type)) {
+ type = Calendar.class;
+ } else if (Date.class.isAssignableFrom(type)) {
+ type = Date.class;
+ } else if (Value.class.isAssignableFrom(type)) {
+ type = Value.class;
+ } else if (Property.class.isAssignableFrom(type)) {
+ type = Property.class;
+ }
+ return type;
+ }
+
+ private Map<String, Object> transformEntries( Map<String, JcrPropertyMapCacheEntry> map) {
+
+ Map<String, Object> transformedEntries = new LinkedHashMap<String, Object>(map.size());
+ for ( Map.Entry<String, JcrPropertyMapCacheEntry> entry : map.entrySet() )
+ transformedEntries.put(entry.getKey(), entry.getValue().getPropertyValueOrNull());
+
+ return transformedEntries;
+ }
+
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("JcrPropertyMap [node=");
+ sb.append(this.node);
+ sb.append(", values={");
+ final Iterator<Map.Entry<String, Object>> iter = this.entrySet().iterator();
+ boolean first = true;
+ while ( iter.hasNext() ) {
+ if ( first ) {
+ first = false;
+ } else {
+ sb.append(", ");
+ }
+ final Map.Entry<String, Object> e = iter.next();
+ sb.append(e.getKey());
+ sb.append("=");
+ sb.append(e.getValue());
+ }
+ sb.append("}]");
+ return sb.toString();
+ }
+
+ private String[] getNamespacePrefixes() throws RepositoryException {
+ return this.helper.getNamespacePrefixes(this.getNode().getSession());
+ }
+
+ private ClassLoader getDynamicClassLoader() {
return helper.getDynamicClassLoader();
}
}
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java?rev=1730493&r1=1730492&r2=1730493&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java Mon Feb 15 10:49:29 2016
@@ -40,15 +40,13 @@ import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import org.apache.commons.lang.ArrayUtils;
-import org.apache.sling.jcr.resource.JcrPropertyMap;
-import org.apache.sling.jcr.resource.JcrResourceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JcrPropertyMapCacheEntry {
/** Global logger */
- private static Logger LOGGER = LoggerFactory.getLogger(JcrPropertyMap.class);
+ private static Logger LOGGER = LoggerFactory.getLogger(JcrPropertyMapCacheEntry.class);
/** The JCR property - only set for existing values. */
private final Property property;
Added: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrResourceUtil.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrResourceUtil.java?rev=1730493&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrResourceUtil.java (added)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrResourceUtil.java Mon Feb 15 10:49:29 2016
@@ -0,0 +1,174 @@
+/*
+ * 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.sling.jcr.resource.internal.helper;
+
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.Calendar;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+
+/**
+ * The <code>JcrResourceUtil</code> class provides helper methods used
+ * throughout this bundle.
+ *
+ */
+public class JcrResourceUtil {
+
+ /**
+ * Helper method to execute a JCR query.
+ *
+ * @param session the session
+ * @param query the query
+ * @param language the language
+ * @return the query's result
+ * @throws RepositoryException if the {@link QueryManager} cannot be retrieved
+ */
+ public static QueryResult query(Session session, String query,
+ String language) throws RepositoryException {
+ QueryManager qManager = session.getWorkspace().getQueryManager();
+ Query q = qManager.createQuery(query, language);
+ return q.execute();
+ }
+
+ /**
+ * Converts a JCR Value to a corresponding Java Object
+ *
+ * @param value the JCR Value to convert
+ * @return the Java Object
+ * @throws RepositoryException if the value cannot be converted
+ */
+ public static Object toJavaObject(Value value) throws RepositoryException {
+ switch (value.getType()) {
+ case PropertyType.DECIMAL:
+ return value.getDecimal();
+ case PropertyType.BINARY:
+ return new LazyInputStream(value);
+ case PropertyType.BOOLEAN:
+ return value.getBoolean();
+ case PropertyType.DATE:
+ return value.getDate();
+ case PropertyType.DOUBLE:
+ return value.getDouble();
+ case PropertyType.LONG:
+ return value.getLong();
+ case PropertyType.NAME: // fall through
+ case PropertyType.PATH: // fall through
+ case PropertyType.REFERENCE: // fall through
+ case PropertyType.STRING: // fall through
+ case PropertyType.UNDEFINED: // not actually expected
+ default: // not actually expected
+ return value.getString();
+ }
+ }
+
+ /**
+ * Converts the value(s) of a JCR Property to a corresponding Java Object.
+ * If the property has multiple values the result is an array of Java
+ * Objects representing the converted values of the property.
+ *
+ * @param property the property to be converted to the corresponding Java Object
+ * @throws RepositoryException if the conversion cannot take place
+ * @return the Object resulting from the conversion
+ */
+ public static Object toJavaObject(Property property)
+ throws RepositoryException {
+ // multi-value property: return an array of values
+ if (property.isMultiple()) {
+ Value[] values = property.getValues();
+ final Object firstValue = values.length > 0 ? toJavaObject(values[0]) : null;
+ final Object[] result;
+ if ( firstValue instanceof Boolean ) {
+ result = new Boolean[values.length];
+ } else if ( firstValue instanceof Calendar ) {
+ result = new Calendar[values.length];
+ } else if ( firstValue instanceof Double ) {
+ result = new Double[values.length];
+ } else if ( firstValue instanceof Long ) {
+ result = new Long[values.length];
+ } else if ( firstValue instanceof BigDecimal) {
+ result = new BigDecimal[values.length];
+ } else if ( firstValue instanceof InputStream) {
+ result = new Object[values.length];
+ } else {
+ result = new String[values.length];
+ }
+ for (int i = 0; i < values.length; i++) {
+ Value value = values[i];
+ if (value != null) {
+ result[i] = toJavaObject(value);
+ }
+ }
+ return result;
+ }
+
+ // single value property
+ return toJavaObject(property.getValue());
+ }
+
+ /**
+ * Creates a {@link javax.jcr.Value JCR Value} for the given object with
+ * the given Session.
+ * Selects the the {@link javax.jcr.PropertyType PropertyType} according
+ * the instance of the object's Class
+ *
+ * @param value object
+ * @param session to create value for
+ * @return the value or null if not convertible to a valid PropertyType
+ * @throws RepositoryException in case of error, accessing the Repository
+ */
+ public static Value createValue(final Object value, final Session session)
+ throws RepositoryException {
+ Value val;
+ ValueFactory fac = session.getValueFactory();
+ if(value instanceof Calendar) {
+ val = fac.createValue((Calendar)value);
+ } else if (value instanceof InputStream) {
+ val = fac.createValue(fac.createBinary((InputStream)value));
+ } else if (value instanceof Node) {
+ val = fac.createValue((Node)value);
+ } else if (value instanceof BigDecimal) {
+ val = fac.createValue((BigDecimal)value);
+ } else if (value instanceof Long) {
+ val = fac.createValue((Long)value);
+ } else if (value instanceof Short) {
+ val = fac.createValue((Short)value);
+ } else if (value instanceof Integer) {
+ val = fac.createValue((Integer)value);
+ } else if (value instanceof Number) {
+ val = fac.createValue(((Number)value).doubleValue());
+ } else if (value instanceof Boolean) {
+ val = fac.createValue((Boolean) value);
+ } else if ( value instanceof String ) {
+ val = fac.createValue((String)value);
+ } else {
+ val = null;
+ }
+ return val;
+ }
+}
Propchange: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrResourceUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrResourceUtil.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/BasicQueryLanguageProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/BasicQueryLanguageProvider.java?rev=1730493&r1=1730492&r2=1730493&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/BasicQueryLanguageProvider.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/BasicQueryLanguageProvider.java Mon Feb 15 10:49:29 2016
@@ -36,7 +36,7 @@ import org.apache.sling.api.resource.Que
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ValueMapDecorator;
-import org.apache.sling.jcr.resource.JcrResourceUtil;
+import org.apache.sling.jcr.resource.internal.helper.JcrResourceUtil;
import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
import org.apache.sling.spi.resource.provider.ProviderContext;
import org.apache.sling.spi.resource.provider.ResolveContext;
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java?rev=1730493&r1=1730492&r2=1730493&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java Mon Feb 15 10:49:29 2016
@@ -56,6 +56,8 @@ import org.slf4j.LoggerFactory;
})
class JcrNodeResource extends JcrItemResource<Node> { // this should be package private, see SLING-1414
+ private static volatile boolean LOG_DEPRECATED_MAP = true;
+
/** marker value for the resourceSupertType before trying to evaluate */
private static final String UNSET_RESOURCE_SUPER_TYPE = "<unset>";
@@ -133,6 +135,10 @@ class JcrNodeResource extends JcrItemRes
} else if (type == Map.class || type == ValueMap.class) {
return (Type) new JcrValueMap(getNode(), this.helper); // unchecked cast
} else if (type == PersistableValueMap.class ) {
+ if ( LOG_DEPRECATED_MAP ) {
+ LOG_DEPRECATED_MAP = false;
+ LOGGER.warn("DEPRECATION WARNING: PersistableValueMap is deprecated, a JcrResource should not be adapted to this anymore. Please switch to ModifiableValueMap.");
+ }
// check write
try {
getNode().getSession().checkPermission(getPath(),