001: package dinamica;
002:
003: import java.awt.image.AffineTransformOp;
004: import java.awt.image.BufferedImage;
005: import java.io.ByteArrayInputStream;
006: import java.io.ByteArrayOutputStream;
007: import java.awt.geom.AffineTransform;
008: import javax.imageio.ImageIO;
009:
010: import java.sql.*;
011: import javax.servlet.ServletOutputStream;
012: import javax.sql.DataSource;
013:
014: /**
015: * Output module to print blob contents stored in PostgreSQL database (v8.0.3),
016: * like images, pdfs and other types of documents
017: * saved in columns of type "bytea". This class was required
018: * because PostgreSQL does implement the standard JDBC BLOB API for
019: * its "bytea" data type, so the default dinamica.BlobOutput cannot be used
020: * with PostgreSQL databases in the current stable versions (7.4 and 8.0.3).
021: * <br>
022: * Creation date: 2-sept-2005<br>
023: * Last Update: 2-sept-2005<br>
024: * (c) 2003 Martin Cordova<br>
025: * This code is released under the LGPL license<br>
026: * @author Martin Cordova
027: * */
028: public class BlobOutputPGSQL extends GenericOutput {
029:
030: /* (non-Javadoc)
031: * @see dinamica.GenericOutput#print(dinamica.GenericTransaction)
032: */
033: public void print(GenericTransaction data) throws Throwable {
034:
035: //get datasource object
036: String jndiPrefix = getContext()
037: .getInitParameter("jndi-prefix");
038: String dataSourceName = getContext().getInitParameter(
039: "def-datasource");
040:
041: /* PATCH 2005-03-10 read datasource name from config.xml if available */
042: if (getConfig().transDataSource != null)
043: dataSourceName = getConfig().transDataSource;
044:
045: if (jndiPrefix == null)
046: jndiPrefix = "";
047:
048: DataSource ds = Jndi.getDataSource(jndiPrefix + dataSourceName);
049:
050: Connection conn = null;
051: Statement s = null;
052: ResultSet rs = null;
053:
054: ServletOutputStream out = null;
055:
056: //si se envio el parametro 'scale' en el url entonces se
057: //asume que es una imagen y se escala, se usa para Thumbnails de imagenes solamente
058: double scaleFactor = 0;
059: String scale = getRequest().getParameter("scale");
060: if (scale != null && !scale.equals("")) {
061: scaleFactor = Double.parseDouble(scale);
062: }
063:
064: try {
065: //connect to database
066: conn = ds.getConnection();
067: s = conn.createStatement();
068:
069: //get recordset with blob metadata
070: Recordset info = data.getRecordset("blobinfo");
071:
072: //get sql to retrieve blob
073: String sql = info.getString("sql");
074:
075: //set BLOB content-type
076: getResponse().setContentType(info.getString("format"));
077:
078: //attach?
079: String fileName = info.getString("filename");
080: if (fileName != null) {
081: getResponse().setHeader("Content-Disposition",
082: "attachment; filename=\"" + fileName + "\";");
083: }
084:
085: //get servlet output stream
086: out = getResponse().getOutputStream();
087:
088: //execute query and retrieve blob
089: rs = s.executeQuery(sql);
090: if (rs.next()) {
091: //read blob
092: byte[] blob = rs.getBytes(1);
093:
094: //scale image if requested
095: if (blob.length > 20000
096: && scaleFactor > 0
097: && info.getString("format")
098: .startsWith("image/")) {
099: BufferedImage bufimg = ImageIO
100: .read(new ByteArrayInputStream(blob));
101: AffineTransform tx = new AffineTransform();
102: tx.scale(scaleFactor, scaleFactor);
103: AffineTransformOp op = new AffineTransformOp(tx,
104: AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
105: BufferedImage newImg = op.filter(bufimg, null);
106: ByteArrayOutputStream bout = new ByteArrayOutputStream();
107: if (info.getString("format").endsWith("png"))
108: ImageIO.write(newImg, "png", bout);
109: else
110: ImageIO.write(newImg, "jpg", bout);
111: blob = bout.toByteArray();
112: }
113:
114: //set content length
115: int size = (int) blob.length;
116: getResponse().setContentLength(size);
117: out.write(blob);
118: }
119:
120: } catch (Throwable e) {
121: throw e;
122: } finally {
123: if (rs != null)
124: rs.close();
125: if (s != null)
126: s.close();
127: if (conn != null)
128: conn.close();
129: if (out != null)
130: out.close();
131: }
132:
133: }
134:
135: }
|