001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.url;
018:
019: import java.awt.Component;
020: import java.awt.Graphics2D;
021: import java.awt.Image;
022: import java.awt.Label;
023: import java.awt.MediaTracker;
024: import java.awt.Toolkit;
025: import java.awt.image.BufferedImage;
026: import java.awt.image.RenderedImage;
027: import java.io.ByteArrayOutputStream;
028: import java.io.IOException;
029: import java.io.InputStream;
030: import java.util.Iterator;
031:
032: import org.apache.batik.ext.awt.image.GraphicsUtil;
033: import org.apache.batik.ext.awt.image.renderable.Filter;
034: import org.apache.batik.ext.awt.image.renderable.RedRable;
035: import org.apache.batik.ext.awt.image.spi.AbstractRegistryEntry;
036: import org.apache.batik.ext.awt.image.spi.MagicNumberRegistryEntry;
037: import org.apache.batik.ext.awt.image.spi.URLRegistryEntry;
038: import org.apache.batik.util.ParsedURL;
039:
040: /**
041: * This Image tag registy entry is setup to wrap the core JDK Image stream tools.
042: *
043: * @version CVS $Id: StreamJDKRegistryEntry.java 433543 2006-08-22 06:22:54Z crossley $
044: */
045: public class StreamJDKRegistryEntry extends AbstractRegistryEntry
046: implements URLRegistryEntry {
047:
048: /**
049: * The priority of this entry.
050: * This entry should in most cases be the last entry.
051: * but if one wishes one could set a priority higher and be called
052: * afterwords
053: */
054: public final static float PRIORITY = 1000 * MagicNumberRegistryEntry.PRIORITY;
055:
056: public StreamJDKRegistryEntry() {
057: super ("Stream-JDK", PRIORITY, new String[0],
058: new String[] { "image/gif" });
059: }
060:
061: /**
062: * Check if the Stream references an image that can be handled by
063: * this format handler. The input stream passed in should be
064: * assumed to support mark and reset.
065: *
066: * If this method throws a StreamCorruptedException then the
067: * InputStream will be closed and a new one opened (if possible).
068: *
069: * This method should only throw a StreamCorruptedException if it
070: * is unable to restore the state of the InputStream
071: * (i.e. mark/reset fails basically).
072: */
073: public boolean isCompatibleURL(ParsedURL purl) {
074: String contentType = purl.getContentType();
075: if (contentType == null) {
076: return false;
077: }
078:
079: Iterator iter = this .getMimeTypes().iterator();
080: while (iter.hasNext()) {
081: if (contentType.equals(iter.next())) {
082: return true;
083: }
084: }
085: return false;
086: }
087:
088: /**
089: * Decode the URL into a RenderableImage
090: *
091: * @param purl The URLto decode
092: * @param needRawData If true the image returned should not have
093: * any default color correction the file may
094: * specify applied.
095: */
096: public Filter handleURL(ParsedURL purl, boolean needRawData) {
097:
098: // Read all bytes from the ParsedURL (too bad, there's no Toolkit.createImage(InputStream))
099: InputStream is = null;
100: byte[] buffer = new byte[1024];
101: int len;
102: ByteArrayOutputStream bos = new ByteArrayOutputStream();
103: try {
104: is = purl.openStream();
105: while ((len = is.read(buffer)) != -1) {
106: bos.write(buffer, 0, len);
107: }
108: } catch (IOException ioe) {
109: return null;
110: } finally {
111: try {
112: if (is != null)
113: is.close();
114: } catch (Exception e) {
115: }
116: }
117:
118: buffer = bos.toByteArray();
119:
120: Toolkit tk = Toolkit.getDefaultToolkit();
121: final Image img = tk.createImage(buffer);
122: if (img == null) {
123: return null;
124: }
125:
126: RenderedImage ri = loadImage(img);
127: if (ri == null) {
128: return null;
129: }
130: return new RedRable(GraphicsUtil.wrap(ri));
131: }
132:
133: // Stuff for Image Loading.
134: static Component mediaComponent = new Label();
135: static MediaTracker mediaTracker = new MediaTracker(mediaComponent);
136: static int id = 0;
137:
138: public RenderedImage loadImage(Image img) {
139: // In some cases the image will be a
140: // BufferedImage (subclass of RenderedImage).
141: if (img instanceof RenderedImage) {
142: return (RenderedImage) img;
143: }
144:
145: // Setup the mediaTracker.
146: int myID;
147: synchronized (mediaTracker) {
148: myID = id++;
149: }
150:
151: // Add our image to the media tracker and wait....
152: mediaTracker.addImage(img, myID);
153: while (true) {
154: try {
155: mediaTracker.waitForID(myID);
156: } catch (InterruptedException ie) {
157: // Something woke us up but the image
158: // isn't done yet, so try again.
159: continue;
160: }
161: // All done!
162: break;
163: }
164:
165: // Clean up our registraction
166: mediaTracker.removeImage(img, myID);
167:
168: if ((img.getWidth(null) == -1) || (img.getHeight(null) == -1)) {
169: return null;
170: }
171:
172: // Build the image to .
173: BufferedImage bi = new BufferedImage(img.getWidth(null), img
174: .getHeight(null), BufferedImage.TYPE_INT_ARGB);
175: Graphics2D g2d = bi.createGraphics();
176:
177: g2d.drawImage(img, 0, 0, null);
178: g2d.dispose();
179: return bi;
180: }
181: }
|