com.adobe.cq.social.srp.internal.MapResourceImpl Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2012 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.cq.social.srp.internal;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingConstants;
import org.apache.sling.api.resource.AbstractResource;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ValueMapDecorator;
import com.adobe.cq.social.srp.SocialResourceProvider;
import com.adobe.cq.social.srp.utilities.internal.InternalSocialResourceUtilities;
import com.adobe.cq.social.srp.utilities.internal.InternalStaticResourceUtilities;
public class MapResourceImpl extends AbstractResource implements MapResource {
private final ResourceResolver resolver;
private final CachingResourceProvider provider;
private final Map doc;
private ResourceMetadata metadata;
private final boolean isAttachment;
private final String resolvedPath;
private static final String ATTACHMENT_SUB_PATH = "attachments";
private static final String CONTENT_SUB_PATH = "content";
public MapResourceImpl(final ResourceResolver resolver, final CachingResourceProvider provider,
final String resolvedPath, final Map doc, final boolean isAttachment) {
this.resolver = resolver;
this.provider = provider;
this.doc = doc;
this.metadata = new ResourceMetadata();
this.metadata.setResolutionPath(resolvedPath);
this.isAttachment = isAttachment;
this.resolvedPath = resolvedPath;
if (isAttachment) {
setAttachmentMetaData();
}
}
/**
* set meta data for attachments
*/
private void setAttachmentMetaData() {
final Calendar created = (Calendar) doc.get(AbstractSchemaMapper.getSocoAddedKey());
if (created != null) {
metadata.setCreationTime(created.getTimeInMillis());
metadata.setModificationTime(created.getTimeInMillis()); // we don't store mod time with attachments yet
}
final Long length = (Long) doc.get(AbstractSchemaMapper.getSchemaAttachmentLengthKey());
if (length != null) {
metadata.setContentLength(length);
}
}
/**
* {@inheritDoc}
*/
@Override
public Resource getParent() {
final String parentPath = (String) doc.get(InternalSocialResourceUtilities.PN_PARENTID);
if (StringUtils.isEmpty(parentPath)) {
return null;
}
return getResourceResolver().getResource(parentPath);
}
/**
* {@inheritDoc}
*/
@Override
public String getPath() {
return metadata.getResolutionPath();
}
/**
* {@inheritDoc}
*/
@Override
public String getResourceType() {
final String type =
(String) doc.get(SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE);
if (type == null) {
return "nt:adobesocialtype";
}
return type;
}
/**
* {@inheritDoc}
*/
@Override
public String getResourceSuperType() {
return (String) doc.get(SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE);
}
/**
* {@inheritDoc}
*/
@Override
public ResourceMetadata getResourceMetadata() {
return metadata;
}
/**
* {@inheritDoc}
*/
@Override
public ResourceResolver getResourceResolver() {
return resolver;
}
/**
* {@inheritDoc}
*/
@Override
public SocialResourceProvider getResourceProvider() {
return provider;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public AdapterType adaptTo(final Class type) {
if (type == ValueMap.class) {
return (AdapterType) new ValueMapDecorator(applyIncrement());
} else if (type == ModifiableValueMap.class) {
return (AdapterType) new SocialModifiableValueMap(this);
} else if (type == Map.class) {
return (AdapterType) doc;
} else if (type == InputStream.class) {
try {
return (AdapterType) this.provider.getAttachmentInputStream(resolver, resolvedPath);
} catch (final IOException e) {
return null; // return null according to adaptTo doc
}
}
return super.adaptTo(type);
}
private Map applyIncrement() {
if (doc.containsKey(CachingResourceProvider.INC) && doc.get(CachingResourceProvider.INC) instanceof Map) {
// apply increment values to properties
final Map incMap = (Map) doc.get(CachingResourceProvider.INC);
final Map temp = new HashMap();
for (final Map.Entry entry : incMap.entrySet()) {
final Long increment = entry.getValue();
if (doc.containsKey(entry.getKey())) {
final Object startValue = doc.get(entry.getKey());
if (startValue instanceof Long) {
temp.put(entry.getKey(), (Long) startValue + increment);
} else if (startValue instanceof Integer) {
temp.put(entry.getKey(), ((Integer) startValue).longValue() + increment);
}
} else {
temp.put(entry.getKey(), increment);
}
}
final Map newDoc = new HashMap();
newDoc.putAll(doc);
newDoc.putAll(temp);
newDoc.remove(CachingResourceProvider.INC);
return newDoc;
} else {
return doc;
}
}
/**
* {@inheritDoc}
*/
public void update() {
this.provider.update(this);
}
@Override
public Resource getRootJCRNode() {
if (this.doc.containsKey(InternalSocialResourceUtilities.PN_CS_ROOT)) {
return this.getResourceResolver().resolve(
(String) this.doc.get(InternalSocialResourceUtilities.PN_CS_ROOT));
}
return null;
}
@Override
public boolean isAttachment() {
return isAttachment;
}
/**
* Unlocks the metadata for this resource. When the resources are cached their metatadata needs to be unlocked
* before being returned to the caller.
*/
@Override
public void unlockMetadata() {
final String resolvedPath = this.metadata.getResolutionPath();
this.metadata = new ResourceMetadata();
this.metadata.setResolutionPath(resolvedPath);
if (isAttachment) {
setAttachmentMetaData();
}
}
private String getJcrAclPath() {
return getAclPathGivenBase(getPath(), provider.getASIPath());
}
public static String getAclPathGivenBase(final String path, final String providerBase) {
final String ugcPathPrefix = StringUtils.removeEnd(InternalSocialResourceUtilities.PATH_UGC, "/");
String aclPath =
ugcPathPrefix + "/" + StringUtils.removeStart(StringUtils.removeStart(path, providerBase), "/");
String attachmentPathPrefix = ugcPathPrefix + "/" + ATTACHMENT_SUB_PATH + "/";
if (StringUtils.startsWith(aclPath, attachmentPathPrefix)) {
String contentPathPrefix = ugcPathPrefix + "/" + CONTENT_SUB_PATH + "/";
// Replacing /content/usergenerated/attachments/ with /content/usergenerated/content/
aclPath = StringUtils.replace(aclPath, attachmentPathPrefix, contentPathPrefix);
}
return aclPath;
}
@Override
public boolean checkPermissions(final String permission) {
return InternalStaticResourceUtilities.checkPermission(resolver, getJcrAclPath(), permission);
}
}