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: * DrawableFactory.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.resourceloader;
030:
031: import java.io.IOException;
032: import java.io.InputStream;
033: import java.net.URL;
034: import java.net.URLConnection;
035: import java.util.ArrayList;
036:
037: import org.jfree.io.IOUtils;
038: import org.jfree.ui.Drawable;
039: import org.jfree.util.Log;
040: import org.jfree.util.ObjectUtilities;
041: import org.jfree.report.util.MemoryByteArrayOutputStream;
042:
043: public class DrawableFactory {
044: private static DrawableFactory singleton;
045: private ArrayList factoryModules;
046:
047: public static synchronized DrawableFactory getInstance() {
048: if (singleton == null) {
049: singleton = new DrawableFactory();
050: }
051: return singleton;
052: }
053:
054: private DrawableFactory() {
055: factoryModules = new ArrayList();
056: }
057:
058: public boolean registerModule(final String className) {
059: try {
060: final Class c = ObjectUtilities.getClassLoader(getClass())
061: .loadClass(className);
062: registerModule((DrawableFactoryModule) c.newInstance());
063: return true;
064: } catch (Exception e) {
065: Log.debug("Failed to register module: " + className, e);
066: return false;
067: }
068: }
069:
070: public synchronized void registerModule(
071: final DrawableFactoryModule module) {
072: if (factoryModules.contains(module) == false) {
073: factoryModules.add(module);
074: }
075: }
076:
077: public Drawable createDrawable(final URL url) throws IOException {
078: final InputStream in = url.openStream();
079: final URLConnection uc = url.openConnection();
080: final Drawable image = createDrawable(uc.getInputStream(), url
081: .getFile(), uc.getContentType());
082: in.close();
083: return image;
084: }
085:
086: public Drawable createDrawable(final InputStream in,
087: final String file, final String contentType)
088: throws IOException {
089: final MemoryByteArrayOutputStream bout = new MemoryByteArrayOutputStream(
090: 32 * 1024, 64 * 1024);
091: IOUtils.getInstance().copyStreams(in, bout, 16 * 1024);
092: return createDrawable(bout.toByteArray(), file, contentType);
093: }
094:
095: public synchronized Drawable createDrawable(final byte[] data,
096: final String fileName, final String mimeType)
097: throws IOException {
098: // first pass: Search by content
099: // this is the safest method to identify the image data
100: // as names might be invalid and mimetypes might be forged ..
101: for (int i = 0; i < factoryModules.size(); i++) {
102: try {
103: final DrawableFactoryModule module = (DrawableFactoryModule) factoryModules
104: .get(i);
105: if (module.getHeaderFingerprintSize() > 0
106: && data.length >= module
107: .getHeaderFingerprintSize()) {
108: if (module.canHandleResourceByContent(data)) {
109: return module.createDrawable(data, fileName,
110: mimeType);
111: }
112: }
113: } catch (IOException ioe) {
114: // first try failed ..
115: Log.info("Failed to load image: Trying harder ..", ioe);
116: }
117: }
118:
119: // second pass: Search by mime type
120: // this is the second safest method to identify the image data
121: // as names might be invalid and mimetypes might be forged ..
122: if (mimeType != null && "".equals(mimeType) == false) {
123: for (int i = 0; i < factoryModules.size(); i++) {
124: try {
125: final DrawableFactoryModule module = (DrawableFactoryModule) factoryModules
126: .get(i);
127: if (module.canHandleResourceByMimeType(mimeType)) {
128: return module.createDrawable(data, fileName,
129: mimeType);
130: }
131: } catch (IOException ioe) {
132: // first try failed ..
133: Log.info("Failed to load image: Trying harder ..",
134: ioe);
135: }
136: }
137: }
138:
139: // third pass: Search by mime type
140: // this is the final method to identify the image data
141: // as names might be invalid and mimetypes might be forged ..
142: if (mimeType != null && "".equals(mimeType) == false) {
143: for (int i = 0; i < factoryModules.size(); i++) {
144: try {
145: final DrawableFactoryModule module = (DrawableFactoryModule) factoryModules
146: .get(i);
147: if (module.canHandleResourceByName(fileName)) {
148: return module.createDrawable(data, fileName,
149: mimeType);
150: }
151: } catch (IOException ioe) {
152: // first try failed ..
153: Log.info("Failed to load image: Trying harder ..",
154: ioe);
155: }
156: }
157: }
158: throw new IOException(
159: "Unable to load the drawable, no suitable loader found.");
160: }
161: }
|