1.1 restoration
[mir.git] / source / mircoders / entity / EntityImages.java
index c139b34..1cff969 100755 (executable)
-/*\r
- * Copyright (C) 2001, 2002  The Mir-coders group\r
- *\r
- * This file is part of Mir.\r
- *\r
- * Mir is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * Mir is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with Mir; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * In addition, as a special exception, The Mir-coders gives permission to link\r
- * the code of this program with the com.oreilly.servlet library, any library\r
- * licensed under the Apache Software License, The Sun (tm) Java Advanced\r
- * Imaging library (JAI), The Sun JIMI library (or with modified versions of\r
- * the above that use the same license as the above), and distribute linked\r
- * combinations including the two.  You must obey the GNU General Public\r
- * License in all respects for all of the code used other than the above\r
- * mentioned libraries.  If you modify this file, you may extend this exception\r
- * to your version of the file, but you are not obligated to do so.  If you do\r
- * not wish to do so, delete this exception statement from your version.\r
- */\r
-\r
-package mircoders.entity;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.sql.PreparedStatement;\r
-import java.sql.ResultSet;\r
-import java.sql.Statement;\r
-\r
-import org.postgresql.largeobject.BlobInputStream;\r
-import org.postgresql.largeobject.LargeObject;\r
-import org.postgresql.largeobject.LargeObjectManager;\r
-\r
-import mir.config.MirPropertiesConfiguration;\r
-import mir.misc.FileUtil;\r
-import mir.misc.WebdbImage;\r
-import mir.log.LoggerWrapper;\r
-import mir.storage.StorageObject;\r
-import mir.storage.StorageObjectFailure;\r
-\r
-/**\r
- * Diese Klasse enth?lt die Daten eines MetaObjekts\r
- *\r
- * @author RK, mh, mir-coders\r
- * @version $Id: EntityImages.java,v 1.16 2003/02/28 18:27:08 idfx Exp $\r
- */\r
-\r
-\r
-public class EntityImages extends EntityUploadedMedia\r
-{\r
-\r
-  public EntityImages()\r
-  {\r
-    super();\r
-\r
-    logger = new LoggerWrapper("Entity.UploadedMedia.Images");\r
-  }\r
-\r
-  public EntityImages(StorageObject theStorage) {\r
-    this();\r
-    setStorage(theStorage);\r
-  }\r
-\r
-  //\r
-  // methods\r
-\r
-\r
-  public InputStream getImage() throws StorageObjectFailure\r
-  {\r
-    logger.debug("EntityImages.getimage started");\r
-    java.sql.Connection con=null;Statement stmt=null;\r
-    BlobInputStream in; InputStream img_in = null;\r
-\r
-    try {\r
-      con = theStorageObject.getPooledCon();\r
-      con.setAutoCommit(false);\r
-      LargeObjectManager lom;\r
-      java.sql.Connection jCon;\r
-      stmt = con.createStatement();\r
-      ResultSet rs = theStorageObject.executeSql(stmt,\r
-          "select image_data from images where id="+getId());\r
-      jCon = ((com.codestudio.sql.PoolManConnectionHandle)con)\r
-           .getNativeConnection();\r
-      lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI();\r
-      if(rs!=null) {\r
-        if (rs.next()) {\r
-          LargeObject lob = lom.open(rs.getInt(1));\r
-          in = (BlobInputStream)lob.getInputStream();\r
-          img_in = new ImageInputStream(in, con, stmt);\r
-        }\r
-        rs.close();\r
-      }\r
-    }\r
-    catch (Exception e) {\r
-      logger.error("EntityImages.getImage failed: "+e.toString());\r
-      e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));\r
-      try {\r
-        con.setAutoCommit(true);\r
-      }\r
-      catch (Exception e2) {\r
-        logger.error("EntityImages.getImage reseting transaction mode failed: " + e2.toString());\r
-        e2.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));\r
-      }\r
-\r
-      try {\r
-        theStorageObject.freeConnection(con, stmt);\r
-      }\r
-      catch (Throwable t) {\r
-      }\r
-\r
-      throwStorageObjectFailure(e, "EntityImages -- getImage failed: ");\r
-    }\r
-    //}\r
-    return img_in;\r
-  }\r
-\r
-  public void setImage(InputStream in, String type)\r
-      throws StorageObjectFailure {\r
-\r
-    if (in!=null) {\r
-      java.sql.Connection con=null;PreparedStatement pstmt=null;\r
-      File f = null;\r
-      try {\r
-        logger.debug("EntityImages.settimage :: making internal representation of image");\r
-\r
-        File tempDir = new File(MirPropertiesConfiguration.instance().getString("TempDir"));\r
-        f = File.createTempFile("mir", ".tmp", tempDir);\r
-        FileUtil.write(f, in);\r
-        WebdbImage webdbImage= new WebdbImage(f, type);\r
-        logger.debug("EntityImages.settimage :: made internal representation of image");\r
-\r
-        con = theStorageObject.getPooledCon();\r
-        con.setAutoCommit(false);\r
-        logger.debug("EntityImages.settimage :: trying to insert image");\r
-\r
-        // setting values\r
-        LargeObjectManager lom;\r
-        java.sql.Connection jCon;\r
-        jCon = ((com.codestudio.sql.PoolManConnectionHandle)con)\r
-             .getNativeConnection();\r
-\r
-        lom = ((org.postgresql.Connection) jCon).getLargeObjectAPI();\r
-\r
-        int oidImage = lom.create();\r
-        int oidIcon = lom.create();\r
-        LargeObject lobImage = lom.open(oidImage);\r
-        LargeObject lobIcon = lom.open(oidIcon);\r
-        webdbImage.setImage(lobImage.getOutputStream());\r
-        webdbImage.setIcon(lobIcon.getOutputStream());\r
-        lobImage.close();\r
-        lobIcon.close();\r
-\r
-        setValueForProperty("img_height", new Integer(webdbImage.getImageHeight()).toString());\r
-        setValueForProperty("img_width", new Integer(webdbImage.getImageWidth()).toString());\r
-        setValueForProperty("icon_height", new Integer(webdbImage.getIconHeight()).toString());\r
-        setValueForProperty("icon_width", new Integer(webdbImage.getIconWidth()).toString());\r
-        setValueForProperty("image_data", new Integer(oidImage).toString());\r
-        setValueForProperty("icon_data", new Integer(oidIcon).toString());\r
-        update();\r
-      }\r
-      catch (Exception e) {\r
-        throwStorageObjectFailure(e, "settimage :: setImage gescheitert: ");\r
-      }\r
-      finally {\r
-        try {\r
-          if (con!=null)\r
-            con.setAutoCommit(true);\r
-          // get rid of the temp. file\r
-          f.delete();\r
-        }\r
-        catch (Exception e) {\r
-        }\r
-\r
-        if (con!=null)\r
-          theStorageObject.freeConnection(con,pstmt);\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Takes an OutputStream as an argument and reads in the data\r
-   * from the DB and writes it to the OutputStream.\r
-   *\r
-   * It will also take care of closing the OutputStream.\r
-   */\r
-  public InputStream getIcon() throws StorageObjectFailure\r
-  {\r
-    java.sql.Connection con=null;Statement stmt=null;\r
-    BlobInputStream in=null;ImageInputStream img_in=null;\r
-\r
-    try {\r
-      con = theStorageObject.getPooledCon();\r
-      con.setAutoCommit(false);\r
-      LargeObjectManager lom;\r
-      java.sql.Connection jCon;\r
-      stmt = con.createStatement();\r
-      ResultSet rs = theStorageObject.executeSql(stmt, "select icon_data from images where id="+getId());\r
-      jCon = ((com.codestudio.sql.PoolManConnectionHandle)con)\r
-           .getNativeConnection();\r
-      lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI();\r
-      if(rs!=null) {\r
-        if (rs.next()) {\r
-          LargeObject lob = lom.open(rs.getInt(1));\r
-          in = (BlobInputStream)lob.getInputStream();\r
-          img_in = new ImageInputStream( in, con ,stmt);\r
-          //img_data = rs.getBytes(1);\r
-        }\r
-        rs.close();\r
-      }\r
-    }\r
-    catch (Throwable e) {\r
-      logger.error("EntityImages.getIcon failed: "+e.toString());\r
-      e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));\r
-      try {\r
-        con.setAutoCommit(true);\r
-      }\r
-      catch (Throwable e2) {\r
-        logger.error("EntityImages.getIcon reseting transaction mode failed: " + e2.toString());\r
-        e2.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));\r
-      }\r
-\r
-      try {\r
-        theStorageObject.freeConnection(con, stmt);\r
-      }\r
-      catch (Throwable t) {\r
-      }\r
-\r
-      throwStorageObjectFailure(e, "EntityImages -- getIcon failed:");\r
-    }\r
-\r
-    return img_in;\r
-  }\r
-\r
-  /**\r
-   * a small wrapper class that allows us to store the DB connection resources\r
-   * that the BlobInputStream is using and free them upon closing of the stream\r
-   */\r
-  private class ImageInputStream extends InputStream {\r
-\r
-    InputStream _in;\r
-    java.sql.Connection _con;\r
-    Statement _stmt;\r
-\r
-    public ImageInputStream(BlobInputStream in, java.sql.Connection con,\r
-                            Statement stmt )\r
-    {\r
-      _in = in;\r
-      _con = con;\r
-      _stmt = stmt;\r
-    }\r
-\r
-    public void close () throws IOException {\r
-      _in.close();\r
-\r
-      try {\r
-        _con.setAutoCommit(true);\r
-        theStorageObject.freeConnection(_con,_stmt);\r
-      }\r
-      catch (Exception e) {\r
-        throw new IOException("close(): "+e.toString());\r
-      }\r
-    }\r
-\r
-    public int read() throws IOException {\r
-      return _in.read();\r
-    }\r
-\r
-  }\r
-}\r
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+
+package mircoders.entity;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.sql.SQLException;
+
+import mir.log.LoggerWrapper;
+import mir.storage.StorageObject;
+import mir.storage.StorageObjectFailure;
+import mir.util.StreamCopier;
+import mircoders.media.ImageProcessor;
+
+/**
+ *
+ * @author RK, mh, mir-coders
+ * @version $Id: EntityImages.java,v 1.21.2.5 2004/11/21 22:07:13 zapata Exp $
+ */
+
+
+public class EntityImages extends EntityUploadedMedia
+{
+  private int maxImageSize = configuration.getInt("Producer.Image.MaxSize");
+  private int maxIconSize = configuration.getInt("Producer.Image.MaxIconSize");
+  private float minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100;
+  private int minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction");
+
+
+  public EntityImages()
+  {
+    super();
+
+    logger = new LoggerWrapper("Entity.UploadedMedia.Images");
+  }
+
+  public EntityImages(StorageObject theStorage) {
+    this();
+    setStorage(theStorage);
+  }
+
+  /**
+   * Retrieves the image data
+   */
+  public InputStream getImage() throws StorageObjectFailure {
+    try {
+      return storageObject.getBinaryField("select image_data from images where id="+getId());
+    }
+    catch (SQLException e) {
+      throw new StorageObjectFailure(e);
+    }
+  }
+
+  /**
+   * Processes and saves image data
+   */
+  public void setImage(InputStream anInputStream, String type) throws StorageObjectFailure {
+    // todo: failures should be treated anInputStream a better way: exception -> rollback instead
+    //  of commit
+    if (anInputStream != null) {
+      try {
+        ByteArrayOutputStream inputData = new ByteArrayOutputStream();
+        StreamCopier.copy(anInputStream, inputData);
+
+        ImageProcessor processor = new ImageProcessor(inputData.toByteArray());
+        processor.descaleImage(maxImageSize, minDescaleRatio, minDescaleReduction);
+
+        ByteArrayOutputStream imageData = new ByteArrayOutputStream();
+        processor.writeScaledData(imageData, type);
+        storageObject.setBinaryField("update images set image_data = ? where id = "+getId(), imageData.toByteArray());
+
+        setFieldValue("img_height", new Integer(processor.getScaledHeight()).toString());
+        setFieldValue("img_width", new Integer(processor.getScaledWidth()).toString());
+
+        imageData.reset();
+        processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction);
+        processor.writeScaledData(imageData, type);
+        storageObject.setBinaryField("update images set icon_data = ? where id = "+getId(), imageData.toByteArray());
+
+        setFieldValue("icon_height", new Integer(processor.getScaledHeight()).toString());
+        setFieldValue("icon_width", new Integer(processor.getScaledWidth()).toString());
+
+        update();
+      }
+      catch (Exception e) {
+        throw new StorageObjectFailure(e);
+      }
+    }
+  }
+
+  /**
+   * Takes an OutputStream as an argument and reads in the data
+   * from the DB and writes it to the OutputStream.
+   *
+   * It will also take care of closing the OutputStream.
+   */
+  public InputStream getIcon() throws StorageObjectFailure {
+    try {
+      return storageObject.getBinaryField("select icon_data from images where id="+getId());
+    }
+    catch (SQLException e) {
+      throw new StorageObjectFailure(e);
+    }
+  }
+}