From: mh Date: Fri, 1 Nov 2002 05:38:20 +0000 (+0000) Subject: Converted media Interface to use streams (Java IO) instead of byte buffers of X-Git-Tag: MIR_1_0_0_RC1~26 X-Git-Url: http://erislabs.net/gitweb/?p=mir.git;a=commitdiff_plain;h=627becfe22637207a6a13f0538cb67bbe96704f4 Converted media Interface to use streams (Java IO) instead of byte buffers of the entire uplaoded files. These saves loads of unecessary memory use. JAI still consumes quite a bit though. A new temporary file (for JAI) parameter is necessary and is in the config.properties file. A nice side effect of this work is the FileHandler interface which is basically a call back mechanism for WebdbMultipartRequest which allows the uploaded file to handled by different classes. For example, for a media upload, the content-type, etc.. needs to be determined, but if say the FileEditor had a feature to upload static files... another handler wood be needed. Right now only the MediaRequest handler exists. --- diff --git a/source/config.properties-dist b/source/config.properties-dist index 1ea10295..dcb56bf8 100755 --- a/source/config.properties-dist +++ b/source/config.properties-dist @@ -35,23 +35,20 @@ # GENERAL SETUP # -Mir.Version=localizer-0 +Mir.Version=pre-1.0 ClearXslCache=no StandardLanguage=de DirectOpenposting=yes -Mir.Localizer=mircoders.localizer.basic.MirBasicLocalizer -Mir.Localizer.Logfile=log/localizer.log -Mir.Localizer.ProducerConfigFile=templates/producer/producers.xml - - +# tempdir to write files for image handling (files are erased) +TempDir=/tmp #note that you can't make pdf's without making fo's GenerateFO=yes GeneratePDF=yes #on-time-password-protection -PasswdProtection=no +PasswdProtection=yes #use rsync to mirror the website to a remote-host Rsync=no diff --git a/source/mir/media/MirMedia.java b/source/mir/media/MirMedia.java index af6dc990..7851d901 100755 --- a/source/mir/media/MirMedia.java +++ b/source/mir/media/MirMedia.java @@ -32,6 +32,7 @@ package mir.media; import java.util.*; +import java.io.InputStream; import freemarker.template.SimpleList; @@ -93,39 +94,39 @@ public interface MirMedia{ * all the info for the specific media type itself. It's job is store the * Media data (content) itself, this could be on the local filesystem, in the * DB or even on a remote host. It then inserts the MetaData in the DB. - * @param uploadedData, a byte array containing the uploaded data. + * @param InputStream, a stream of the uploaded data. * @param ent, an Entity holding the media MetaData * @param mediaType, an Entity holding the media_table entry * @return boolean, success/fail * @see mir.entity.Entity */ - public abstract boolean set (byte[] uploadedData, Entity ent, + public abstract void set (InputStream in, Entity ent, Entity mediaTypeEnt ) throws MirMediaException; public abstract void produce (Entity ent, Entity mediaTypeEnt ) throws MirMediaException; /** - * Get's the media data from storage and returns it as a byte array + * Get's the media data from storage and returns it as an InputStream * Not very useful for most media types as they are stored in a file, * but very usefull for ones stored in the DB as it is necessary to get * it first before making a file out of it (in Producer*). * @param ent, an Entity holding the media MetaData * @param mediaType, an Entity holding the media_table entry - * @return byte[] + * @return java.io.InputStream * @see mir.entity.Entity */ - public abstract byte[] get (Entity ent, Entity mediaTypeEnt) + public abstract InputStream getMedia (Entity ent, Entity mediaTypeEnt) throws MirMediaException; /** * Pretty much like get() above. But get's the specific Icon * representation. useful for media stored in the DB. * @param ent, an Entity holding the media MetaData - * @return byte[] + * @return java.io.InputStream * @see mir.entity.Entity */ - public abstract byte[] getIcon (Entity ent) throws MirMediaException; + public abstract InputStream getIcon (Entity ent) throws MirMediaException; /** * gets the final content representation for the media @@ -187,7 +188,7 @@ public interface MirMedia{ * @return String, the icon filename. * @see mir.misc.MirConfig */ - public abstract String getBigIcon (); + public abstract String getBigIconName (); /** * Returns the file name of the small Icon representing @@ -199,14 +200,14 @@ public interface MirMedia{ * @return String, the icon filename. * @see mir.misc.MirConfig */ - public abstract String getTinyIcon (); + public abstract String getTinyIconName (); /** * Returns the IMG SRC "ALT" text to be used * for the Icon representations * @return String, the ALT text. */ - public abstract String getIconAlt (); + public abstract String getIconAltName (); /** * your can all figure it out. diff --git a/source/mir/misc/FileHandler.java b/source/mir/misc/FileHandler.java new file mode 100755 index 00000000..103a9146 --- /dev/null +++ b/source/mir/misc/FileHandler.java @@ -0,0 +1,55 @@ +/* + * 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 the com.oreilly.servlet library, 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 mir.misc; + +import com.oreilly.servlet.multipart.*; +import java.util.HashMap; + + +/** + * Interface that classes wishing to be used as a callback on FileParts for the + * WebdbMultipartRequest class should implement this interface. + * + * @author mh + * @version $Id: FileHandler.java,v 1.1.2.1 2002/11/01 05:38:20 mh Exp $ + * @see mir.misc.WebdbMultipartRequest + * + */ + +public interface FileHandler { + + public void setFile (FilePart filePart, int fileNum, HashMap Params) + throws FileHandlerException, FileHandlerUserException; + +} + + diff --git a/source/mir/misc/FileHandlerException.java b/source/mir/misc/FileHandlerException.java new file mode 100755 index 00000000..69081e45 --- /dev/null +++ b/source/mir/misc/FileHandlerException.java @@ -0,0 +1,71 @@ +/* + * 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 the com.oreilly.servlet library, 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 mir.misc; + +import java.lang.*; + +/* + * + * @version $Revision: 1.1.2.1 $ + * @author $Author: mh $ + * + * $Log: FileHandlerException.java,v $ + * Revision 1.1.2.1 2002/11/01 05:38:20 mh + * Converted media Interface to use streams (Java IO) instead of byte buffers of + * the entire uplaoded files. These saves loads of unecessary memory use. JAI + * still consumes quite a bit though. + * + * A new temporary file (for JAI) parameter is necessary and is in the config.properties file. + * + * A nice side effect of this work is the FileHandler interface which is + * basically a call back mechanism for WebdbMultipartRequest which allows the + * uploaded file to handled by different classes. For example, for a media + * upload, the content-type, etc.. needs to be determined, but if say the + * FileEditor had a feature to upload static files... another handler wood be + * needed. Right now only the MediaRequest handler exists. + * + * + */ + +public final class FileHandlerException extends Exception { + String msg; + + public FileHandlerException(String msg) { + super(msg); + this.msg = msg; + } + + public String getMsg() { + return msg; + } +} + diff --git a/source/mir/misc/FileHandlerUserException.java b/source/mir/misc/FileHandlerUserException.java new file mode 100755 index 00000000..b016c242 --- /dev/null +++ b/source/mir/misc/FileHandlerUserException.java @@ -0,0 +1,73 @@ +/* + * 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 the com.oreilly.servlet library, 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 mir.misc; + +import java.lang.*; + +/* + * differentiates itself from a bug in that it + * represents a probable user error + * + * @version $Revision: 1.1.2.1 $ + * @author $Author: mh $ + * + * $Log: FileHandlerUserException.java,v $ + * Revision 1.1.2.1 2002/11/01 05:38:20 mh + * Converted media Interface to use streams (Java IO) instead of byte buffers of + * the entire uplaoded files. These saves loads of unecessary memory use. JAI + * still consumes quite a bit though. + * + * A new temporary file (for JAI) parameter is necessary and is in the config.properties file. + * + * A nice side effect of this work is the FileHandler interface which is + * basically a call back mechanism for WebdbMultipartRequest which allows the + * uploaded file to handled by different classes. For example, for a media + * upload, the content-type, etc.. needs to be determined, but if say the + * FileEditor had a feature to upload static files... another handler wood be + * needed. Right now only the MediaRequest handler exists. + * + * + */ + +public final class FileHandlerUserException extends Exception { + String msg; + + public FileHandlerUserException(String msg) { + super(msg); + this.msg = msg; + } + + public String getMsg() { + return msg; + } +} + diff --git a/source/mir/misc/FileUtil.java b/source/mir/misc/FileUtil.java index a7319a2a..0df35e09 100755 --- a/source/mir/misc/FileUtil.java +++ b/source/mir/misc/FileUtil.java @@ -62,28 +62,87 @@ public final class FileUtil { private FileUtil () { } - public static boolean write(String filename, byte[] in) + public static File getFile(String filename) throws IOException { - boolean retVal = false; + try { + File f = null; + f = new File(filename); + File dir = new File(f.getParent()); + dir.mkdirs(); + + return f; + } catch(Exception e) { + throw new IOException(e.toString()); + } + + } + + public static long write(File f, InputStream in) + throws IOException { + + long size = 0; + + if (in!=null) { + try { + FileOutputStream out = new FileOutputStream(f); + + int read; + byte[] buf = new byte[8 * 1024]; + while((read = in.read(buf)) != -1) { + out.write(buf, 0, read); + size += read; + } + + in.close(); + out.close(); + } catch(IOException e) { + throw new IOException(e.toString()); + } + } + return size; + } + + public static long write(String filename, InputStream in) + throws IOException { + + long size = 0; + + if (in!=null) { + try { + File f = getFile(filename); + size = write(f, in); + } catch(IOException e) { + throw new IOException(e.toString()); + } + } + return size; + } + + public static long write(String filename, Reader in, String encoding) + throws IOException { + + long size = 0; if (in!=null) { try { - File f = null; - f = new File(filename); - File dir = new File(f.getParent()); - dir.mkdirs(); - - FileOutputStream outStream; - outStream = new FileOutputStream(f); - outStream.write(in); - outStream.close(); - retVal = true; + File f = getFile(filename); + FileOutputStream fOut = new FileOutputStream(f); + OutputStreamWriter out = new OutputStreamWriter(fOut, encoding); + int read; + char[] cbuf = new char[8*1024]; + while((read = in.read(cbuf)) != -1) { + out.write(cbuf, 0, read); + size += read; + } + + out.close(); + in.close(); } catch(IOException e) { throw new IOException(e.toString()); } } - return retVal; + return size; } public static boolean read(String filename, byte out[]) diff --git a/source/mir/misc/MpRequest.java b/source/mir/misc/MpRequest.java deleted file mode 100755 index 92158a24..00000000 --- a/source/mir/misc/MpRequest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 the com.oreilly.servlet library, 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 mir.misc; - -/** - * Datamodel of a MulitpartRequest - * (inner class) - */ -public class MpRequest{ - byte[] uploadData=null; - String fileName=null; - String fileContentType=null; - - public MpRequest(byte[] i_uploadData, String i_fileName, - String i_contentType){ - setFilename(i_fileName); - setContentType(i_contentType); - setMedia(i_uploadData); - } - - public byte[] getMedia() { - return uploadData; - } - - public String getFilename() { - return fileName; - } - - public String getContentType() { - return fileContentType; - } - - public void setMedia(byte[] i_uploadData) { - uploadData=i_uploadData; - } - - public void setFilename(String i_fileName) { - fileName=i_fileName; - } - - public void setContentType(String i_contentType) { - fileContentType=i_contentType; - } -} diff --git a/source/mir/misc/WebdbImage.java b/source/mir/misc/WebdbImage.java index 4e61947b..bf1a9e20 100755 --- a/source/mir/misc/WebdbImage.java +++ b/source/mir/misc/WebdbImage.java @@ -34,14 +34,14 @@ package mir.misc; /** * Title: * Description: - * Copyright: Copyright (c) 2001 - * Company: Indymedia - * @author - * @version 1.0 + * Copyright: Copyright (c) 2002 Mir-coders + * @author $Author: mh $ + * @version $Id: WebdbImage.java,v 1.6.4.2 2002/11/01 05:38:20 mh Exp $ */ import java.io.*; import java.util.Vector; +import java.util.Random; import javax.media.jai.*; import com.sun.media.jai.codec.*; import java.awt.image.renderable.ParameterBlock; @@ -53,11 +53,11 @@ public class WebdbImage private int maxIconSize=120; private int maxImageSize=640; - private byte[] iconData; - private byte[] imageData; private int iconWidth; private int iconHeight; + Random r = new Random(); + // internal representation of the image private PlanarImage planarImage; @@ -66,41 +66,25 @@ public class WebdbImage // constructor - public WebdbImage(byte[] image, String type) - throws IOException - { - planarImage = JAI.create("stream",new ByteArraySeekableStream(image)); - _type = type; - scaleImage(); - } - - public WebdbImage(byte[] image, String type, int iconMax) - throws IOException - { - maxIconSize=iconMax; - planarImage = JAI.create("stream",new ByteArraySeekableStream(image)); - _type = type; - scaleImage(); - } - - public WebdbImage(byte[] image, String type, int iconMax, int imageMax) + // takes a temporary file as a parameter + public WebdbImage(File f, String type) throws IOException { - maxIconSize=iconMax; - maxImageSize=imageMax; - planarImage = JAI.create("stream",new ByteArraySeekableStream(image)); + // It has to be a FileSeekableStream cause the image conversion + // needs to seek backwards. + planarImage = JAI.create("stream",new FileSeekableStream(f)); _type = type; scaleImage(); } // acc3ssor-methods + // must be run after scaleIcon() public int getIconWidth() throws IOException { - if (iconData==null) scaleIcon(); return iconWidth; } + // must be run after scaleIcon() public int getIconHeight() throws IOException { - if (iconData==null) scaleIcon(); return iconHeight; } @@ -112,20 +96,14 @@ public class WebdbImage return (int)planarImage.getHeight(); } - public byte[] getImage() { - if (imageData==null) { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - JAI.create("encode", planarImage, outStream, _type, null); - imageData = outStream.toByteArray(); - } - return imageData; + public void setImage(OutputStream outStream) { + JAI.create("encode", planarImage, outStream, _type, null); } - public byte[] getIcon() + public void setIcon(OutputStream outStream) throws IOException { - if (iconData == null) scaleIcon(); - return iconData; + scaleIcon(outStream); } private void scaleImage() @@ -133,7 +111,6 @@ public class WebdbImage { if (maxImageSize>0 && ( getImageHeight()> maxImageSize|| getImageWidth() >maxImageSize)) { - System.out.println("SCALE_IMAGE"); float scale; ParameterBlockJAI params = new ParameterBlockJAI("scale"); params.addSource(planarImage); @@ -151,31 +128,26 @@ public class WebdbImage } } - private void scaleIcon() + private void scaleIcon(OutputStream outStream) throws java.io.IOException { - System.out.println("SCALE_ICON"); - if (iconData==null) { - float scale; - ParameterBlockJAI params = new ParameterBlockJAI("scale"); - params.addSource(planarImage); - if (getImageHeight() > getImageWidth()) - scale = (float)maxIconSize / (float)getImageHeight(); - else - scale = (float)maxIconSize / (float)getImageWidth(); - - params.setParameter("xScale", scale); - params.setParameter("yScale", scale); - params.setParameter("xTrans",0.0F); - params.setParameter("yTrans",0.0F); - params.setParameter("interpolation",new InterpolationBilinear()); - PlanarImage temp = JAI.create("scale", params); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - JAI.create("encode", temp, outStream, _type, null); - iconData = outStream.toByteArray(); - iconWidth=temp.getWidth(); - iconHeight=temp.getHeight(); - } + float scale; + ParameterBlockJAI params = new ParameterBlockJAI("scale"); + params.addSource(planarImage); + if (getImageHeight() > getImageWidth()) + scale = (float)maxIconSize / (float)getImageHeight(); + else + scale = (float)maxIconSize / (float)getImageWidth(); + + params.setParameter("xScale", scale); + params.setParameter("yScale", scale); + params.setParameter("xTrans",0.0F); + params.setParameter("yTrans",0.0F); + params.setParameter("interpolation",new InterpolationBilinear()); + PlanarImage temp = JAI.create("scale", params); + JAI.create("encode", temp, outStream, _type, null); + iconWidth=temp.getWidth(); + iconHeight=temp.getHeight(); } } diff --git a/source/mir/misc/WebdbMultipartRequest.java b/source/mir/misc/WebdbMultipartRequest.java index 5d8176f4..7b0c82cf 100755 --- a/source/mir/misc/WebdbMultipartRequest.java +++ b/source/mir/misc/WebdbMultipartRequest.java @@ -52,14 +52,15 @@ public class WebdbMultipartRequest HttpServletRequest req=null; Hashtable parameters = new Hashtable(); MultipartParser mp=null; - public static ArrayList requestList; + FileHandler _fHandler; - public WebdbMultipartRequest(HttpServletRequest theReq) throws IOException + public WebdbMultipartRequest(HttpServletRequest theReq, FileHandler handler) + throws FileHandlerException, FileHandlerUserException, IOException { req=theReq; int maxSize = Integer.parseInt(MirConfig.getProp("MaxMediaUploadSize")); mp = new MultipartParser(req, 1024*maxSize); - requestList = new ArrayList(); + _fHandler = handler; _evaluateRequest(); } @@ -123,10 +124,11 @@ public class WebdbMultipartRequest } } - private void _evaluateRequest() throws IOException{ + private void _evaluateRequest() throws FileHandlerException, + FileHandlerUserException, IOException { Part part; - int i = 0; + int i = 1; while ((part = mp.readNextPart()) != null) { String name = part.getName(); if (part.isParam()) { @@ -145,9 +147,8 @@ public class WebdbMultipartRequest FilePart filePart = (FilePart) part; String fn = filePart.getFileName(); if (filePart.getFileName() != null) { - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - filePart.writeTo(byteStream); - requestList.add(i,new MpRequest(byteStream.toByteArray(),filePart.getFileName(),filePart.getContentType())); + if (_fHandler != null) + _fHandler.setFile(filePart, i, getParameters()); i++; } } diff --git a/source/mircoders/entity/EntityAudio.java b/source/mircoders/entity/EntityAudio.java index 3592376a..8846ab94 100755 --- a/source/mircoders/entity/EntityAudio.java +++ b/source/mircoders/entity/EntityAudio.java @@ -53,7 +53,7 @@ import mir.storage.*; * This class handles storage of audio data and meta data * * @author mh - * @version 11.11.2000 + * @version $Id: EntityAudio.java,v 1.2.4.2 2002/11/01 05:38:20 mh Exp $ */ @@ -69,102 +69,6 @@ public class EntityAudio extends EntityUploadedMedia setStorage(theStorage); } - // - // methods - - - - public byte[] getAudio() throws StorageObjectException - { - theLog.printDebugInfo("--getaudio started"); - java.sql.Connection con=null;Statement stmt=null; - byte[] data=null; - - try { - con = theStorageObject.getPooledCon(); - con.setAutoCommit(false); - LargeObjectManager lom; - java.sql.Connection jCon; - stmt = con.createStatement(); - ResultSet rs = theStorageObject.executeSql(stmt, - "select audio_data from audio where id="+getId()); - jCon = ((com.codestudio.sql.PoolManConnectionHandle)con) - .getNativeConnection(); - lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI(); - if(rs!=null) { - if (rs.next()) { - LargeObject lob = lom.open(rs.getInt(1)); - data = lob.read(lob.size()); - lob.close(); - //data = rs.getBytes(1); - } - rs.close(); - } - } catch (Exception e) { - e.printStackTrace(); - theLog.printError("EntityAudio -- getAudio failed"+e.toString()); - throwStorageObjectException(e, "EntityAudio -- getAudio failed: "); - } - finally { - try { - con.setAutoCommit(true); - } catch (Exception e) { - e.printStackTrace(); - theLog.printError( - "EntityAudio -- getAudio reseting transaction mode failed" - +e.toString()); - } - theStorageObject.freeConnection(con,stmt); - } - - return data; - } - - public void setAudio(byte[] uploadData) - throws StorageObjectException { - - if (uploadData!=null) { - java.sql.Connection con=null;PreparedStatement pstmt=null; - try { - - if (uploadData!=null) { - con = theStorageObject.getPooledCon(); - con.setAutoCommit(false); - theLog.printDebugInfo("setaudio :: trying to insert audio"); - - // setting values - LargeObjectManager lom; - java.sql.Connection jCon; - jCon = ((com.codestudio.sql.PoolManConnectionHandle)con) - .getNativeConnection(); - lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI(); - int oid = lom.create(); - LargeObject lob = lom.open(oid); - lob.write(uploadData); - lob.close(); - String sql = "update images set" - +" audio_data="+oid - +" where id="+getId(); - theLog.printDebugInfo("setaudio :: updating: "+ sql); - pstmt = con.prepareStatement(sql); - //pstmt.setBytes(1, imageData); - //pstmt.setBytes(2, iconData); - pstmt.executeUpdate(); - sql="update content set is_produced='0' where to_media="+getId(); - pstmt = con.prepareStatement(sql); - pstmt.executeUpdate(); - } - } - catch (Exception e) { - throwStorageObjectException(e,"setaudio ::failed: "); - } - finally { - try { if (con!=null) con.setAutoCommit(true); } catch (Exception e) {;} - theStorageObject.freeConnection(con,pstmt); } - } - } - - public void update() throws StorageObjectException { super.update(); try { diff --git a/source/mircoders/entity/EntityContent.java b/source/mircoders/entity/EntityContent.java index b45dd3b3..bbf142cd 100755 --- a/source/mircoders/entity/EntityContent.java +++ b/source/mircoders/entity/EntityContent.java @@ -50,10 +50,24 @@ import mircoders.storage.*; * this class implements mapping of one line of the database table content * to a java object * - * @version $Revision: 1.9.2.1 $ $Date: 2002/09/01 21:31:43 $ + * @version $Revision: 1.9.2.2 $ $Date: 2002/11/01 05:38:20 $ * @author $Author: mh $ * * $Log: EntityContent.java,v $ + * Revision 1.9.2.2 2002/11/01 05:38:20 mh + * Converted media Interface to use streams (Java IO) instead of byte buffers of + * the entire uplaoded files. These saves loads of unecessary memory use. JAI + * still consumes quite a bit though. + * + * A new temporary file (for JAI) parameter is necessary and is in the config.properties file. + * + * A nice side effect of this work is the FileHandler interface which is + * basically a call back mechanism for WebdbMultipartRequest which allows the + * uploaded file to handled by different classes. For example, for a media + * upload, the content-type, etc.. needs to be determined, but if say the + * FileEditor had a feature to upload static files... another handler wood be + * needed. Right now only the MediaRequest handler exists. + * * Revision 1.9.2.1 2002/09/01 21:31:43 mh * Mir goes GPL * @@ -394,8 +408,8 @@ public class EntityContent extends Entity tinyIcon = MirConfig.getProp("Producer.Icon.TinyAudio"); iconAlt = "Audio"; } else if (tinyIcon == null && !mediaHandler.isImage()) { - tinyIcon = mediaHandler.getTinyIcon(); - iconAlt = mediaHandler.getIconAlt(); + tinyIcon = mediaHandler.getTinyIconName(); + iconAlt = mediaHandler.getIconAltName(); } } diff --git a/source/mircoders/entity/EntityImages.java b/source/mircoders/entity/EntityImages.java index 75da1ee1..b4f0440e 100755 --- a/source/mircoders/entity/EntityImages.java +++ b/source/mircoders/entity/EntityImages.java @@ -44,6 +44,7 @@ import java.sql.*; import org.postgresql.Connection; import org.postgresql.largeobject.LargeObject; import org.postgresql.largeobject.LargeObjectManager; +import org.postgresql.largeobject.BlobInputStream; import mir.entity.*; import mir.misc.*; @@ -52,13 +53,16 @@ import mir.storage.*; /** * Diese Klasse enthält die Daten eines MetaObjekts * - * @author RK - * @version 11.11.2000 + * @author RK, mh + * @version $Id: EntityImages.java,v 1.6.4.2 2002/11/01 05:38:20 mh Exp $ */ public class EntityImages extends EntityUploadedMedia { + + Random r = new Random(); + public EntityImages() { super(); @@ -73,109 +77,109 @@ public class EntityImages extends EntityUploadedMedia // methods - - public byte[] getImage() throws StorageObjectException + public InputStream getImage() throws StorageObjectException { theLog.printDebugInfo("--getimage started"); java.sql.Connection con=null;Statement stmt=null; - byte[] img_data=null; + BlobInputStream in; InputStream img_in = null; try { con = theStorageObject.getPooledCon(); con.setAutoCommit(false); LargeObjectManager lom; - java.sql.Connection jCon; - stmt = con.createStatement(); + java.sql.Connection jCon; + stmt = con.createStatement(); ResultSet rs = theStorageObject.executeSql(stmt, "select image_data from images where id="+getId()); - jCon = ((com.codestudio.sql.PoolManConnectionHandle)con) - .getNativeConnection(); - lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI(); + jCon = ((com.codestudio.sql.PoolManConnectionHandle)con) + .getNativeConnection(); + lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI(); if(rs!=null) { - if (rs.next()) { - LargeObject lob = lom.open(rs.getInt(1)); - img_data = lob.read(lob.size()); - lob.close(); - //img_data = rs.getBytes(1); - } - rs.close(); + if (rs.next()) { + LargeObject lob = lom.open(rs.getInt(1)); + in = (BlobInputStream)lob.getInputStream(); + img_in = new ImageInputStream(in, con, stmt); + } + rs.close(); } } catch (Exception e) { - e.printStackTrace(); - theLog.printError("EntityImages -- getImage failed"+e.toString()); - throwStorageObjectException(e, "EntityImages -- getImage failed: "); - } - finally { - try { - con.setAutoCommit(true); - } catch (Exception e) { - e.printStackTrace(); - theLog.printError( - "EntityImages -- getImage reseting transaction mode failed" - +e.toString()); - } - theStorageObject.freeConnection(con,stmt); - } - - return img_data; + e.printStackTrace(); + theLog.printError("EntityImages -- getImage failed"+e.toString()); + throwStorageObjectException(e, "EntityImages -- getImage failed: "); + try { + con.setAutoCommit(true); + } catch (Exception e2) { + e.printStackTrace(); + theLog.printError( + "EntityImages -- getImage reseting transaction mode failed" + +e2.toString()); + } + theStorageObject.freeConnection(con,stmt); + } + //} + return img_in; } - public void setImage(byte[] uploadData, String type) + public void setImage(InputStream in, String type) throws StorageObjectException { - if (uploadData!=null) { + if (in!=null) { java.sql.Connection con=null;PreparedStatement pstmt=null; + File f = null; try { theLog.printDebugInfo("settimage :: making internal representation of image"); - WebdbImage webdbImage= new WebdbImage(uploadData, type); + + String fName = MirConfig.getProp("TempDir")+File.separator+r.nextInt(); + f = new File(fName); + FileUtil.write(f, in); + WebdbImage webdbImage= new WebdbImage(f, type); theLog.printDebugInfo("settimage :: made internal representation of image"); - byte[] imageData = webdbImage.getImage(); - theLog.printDebugInfo("settimage :: getImage"); - byte[] iconData = webdbImage.getIcon(); - theLog.printDebugInfo("settimage :: getIcon"); - - - if (iconData!=null && imageData!=null) { - con = theStorageObject.getPooledCon(); - con.setAutoCommit(false); - theLog.printDebugInfo("settimage :: trying to insert image"); - - // setting values - LargeObjectManager lom; - java.sql.Connection jCon; - jCon = ((com.codestudio.sql.PoolManConnectionHandle)con) - .getNativeConnection(); - lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI(); - int oidImage = lom.create(); - int oidIcon = lom.create(); - LargeObject lobImage = lom.open(oidImage); - LargeObject lobIcon = lom.open(oidIcon); - lobImage.write(imageData); - lobIcon.write(iconData); - lobImage.close(); - lobIcon.close(); - String sql = "update images set img_height='" - +webdbImage.getImageHeight() + - "',img_width='" + webdbImage.getImageWidth() + - "',icon_height='" + webdbImage.getIconHeight() + - "',icon_width='" + webdbImage.getIconWidth() - + "', image_data="+oidImage+", icon_data="+oidIcon - +" where id="+getId(); - theLog.printDebugInfo("settimage :: updating sizes: "+ sql); - pstmt = con.prepareStatement(sql); - //pstmt.setBytes(1, imageData); - //pstmt.setBytes(2, iconData); - pstmt.executeUpdate(); - sql="update content set is_produced='0' where to_media="+getId(); - pstmt = con.prepareStatement(sql); - pstmt.executeUpdate(); - } + + con = theStorageObject.getPooledCon(); + con.setAutoCommit(false); + theLog.printDebugInfo("settimage :: trying to insert image"); + + // setting values + LargeObjectManager lom; + java.sql.Connection jCon; + jCon = ((com.codestudio.sql.PoolManConnectionHandle)con) + .getNativeConnection(); + lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI(); + int oidImage = lom.create(); + int oidIcon = lom.create(); + LargeObject lobImage = lom.open(oidImage); + LargeObject lobIcon = lom.open(oidIcon); + webdbImage.setImage(lobImage.getOutputStream()); + webdbImage.setIcon(lobIcon.getOutputStream()); + lobImage.close(); + lobIcon.close(); + String sql = "update images set img_height='" + +webdbImage.getImageHeight() + + "',img_width='" + webdbImage.getImageWidth() + + "',icon_height='" + webdbImage.getIconHeight() + + "',icon_width='" + webdbImage.getIconWidth() + + "', image_data="+oidImage+", icon_data="+oidIcon + +" where id="+getId(); + theLog.printDebugInfo("settimage :: updating sizes: "+ sql); + pstmt = con.prepareStatement(sql); + //pstmt.setBytes(1, imageData); + //pstmt.setBytes(2, iconData); + pstmt.executeUpdate(); + sql="update content set is_produced='0' where to_media="+getId(); + pstmt = con.prepareStatement(sql); + pstmt.executeUpdate(); } catch (Exception e) {throwStorageObjectException(e, "settimage :: setImage gescheitert: ");} finally { - try { if (con!=null) con.setAutoCommit(true); } catch (Exception e) {;} - theStorageObject.freeConnection(con,pstmt); } + try { + if (con!=null) + con.setAutoCommit(true); + // get rid of the temp. file + f.delete(); + } catch (Exception e) {;} + theStorageObject.freeConnection(con,pstmt); + } } } @@ -197,48 +201,88 @@ public class EntityImages extends EntityUploadedMedia super.setValues(theStringValues); } - public byte[] getIcon() throws StorageObjectException + /** + * 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 StorageObjectException { java.sql.Connection con=null;Statement stmt=null; - byte[] img_data=null; + BlobInputStream in=null;ImageInputStream img_in=null; try { con = theStorageObject.getPooledCon(); con.setAutoCommit(false); - LargeObjectManager lom; - java.sql.Connection jCon; + LargeObjectManager lom; + java.sql.Connection jCon; stmt = con.createStatement(); ResultSet rs = theStorageObject.executeSql(stmt, "select icon_data from images where id="+getId()); - jCon = ((com.codestudio.sql.PoolManConnectionHandle)con) + jCon = ((com.codestudio.sql.PoolManConnectionHandle)con) .getNativeConnection(); - lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI(); + lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI(); if(rs!=null) { if (rs.next()) { - LargeObject lob = lom.open(rs.getInt(1)); - img_data = lob.read(lob.size()); - lob.close(); - //img_data = rs.getBytes(1); + LargeObject lob = lom.open(rs.getInt(1)); + in = (BlobInputStream)lob.getInputStream(); + img_in = new ImageInputStream( in, con ,stmt); + //img_data = rs.getBytes(1); } - rs.close(); + rs.close(); } } catch (Exception e) { - e.printStackTrace(); - theLog.printError("EntityImages -- getIcon failed"+e.toString()); - throwStorageObjectException(e, "EntityImages -- getIcon failed:"); - } finally { - try { - con.setAutoCommit(true); - } catch (Exception e) { - e.printStackTrace(); - theLog.printError( - "EntityImages -- getIcon reseting transaction mode failed" - +e.toString()); - } - theStorageObject.freeConnection(con,stmt); - } - - return img_data; + e.printStackTrace(); + theLog.printError("EntityImages -- getIcon failed"+e.toString()); + throwStorageObjectException(e, "EntityImages -- getIcon failed:"); + try { + con.setAutoCommit(true); + } catch (Exception e2) { + e.printStackTrace(); + theLog.printError( + "EntityImages -- getIcon reseting transaction mode failed" + +e2.toString()); + } + theStorageObject.freeConnection(con,stmt); + } + + return img_in; } + /** + * a small wrapper class that allows us to store the DB connection resources + * that the BlobInputStream is using and free them upon closing of the stream + */ + private class ImageInputStream extends InputStream { + + InputStream _in; + java.sql.Connection _con; + Statement _stmt; + + public ImageInputStream(BlobInputStream in, java.sql.Connection con, + Statement stmt ) + { + _in = in; + _con = con; + _stmt = stmt; + } + + public void close () throws IOException { + _in.close(); + + try { + _con.setAutoCommit(true); + theStorageObject.freeConnection(_con,_stmt); + } catch (Exception e) { + throw new IOException("close(): "+e.toString()); + } + } + + public int read() throws IOException { + return _in.read(); + } + + } + } diff --git a/source/mircoders/entity/EntityOther.java b/source/mircoders/entity/EntityOther.java index 1c063fef..de1334b6 100755 --- a/source/mircoders/entity/EntityOther.java +++ b/source/mircoders/entity/EntityOther.java @@ -69,87 +69,6 @@ public class EntityOther extends EntityUploadedMedia setStorage(theStorage); } - // - // methods - - - - public byte[] getOther() throws StorageObjectException - { - theLog.printDebugInfo("--getother started"); - java.sql.Connection con=null;Statement stmt=null; - byte[] img_data=null; - - try { - con = theStorageObject.getPooledCon(); - con.setAutoCommit(false); - LargeObjectManager lom; - java.sql.Connection jCon; - stmt = con.createStatement(); - ResultSet rs = theStorageObject.executeSql(stmt, - "select other_data from other where id="+getId()); - jCon = ((com.codestudio.sql.PoolManConnectionHandle)con) - .getNativeConnection(); - lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI(); - if(rs!=null) { - if (rs.next()) { - LargeObject lob = lom.open(rs.getInt(1)); - img_data = lob.read(lob.size()); - lob.close(); - //img_data = rs.getBytes(1); - } - rs.close(); - } - } catch (Exception e) { - e.printStackTrace(); - theLog.printError("EntityOther -- getOther failed"+e.toString()); - throwStorageObjectException(e, "EntityOther -- getOther failed: "); - } - finally { - try { - con.setAutoCommit(true); - } catch (Exception e) { - e.printStackTrace(); - theLog.printError( - "EntityOther -- getOther reseting transaction mode failed" - +e.toString()); - } - theStorageObject.freeConnection(con,stmt); - } - - return img_data; - } - - public void setOther(byte[] otherData, String otherType) - throws StorageObjectException { - - if (otherData!=null) { - java.sql.Connection con=null;PreparedStatement pstmt=null; - try { - - theLog.printDebugInfo("settother :: making internal representation of other"); - theLog.printDebugInfo("settother :: made internal representation of other"); - theLog.printDebugInfo("settother :: getOther"); - - if ( otherData!=null) { - con = theStorageObject.getPooledCon(); - con.setAutoCommit(false); - theLog.printDebugInfo("settother :: trying to insert other"); - - // setting values - pstmt.setBytes(1, otherData); - String sql="update content set is_produced='0' where to_media="+getId(); - pstmt = con.prepareStatement(sql); - pstmt.executeUpdate(); - } - } - catch (Exception e) {throwStorageObjectException(e, "settother :: setOther gescheitert: ");} - finally { - try { if (con!=null) con.setAutoCommit(true); } catch (Exception e) {;} - theStorageObject.freeConnection(con,pstmt); } - } - } - public void update() throws StorageObjectException { super.update(); try { diff --git a/source/mircoders/entity/EntityUploadedMedia.java b/source/mircoders/entity/EntityUploadedMedia.java index 750e5395..1b255423 100755 --- a/source/mircoders/entity/EntityUploadedMedia.java +++ b/source/mircoders/entity/EntityUploadedMedia.java @@ -94,7 +94,7 @@ public class EntityUploadedMedia extends Entity { if (key != null) { if (key.equals("big_icon")) - returnValue = getBigIcon(); + returnValue = getBigIconName(); else if (key.equals("descr")) returnValue = getDescr(); else if (key.equals("mediatype")) @@ -139,17 +139,17 @@ public class EntityUploadedMedia extends Entity { return null; } - private String getBigIcon() { + private String getBigIconName() { MirMedia mediaHandler = null; Entity mediaType = null; try { mediaType = getMediaType(); mediaHandler = MediaHelper.getHandler(mediaType); - return mediaHandler.getBigIcon(); + return mediaHandler.getBigIconName(); } catch (Exception ex) { - theLog.printWarning("-- getBigIcon: could not fetch data " + theLog.printWarning("-- getBigIconName: could not fetch data " + this.getClass().toString() + " " + ex.toString()); } return null; @@ -194,7 +194,7 @@ public class EntityUploadedMedia extends Entity { return mediaType.getValue("mime_type"); } catch (Exception ex) { - theLog.printWarning("-- getBigIcon: could not fetch data " + theLog.printWarning("-- getBigIconName: could not fetch data " + this.getClass().toString() + " " + ex.toString()); } return null; diff --git a/source/mircoders/entity/EntityVideo.java b/source/mircoders/entity/EntityVideo.java index dfb1cf7d..65397b5b 100755 --- a/source/mircoders/entity/EntityVideo.java +++ b/source/mircoders/entity/EntityVideo.java @@ -64,59 +64,6 @@ public class EntityVideo extends EntityUploadedMedia // // methods - public byte[] getVideoData() throws StorageObjectException - { - - Connection con=null;Statement stmt=null; - byte[] video_data=null; - - try { - con = theStorageObject.getPooledCon(); - con.setAutoCommit(false); - stmt = con.createStatement(); - ResultSet rs = theStorageObject.executeSql(stmt,"select video_data from video where id="+getId()); - if(rs!=null) { - if (rs.next()) { - video_data = rs.getBytes(1); - } - rs.close(); - } - } - catch (Exception e) {theLog.printDebugInfo("-- getImage gescheitert: "+e.toString());} - finally { - try {con.setAutoCommit(true); } catch (Exception e) {;} - theStorageObject.freeConnection(con,stmt); } - - return video_data; - } - - public void setVideoData(byte[] uploadData) throws StorageObjectException - { - if (uploadData!=null) { - Connection con=null;PreparedStatement pstmt=null; - try { - - con = theStorageObject.getPooledCon(); - con.setAutoCommit(false); - theLog.printDebugInfo("setvideo :: trying to insert video"); - - // setting values - String sql = "update videos set image_data=? where id="+getId(); - theLog.printDebugInfo("setvideo: "+ sql); - pstmt = con.prepareStatement(sql); - pstmt.setBytes(1, uploadData); - pstmt.executeUpdate(); - sql="update content set is_produced='0' where to_media="+getId(); - pstmt = con.prepareStatement(sql); - pstmt.executeUpdate(); - } - catch (Exception e) {theLog.printDebugInfo("setvideo :: setvideo gescheitert: "+e.toString());} - finally { - try {con.setAutoCommit(true); } catch (Exception e) {;} - theStorageObject.freeConnection(con,pstmt); } - } - } - public void update() throws StorageObjectException { super.update(); try { diff --git a/source/mircoders/media/MediaHandlerAudio.java b/source/mircoders/media/MediaHandlerAudio.java index 709c1ac1..5d7e2446 100755 --- a/source/mircoders/media/MediaHandlerAudio.java +++ b/source/mircoders/media/MediaHandlerAudio.java @@ -60,7 +60,7 @@ public class MediaHandlerAudio extends MediaHandlerGeneric implements MirMedia return tinyIcon; } - public String getBigIcon() + public String getBigIconName() { return bigIcon; } diff --git a/source/mircoders/media/MediaHandlerGeneric.java b/source/mircoders/media/MediaHandlerGeneric.java index 4953b852..f0402e72 100755 --- a/source/mircoders/media/MediaHandlerGeneric.java +++ b/source/mircoders/media/MediaHandlerGeneric.java @@ -68,29 +68,24 @@ public class MediaHandlerGeneric implements MirMedia protected static String imageRoot = MirConfig.getProp("Producer.ImageRoot"); protected static Logfile theLog = Logfile.getInstance(MirConfig.getProp("Home")+ "log/media.log"); - public boolean set (byte[] uploadedData, Entity ent, Entity mediaTypeEnt ) + public void set (InputStream in, Entity ent, Entity mediaTypeEnt ) throws MirMediaException { String ext = mediaTypeEnt.getValue("name"); String mediaFname = ent.getId()+"."+ext; String date = ent.getValue("date"); String datePath = StringUtil.webdbDate2path(date); - Integer size = new Integer(uploadedData.length); try { - FileUtil.write(getStoragePath()+"/"+datePath+"/"+mediaFname, - uploadedData); - //were done with the data, dereference. - uploadedData=null; - + long size = FileUtil.write(getStoragePath()+"/"+datePath+"/"+ + mediaFname, in); ent.setValueForProperty("publish_path",datePath+"/"+mediaFname); - ent.setValueForProperty("size", size.toString()); + ent.setValueForProperty("size", new Long(size).toString()); ent.update(); } catch (Exception e) { theLog.printError(e.toString()); throw new MirMediaException(e.toString()); } - return true; } public void produce (Entity ent, Entity mediaTypeEnt ) @@ -108,30 +103,24 @@ public class MediaHandlerGeneric implements MirMedia } - //a method that will probably never get used.. - private byte[] getFile (String fileName) - throws MirMediaException { - - long size = FileUtil.getSize(fileName); - if (size < 0) return null; - - byte[] container = new byte[(int)size]; - - try { - FileUtil.read(fileName, container); - } catch (Exception e) { - theLog.printError(e.toString()); - throw new MirMediaException(e.toString()); - } - - return container; - } - - public byte[] get (Entity ent, Entity mediaTypeEnt) { - return null; + public InputStream getMedia (Entity ent, Entity mediaTypeEnt) + throws MirMediaException { + String publishPath = mediaTypeEnt.getValue("publish_path"); + String fname = getStoragePath()+publishPath; + File f = new File(fname); + if(! f.exists()) + throw new MirMediaException("error in MirMedia.getMedia(): "+fname+ + "does not exist!"); + FileInputStream in; + try { + in = new FileInputStream(f); + } catch (IOException e) { + throw new MirMediaException("getMedia(): "+e.toString()); + } + return in; } - public byte[] getIcon (Entity ent) { + public InputStream getIcon (Entity ent) { return null; } @@ -150,17 +139,17 @@ public class MediaHandlerGeneric implements MirMedia return MirConfig.getProp("Producer.Media.Host"); } - public String getTinyIcon() + public String getTinyIconName() { return MirConfig.getProp("Producer.Icon.TinyText"); } - public String getBigIcon() + public String getBigIconName() { return MirConfig.getProp("Producer.Icon.BigText"); } - public String getIconAlt() + public String getIconAltName() { return "Generic media"; } diff --git a/source/mircoders/media/MediaHandlerImages.java b/source/mircoders/media/MediaHandlerImages.java index 7755cc3e..8c89bb6e 100755 --- a/source/mircoders/media/MediaHandlerImages.java +++ b/source/mircoders/media/MediaHandlerImages.java @@ -59,7 +59,7 @@ import mircoders.entity.EntityImages; * * @see mir.media.MirMedia * @author mh - * @version 24.09.2001 + * @version $Date: 2002/11/01 05:38:21 $ $Revision: 1.9.2.2 $ */ @@ -72,34 +72,30 @@ public abstract class MediaHandlerImages implements MirMedia abstract String getType(); - public byte[] get(Entity ent, Entity mediaTypeEnt) + public InputStream getMedia(Entity ent, Entity mediaTypeEnt) throws MirMediaException { - byte[] image_data = null; - + InputStream in; try { - image_data = ((EntityImages)ent).getImage(); + in = ((EntityImages)ent).getImage(); } catch ( StorageObjectException e) { - theLog.printDebugInfo("MediaHandlerImages.get: "+e.toString()); + theLog.printDebugInfo("MediaHandlerImages.getImage: "+e.toString()); throw new MirMediaException(e.toString()); } - return image_data; + return in; } - public boolean set(byte[] uploadData, Entity ent, Entity mediaTypeEnt) + public void set(InputStream in, Entity ent, Entity mediaTypeEnt) throws MirMediaException { try { - ((EntityImages)ent).setImage(uploadData, getType()); + ((EntityImages)ent).setImage(in, getType()); } catch ( StorageObjectException e) { theLog.printError("MediaHandlerImages.set: "+e.toString()); throw new MirMediaException(e.toString()); } - //deref. -mh - uploadData=null; - return true; } public void produce(Entity ent, Entity mediaTypeEnt) throws MirMediaException @@ -110,15 +106,17 @@ public abstract class MediaHandlerImages implements MirMedia String filepath = datePath+ent.getId()+ext; String iconFilePath = MirConfig.getProp("Producer.StorageRoot") +getIconStoragePath() + filepath; - String productionFilePath = getStoragePath() + "/" + filepath; + String productionFilePath = getStoragePath() + File.separator + filepath; if (ent.getValue("icon_data")!= null && ent.getValue("image_data")!= null) { // make icon try { - FileUtil.write(iconFilePath,((EntityImages)ent).getIcon()); - FileUtil.write(productionFilePath,((EntityImages)ent).getImage()); + InputStream in = ((EntityImages)ent).getIcon(); + FileUtil.write(iconFilePath, in); + in = ((EntityImages)ent).getImage(); + FileUtil.write(productionFilePath, in); ent.setValueForProperty("icon_path",getIconStoragePath()+filepath); ent.setValueForProperty("publish_path",filepath); ent.update(); @@ -136,18 +134,17 @@ public abstract class MediaHandlerImages implements MirMedia } - public byte[] getIcon(Entity ent) throws MirMediaException + public InputStream getIcon(Entity ent) throws MirMediaException { - byte[] icon_data = null; - + InputStream in; try { - icon_data = ((EntityImages)ent).getIcon(); + in = ((EntityImages)ent).getIcon(); } catch ( StorageObjectException e) { theLog.printDebugInfo("MediaHandlerImages.getIcon: "+e.toString()); throw new MirMediaException(e.toString()); } - return icon_data; + return in; } public SimpleList getURL(Entity ent, Entity mediaTypeEnt) @@ -172,27 +169,27 @@ public abstract class MediaHandlerImages implements MirMedia return MirConfig.getProp("Producer.Image.Host"); } - public String getTinyIcon () + public String getTinyIconName() { return MirConfig.getProp("Producer.Icon.TinyImage"); } - public String getBigIcon () + public String getBigIconName() { return MirConfig.getProp("Producer.Icon.BigImage"); } - public String getIconAlt () + public String getIconAltName() { return "Image"; } - public boolean isVideo () + public boolean isVideo() { return false; } - public boolean isAudio () + public boolean isAudio() { return false; } diff --git a/source/mircoders/media/MediaHandlerMp3.java b/source/mircoders/media/MediaHandlerMp3.java index c964a89f..489f6bcb 100755 --- a/source/mircoders/media/MediaHandlerMp3.java +++ b/source/mircoders/media/MediaHandlerMp3.java @@ -32,6 +32,7 @@ package mircoders.media; import java.util.*; +import java.io.StringReader; import freemarker.template.SimpleList; import freemarker.template.SimpleHash; @@ -89,10 +90,10 @@ public class MediaHandlerMp3 extends MediaHandlerAudio implements MirMedia //write the "meta" files //first the .m3u since it only contains one line FileUtil.write(getStoragePath()+"/"+datePath+"/"+mpegURLFile, - mp3Pointer.getBytes()); + new StringReader(mp3Pointer), "US-ASCII"); //now the .pls file FileUtil.write(getStoragePath()+"/"+datePath+"/"+playlistFile, - mp3Pointer.getBytes()); + new StringReader(mp3Pointer), "US-ASCII"); } catch (Exception e) { theLog.printError(e.toString()); throw new MirMediaException(e.toString()); diff --git a/source/mircoders/media/MediaHandlerRealAudio.java b/source/mircoders/media/MediaHandlerRealAudio.java index 90830b50..5b16e4ad 100755 --- a/source/mircoders/media/MediaHandlerRealAudio.java +++ b/source/mircoders/media/MediaHandlerRealAudio.java @@ -32,6 +32,7 @@ package mircoders.media; import java.util.*; +import java.io.StringReader; import freemarker.template.SimpleList; import freemarker.template.SimpleHash; @@ -75,7 +76,7 @@ public class MediaHandlerRealAudio extends MediaHandlerAudio implements try { //write an rm (ram?. -mh) file FileUtil.write(super.getStoragePath()+"/"+RealMediaFile, - RealMediaPointer.getBytes()); + new StringReader(RealMediaPointer), "US-ASCII"); } catch (Exception e) { theLog.printError(e.toString()); throw new MirMediaException(e.toString()); diff --git a/source/mircoders/media/MediaHandlerRealVideo.java b/source/mircoders/media/MediaHandlerRealVideo.java index f5e3911f..47ece1fe 100755 --- a/source/mircoders/media/MediaHandlerRealVideo.java +++ b/source/mircoders/media/MediaHandlerRealVideo.java @@ -32,6 +32,7 @@ package mircoders.media; import java.util.*; +import java.io.StringReader; import freemarker.template.SimpleList; import freemarker.template.SimpleHash; @@ -75,7 +76,7 @@ public class MediaHandlerRealVideo extends MediaHandlerVideo implements try { //write an rm (ram?. -mh) file FileUtil.write(super.getStoragePath()+"/"+RealMediaFile, - RealMediaPointer.getBytes()); + new StringReader(RealMediaPointer), "US-ASCII"); } catch (Exception e) { theLog.printError(e.toString()); throw new MirMediaException(e.toString()); diff --git a/source/mircoders/media/MediaHandlerVideo.java b/source/mircoders/media/MediaHandlerVideo.java index 65dae737..08144e44 100755 --- a/source/mircoders/media/MediaHandlerVideo.java +++ b/source/mircoders/media/MediaHandlerVideo.java @@ -61,7 +61,7 @@ public class MediaHandlerVideo extends MediaHandlerGeneric implements MirMedia return tinyIcon; } - public String getBigIcon() + public String getBigIconName() { return bigIcon; } diff --git a/source/mircoders/media/MediaRequest.java b/source/mircoders/media/MediaRequest.java index 926e4412..94fd555d 100755 --- a/source/mircoders/media/MediaRequest.java +++ b/source/mircoders/media/MediaRequest.java @@ -32,10 +32,13 @@ package mircoders.media; import java.util.*; +import java.io.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.ServletContext; +import com.oreilly.servlet.multipart.FilePart; + import mircoders.storage.DatabaseMediaType; import mircoders.producer.ProducerMedia; import mir.storage.StorageObjectException; @@ -52,9 +55,23 @@ import mir.media.*; * appropriate media objects are set. * * @author $Author: mh $ - * @version $Revision: 1.1.2.1 $ + * @version $Revision: 1.1.2.2 $ * * $Log: MediaRequest.java,v $ + * Revision 1.1.2.2 2002/11/01 05:38:21 mh + * Converted media Interface to use streams (Java IO) instead of byte buffers of + * the entire uplaoded files. These saves loads of unecessary memory use. JAI + * still consumes quite a bit though. + * + * A new temporary file (for JAI) parameter is necessary and is in the config.properties file. + * + * A nice side effect of this work is the FileHandler interface which is + * basically a call back mechanism for WebdbMultipartRequest which allows the + * uploaded file to handled by different classes. For example, for a media + * upload, the content-type, etc.. needs to be determined, but if say the + * FileEditor had a feature to upload static files... another handler wood be + * needed. Right now only the MediaRequest handler exists. + * * Revision 1.1.2.1 2002/09/01 21:31:43 mh * Mir goes GPL * @@ -64,15 +81,21 @@ import mir.media.*; * */ -public class MediaRequest +public class MediaRequest implements FileHandler { - WebdbMultipartRequest _mp; String _user; + EntityList _returnList = new EntityList(); + boolean _produce, _publish; - public MediaRequest(WebdbMultipartRequest mPreq, String user) { - _mp = mPreq; + public MediaRequest(String user, boolean produce, boolean publish) { _user = user; + _produce = produce; + _publish = publish; + } + + public EntityList getEntityList() { + return _returnList; } /* @@ -82,186 +105,199 @@ public class MediaRequest * is_published parameter (from the upload form) is supplied. (for backwards * compatibility.) */ - public EntityList getMedia(boolean produce, boolean publish) - throws MirMediaException, - MirMediaUserException { + public void setFile(FilePart filePart, int fileNum, HashMap mediaValues) + throws FileHandlerException, FileHandlerUserException { + String mediaId=null; - HashMap mediaValues = _mp.getParameters(); - EntityList returnList = new EntityList(); MirMedia mediaHandler; Database mediaStorage = null; ProducerMedia mediaProducer = null; - int i=1; - for(Iterator it = _mp.requestList.iterator(); it.hasNext();){ - try { - MpRequest mpReq = (MpRequest)it.next(); - String fileName = mpReq.getFilename(); - - //get the content-type from what the client browser - //sends us. (the "Oreilly method") - String contentType = mpReq.getContentType(); - - //theLog.printInfo("FROM BROWSER: "+contentType); - - //if the client browser sent us unknown (text/plain is default) - //or if we got application/octet-stream, it's possible that - //the browser is in error, better check against the file extension - if (contentType.equals("text/plain") || - contentType.equals("application/octet-stream")) { - /** - * Fallback to finding the mime-type through the standard ServletApi - * ServletContext getMimeType() method. - * - * This is a way to get the content-type via the .extension, - * we could maybe use a magic method as an additional method of - * figuring out the content-type, by looking at the header (first - * few bytes) of the file. (like the file(1) command). We could - * also call the "file" command through Runtime. This is an - * option that I almost prefer as it is already implemented and - * exists with an up-to-date map on most modern Unix like systems. - * I haven't found a really nice implementation of the magic method - * in pure java yet. - * - * The first method we try thought is the "Oreilly method". It - * relies on the content-type that the client browser sends and - * that sometimes is application-octet stream with - * broken/mis-configured browsers. - * - * The map file we use for the extensions is the standard web-app - * deployment descriptor file (web.xml). See Mir's web.xml or see - * your Servlet containers (most likely Tomcat) documentation. - * So if you support a new media type you have to make sure that - * it is in this file -mh - */ - ServletContext ctx = - (ServletContext)MirConfig.getPropAsObject("ServletContext"); - contentType = ctx.getMimeType(fileName); - if (contentType==null) - contentType = "text/plain"; // rfc1867 says this is the default - } - //theLog.printInfo("CONTENT TYPE IS: "+contentType); - - if (contentType.equals("text/plain") || - contentType.equals("application/octet-stream")) { - _throwBadContentType(fileName, contentType); - } + try { + String fileName = filePart.getFileName(); - String mediaTitle = (String)mediaValues.get("media_title"+i); - i++; - if ( (mediaTitle == null) || (mediaTitle.length() == 0)) - throw new MirMediaUserException("Missing field: media title"); - - // TODO: need to add all the extra fields that can be present in the - // admin upload form. -mh - mediaValues.put("title", mediaTitle); - mediaValues.put("date", StringUtil.date2webdbDate( - new GregorianCalendar())); - mediaValues.put("to_publisher", _user); - //mediaValues.put("to_media_folder", "7"); // op media_folder - mediaValues.put("is_produced", "0"); - - // icky backwards compatibility code -mh - if (publish == true) { - mediaValues.put("is_published", "1"); - } else { - if (!mediaValues.containsKey("is_published")) - mediaValues.put("is_published", "0"); - } + //get the content-type from what the client browser + //sends us. (the "Oreilly method") + String contentType = filePart.getContentType(); - // @todo this should probably be moved to DatabaseMediaType -mh - String[] cTypeSplit = StringUtil.split(contentType, "/"); - String wc = " mime_type LIKE '"+cTypeSplit[0]+"%'"; + //theLog.printInfo("FROM BROWSER: "+contentType); - DatabaseMediaType mediaTypeStor = DatabaseMediaType.getInstance(); - EntityList mediaTypesList = mediaTypeStor.selectByWhereClause(wc); + //if the client browser sent us unknown (text/plain is default) + //or if we got application/octet-stream, it's possible that + //the browser is in error, better check against the file extension + if (contentType.equals("text/plain") || + contentType.equals("application/octet-stream")) { + /** + * Fallback to finding the mime-type through the standard ServletApi + * ServletContext getMimeType() method. + * + * This is a way to get the content-type via the .extension, + * we could maybe use a magic method as an additional method of + * figuring out the content-type, by looking at the header (first + * few bytes) of the file. (like the file(1) command). We could + * also call the "file" command through Runtime. This is an + * option that I almost prefer as it is already implemented and + * exists with an up-to-date map on most modern Unix like systems. + * I haven't found a really nice implementation of the magic method + * in pure java yet. + * + * The first method we try thought is the "Oreilly method". It + * relies on the content-type that the client browser sends and + * that sometimes is application-octet stream with + * broken/mis-configured browsers. + * + * The map file we use for the extensions is the standard web-app + * deployment descriptor file (web.xml). See Mir's web.xml or see + * your Servlet containers (most likely Tomcat) documentation. + * So if you support a new media type you have to make sure that + * it is in this file -mh + */ + ServletContext ctx = + (ServletContext)MirConfig.getPropAsObject("ServletContext"); + contentType = ctx.getMimeType(fileName); + if (contentType==null) + contentType = "text/plain"; // rfc1867 says this is the default + } + //theLog.printInfo("CONTENT TYPE IS: "+contentType); + + if (contentType.equals("text/plain") || + contentType.equals("application/octet-stream")) { + _throwBadContentType(fileName, contentType); + } - String mediaTypeId = null; + String mediaTitle = (String)mediaValues.get("media_title"+fileNum); + if ( (mediaTitle == null) || (mediaTitle.length() == 0)) + throw new FileHandlerUserException("Missing field: media title "+mediaTitle+fileNum); - //if we didn't find an entry matching the - //content-type int the table. - if (mediaTypesList.size() == 0) { - _throwBadContentType(fileName, contentType); - } + // TODO: need to add all the extra fields that can be present in the + // admin upload form. -mh + mediaValues.put("title", mediaTitle); + mediaValues.put("date", StringUtil.date2webdbDate( + new GregorianCalendar())); + mediaValues.put("to_publisher", _user); + //mediaValues.put("to_media_folder", "7"); // op media_folder + mediaValues.put("is_produced", "0"); - Entity mediaType = null; - Entity mediaType2 = null; - - // find out if we an exact content-type match if so take it. - // otherwise try to match majortype/* - // @todo this should probably be moved to DatabaseMediaType -mh - for(int j=0;j - ${lang("open.posting.media.media")} ${m} - - -
(${lang("open.optional")}) - - - ${lang("open.posting.media.title")} ${m}: @@ -195,6 +188,13 @@
+ + ${lang("open.posting.media.media")} ${m} + + +
(${lang("open.optional")}) + +