From ec5a4ff46fc081cc897a8e0f1017bcce7803b6ba Mon Sep 17 00:00:00 2001 From: Bauke Scholtz Date: Sat, 23 Jul 2016 18:01:07 +0200 Subject: [PATCH] #289 improved javadoc --- .../org/omnifaces/cdi/GraphicImageScoped.java | 61 ++++++++++++++++++- .../component/output/GraphicImage.java | 4 ++ .../resourcehandler/GraphicResource.java | 3 +- 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/omnifaces/cdi/GraphicImageScoped.java b/src/main/java/org/omnifaces/cdi/GraphicImageScoped.java index d8572cc4b..c5851a810 100644 --- a/src/main/java/org/omnifaces/cdi/GraphicImageScoped.java +++ b/src/main/java/org/omnifaces/cdi/GraphicImageScoped.java @@ -21,12 +21,19 @@ import java.lang.annotation.Documented; 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.Qualifier; 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; /** *

@@ -52,13 +59,61 @@ *

* When using {@link ApplicationScoped} 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. The {@link GraphicImageScoped} basically enables serving images without - * the need to reference them via a JSF page. + * 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 {@link GraphicImageScoped} basically enables endusers to + * invoke any public method returning a byte[] or InputStream on the bean by just a HTTP GET + * request. + * + *

Usage

+ *

+ * You can use #{of:graphicImageURL()} EL functions to generate URLs referring the + * {@link GraphicImageScoped} bean, optionally with the image type and lastModified arguments. + * Below are some usage examples: + *

+ * <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>
+ * 
+ *

+ * Note that in the #{of:graphicImageURL()} EL functions the expression string represents the same value as + * you would use in <o:graphicImage> and that it must be a quoted string. Any nested quotes can be + * escaped with backslash. + *

+ * The type 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 "image" + * 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 type argument/attribute + * which must represent a valid file extension. + *

+ * The lastModified 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 + * com.sun.faces.defaultResourceMaxAge or MyFaces specific context parameter + * org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES 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 */ @Documented @Qualifier diff --git a/src/main/java/org/omnifaces/component/output/GraphicImage.java b/src/main/java/org/omnifaces/component/output/GraphicImage.java index 6cd340d2d..3551044b1 100644 --- a/src/main/java/org/omnifaces/component/output/GraphicImage.java +++ b/src/main/java/org/omnifaces/component/output/GraphicImage.java @@ -132,6 +132,10 @@ * <o:graphicImage value="#{images.get(image.id)}" lastModified="#{image.lastModified}" /> * </ui:repeat> * + *

+ * When unspecified, then the "default resource maximum age" as set in either the Mojarra specific context parameter + * com.sun.faces.defaultResourceMaxAge or MyFaces specific context parameter + * org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES will be used, else a default of 1 week will be assumed. * *

Image types

*

diff --git a/src/main/java/org/omnifaces/resourcehandler/GraphicResource.java b/src/main/java/org/omnifaces/resourcehandler/GraphicResource.java index 4f14a93fe..79a6fcc8c 100644 --- a/src/main/java/org/omnifaces/resourcehandler/GraphicResource.java +++ b/src/main/java/org/omnifaces/resourcehandler/GraphicResource.java @@ -12,6 +12,7 @@ */ package org.omnifaces.resourcehandler; +import static java.lang.reflect.Modifier.isPublic; import static java.util.Arrays.asList; import static java.util.Collections.singletonMap; import static org.omnifaces.util.Faces.getContext; @@ -273,7 +274,7 @@ else if (content instanceof byte[]) { public static void registerGraphicImageScopedBeans() { for (Object bean : CDI.current().select(GRAPHIC_IMAGE_SCOPED)) { for (Method method : bean.getClass().getMethods()) { - if (isOneOf(method.getReturnType(), REQUIRED_RETURN_TYPES)) { + if (isPublic(method.getModifiers()) && isOneOf(method.getReturnType(), REQUIRED_RETURN_TYPES)) { String resourceBaseName = getResourceBaseName(bean.getClass().getSuperclass(), method); MethodReference methodReference = new MethodReference(bean, method); ALLOWED_METHODS.put(resourceBaseName, methodReference);