001    /*
002     * Apache License
003     * Version 2.0, January 2004
004     * http://www.apache.org/licenses/
005     *
006     * Copyright 2008-2010 by chenillekit.org
007     *
008     * Licensed under the Apache License, Version 2.0 (the "License");
009     * you may not use this file except in compliance with the License.
010     * You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     */
014    
015    package org.chenillekit.tapestry.core.components;
016    
017    import org.apache.tapestry5.Asset;
018    import org.apache.tapestry5.BindingConstants;
019    import org.apache.tapestry5.ClientElement;
020    import org.apache.tapestry5.ComponentResources;
021    import org.apache.tapestry5.MarkupWriter;
022    import org.apache.tapestry5.annotations.Environmental;
023    import org.apache.tapestry5.annotations.Import;
024    import org.apache.tapestry5.annotations.Parameter;
025    import org.apache.tapestry5.annotations.SupportsInformalParameters;
026    import org.apache.tapestry5.ioc.annotations.Inject;
027    import org.apache.tapestry5.services.AssetSource;
028    import org.apache.tapestry5.services.javascript.JavaScriptSupport;
029    import org.chenillekit.tapestry.core.services.ThumbNailService;
030    
031    /**
032     * converts a image asset into a <a href="http://en.wikipedia.org/wiki/Thumbnail">thumbnail</a>.
033     *
034     * @version $Id: ThumbNail.java 674 2010-07-29 12:47:25Z homburgs $
035     */
036    @SupportsInformalParameters
037    @Import(library = {"../Chenillekit.js", "ThumbNail.js"})
038    public class ThumbNail implements ClientElement
039    {
040            /**
041             * The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
042             * times, a suffix will be appended to the to id to ensure uniqueness. The uniqued value may be accessed via the
043             * {@link #getClientId() clientId property}.
044             */
045            @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
046            private String clientId;
047    
048            /**
049             * the asset path or asset itself, that converted to thumbnail.
050             */
051            @Parameter(name = "asset", required = true, defaultPrefix = BindingConstants.LITERAL)
052            private Object assetObject;
053    
054            /**
055             * the height (pixel) of the thumbnail.
056             */
057            @Parameter(required = true, defaultPrefix = BindingConstants.PROP)
058            private int thumbHeight;
059    
060            /**
061             * output quality of the thumbnail.
062             */
063            @Parameter(value = "80", required = false, defaultPrefix = BindingConstants.PROP)
064            private float quality;
065    
066            /**
067             * if true, clicking mouse over the thumbnail show the original image.
068             */
069            @Parameter(value = "false", required = false, defaultPrefix = BindingConstants.PROP)
070            private boolean onClickAction;
071    
072            private String assignedClientId;
073    
074            @Environmental
075            private JavaScriptSupport javascriptSupport;
076    
077            @Inject
078            private ComponentResources resources;
079    
080            @Inject
081            private AssetSource assetSource;
082    
083            @Inject
084            private ThumbNailService thumbNailService;
085    
086            private Asset asset;
087    
088            /**
089             * Tapestry render phase method.
090             * Initialize temporary instance variables here.
091             */
092            void setupRender()
093            {
094                    // By default, use the component id as the (base) client id. If the clientid
095                    // parameter is bound, then that is the value to use.
096                    // Often, these controlName and _clientId will end up as the same value. There are many
097                    // exceptions, including a form that renders inside a loop, or a form inside a component
098                    // that is used multiple times.
099                    assignedClientId = javascriptSupport.allocateClientId(clientId);
100    
101                    if (assetObject instanceof String)
102                            asset = assetSource.getAsset(resources.getBaseResource(), (String) assetObject, null);
103                    else if (assetObject instanceof Asset)
104                            asset = (Asset) assetObject;
105                    else
106                            throw new RuntimeException("parameter 'asset' neither a string nor an asset object");
107            }
108    
109            /**
110             * Tapestry render phase method.
111             * Start a tag here, end it in afterRender
112             *
113             * @param writer the markup writer
114             */
115            void beginRender(MarkupWriter writer)
116            {
117                    writer.element("img", "id", getClientId(), "src", generateThumbNail().toClientURL());
118                    resources.renderInformalParameters(writer);
119            }
120    
121            /**
122             * Tapestry render phase method. End a tag here.
123             *
124             * @param writer the markup writer
125             */
126            void afterRender(MarkupWriter writer)
127            {
128                    writer.end();
129    
130                    if (onClickAction)
131                            javascriptSupport.addScript("new Ck.ThumbNail('%s', '%s');", getClientId(), asset.toClientURL());
132            }
133    
134            private Asset generateThumbNail()
135            {
136                    return thumbNailService.convertToThumbnail(asset, thumbHeight, quality);
137            }
138    
139    
140            /**
141             * Returns a unique id for the element. This value will be unique for any given rendering of a
142             * page. This value is intended for use as the id attribute of the client-side element, and will
143             * be used with any DHTML/Ajax related JavaScript.
144             */
145            public String getClientId()
146            {
147                    return assignedClientId;
148            }
149    }