All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.crx.packaging.gfx.DownloadResource Maven / Gradle / Ivy

/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
*  Copyright 2011 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.day.crx.packaging.gfx;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.jackrabbit.util.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provides convenience methods for rendering download paragraphs.
 */
public class DownloadResource  {

    /**
     * internal logger
     */
    private static final Logger log = LoggerFactory.getLogger(DownloadResource.class);

    /**
     * name of the file reference property. this can hold a path to a
     * file or resource node, to a binary property or a uuid to a resource node.
     */
    public static final String PN_REFERENCE = "fileReference";

    /**
     * name of the file node.
     */
    public static final String NN_FILE = "file";

    /**
     * name of the 'file name' property.
     */
    public static final String PN_FILE_NAME = "fileName";

    /**
     * name of the title property.
     */
    public static final String PN_TITLE = Property.JCR_TITLE;

    /**
     * name of the description property
     */
    public static final String PN_DESCRIPTION = Property.JCR_DESCRIPTION;

    /**
     * internal node
     */
    protected final Node node;

    /**
     * map of overlaid properties.
      */
    private final Map overlaid = new HashMap();

    /**
     * path to the file node.
     */
    private String fileNodePath = null;

    /**
     * href/src attribute
     */
    private String source = null;

    /**
     * extension for the source attribute
     */
    private String extension = ".res";

    /**
     * selector for the src attribute.
     */
    private String selector = "";

    /**
     * suffix for the src attribute
     */
    private String suffix = null;

    /**
     * map of tag attributes
     */
    protected Map attrs;

    /**
     * the inner html object for drawing the link.
     */
    private Object innerHtml;

    /**
     * cached file data property
     * @see #getData()
     */
    private Property data;

    /**
     * internal mapping for item names.
     */
    private Map itemNames = new HashMap();

    /**
     * Creates a new download based on the given resource. the file properties
     * are considered to be 'on' the given resource.
     *
     * @param node node of the resource
     * @throws IllegalArgumentException if the given resource is not adaptable to node.
     */
    public DownloadResource(Node node) {
        this.node = node;
    }

    /**
     * Get a property either from the overlaid map or the underlying properties.
     *
     * @param name name of the property
     * @return string value of the property or an empty string
     */
    public String get(String name) {
        String value = overlaid.get(name);
        if (value == null) {
            try {
                value = node.getProperty(name).getString();
            } catch (RepositoryException e) {
                // ignore
                value = "";
            }
        }
        return value;
    }

