001: package com.quadcap.app.dbimage;
002:
003: /* Copyright 2000 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.ByteArrayOutputStream;
042: import java.io.IOException;
043: import java.io.InputStream;
044: import java.io.OutputStream;
045:
046: import java.util.Enumeration;
047: import java.util.Properties;
048:
049: import java.sql.Connection;
050: import java.sql.DatabaseMetaData;
051: import java.sql.DriverManager;
052: import java.sql.PreparedStatement;
053: import java.sql.ResultSet;
054: import java.sql.Statement;
055: import java.sql.SQLException;
056:
057: import javax.servlet.ServletConfig;
058: import javax.servlet.ServletException;
059:
060: import javax.servlet.http.HttpServlet;
061: import javax.servlet.http.HttpServletRequest;
062: import javax.servlet.http.HttpServletResponse;
063:
064: // ---- image libraries
065: import java.awt.Image;
066: import java.awt.Graphics2D;
067: import java.awt.geom.AffineTransform;
068: import java.awt.image.BufferedImage;
069: import java.io.IOException;
070: import java.io.OutputStream;
071: import java.io.FileOutputStream;
072: import javax.swing.ImageIcon;
073: import com.sun.image.codec.jpeg.JPEGCodec;
074: import com.sun.image.codec.jpeg.JPEGImageEncoder;
075:
076: /**
077: * This servlet fetches and returns images from the database.
078: *
079: * @author Stan Bailes
080: */
081: public class DbImageServlet extends HttpServlet {
082: String url = null;
083:
084: public void init(ServletConfig config) throws ServletException {
085: super .init(config);
086: try {
087: url = config.getInitParameter("jdbc.url");
088: if (url == null) {
089: throw new ServletException("No jdbc.url property");
090: } else {
091: String driver = "com.quadcap.jdbc.JdbcDriver";
092: String d = config.getInitParameter("jdbc.driver");
093: if (d != null)
094: driver = d;
095: Class.forName(driver);
096: }
097: config.getServletContext().setAttribute("servlet", this );
098:
099: Connection conn = getConnection();
100: Statement stmt = conn.createStatement();
101: try {
102: DatabaseMetaData dbmeta = conn.getMetaData();
103: ResultSet rs = dbmeta.getTables(null, null, "images",
104: null);
105: if (!rs.next()) {
106: stmt.execute("create table images("
107: + " name varchar(99999), "
108: + " maxDim int, " + " data blob,"
109: + " size int)");
110: stmt
111: .execute("create unique index images1 on images(name, maxDim)");
112: }
113: rs.close();
114: } finally {
115: stmt.close();
116: conn.close();
117: }
118:
119: } catch (Exception e) {
120: e.printStackTrace(System.err);
121: throw new ServletException(e);
122: }
123: }
124:
125: public Connection getConnection() throws SQLException {
126: Properties p = new Properties();
127: p.put("create", "true");
128: return DriverManager.getConnection(url, p);
129: }
130:
131: byte[] resizeImage(byte[] imageBytes, int maxDim)
132: throws IOException {
133: ImageIcon inImage = new ImageIcon(imageBytes);
134:
135: // Determine the scale.
136: double scale = (double) maxDim
137: / (double) inImage.getIconHeight();
138:
139: if (inImage.getIconWidth() > inImage.getIconHeight()) {
140: scale = (double) maxDim / (double) inImage.getIconWidth();
141: }
142:
143: // Determine size of new image.
144: // One of them hould equal maxDim.
145: int scaledW = (int) (scale * inImage.getIconWidth());
146: int scaledH = (int) (scale * inImage.getIconHeight());
147:
148: // Create an image buffer in which to paint on.
149: BufferedImage outImage = new BufferedImage(scaledW, scaledH,
150: BufferedImage.TYPE_INT_RGB);
151:
152: // Set the scale.
153: AffineTransform tx = new AffineTransform();
154:
155: // If the image is smaller than the desired image size,
156: // don't bother scaling.
157: if (scale < 1.0d) {
158: tx.scale(scale, scale);
159: }
160:
161: // Paint image.
162: Graphics2D g2d = outImage.createGraphics();
163: g2d.drawImage(inImage.getImage(), tx, null);
164: g2d.dispose();
165:
166: // JPEG-encode the image and write the response
167: ByteArrayOutputStream os = new ByteArrayOutputStream();
168: JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
169: encoder.encode(outImage);
170:
171: return os.toByteArray();
172: }
173:
174: void sendImage(byte[] image, HttpServletResponse response)
175: throws ServletException, IOException {
176: OutputStream os = response.getOutputStream();
177: response.setContentLength(image.length);
178: os.write(image);
179: }
180:
181: void storeImage(Connection conn, byte[] image, String name, int dim)
182: throws SQLException {
183: PreparedStatement p = conn
184: .prepareStatement("insert into images(?,?,?,?)");
185: p.clearParameters();
186: p.setString(1, name);
187: p.setInt(2, image.length);
188: p.setBytes(3, image);
189: p.setInt(4, dim);
190: p.executeUpdate();
191: p.close();
192: }
193:
194: public void doGet(HttpServletRequest request,
195: HttpServletResponse response) throws ServletException {
196: String s = request.getServletPath();
197: response.setContentType(getServletContext().getMimeType(s));
198: Connection conn;
199: try {
200: conn = getConnection();
201: } catch (SQLException ex) {
202: throw new ServletException(ex);
203: }
204: int dim = -1;
205: String mdim = request.getParameter("maxDim");
206: if (mdim != null) {
207: dim = Integer.parseInt(mdim);
208: }
209: try {
210: Statement stmt = conn.createStatement();
211: if (dim <= 0) {
212: ResultSet rs = stmt
213: .executeQuery("select data from images where name = '"
214: + s + "' and maxDim <= 0");
215: if (rs.next()) {
216: byte[] image = rs.getBytes(1);
217: rs.close();
218: sendImage(image, response);
219: } else {
220: rs.close();
221: // not found
222: }
223: } else {
224: ResultSet rs = stmt
225: .executeQuery("select data from images where name ='"
226: + s + "' and maxDim = " + dim);
227: if (rs.next()) {
228: byte[] image = rs.getBytes(1);
229: rs.close();
230: sendImage(image, response);
231: } else {
232: rs.close();
233: rs = stmt
234: .executeQuery("select data, size from images where name = '"
235: + s + "' and maxDim <= 0");
236: if (rs.next()) {
237: byte[] image = rs.getBytes(1);
238: rs.close();
239: byte[] resized = resizeImage(image, dim);
240: storeImage(conn, resized, s, dim);
241: sendImage(resized, response);
242: } else {
243: // not found
244: rs.close();
245: }
246: }
247: }
248: } catch (Throwable t) {
249: throw new ServletException(t);
250: } finally {
251: try {
252: conn.close();
253: } catch (Throwable t) {
254: throw new ServletException(t);
255: }
256: }
257: }
258:
259: }
|