org.sakaiproject.nakamura.api.resource.lite.SparseContentResource.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.nakamura.api.resource.lite.SparseContentResource.java

Source

/**
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF 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.sakaiproject.nakamura.api.resource.lite;

import static org.apache.commons.lang.CharEncoding.UTF_8;

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.commons.json.JSONException;
import org.sakaiproject.nakamura.api.lite.Session;
import org.sakaiproject.nakamura.api.lite.StorageClientException;
import org.sakaiproject.nakamura.api.lite.StorageClientUtils;
import org.sakaiproject.nakamura.api.lite.accesscontrol.AccessDeniedException;
import org.sakaiproject.nakamura.api.lite.content.Content;
import org.sakaiproject.nakamura.api.lite.content.ContentManager;
import org.sakaiproject.nakamura.util.ExtendedJSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.Map;

/**
 * Wrapper for {@link Content} objects to become a {@link Resource}
 */
public class SparseContentResource extends AbstractResource {
    /**
     * Servlets that are designed to deal with any Sparse Content may bind to this resource Type. All Sparse Content has this Resource Type as a Super type.
     * Do not bind to sling/servlet/default or try and using an opting servlet as this will not work.
     */
    public static final String SPARSE_CONTENT_RT = "sparse/Content";

    /**
     * If the Sparse Content contains no "sling:resourceType" property, then the
     * Resource will return this as the fallback resource type. (More or less
     * takes the place of "nt:unstructured" in the JCR world.)
     */
    public static final String SPARSE_CONTENT_UNKNOWN_RT = "sparse/unknown";

    private static final Logger logger = LoggerFactory.getLogger(SparseContentResource.class);

    private Content content;
    private Session session;
    private ResourceResolver resourceResolver;
    private ResourceMetadata metadata;
    private String resourcePath;

    private ContentManager contentManager;

    public SparseContentResource(Content content, Session session, ResourceResolver resourceResolver)
            throws StorageClientException {
        this(content, session, resourceResolver, null);
    }

    public SparseContentResource(Content content, Session session, ResourceResolver resourceResolver,
            String resourcePath) throws StorageClientException {
        this.content = content;
        this.session = session;
        this.contentManager = session.getContentManager();
        this.resourceResolver = resourceResolver;
        this.resourcePath = resourcePath;

        if (content != null) {
            Map<String, Object> props = content.getProperties();
            metadata = new ResourceMetadata();
            metadata.setCharacterEncoding(UTF_8);
            metadata.setContentLength(StorageClientUtils.toLong(props.get(Content.LENGTH_FIELD)));
            metadata.setCreationTime(StorageClientUtils.toLong(props.get(Content.CREATED_FIELD)));
            metadata.setModificationTime(StorageClientUtils.toLong(props.get(Content.LASTMODIFIED_FIELD)));
            metadata.setResolutionPath(content.getPath());
            metadata.setResolutionPathInfo(content.getPath());
            if (content.hasProperty(Content.MIMETYPE_FIELD)) {
                metadata.setContentType((String) content.getProperty(Content.MIMETYPE_FIELD));
            }
        } else {
            // TODO Better argument checking? Throw IAE?
            IllegalArgumentException iae = new IllegalArgumentException("content is null");
            logger.warn(iae.getLocalizedMessage(), iae);
        }
    }

    /**
     * {@inheritDoc}
     * @see org.sakaiproject.nakamura.api.resource.lite.AbstractResource#adaptTo(java.lang.Class)
     */
    @SuppressWarnings("unchecked")
    @Override
    public <Type> Type adaptTo(Class<Type> type) {
        Type retval = null;
        if (type == Content.class) {
            retval = (Type) content;
        } else if (type == ContentManager.class) {
            retval = (Type) contentManager;
        } else if (type == Session.class) {
            retval = (Type) session;
        } else if (type == InputStream.class) {
            try {
                retval = (Type) contentManager.getInputStream(content.getPath());
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            } catch (AccessDeniedException e) {
                logger.error(e.getMessage(), e);
            } catch (StorageClientException e) {
                logger.error(e.getMessage(), e);
            }
            if (retval == null) {
                try {
                    StringWriter sw = new StringWriter();
                    ExtendedJSONWriter writer = new ExtendedJSONWriter(sw);
                    writer.valueMap(content.getProperties());
                    String s = sw.toString();
                    ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes(UTF_8));
                    retval = (Type) bais;
                } catch (JSONException e) {
                    logger.error(e.getMessage(), e);
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        } else if (type == ValueMap.class) {
            // TODO BL120 logic in SparseValueMapDecorator may need another look
            SparseValueMapDecorator vm = new SparseValueMapDecorator(content.getProperties());
            retval = (Type) vm;
        } else {
            retval = super.adaptTo(type);
        }
        return retval;
    }

    /**
     * Returns the path at which the Resource was resolved, or the Content path
     * if the Resource path was not explicitly set. This allows divergences
     * between internal storage paths and externalized paths.
     *
     * @see org.apache.sling.api.resource.Resource#getPath()
     */
    public String getPath() {
        if (resourcePath != null) {
            return resourcePath;
        } else {
            return content.getPath();
        }
    }

    /**
     * {@inheritDoc}
     * @see org.apache.sling.api.resource.Resource#getResourceType()
     */
    public String getResourceType() {
        String type = (String) content.getProperty("sling:resourceType");
        if (type == null) {
            type = SPARSE_CONTENT_UNKNOWN_RT;
        }
        return type;
    }

    /**
     * {@inheritDoc}
     * @see org.apache.sling.api.resource.Resource#getResourceSuperType()
     */
    public String getResourceSuperType() {
        return SPARSE_CONTENT_RT;
    }

    /**
     * {@inheritDoc}
     * @see org.apache.sling.api.resource.Resource#getResourceMetadata()
     */
    public ResourceMetadata getResourceMetadata() {
        return metadata;
    }

    /**
     * {@inheritDoc}
     * @see org.apache.sling.api.resource.Resource#getResourceResolver()
     */
    public ResourceResolver getResourceResolver() {
        return resourceResolver;
    }

    /**
     * @see org.sakaiproject.nakamura.api.resource.lite.AbstractResource#listChildren()
     */
    @Override
    public Iterator<Resource> listChildren() {
        return new SparseContentResourceIterator(content.listChildren().iterator(), session, resourceResolver,
                this);
    }

    @Override
    public String toString() {
        return "{ path=\"" + getPath() + "\", resourceType=\"" + getResourceType() + "\", resourceSuperType=\""
                + getResourceSuperType() + "\" metadata=\"" + getResourceMetadata() + "\" }";
    }
}