001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.user.client.ui;
017:
018: /**
019: * A tag interface that is used in the generation of image bundles. An image
020: * bundle is a composition of multiple images into a single large image, along
021: * with an interface for accessing a specific image's
022: * {@link com.google.gwt.user.client.ui.AbstractImagePrototype prototype} from
023: * within the composition. Obtain an image bundle instance by calling
024: * <code>GWT.create(<i>T</i>)</code>, where <code>T</code> is an
025: * interface that directly or indirectly extends <code>ImageBundle</code>.
026: *
027: * <p>
028: * To create and use an image bundle, extend the <code>ImageBundle</code>
029: * interface, and add a method declaration for each image that is to be part of
030: * the bundle. Each method must take no parameters and must have a return type
031: * of
032: * {@link com.google.gwt.user.client.ui.AbstractImagePrototype AbstractImagePrototype}.
033: * The image name can optionally be specified using the
034: * <code>gwt.resource</code> metadata tag. Valid image name extensions are
035: * <code>png</code>, <code>gif</code>, or <code>jpg</code>. If the
036: * image name contains '/' characters, it is assumed to be the name of a
037: * resource on the classpath, formatted as would be expected by
038: * <code>
039: * <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)">ClassLoader.getResource(String)</a>.
040: * </code>
041: * Otherwise, the image must be located in the same package as the user-defined
042: * image bundle.
043: * </p>
044: *
045: * <p>
046: * The easiest way to create an image bundle is to omit the
047: * <code>gwt.resource</code> metadata tag, and name the method the same as the
048: * image name, excluding the extension. When the image name is inferred in this
049: * manner, the image name's extension is assumed to be either <code>png</code>,
050: * <code>gif</code>, or <code>jpg</code>, and the image location must be
051: * in the same package as the user-defined image bundle. In the event that there
052: * are multiple image files that have the same name with different extensions,
053: * the order of extension precedence is <code>png</code>, <code>gif</code>,
054: * <code>jpg</code>.
055: *
056: * <h3>Example</h3>
057: *
058: * <pre class="code">
059: * public interface MyImageBundle extends ImageBundle {
060: *
061: * /**
062: * * Notice that the gwt.resource metadata tag is not present,
063: * * so the method name itself is assumed to match the associated
064: * * image filename.
065: * *
066: * * One of btn_submit_icon.png, btn_submit_icon.gif, or
067: * * btn_submit_icon.jpg must be located in the same package
068: * * as MyImageBundle.
069: * */
070: * public AbstractImagePrototype btn_submit_icon();
071: *
072: * // No doc comment is required if you want the default
073: * // name-matching behavior.
074: * public AbstractImagePrototype cancelButtonIcon();
075: * }
076: * </pre>
077: *
078: * </p>
079: *
080: * <p>
081: * An image bundle that uses the <code>gwt.resource</code> metadata tag to
082: * specify image names might look something like this:
083: *
084: * <pre class="code">
085: * public interface MyImageBundle extends ImageBundle {
086: *
087: * /**
088: * * The metadata tag contains no '/' characters, so
089: * * btn_submit_icon.gif must be located in the same
090: * * package as MyImageBundle.
091: * *
092: * * @gwt.resource btn_submit_icon.gif
093: * */
094: * public AbstractImagePrototype submitButtonIcon();
095: *
096: * /**
097: * * btn_cancel_icon.png must be located in the package
098: * * com.mycompany.myapp.icons (which must be on the classpath).
099: * *
100: * * @gwt.resource com/mycompany/myapp/icons/btn_cancel_icon.png
101: * */
102: * public AbstractImagePrototype cancelButtonIcon();
103: * }
104: * </pre>
105: *
106: * </p>
107: *
108: * <p>
109: * Here is how MyImageBundle might be used in an application:
110: *
111: * <pre class="code">
112: * ...
113: *
114: * // Create a new instance of MyImageBundle using GWT.create.
115: * // This only needs to be done once - a reference to myImageBundle can
116: * // be kept for use by other parts of the application.
117: * MyImageBundle myImageBundle = GWT.create(MyImageBundle.class);
118: *
119: * // Retrieve the image prototypes from myImageBundle.
120: * AbstractImagePrototype submitButtonImgPrototype = myImageBundle.btn_submit_icon();
121: * AbstractImagePrototype cancelButtonImgPrototype = myImageBundle.cancelButtonIcon();
122: *
123: * // Add the images that are created based on the prototypes to the panel.
124: * panel.add(submitButtonImgPrototype.createImage());
125: * panel.add(cancelButtonImgPrototype.createImage());
126: *
127: * ...
128: * </pre>
129: *
130: * </p>
131: *
132: * <h3>Security Warning: Image Bundle's use of the javax.image.imageio Classes</h3>
133: * Certain versions of the JVM are susceptible to a vulnerability in the
134: * javax.image.imageio classes, which are generally used to parse images.
135: * These classes are used by image bundle's implementation to combine all
136: * of the images into a single composite image.
137: *
138: * <p>
139: * It is possible that the vulnerability could be exploited by using a
140: * specially crafted image as part of an image bundle. To prevent this
141: * type of attack from occurring, use a version of the JVM that
142: * includes a fix for this vulnerability. See the following link for more
143: * information:
144: * </p>
145: *
146: * <pre>
147: * <a href="http://sunsolve.sun.com/search/document.do?assetkey=1-26-102934-1">http://sunsolve.sun.com/search/document.do?assetkey=1-26-102934-1</a>
148: * </pre>
149: *
150: * <p>
151: * Alternatively, if the images to be used in the bundle are trusted, then
152: * it is not necessary to upgrade the JVM.
153: * </p>
154: *
155: * <h3>Caching Recommendations for Image Bundle Files</h3>
156: * Since the filename for the image bundle's composite image is based on a hash
157: * of the file's contents, the server can tell the browser to cache the file
158: * permanently.
159: *
160: * <p>
161: * To make all image bundle files permanently cacheable, set up a rule in your
162: * web server to emit the <code>Expires</code> response header for any files
163: * ending with <code>".cache.*"</code>. Such a rule would automatically match
164: * generated image bundle filenames
165: * (e.g. <code>320ADF600D31858000C612E939F0AD1A.cache.png</code>).
166: * The HTTP/1.1 specification recommends specifying date of approximately one
167: * year in the future for the <code>Expires</code> header to indicate that the
168: * resource is permanently cacheable.
169: * </p>
170: *
171: * <h3>Using Security Constraints to Protect Image Bundle Files</h3>
172: * When a web application has a security constraint set for the composite
173: * image, web application servers may change the image's HTTP response headers
174: * so that web browsers will not cache it. For example, Tomcat and Glassfish
175: * set the HTTP response headers <code>Pragma: No-cache</code>,
176: * <code>Cache-Control: None</code>, and <code>Expires: Thu, 1 Jan 1970 00:00:00</code>
177: * (or some other date in the past).
178: *
179: * <p>
180: * This can lead to performance problems when using image bundles, because the
181: * large composite image will be re-requested unecessarily. In addition,
182: * <code>clear.cache.gif</code>, which is a blank image used by the image bundle
183: * implementation, will be re-requested as well. While some browsers will only
184: * re-request these images for each page load, others will re-request them for
185: * each image on the page that is part of an image bundle.
186: * </p>
187: *
188: * There are several ways to work around this issue:
189: *
190: * <ol>
191: * <li>
192: * Modify the servlet which serves <code>png</code> and <code>gif</code> files
193: * so that it explicitly sets the <code>Pragma</code>, <code>Cache-Control</code>,
194: * and <code>Expires</code> headers. The <code>Pragma</code> and
195: * <code>Cache-Control</code> headers should be removed. The
196: * <code>Expires</code> header should be set according to the
197: * caching recommendations mentioned in the previous section.
198: * </li>
199: * <li>
200: * If using Tomcat, use the <code>disableProxyCaching</code>
201: * property in your web application configuration file to prevent the
202: * <code>Pragma</code>, <code>Cache-Control</code>, and <code>Expires</code>
203: * headers from being changed by the server. Refer to your web application
204: * server's documentation for more information.
205: * </li>
206: * <li>
207: * Exclude the image bundle's composite image from the web application's
208: * security constraint.
209: * </li>
210: * <li>
211: * If there is sensitive data in any of the images in the image bundle,
212: * exclude that image from the bundle and include it in the web application's
213: * security constraint. Then, rebuild the image bundle, and exclude the updated
214: * bundle's composite image from the security constraint.
215: * </li>
216: * </ol>
217: *
218: * <h3>Image Bundles and the HTTPS Protocol</h3>
219: * There is an issue with displaying image bundle images in Internet Explorer
220: * when:
221: *
222: * <ul>
223: * <li>The image bundle's composite image is requested using the HTTPS protocol, and</li>
224: * <li>The web application has a security constraint set for the composite image</li>
225: * </ul>
226: *
227: * This issue is known to occur with the web application servers Tomcat and
228: * Glassfish.
229: *
230: * <p>
231: * The native format for the composite image is <code>png</code>, and
232: * versions of Internet Explorer prior to 7 cannot render <code>png</code>
233: * transparerency. To get around this problem, we make use of a plugin built
234: * into the operating system.
235: * </p>
236: *
237: * <p>
238: * Internet Explorer specifies that files which require a plugin for viewing
239: * must be cached by the browser. That way, the plugin can read the cached file
240: * from the disk. Whenever the composite image is protected by a security
241: * constraint, the web application server sets caching headers on the response
242: * to prevent the browser from caching the image (see the previous section for
243: * details).
244: * </p>
245: *
246: * <p>
247: * When using the HTTP protocol, Internet Explorer will disregard the
248: * <code>Pragma: No-cache</code> and <code>Cache-Control: None</code> headers,
249: * and will cache the image. However, When using the HTTPS protocol, Internet
250: * Explorer will enforce these headers, and will not cache the image.
251: * Since the composite image is not stored on disk, the plugin is unable to render
252: * it, and all of the images in the application which rely on the composite image
253: * will not be displayed.
254: * </p>
255: *
256: * <p>
257: * To work around this issue, follow the recommendations outlined in the previous
258: * section.
259: * </p>
260: *
261: * <h3>For More Information</h3>
262: * See the GWT Developer Guide for an introduction to image bundles.
263: * @see com.google.gwt.user.client.ui.AbstractImagePrototype
264: * @see com.google.gwt.user.client.ui.Image#Image(String, int, int, int, int)
265: * @see com.google.gwt.user.client.ui.Image#setVisibleRect(int, int, int, int)
266: * @see com.google.gwt.user.client.ui.Image#setUrlAndVisibleRect(String, int,
267: * int, int, int)
268: */
269: public interface ImageBundle {
270: }
|