Source Code Cross Referenced for ImageBundleBuilder.java in  » Ajax » GWT » com » google » gwt » user » rebind » ui » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » GWT » com.google.gwt.user.rebind.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.rebind.ui;
017:
018:        import com.google.gwt.core.ext.GeneratorContext;
019:        import com.google.gwt.core.ext.TreeLogger;
020:        import com.google.gwt.core.ext.UnableToCompleteException;
021:        import com.google.gwt.dev.util.Util;
022:
023:        import java.awt.image.BufferedImage;
024:        import java.awt.Graphics2D;
025:        import java.io.IOException;
026:        import java.io.OutputStream;
027:        import java.io.ByteArrayOutputStream;
028:        import java.net.URL;
029:        import java.util.HashMap;
030:        import java.util.Map;
031:        import java.util.Collection;
032:        import java.util.SortedMap;
033:        import java.util.TreeMap;
034:
035:        import javax.imageio.ImageIO;
036:
037:        /**
038:         * Accumulates state for the bundled image.
039:         */
040:        class ImageBundleBuilder {
041:
042:            /**
043:             * The rectangle at which the original image is placed into the composite
044:             * image.
045:             */
046:            public static class ImageRect {
047:
048:                public final int height;
049:                public final BufferedImage image;
050:                public int left;
051:                public final int width;
052:
053:                public ImageRect(BufferedImage image) {
054:                    this .image = image;
055:                    this .width = image.getWidth();
056:                    this .height = image.getHeight();
057:                }
058:            }
059:
060:            /*
061:             * Only PNG is supported right now. In the future, we may be able to infer the
062:             * best output type, and get rid of this constant.
063:             */
064:            private static final String BUNDLE_FILE_TYPE = "png";
065:
066:            private final Map<String, ImageRect> imageNameToImageRectMap = new HashMap<String, ImageRect>();
067:
068:            /**
069:             * Assimilates the image associated with a particular image method into the
070:             * master composite. If the method names an image that has already been
071:             * assimilated, the existing image rectangle is reused.
072:             * 
073:             * @param logger a hierarchical logger which logs to the hosted console
074:             * @param imageName the name of an image that can be found on the classpath
075:             * @throws UnableToCompleteException if the image with name
076:             *           <code>imageName</code> cannot be added to the master composite
077:             *           image
078:             */
079:            public void assimilate(TreeLogger logger, String imageName)
080:                    throws UnableToCompleteException {
081:
082:                /*
083:                 * Decide whether or not we need to add to the composite image. Either way,
084:                 * we associated it with the rectangle of the specified image as it exists
085:                 * within the composite image. Note that the coordinates of the rectangle
086:                 * aren't computed until the composite is written.
087:                 */
088:                ImageRect rect = getMapping(imageName);
089:                if (rect == null) {
090:                    // Assimilate the image into the composite.
091:                    rect = addImage(logger, imageName);
092:
093:                    // Map the URL to its image so that even if the same URL is used more than
094:                    // once, we only include the referenced image once in the bundled image.
095:                    putMapping(imageName, rect);
096:                }
097:            }
098:
099:            public ImageRect getMapping(String imageName) {
100:                return imageNameToImageRectMap.get(imageName);
101:            }
102:
103:            public String writeBundledImage(TreeLogger logger,
104:                    GeneratorContext context) throws UnableToCompleteException {
105:
106:                // Create the bundled image from all of the constituent images.
107:                BufferedImage bundledImage = drawBundledImage();
108:
109:                // Write the bundled image into a byte array, so that we can compute
110:                // its strong name.
111:                byte[] imageBytes;
112:
113:                try {
114:                    ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
115:                    ImageIO.write(bundledImage, BUNDLE_FILE_TYPE,
116:                            byteOutputStream);
117:                    imageBytes = byteOutputStream.toByteArray();
118:                } catch (IOException e) {
119:                    logger
120:                            .log(
121:                                    TreeLogger.ERROR,
122:                                    "Unable to generate file name for image bundle file",
123:                                    null);
124:                    throw new UnableToCompleteException();
125:                }
126:
127:                // Compute the file name. The strong name is generated from the bytes of
128:                // the bundled image. The '.cache' part indicates that it can be
129:                // permanently cached.
130:                String bundleFileName = Util.computeStrongName(imageBytes)
131:                        + ".cache." + BUNDLE_FILE_TYPE;
132:
133:                // Try and write the file to disk. If a file with bundleFileName already
134:                // exists, then the file will not be written.
135:                OutputStream outStream = context.tryCreateResource(logger,
136:                        bundleFileName);
137:
138:                if (outStream != null) {
139:                    try {
140:                        // Write the image bytes from the byte array to the pending stream.
141:                        outStream.write(imageBytes);
142:
143:                        // Commit the stream.
144:                        context.commitResource(logger, outStream);
145:
146:                    } catch (IOException e) {
147:                        logger.log(TreeLogger.ERROR, "Failed while writing", e);
148:                        throw new UnableToCompleteException();
149:                    }
150:                } else {
151:                    logger
152:                            .log(
153:                                    TreeLogger.TRACE,
154:                                    "Generated image bundle file already exists; no need to rewrite it.",
155:                                    null);
156:                }
157:
158:                return bundleFileName;
159:            }
160:
161:            private ImageRect addImage(TreeLogger logger, String imageName)
162:                    throws UnableToCompleteException {
163:
164:                logger = logger.branch(TreeLogger.TRACE, "Adding image '"
165:                        + imageName + "'", null);
166:
167:                // Fetch the image.
168:                try {
169:                    // Could turn this lookup logic into an externally-supplied policy for
170:                    // increased generality.
171:                    URL imageUrl = getClass().getClassLoader().getResource(
172:                            imageName);
173:                    if (imageUrl == null) {
174:                        // This should never happen, because this check is done right after
175:                        // the image name is retrieved from the metadata or the method name.
176:                        // If there is a failure in obtaining the resource, it will happen
177:                        // before this point.
178:                        logger.log(TreeLogger.ERROR,
179:                                "Resource not found on classpath (is the name specified as "
180:                                        + "Class.getResource() would expect?)",
181:                                null);
182:                        throw new UnableToCompleteException();
183:                    }
184:
185:                    BufferedImage image;
186:                    // Load the image
187:                    try {
188:                        image = ImageIO.read(imageUrl);
189:                    } catch (IllegalArgumentException iex) {
190:                        if (imageName.toLowerCase().endsWith("png")
191:                                && iex.getMessage() != null
192:                                && iex.getStackTrace()[0]
193:                                        .getClassName()
194:                                        .equals(
195:                                                "javax.imageio.ImageTypeSpecifier$Indexed")) {
196:                            logger
197:                                    .log(
198:                                            TreeLogger.ERROR,
199:                                            "Unable to read image. The image may not be in valid PNG format. "
200:                                                    + "This problem may also be due to a bug in versions of the "
201:                                                    + "JRE prior to 1.6. See "
202:                                                    + "http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5098176 "
203:                                                    + "for more information. If this bug is the cause of the "
204:                                                    + "error, try resaving the image using a different image "
205:                                                    + "program, or upgrade to a newer JRE.",
206:                                            null);
207:                            throw new UnableToCompleteException();
208:                        } else {
209:                            throw iex;
210:                        }
211:                    }
212:
213:                    if (image == null) {
214:                        logger.log(TreeLogger.ERROR,
215:                                "Unrecognized image file format", null);
216:                        throw new UnableToCompleteException();
217:                    }
218:
219:                    return new ImageRect(image);
220:
221:                } catch (IOException e) {
222:                    logger.log(TreeLogger.ERROR,
223:                            "Unable to read image resource", null);
224:                    throw new UnableToCompleteException();
225:                }
226:            }
227:
228:            /*
229:             * This method creates the bundled image through the composition of the other
230:             * images.
231:             * 
232:             * This method could be implemented in a variety of ways. For example, one
233:             * could use a knapsack algorithm to draw these images in an optimal amount of
234:             * space.
235:             * 
236:             * In this particular implementation, we iterate through the image rectangles
237:             * in ascending order of associated filename, and draw the rectangles from
238:             * left to right in a single row.
239:             * 
240:             * The most important aspect of drawing the bundled image is that it be drawn
241:             * in a deterministic way. The drawing of the image should not rely on
242:             * implementation details of the Generator system which may be subject to
243:             * change. For example, at the time of this writing, the image names are added
244:             * to imageNameToImageRectMap based on the alphabetical ordering of their
245:             * associated methods. This behavior is the result of the oracle returning the
246:             * list of a type's methods in alphabetical order. However, this behavior is
247:             * undocumented, and should not be relied on. If this behavior were to change,
248:             * it would inadvertently affect the generation of bundled images.
249:             */
250:            private BufferedImage drawBundledImage() {
251:
252:                // Impose an ordering on the image rectangles, so that we construct
253:                // the bundled image in a deterministic way.
254:                SortedMap<String, ImageRect> sortedImageNameToImageRectMap = new TreeMap<String, ImageRect>();
255:                sortedImageNameToImageRectMap.putAll(imageNameToImageRectMap);
256:                Collection<ImageRect> orderedImageRects = sortedImageNameToImageRectMap
257:                        .values();
258:
259:                // Determine how big the composited image should be by taking the
260:                // sum of the widths and the max of the heights.
261:                int nextLeft = 0;
262:                int maxHeight = 0;
263:                for (ImageRect imageRect : orderedImageRects) {
264:                    imageRect.left = nextLeft;
265:                    nextLeft += imageRect.width;
266:                    if (imageRect.height > maxHeight) {
267:                        maxHeight = imageRect.height;
268:                    }
269:                }
270:
271:                // Create the bundled image.
272:                BufferedImage bundledImage = new BufferedImage(nextLeft,
273:                        maxHeight, BufferedImage.TYPE_INT_ARGB_PRE);
274:                Graphics2D g2d = bundledImage.createGraphics();
275:
276:                for (ImageRect imageRect : orderedImageRects) {
277:
278:                    // We do not need to pass in an ImageObserver, because we are working
279:                    // with BufferedImages. ImageObservers only need to be used when
280:                    // the image to be drawn is being loaded asynchronously. See
281:                    // http://java.sun.com/docs/books/tutorial/2d/images/drawimage.html
282:                    // for more information.
283:                    g2d.drawImage(imageRect.image, imageRect.left, 0, null);
284:                }
285:                g2d.dispose();
286:
287:                return bundledImage;
288:            }
289:
290:            private void putMapping(String imageName, ImageRect rect) {
291:                imageNameToImageRectMap.put(imageName, rect);
292:            }
293:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.