Package org.apache.sling.jcr.resource.internal.helper.jcr

Source Code of org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResourceMetadata

/*
* 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.jcr;

import static org.apache.jackrabbit.JcrConstants.JCR_CONTENT;
import static org.apache.jackrabbit.JcrConstants.JCR_CREATED;
import static org.apache.jackrabbit.JcrConstants.JCR_DATA;
import static org.apache.jackrabbit.JcrConstants.JCR_ENCODING;
import static org.apache.jackrabbit.JcrConstants.JCR_LASTMODIFIED;
import static org.apache.jackrabbit.JcrConstants.JCR_MIMETYPE;
import static org.apache.jackrabbit.JcrConstants.NT_FILE;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;

import org.apache.sling.api.resource.ResourceMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class JcrNodeResourceMetadata extends ResourceMetadata {

    private static final long serialVersionUID = 1L;

    /** default log */
    private static final Logger LOGGER = LoggerFactory.getLogger(JcrNodeResource.class);

    private final Node node;
    private Node contentNode;
    private boolean nodePromotionChecked = false;
    private long creationTime = -1;
    private boolean populated = false;

    public JcrNodeResourceMetadata(final Node inNode) {
        this.node = inNode;
    }

    private Node promoteNode() {
        // check stuff for nt:file nodes
        try {
            if ( (!nodePromotionChecked) && node.isNodeType(NT_FILE)) {
                creationTime = node.getProperty(JCR_CREATED).getLong();

                // continue our stuff with the jcr:content node
                // which might be nt:resource, which we support below
                // if the node is new, the content node might not exist yet
                if (!node.isNew() || node.hasNode(JCR_CONTENT) ) {
                    contentNode = node.getNode(JCR_CONTENT);
                }
                nodePromotionChecked = true;
            }
        } catch (final RepositoryException re) {
            report(re);
        }
        return contentNode != null ? contentNode : node;
    }

    private void report(final RepositoryException re) {
        String nodePath = "<unknown node path>";
        try {
            nodePath = contentNode != null ? contentNode.getPath() : node.getPath();
        } catch (RepositoryException e) {
            // ignore
        }
        LOGGER.info(
            "setMetaData: Problem extracting metadata information for "
                    + nodePath, re);
    }

    @Override
    public Object get(final Object key) {
        final Object result = super.get(key);
        if (result != null) {
            return result;
        }

        if (CREATION_TIME.equals(key)) {
            promoteNode();
            internalPut(CREATION_TIME, creationTime);
            return creationTime;
        } else if (CONTENT_TYPE.equals(key)) {
            String contentType = null;
            final Node targetNode = promoteNode();
            try {
                if (targetNode.hasProperty(JCR_MIMETYPE)) {
                    contentType = targetNode.getProperty(JCR_MIMETYPE).getString();
                }
            } catch (final RepositoryException re) {
                report(re);
            }

            internalPut(CONTENT_TYPE, contentType);
            return contentType;
        } else if (CHARACTER_ENCODING.equals(key)) {
            String characterEncoding = null;
            final Node targetNode = promoteNode();
            try {
                if (targetNode.hasProperty(JCR_ENCODING)) {
                    characterEncoding = targetNode.getProperty(JCR_ENCODING).getString();
                }
            } catch (final RepositoryException re) {
                report(re);
            }
            internalPut(CHARACTER_ENCODING, characterEncoding);
            return characterEncoding;
        } else if (MODIFICATION_TIME.equals(key)) {
            long modificationTime = -1;
            final Node targetNode = promoteNode();
            try {
                if (targetNode.hasProperty(JCR_LASTMODIFIED)) {
                    // We don't check node type, so JCR_LASTMODIFIED might not be a long
                    final Property prop = targetNode.getProperty(JCR_LASTMODIFIED);
                    try {
                        modificationTime = prop.getLong();
                    } catch (final ValueFormatException vfe) {
                        LOGGER.debug("Property {} cannot be converted to a long, ignored ({})",
                            prop.getPath(), vfe);
                    }
                }
            } catch (final RepositoryException re) {
                report(re);
            }
            internalPut(MODIFICATION_TIME, modificationTime);
            return modificationTime;
        } else if (CONTENT_LENGTH.equals(key)) {
            long contentLength = -1;
            final Node targetNode = promoteNode();
            try {
                // if the node has a jcr:data property, use that property
                if (targetNode.hasProperty(JCR_DATA)) {
                    final Property prop = targetNode.getProperty(JCR_DATA);
                    contentLength = JcrItemResource.getContentLength(prop);
                } else {
                    // otherwise try to follow default item trail
                    Item item = getPrimaryItem(targetNode);
                    while (item != null && item.isNode()) {
                        item = getPrimaryItem((Node) item);
                    }
                    if ( item != null ) {
                        final Property data = (Property) item;

                        // set the content length property as a side effect
                        // for resources which are not nt:file based and whose
                        // data is not in jcr:content/jcr:data this will lazily
                        // set the correct content length
                        contentLength = JcrItemResource.getContentLength(data);
                    }
                }
            } catch (final RepositoryException re) {
                report(re);
            }
            internalPut(CONTENT_LENGTH, contentLength);
            return contentLength;
        }
        return null;
    }

    private Item getPrimaryItem(final Node node)
    throws RepositoryException {
        String name = node.getPrimaryNodeType().getPrimaryItemName();
        if (name == null) {
            return null;
        }
        if (node.hasProperty(name)) {
            return node.getProperty(name);
        } else if (node.hasNode(name)) {
            return node.getNode(name);
        } else {
            return null;
        }
    }

    private void populate() {
        if (populated) {
            return;
        }
        get(CREATION_TIME);
        get(CONTENT_TYPE);
        get(CHARACTER_ENCODING);
        get(MODIFICATION_TIME);
        get(CONTENT_LENGTH);
        populated = true;
    }

    @Override
    public Set<Map.Entry<String, Object>> entrySet() {
        populate();
        return super.entrySet();
    }

    @Override
    public Set<String> keySet() {
        populate();
        return super.keySet();
    }

    @Override
    public Collection<Object> values() {
        populate();
        return super.values();
    }

    @Override
    public int size() {
        populate();
        return super.size();
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    @Override
    public boolean containsKey(final Object key) {
        if (super.containsKey(key)) {
            return true;
        }
        if (CREATION_TIME.equals(key) ||
            CONTENT_TYPE.equals(key) ||
            CHARACTER_ENCODING.equals(key) ||
            MODIFICATION_TIME.equals(key) ||
            CONTENT_LENGTH.equals(key)) {
            return true;
        }
        return false;
    }

    @Override
    public boolean containsValue(final Object value) {
        if (super.containsValue(value)) {
            return true;
        }
        if (!populated) {
            populate();
            return super.containsValue(value);
        }
        return false;
    }
}
TOP

Related Classes of org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResourceMetadata

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.