com.adobe.granite.rest.utils.DeepModifiableValueMapDecorator Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2014 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.granite.rest.utils;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.ArrayUtils;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ModifiableValueMapDecorator;
import org.apache.sling.api.wrappers.ValueMapDecorator;
/**
* A value map wrapper which implements deep reading/writing of properties
* based on the resource tree and a set of exposed sub-nodes. Note that only
* properties of exposed sub-nodes can be updated.
*/
public class DeepModifiableValueMapDecorator extends ModifiableValueMapDecorator {
protected final String pathPrefix;
protected final ResourceResolver resolver;
protected final Map base;
protected final String[] subnodes;
public DeepModifiableValueMapDecorator(final Resource resource, final Map base, final String[] subnodes) {
super(base);
this.pathPrefix = resource.getPath() + "/";
this.resolver = resource.getResourceResolver();
this.base = base;
this.subnodes = subnodes;
}
public DeepModifiableValueMapDecorator(final Resource resource, final Map base) {
this(resource, base, new String[]{});
}
protected ValueMap getValueMap(final String name) {
final int pos = name.lastIndexOf("/");
if ( pos == -1 ) {
return new ModifiableValueMapDecorator(this.base);
}
final Resource rsrc = this.resolver.getResource(pathPrefix + name.substring(0, pos));
if ( rsrc != null ) {
final ValueMap vm = rsrc.adaptTo(ModifiableValueMap.class);
if ( vm != null ) {
return new ModifiableValueMapDecorator(vm);
}
}
// fall back
return ModifiableValueMap.EMPTY;
}
protected String getPropertyName(final String name) {
final int pos = name.lastIndexOf("/");
if ( pos == -1 ) {
return name;
}
return name.substring(pos + 1);
}
/**
* {@inheritDoc}
*/
@Override
public T get(String name, final Class type) {
return this.getValueMap(name).get(this.getPropertyName(name), type);
}
/**
* {@inheritDoc}
*/
@Override
public T get(String name, T defaultValue) {
return this.getValueMap(name).get(this.getPropertyName(name), defaultValue);
}
/**
* {@inheritDoc}
*/
@Override
public boolean containsKey(final Object key) {
if ( key == null ) {
return false;
}
final String name = key.toString();
return this.getValueMap(name).containsKey(this.getPropertyName(name));
}
/**
* {@inheritDoc}
*/
@Override
public Object get(final Object key) {
if ( key == null ) {
return null;
}
String name = key.toString();
if (ArrayUtils.contains(subnodes, name)) {
return this.getValueMap(name + "/");
}
return this.getValueMap(name).get(this.getPropertyName(name));
}
/**
* {@inheritDoc}
*/
@Override
public Object put(String key, Object value) {
if ( key == null ) {
return null;
}
final String name = key.toString();
// only allow exposed sub-nodes to be updated
if (name.indexOf("/") > -1) {
String subnode = name.substring(0, name.indexOf("/"));
if (ArrayUtils.contains(subnodes, subnode)) {
return this.getValueMap(name).put(this.getPropertyName(name), value);
} else {
return null;
}
}
return this.getValueMap(name).put(this.getPropertyName(name), value);
}
/**
* {@inheritDoc}
*/
@Override
public void putAll(Map t) {
for (String key : t.keySet()) {
put(key, t.get(key));
}
}
/**
* {@inheritDoc}
*/
public Set keySet() {
return buildAggregatedMap().keySet();
}
/**
* {@inheritDoc}
*/
public Collection