001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * DefaultImageReference.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report;
030:
031: import java.awt.Image;
032: import java.io.IOException;
033: import java.io.Serializable;
034: import java.net.URL;
035:
036: import org.jfree.report.resourceloader.ImageFactory;
037: import org.jfree.util.ObjectUtilities;
038: import org.jfree.util.WaitingImageObserver;
039:
040: /**
041: * An DefaultImageReference encapsulates the source of an image together with a <code>java.awt.Image</code>. The source
042: * is used to create a higher resolution version if needed. The source file/URL may also be inlined into the output
043: * target, to create better results.
044: * <p/>
045: * This implementation provides a reasonable default implementation to encapsualte local AWT-images into reports.
046: * <p/>
047: * The given image might specify a fixed scale factor for the given image. The scaling will be applied before any layout
048: * computations will be performed.
049: *
050: * @author Thomas Morgner
051: */
052: public class DefaultImageReference implements Serializable,
053: URLImageContainer, LocalImageContainer {
054: /**
055: * A unique identifier for long term persistance.
056: */
057: private static final long serialVersionUID = 3223926147102983309L;
058:
059: /**
060: * The image.
061: */
062: private Image image;
063:
064: /**
065: * The image URL.
066: */
067: private URL url;
068:
069: /**
070: * The width of the (unscaled) image.
071: */
072: private int width;
073:
074: /**
075: * The height of the (unscaled) image.
076: */
077: private int height;
078:
079: /**
080: * The scale factor.
081: */
082: private float scaleX = 1.0f;
083:
084: /**
085: * The scale factor.
086: */
087: private float scaleY = 1.0f;
088:
089: /**
090: * Creates a new ImageReference with an origin of 0,0 and the desired width. The image data is read from the given
091: * URL.
092: *
093: * @param url the source url. The url must be readable during the report generation.
094: * @throws IOException if the url could not be read.
095: * @throws NullPointerException if the given URL is null.
096: */
097: public DefaultImageReference(final URL url) throws IOException {
098: if (url == null) {
099: throw new NullPointerException("URL must not be null.");
100: }
101: this .url = url;
102: this .image = ImageFactory.getInstance().createImage(url);
103: if (image == null) {
104: // no image ...
105: throw new IOException("The image could not be loaded.");
106: }
107:
108: final WaitingImageObserver wob = new WaitingImageObserver(image);
109: wob.waitImageLoaded();
110: if (wob.isError()) {
111: throw new IOException(
112: "Failed to load the image. ImageObserver signaled an error.");
113: }
114: this .width = image.getWidth(null);
115: this .height = image.getHeight(null);
116: }
117:
118: /**
119: * Creates a new ImageReference without an assigned URL for the Image. This image reference will not be loadable and
120: * cannot be used to embedd the original rawdata of the image into the generated content.
121: *
122: * @param img the image for this reference.
123: * @throws NullPointerException if the image is null.
124: * @throws java.io.IOException if an IOError occured while loading the image.
125: */
126: public DefaultImageReference(final Image img) throws IOException {
127: if (img == null) {
128: throw new NullPointerException();
129: }
130: this .image = img;
131: final WaitingImageObserver obs = new WaitingImageObserver(image);
132: obs.waitImageLoaded();
133: if (obs.isError()) {
134: throw new IOException(
135: "Failed to load the image. ImageObserver signaled an error.");
136: }
137: this .width = image.getWidth(null);
138: this .height = image.getHeight(null);
139: }
140:
141: /**
142: * Creates a new image reference without assigning either an Image or an URL. This DefaultImageReference will act as
143: * place holder to reserve space during the layouting, no content will be generated.
144: *
145: * @param w the width of the unscaled image.
146: * @param h the height of the unscaled image.
147: */
148: public DefaultImageReference(final int w, final int h) {
149: this .width = w;
150: this .height = h;
151: }
152:
153: /**
154: * Copies the contents of the given DefaultImageReference.
155: *
156: * @param parent the parent.
157: */
158: public DefaultImageReference(final DefaultImageReference parent) {
159: if (parent == null) {
160: throw new NullPointerException(
161: "The given parent must not be null.");
162: }
163: this .width = parent.width;
164: this .height = parent.height;
165: this .image = parent.image;
166: this .url = parent.url;
167: }
168:
169: /**
170: * Returns the original image if available.
171: *
172: * @return The current image instance, or null, if no image has been assigned.
173: */
174: public Image getImage() {
175: return image;
176: }
177:
178: /**
179: * Returns the source URL for the image.
180: *
181: * @return The URL from where the image has been loaded, or null, if the source URL is not known.
182: */
183: public URL getSourceURL() {
184: return url;
185: }
186:
187: /**
188: * Returns the a string version of the source URL. If no URL has been assigned, this method will return null.
189: *
190: * @return a String representing the assigned URL.
191: */
192: public String getSourceURLString() {
193: if (url == null) {
194: return null;
195: }
196: return url.toExternalForm();
197: }
198:
199: /**
200: * Returns a String representing this object. Useful for debugging.
201: *
202: * @return The string.
203: */
204: public String toString() {
205: final StringBuffer buf = new StringBuffer();
206:
207: buf.append("ImageReference={ URL=");
208: buf.append(getSourceURL());
209: buf.append(", image=");
210: buf.append(getImage());
211: buf.append(", width=");
212: buf.append(getImageWidth());
213: buf.append(", height=");
214: buf.append(getImageHeight());
215: buf.append(", scaleX=");
216: buf.append(getScaleX());
217: buf.append(", scaleY=");
218: buf.append(getScaleY());
219: buf.append('}');
220:
221: return buf.toString();
222: }
223:
224: /**
225: * Checks for equality.
226: *
227: * @param obj the object to test.
228: * @return true if the specified object is equal to this one.
229: */
230: public boolean equals(final Object obj) {
231: if (obj == null) {
232: return false;
233: }
234: if (obj instanceof DefaultImageReference == false) {
235: return false;
236: }
237: final DefaultImageReference ref = (DefaultImageReference) obj;
238: if (ObjectUtilities.equal(String.valueOf(url), String
239: .valueOf(ref.url)) == false) {
240: return false;
241: }
242: if (width != ref.width) {
243: return false;
244: }
245: if (height != ref.height) {
246: return false;
247: }
248: if (scaleX != ref.scaleX) {
249: return false;
250: }
251: if (scaleY != ref.scaleY) {
252: return false;
253: }
254: return true;
255: }
256:
257: /**
258: * Compute a hashcode for this imageReference.
259: *
260: * @return the hashcode
261: */
262: public int hashCode() {
263: int result = width;
264: result = 29 * result + height;
265: result = 29 * result + Float.floatToIntBits(scaleX);
266: result = 29 * result + Float.floatToIntBits(scaleY);
267: result = 29 * result + (image != null ? image.hashCode() : 0);
268: result = 29 * result
269: + (url != null ? url.toString().hashCode() : 0);
270: return result;
271: }
272:
273: /**
274: * Clones this Element.
275: *
276: * @return a clone of this element.
277: * @throws CloneNotSupportedException this should never be thrown.
278: */
279: public Object clone() throws CloneNotSupportedException {
280: return super .clone();
281: }
282:
283: /**
284: * Returns the (unscaled) image width.
285: *
286: * @return the image width.
287: */
288: public int getImageWidth() {
289: return width;
290: }
291:
292: /**
293: * Returns the (unscaled) image height.
294: *
295: * @return the image height.
296: */
297: public int getImageHeight() {
298: return height;
299: }
300:
301: /**
302: * Checks, whether this image reference is loadable. A default image reference is loadable, if a valid URL has been
303: * set.
304: *
305: * @return true, if it is loadable, false otherwise.
306: */
307: public boolean isLoadable() {
308: return getSourceURL() != null;
309: }
310:
311: /**
312: * Returns the identity information. This instance returns the URL of the image, if any.
313: *
314: * @return the image identifier.
315: */
316: public Object getIdentity() {
317: return url;
318: }
319:
320: /**
321: * Returns the name of this image reference. If an URL has been set, this will return the URL of the image, else null
322: * is returned.
323: *
324: * @return the name.
325: */
326: public String getName() {
327: if (url != null) {
328: return url.toExternalForm();
329: }
330: return null;
331: }
332:
333: /**
334: * Checks, whether this image has a assigned identity. Two identities should be equal, if the image contents are
335: * equal.
336: *
337: * @return true, if that image contains contains identity information, false otherwise.
338: */
339: public boolean isIdentifiable() {
340: return url != null;
341: }
342:
343: /**
344: * Returns a predefined scaling factor. That scaling will be applied before any layout specific scaling is done.
345: *
346: * @return the scale factor.
347: */
348: public float getScaleX() {
349: return scaleX;
350: }
351:
352: /**
353: * Returns a predefined scaling factor. That scaling will be applied before any layout specific scaling is done.
354: *
355: * @return the scale factor.
356: */
357: public float getScaleY() {
358: return scaleY;
359: }
360:
361: /**
362: * Defines a predefined scaling factor. That scaling will be applied before any layout specific scaling is done.
363: * <p/>
364: * If your image has a higher resolution than 72dpi, this factor should be a value lower than 1 (the image will be
365: * scaled down).
366: *
367: * @param sx the scale factor.
368: * @param sy the scale factor.
369: */
370: public void setScale(final float sx, final float sy) {
371: this.scaleX = sx;
372: this.scaleY = sy;
373: }
374: }
|