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

com.day.cq.wcm.foundation.Image Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 1997-2008 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */

package com.day.cq.wcm.foundation;

import java.io.PrintWriter;
import java.util.Calendar;
import java.util.Map;

import com.day.cq.wcm.api.designer.Designer;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;

import com.day.cq.commons.ImageResource;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.Rendition;
import com.day.cq.wcm.api.components.Component;
import com.day.cq.wcm.api.components.DropTarget;
import com.day.cq.wcm.api.designer.Style;
import com.day.cq.wcm.commons.WCMUtils;
import com.day.cq.wcm.core.impl.warp.TimeWarpFilter;
import com.day.text.Text;

/**
 * Provides convenience methods for displaying images.
 */
public class Image extends ImageResource {

    /**
     * name of the image map property
     */
    public static final String PN_IMAGE_MAP = "imageMap";

    /**
     * id of the image map
     */
    private String imageMapId;

    /**
     * deserialized image map
     */
    private ImageMap imageMap;

    /**
     * flag controlling if a placeholder image should be rendered if this image
     * has no content.
     */
    private boolean noPlaceholder;

    /**
     * Designer for image resource
     */
    private Designer designer;

    /**
     * Default image to use when no image is selected
     */
    private static final String DEFAULT_IMAGEPATH = "/resources/0.gif";

    /**
     * Creates a new image based on the given resource. the image properties are
     * considered to 'on' the given resource.
     *
     * @param resource resource of the image
     * @throws IllegalArgumentException if the given resource is not adaptable to node.
     */
    public Image(Resource resource) {
        super(resource);

        // init default params
        imageMap = null;

        designer = resource.getResourceResolver().adaptTo(Designer.class);

        if (properties.containsKey(PN_IMAGE_MAP)) {
            try {
                String mapDefinition = properties.get(PN_IMAGE_MAP, "");
                if (mapDefinition.length() > 0) {
                    imageMap = ImageMap.fromString(mapDefinition);
                    imageMapId = "map_"
                            + Math.round(Math.random() * Integer.MAX_VALUE) + "_"
                            + System.currentTimeMillis();
                }
            } catch (IllegalArgumentException iae) {
                // ignore wrong map definition
                imageMap = null;
                imageMapId = null;
            }
        }

        setTimewarpParametersIfSupported(resource);
    }

    /**
     * If a timewarp is performed it needs to forward the timestamp.
     * 
     * @param resource Image resource
     */
    private void setTimewarpParametersIfSupported(Resource resource) {
        Object timewarpTime = resource.getResourceResolver().getAttribute(
            TimeWarpFilter.TIMEWARP);
        if (timewarpTime != null && timewarpTime instanceof Calendar) {
            long time = ((Calendar) timewarpTime).getTimeInMillis();
            addQueryParam(TimeWarpFilter.TIMEWARP, String.valueOf(time));
            adjustSuffixToTimewarpTime(time);
        }
    }

    /**
     * When an image component is newer than asset versions, the timestamp in
     * the suffix will be the one of the component. This causes caching problems
     * and it needs to adjust the timestamp to the requested by the timewarp.
     * 
     * @param time Timewarp time
     */
    private void adjustSuffixToTimewarpTime(long time) {
        String suffix = getSuffix();
        String[] tokens = StringUtils.split(suffix, ".", 2);
        if (tokens.length == 2
            && Long.parseLong(StringUtils.removeStart(tokens[0], "/")) > time) {
            setSuffix(String.valueOf(time) + '.' + tokens[1]);
        }
    }

    /**
     * Creates a new image based on the given resource. the image properties are
     * considered to 'on' the given resource unless imageName
     * is specified. then the respective child resource holds the image
     * properties.
     *
     * @param resource  current resource
     * @param imageName name of the image resource
     * @throws IllegalArgumentException if the given resource is not adaptable to node.
     */
    public Image(Resource resource, String imageName) {
        this(getRelativeResource(resource, imageName));
    }