    /**
     * Get a property and convert it to an integer. If any exception
     * occurs, return the default value.
     *
     * @param name name of the property
     * @param defaultValue default value
     * @return integer value
     */
    public int get(String name, int defaultValue) {
        try {
            return Integer.parseInt(get(name));
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * Set a property to the overlaid map.
     *
     * @param name  name of the property
     * @param value value of the property
     */
    public void set(String name, String value) {
        overlaid.put(name, value);
    }

    /**
     * Adds a tag attribute to this download. The attributes are included when
     * {@link #draw(Writer) drawing} the tag.
     *
     * @param name  name of the attribute
     * @param value value of the attribute
     */
    public void addAttribute(String name, String value) {
        if (attrs == null) {
            attrs = new HashMap();
        }
        attrs.put(name, value);
    }

    /**
     * Adds a CSS class name to the respective attribute. If the class name
     * is already present, nothing is added.
     * @param name the class name
     */
    public void addCssClass(String name) {
        if (attrs == null || !attrs.containsKey("class")) {
            addAttribute("class", name);
        } else {
            String prev = attrs.get("class");
            if (prev.length() == 0) {
                prev = name;
            } else if (!prev.equals(name)
                    && !prev.contains(" " + name)
                    && !prev.contains(name + " ")) {
                prev += " " + name;
            }
            attrs.put("class", prev);
        }
    }

    /**
     * Calculates all default values if 'source' is null
     */
    public void init() {
        if (source == null) {
            // calculate default file node path
            if (fileNodePath == null) {
                fileNodePath = getItemName(NN_FILE);
            }
            if (fileNodePath.length() > 0 && fileNodePath.charAt(0) != '/') {
                try {
                    if (node != null && node.hasNode(fileNodePath)) {
                        fileNodePath = node.getNode(fileNodePath).getPath();
                    } else {
                        fileNodePath = "";
                    }
                } catch (RepositoryException e) {
                    fileNodePath = "";
                    log.warn("Error while accessing the repository.", e);
                }
            }

            // calculate file name
            String fileName = get(getItemName(PN_FILE_NAME));
            if (fileName.length() == 0) {
                String fileRef = getFileReference();
                if (fileRef != null && fileRef.length() > 0) {
                    fileName = Text.getName(fileRef);
                } else {
                    fileName = "";
                }
                set(getItemName(PN_FILE_NAME), fileName);
            }
            // override suffix if not defined
            if (suffix == null) {
                setSuffix(fileName);
            }

            // calculate source
            if (selector.length() > 0) {
                source = getPath() + getSelector() + getExtension() + getSuffix();
            } else if (fileNodePath.length() > 0) {
                source = fileNodePath + getExtension() + getSuffix();
            } else if (getFileReference().length() > 0) {
                source = getFileReference();
            }
        }
    }

    public String getPath() {
        try {
            return node.getPath();
        } catch (RepositoryException e) {
            return "";
        }
    }

    /**
     * Returns the name of the given item which is either the default or
     * can be redefined by {@link #setItemName(String, String)}. If the name
     * is not defined, the given name is returned.
     *
     * Example: Download.getItemName(Download.PN_FILE_NAME)
     * @param name item name
     * @return defined item name
     */
    public String getItemName(String name) {
        return itemNames.containsKey(name) ? itemNames.get(name) : name;
    }

    /**
     * Defines the name of an item.
     * @param key key. eg {@link #PN_FILE_NAME}.
     * @param name redefined name
     */
    public void setItemName(String key, String name) {
        itemNames.put(key, name);
    }

    /**
     * Returns the file reference.
     * @return the file reference.
     */
    public String getFileReference() {
        return get(getItemName(PN_REFERENCE));
    }

    /**
     * Sets the file reference.
     *
     * @param fileReference the file reference.
     */
    public void setFileReference(String fileReference) {
        set(getItemName(PN_REFERENCE), fileReference);
    }

    /**
     * Returns the inner html object for the download link.
     * @return the inner html or null if not defined.
     */
    public Object getInnerHtml() {
        return innerHtml;
    }

    /**
     * Sets the inner html object for the download. If not inner html is defined
     * the file name is used when drawing the download link.
     *
     * @param innerHtml the inner html object
     */
    public void setInnerHtml(Object innerHtml) {
        this.innerHtml = innerHtml;
    }

    /**
     * Returns the file path. This defaults to the path of the node addressed
     * by 'getItemName(NN_FILE)' or an empty string if that node does
     * not exist.
     *
     * @return path of the file node.
     */
    public String getFileNodePath() {
        init();
        return fileNodePath;
    }

    /**
     * Sets the path to the file node. Set this to an empty string to disable
     * fetching data from the respective node. the path can be relative to
     * address a node relative to the image node.
     *
     * @param fileNodePath path of the file node.
     */
    public void setFileNodePath(String fileNodePath) {
        this.fileNodePath = fileNodePath;
    }

    /**
     * Returns the file name of this download as defined by the property with
     * the name from 'getItemName(PN_FILE_NAME). this is an informative property
     * and is not used for any logic. the file name is added per default as
     * suffix to the link path.
     *
     * @return file name.
     */
    public String getFileName() {
        init();
        return get(getItemName(PN_FILE_NAME));
    }

    /**
     * Sets the file name.
     * @param fileName the file name
     */
    public void setFileName(String fileName) {
        set(getItemName(PN_FILE_NAME), fileName);
    }

    /**
     * Returns the image title as defined by 'getItemName(PN_TITLE)'
     * or overridden by {@link #setTitle(String)}.
     *
     * @return the title
     */
    public String getTitle() {
        return getTitle(false);
    }

    /**
     * Returns the image title as defined by 'getItemName(PN_TITLE)'
     * or overridden by {@link #setTitle(String)}.
     *
     * @param escape if true the string is HTML escaped
     * @return the title
     */
    public String getTitle(boolean escape) {
        return escape
                ? StringEscapeUtils.escapeHtml4(get(getItemName(PN_TITLE)))
                : get(getItemName(PN_TITLE));
    }

    /**
     * Sets the title.
     *
     * @param title the title.
     */
    public void setTitle(String title) {
        set(getItemName(PN_TITLE), title);
    }

    /**
     * Returns the image description as defined by getItemName(PN_DESCRIPTION)
     * or overridden by {@link #setDescription(String)}.
     *
     * @return the description
     */
    public String getDescription() {
        return getDescription(false);
    }

    /**
     * Returns the image description as defined by 'getItemName(PN_DESCRIPTION)'
     * or overridden by {@link #setDescription(String)}.
     *
     * @param escape if true the string is HTML escaped
     * @return the description
     */
    public String getDescription(boolean escape) {
        return escape
                ? StringEscapeUtils.escapeHtml4(get(getItemName(PN_DESCRIPTION)))
                : get(getItemName(PN_DESCRIPTION));
    }

    /**
     * Sets the description.
     * @param description the description.
     */
    public void setDescription(String description) {
        set(getItemName(PN_DESCRIPTION), description);
    }

    /**
     * Returns the href attribute of this download. the source is computed as
     * follows:
     * 
    *
  • if a selector is defined the path of the current resource concatenated * with the selector, extension, and suffix is used. *
  • if a file node path is defined it is concatenated with the extension and suffix. *
  • if a file reference is defined it is concatenated with the suffix. *
* * @return the href attribute */ public String getHref() { init(); return source; } /** * Sets the href attribute * @param href the href attribute */ public void setHref(String href) { this.source = href; } /** * Returns the extension. defaults to .res * @return the extension. */ public String getExtension() { return extension; } /** * Sets the extension. * @param extension the extension. */ public void setExtension(String extension) { if (extension == null) { this.extension = ""; } else if (!extension.startsWith(".")) { this.extension = "." + extension; } else { this.extension = extension; } } /** * Returns the icon type of this file. * * Note: currently the mime type of the file is not respected but only the * extension of the file name is used. * * @return the icon type. */ public String getIconType() { String fileName = getFileName(); if (fileName.lastIndexOf('.') > 0) { return fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase(); } return "dat"; } /** * Returns a path to an icon representing the file. * * @return a path to an icon or null. */ public String getIconPath() { return null; } /** * Returns the suffix. defaults to "" * @return the suffix. */ public String getSuffix() { return suffix; } /** * Sets the suffix. * @param suffix the suffix. */ public void setSuffix(String suffix) { if (source != null) { log.warn("Illegal call to setSuffix() after source already calculated."); } if (suffix == null || suffix.length() == 0) { this.suffix = ""; } else if (!suffix.startsWith("/")) { this.suffix = "/" + suffix; } else { this.suffix = suffix; } } /** * Returns the selector string. defaults to an empty string. * * Note: in order to use a spool script, you need to defined the selector, * otherwise the file will be addressed directly. * * @return the selector string. */ public String getSelector() { return selector; } /** * Sets the selector string. * @param selector the selector string. */ public void setSelector(String selector) { if (source != null) { log.warn("Illegal call to setSelector() after source already calculated."); } if (selector == null) { this.selector = ""; } else if (!selector.startsWith(".")) { this.selector = "." + selector; } else { this.selector = selector; } } /** * Checks if this download has content. i.e. if there either an file or an * file reference defined and they have binary data. * * @return true if this download has content. */ public boolean hasContent() { try { return getData() != null; } catch (RepositoryException e) { // ignore return false; } } /** * Writes this download as link tag to the given writer * @param w the writer * @throws IOException if an I/O error occurs */ public void draw(Writer w) throws IOException { if (!hasContent()) { return; } PrintWriter out = new PrintWriter(w); out.printf(" e : attrs.entrySet()) { out.printf("%s=\"%s\" ", StringEscapeUtils.escapeHtml4(e.getKey()), StringEscapeUtils.escapeHtml4(e.getValue())); } } out.print(">"); out.print(innerHtml == null ? getFileName() : innerHtml); out.print(""); } /** * Returns a string representation as HTML tag of this image. * @return the HTML tag. */ public String getString() { StringWriter w = new StringWriter(); try { draw(w); } catch (IOException e) { // should never occur } return w.getBuffer().toString(); } /** * Returns the mime type of this image. This is a convenience method that * gets the {@value Property#JCR_MIMETYPE} sibling property of the * data property returned by {@link #getData()}. * * @return the mime type of the image or null if the image * has no content. * @throws RepositoryException if an error accessing the repository occurs. */ public String getMimeType() throws RepositoryException { Property data = getData(); if (data == null) { return null; } return data.getParent().getProperty(Property.JCR_MIMETYPE).getString(); } /** * Returns the last modified of this image. This is a convenience method that * gets the {@value Property#JCR_LAST_MODIFIED} sibling property of the * data property returned by {@link #getData()}. * * @return the last modified of the image or null if the image * has no content. * @throws RepositoryException if an error accessing the repository occurs. */ public Calendar getLastModified() throws RepositoryException { Property data = getData(); if (data == null) { return null; } return data.getParent().getProperty(Property.JCR_LAST_MODIFIED).getDate(); } /** * Returns the property that contains the binary data of this download. This * can either by a property addressed by the internal file resource or a * property addressed by an external file reference. * * @return binary property or null * @throws RepositoryException if an error accessing the repository occurs. */ public Property getData() throws RepositoryException { if (data != null) { return data; } if (node == null) { return null; } String ref = getFileReference(); Session s = node.getSession(); Node fileNode; if (ref.length() > 0) { if (ref.charAt(0) != '/') { // assume uuid //noinspection deprecation fileNode = s.getNodeByUUID(ref); } else { Node res = getReferencedNode(ref); if (res != null) { fileNode = res; } else { return null; } } } else if (node.hasNode(getItemName(NN_FILE))) { fileNode = node.getNode(getItemName(NN_FILE)); } else { return null; } if (fileNode.hasNode(Property.JCR_CONTENT)) { fileNode = fileNode.getNode(Property.JCR_CONTENT); } if (fileNode.hasProperty(Property.JCR_DATA)) { return data = fileNode.getProperty(Property.JCR_DATA); } return null; } /** * Returns the resource that is referenced by path. Subclasses can provide * further semantics. * @param path path to the resource * @return the resource or null. */ protected Node getReferencedNode(String path) { try { return node.getSession().getNode(path); } catch (RepositoryException e) { return null; } } /** * Returns a map of attributes. * @return the attributes map. */ public Map getAttributes() { return attrs; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy