/* * Copyright 2017 OmniFaces * * Licensed 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.omnifaces.cdi; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.Date; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Stereotype; import javax.inject.Named; import org.omnifaces.component.output.GraphicImage; import org.omnifaces.el.ExpressionInspector; import org.omnifaces.el.MethodReference; import org.omnifaces.resourcehandler.DefaultResourceHandler; import org.omnifaces.resourcehandler.DynamicResource; import org.omnifaces.resourcehandler.GraphicResource; import org.omnifaces.resourcehandler.GraphicResourceHandler; /** * <p> * Stereo type that designates a bean with one or more methods returning <code>byte[]</code> or <code>InputStream</code> * as a named application scoped bean specifically for serving graphic images via <code><o:graphicImage></code> * component or <code>#{of:graphicImageURL()}</code> EL functions. * <pre> * import org.omnifaces.cdi.GraphicImageBean; * * @GraphicImageBean * public class Images { * * @Inject * private ImageService service; * * public byte[] get(Long id) { * return service.getContent(id); * } * * } * </pre> * <p> * When using <code>@Named @ApplicationScoped</code> instead, serving graphic images via a JSF page will continue to * work, but when the server restarts, then hotlinking/bookmarking will stop working until the JSF page referencing the * same bean method is requested for the first time. This is caused by a security restriction which should prevent users * from invoking arbitrary bean methods by manipulating the URL. The <code>@GraphicImageBean</code> basically enables * endusers to invoke any public method returning a <code>byte[]</code> or <code>InputStream</code> on the bean by just * a HTTP GET request. * * <h3>Usage</h3> * <p> * You can use <code>#{of:graphicImageURL()}</code> EL functions to generate URLs referring the * <code>@GraphicImageBean</code> bean, optionally with the image <code>type</code> and <code>lastModified</code> * arguments. Below are some usage examples: * <pre> * <ui:repeat value="#{bean.products}" var="product"> * * <!-- Basic, using default type and last modified. --> * <a href="#{of:graphicImageURL('images.full(product.imageId)')}"> * <o:graphicImage value="#{images.thumb(product.imageId)}" /> * </a> * * <!-- With specified type and default last modified. --> * <a href="#{of:graphicImageURLWithType('images.full(product.imageId)', 'png')}"> * <o:graphicImage value="#{images.thumb(product.imageId)}" type="png" /> * </a> * * <!-- With specified type and last modified. --> * <a href="#{of:graphicImageURLWithTypeAndLastModified('images.full(product.imageId)', 'png', product.lastModified)}"> * <o:graphicImage value="#{images.thumb(product.imageId)}" type="png" lastModified="#{product.lastModified}" /> * </a> * </ui:repeat> * </pre> * <p> * Note that in the <code>#{of:graphicImageURL()}</code> EL functions the expression string represents the same value as * you would use in <code><o:graphicImage></code> and that it must be a quoted string. Any nested quotes can be * escaped with backslash. * <p> * The <code>type</code> argument/attribute is the image type represented as file extension. E.g. "jpg", "png", "gif", * "ico", "svg", "bmp", "tiff", etc. When unspecified then the content type will default to <code>"image"</code> * without any subtype. This should work for most images in most browsers. This may however fail on newer images or in * older browsers. In that case, you can explicitly specify the image type via the <code>type</code> argument/attribute * which must represent a valid file extension. * <p> * The <code>lastModified</code> argument/attribute is the "last modified" timestamp, can be {@link Long} or * {@link Date}, or otherwise an attempt will be made to parse it as {@link Long}. When unspecified, then the "default * resource maximum age" as set in either the Mojarra specific context parameter * <code>com.sun.faces.defaultResourceMaxAge</code> or MyFaces specific context parameter * <code>org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES</code> will be used, else a default of 1 week will be assumed. * * @since 2.5 * @author Bauke Scholtz * @see GraphicImage * @see GraphicResource * @see DynamicResource * @see GraphicResourceHandler * @see DefaultResourceHandler * @see ExpressionInspector * @see MethodReference */ @Inherited @Documented @Stereotype @Named @ApplicationScoped @Retention(RUNTIME) @Target(TYPE) public @interface GraphicImageBean { // }