    /**
     * Sets the drop target id for this image. the id is added as css class
     * to the image attribute. and has the format:
     * "{@value DropTarget#CSS_CLASS_PREFIX}{id}-{classifier}"
     *
     * @param id the drop target id as configured in edit config.
     * @param classifier optional classifier
     */
    public void setDropTargetId(String id, String classifier) {
        if (classifier == null) {
            classifier = "";
        }
        if (!classifier.startsWith("-")) {
            classifier = "-" + classifier;
        }
        addCssClass(DropTarget.CSS_CLASS_PREFIX + id + classifier);
    }

    /**
     *
     * Sets the drop target id for this image, using the name of the resources
     * as path.
     *
     * @param id the drop target id as configured in edit config.
     */
    public void setDropTargetId(String id) {
        String classifier = ResourceUtil.isNonExistingResource(this)
                ? String.valueOf(System.currentTimeMillis())
                : Text.getName(getPath());
        setDropTargetId(id, classifier);
    }

    /**
     * Returns the placeholder flag.
     * @return true if no placeholder for empty content should be
     *         drawn.
     */
    public boolean hasNoPlaceholder() {
        return noPlaceholder;
    }

    /**
     * Sets the placeholder flag.
     * @param noPlaceholder if true no placeholder for empty content
     *        is used.
     */
    public void setNoPlaceholder(boolean noPlaceholder) {
        this.noPlaceholder = noPlaceholder;
    }

    /**
     * Loads several definitions from style.
     * 

* Currently, the minimum/maximum width and height are transferred from the given style. * * @param style style to load definitions from */ public void loadStyleData(Style style) { // load additional definitions from style if (style != null) { this.set(Image.PN_MIN_WIDTH, style.get("minWidth", "")); this.set(Image.PN_MIN_HEIGHT, style.get("minHeight", "")); this.set(Image.PN_MAX_WIDTH, style.get("maxWidth", "")); this.set(Image.PN_MAX_HEIGHT, style.get("maxHeight", "")); } } /** * {@inheritDoc} * * @return true if {@link #hasNoPlaceholder()} is false * or the image has content. */ @Override protected boolean canDraw() { return !noPlaceholder || hasContent(); } @Override protected Map getImageTagAttributes() { String src = null; if (!hasContent()) { // when there is no content to display use default image src if (designer != null) { src = designer.getDefaultDesign().getPath() + DEFAULT_IMAGEPATH; } if (isTouchAuthoringUIMode()) { // add default empty text if necessary Map attrs = getAttributes(); if (attrs.get(Placeholder.ATTRIBUTE_EMTPYTEXT) == null) { addAttribute(Placeholder.ATTRIBUTE_EMTPYTEXT, "Image"); } // add placeholder classes addCssClass(Placeholder.DEFAULT_PLACEHOLDER_TOUCH); addCssClass("file"); } else { addCssClass("cq-image-placeholder"); } } Map attributes = super.getImageTagAttributes(); if (src != null) { attributes.put("src", src); } if (imageMap != null) { attributes.put("usemap", "#" + imageMapId); } return attributes; } /** * {@inheritDoc} */ @Override protected void doDraw(PrintWriter w) { super.doDraw(w); if (imageMap != null) { w.print(imageMap.draw(imageMapId)); } } /** * {@inheritDoc} * * Checks if the component of the resource provides an icon for the * respective type. */ @Override public String getIconPath() { // Note: copied from Download.java, since we cannot extend from 2 classes. // whenever you change this, also update the copy in Download.java Component c = WCMUtils.getComponent(this); if (c == null) { return null; } Resource icon = c.getLocalResource("resources/" + getIconType() + ".gif"); if (icon == null) { icon = c.getLocalResource("resources/default.gif"); } return icon == null ? null : icon.getPath(); } /** * {@inheritDoc} * * Checks if the resource is an asset and returns the correct rendition. */ @Override protected Resource getReferencedResource(String path) { // Note: copied from Download.java, since we cannot extend from 2 classes. // whenever you change this, also update the copy in Download.java Resource res = super.getReferencedResource(path); if (res != null) { // check for asset Asset asset = res.adaptTo(Asset.class); if (asset != null) { final Rendition rendition = asset.getRendition(new WCMRenditionPicker()); res = (null != rendition) ? rendition.adaptTo(Resource.class) : null; } } return res; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy