implemented user photos! (imagestore table, ImageRetrieve servlet, a lot of
the underlying support) - incidentally, this is a lot of support for the SIG logo as well, just need some front end work for that in the future (of course, we now require JAI 1.1.1)
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.venice.core;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface BinaryData
|
||||
{
|
||||
public abstract String getMIMEType();
|
||||
|
||||
public abstract String getFilename();
|
||||
|
||||
public abstract int getLength();
|
||||
|
||||
public abstract InputStream getData() throws DataException;
|
||||
|
||||
} // end interface BinaryData
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.silverwrist.venice.core;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
import java.sql.Connection;
|
||||
|
||||
@@ -92,6 +93,8 @@ public interface ContactInfo
|
||||
|
||||
public abstract void setPhotoURL(String addr);
|
||||
|
||||
public abstract void setPhotoData(String prefix, String mimetype, int length, InputStream data);
|
||||
|
||||
public abstract String getURL();
|
||||
|
||||
public abstract void setURL(String addr);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.silverwrist.venice.core;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import org.w3c.dom.Document;
|
||||
@@ -81,4 +82,8 @@ public interface VeniceEngine extends SearchMode
|
||||
|
||||
public abstract Advertisement selectAd();
|
||||
|
||||
public abstract BinaryData loadImage(int id) throws DataException;
|
||||
|
||||
public abstract Dimension getUserPhotoSize();
|
||||
|
||||
} // end interface VeniceEngine
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import org.apache.log4j.*;
|
||||
@@ -25,6 +26,74 @@ import com.silverwrist.venice.db.*;
|
||||
|
||||
class ContactInfoImpl implements ContactInfo, Stashable
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* "Hook" classes used to store an image in the image store and modify the image
|
||||
* URL prior to saving contact info
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
abstract class ImageHook
|
||||
{
|
||||
protected String mimetype;
|
||||
protected int length;
|
||||
protected InputStream data;
|
||||
|
||||
protected ImageHook(String mimetype, int length, InputStream data)
|
||||
{
|
||||
this.mimetype = mimetype;
|
||||
this.length = length;
|
||||
this.data = data;
|
||||
|
||||
} // end constructor
|
||||
|
||||
public abstract String doImage(Connection conn) throws SQLException;
|
||||
|
||||
} // end class ImageHook
|
||||
|
||||
class NewImageHook extends ImageHook
|
||||
{
|
||||
private String prefix;
|
||||
private short type;
|
||||
private int ownerid;
|
||||
|
||||
public NewImageHook(String prefix, short type, int ownerid, String mimetype, int length, InputStream data)
|
||||
{
|
||||
super(mimetype,length,data);
|
||||
this.prefix = prefix;
|
||||
this.type = type;
|
||||
this.ownerid = ownerid;
|
||||
|
||||
} // end constructor
|
||||
|
||||
public String doImage(Connection conn) throws SQLException
|
||||
{
|
||||
int id = ImageStore.storeNewImage(conn,type,ownerid,mimetype,length,data);
|
||||
return prefix + id;
|
||||
|
||||
} // end doImage
|
||||
|
||||
} // end class NewImageHook
|
||||
|
||||
class ExistingImageHook extends ImageHook
|
||||
{
|
||||
private int imgid;
|
||||
|
||||
public ExistingImageHook(int imgid, String mimetype, int length, InputStream data)
|
||||
{
|
||||
super(mimetype,length,data);
|
||||
this.imgid = imgid;
|
||||
|
||||
} // end constructor
|
||||
|
||||
public String doImage(Connection conn) throws SQLException
|
||||
{
|
||||
ImageStore.replaceImage(conn,imgid,mimetype,length,data);
|
||||
return null;
|
||||
|
||||
} // end doImage
|
||||
|
||||
} // end class ExistingImageHook
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
@@ -64,6 +133,7 @@ class ContactInfoImpl implements ContactInfo, Stashable
|
||||
private int owner_sigid; // SIGID this contact record is in (-1 for none)
|
||||
private java.util.Date last_update; // date of last update
|
||||
private boolean is_modified = false; // have we modified this ContactInfo?
|
||||
private ImageHook image_hook = null; // image hook object
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructors
|
||||
@@ -502,10 +572,32 @@ class ContactInfoImpl implements ContactInfo, Stashable
|
||||
photo_url = addr.substring(0,255);
|
||||
else
|
||||
photo_url = addr;
|
||||
image_hook = null;
|
||||
is_modified = true;
|
||||
|
||||
} // end setPhotoURL
|
||||
|
||||
public void setPhotoData(String prefix, String mimetype, int length, InputStream data)
|
||||
{
|
||||
if ((photo_url!=null) && (photo_url.startsWith(prefix)))
|
||||
{ // extract the image ID and create an image hook object
|
||||
int img_id = Integer.parseInt(photo_url.substring(prefix.length()));
|
||||
image_hook = new ExistingImageHook(img_id,mimetype,length,data);
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // figure out how to create the image hook object
|
||||
if (owner_sigid>=0)
|
||||
image_hook = new NewImageHook(prefix,ImageStore.TYPE_SIG_LOGO,owner_sigid,mimetype,length,data);
|
||||
else
|
||||
image_hook = new NewImageHook(prefix,ImageStore.TYPE_USER_PHOTO,owner_uid,mimetype,length,data);
|
||||
|
||||
} // end else
|
||||
|
||||
is_modified = true;
|
||||
|
||||
} // end setPhotoData
|
||||
|
||||
public String getURL()
|
||||
{
|
||||
return url;
|
||||
@@ -617,6 +709,15 @@ class ContactInfoImpl implements ContactInfo, Stashable
|
||||
Statement stmt = conn.createStatement();
|
||||
StringBuffer buf;
|
||||
|
||||
if (image_hook!=null)
|
||||
{ // call the image hook to store an image and get a new photo URL (where applicable)
|
||||
String new_photo_url = image_hook.doImage(conn);
|
||||
if (new_photo_url!=null)
|
||||
photo_url = new_photo_url;
|
||||
image_hook = null;
|
||||
|
||||
} // end if
|
||||
|
||||
if (contactid>=0)
|
||||
{ // this involves updating an existing record
|
||||
buf = new StringBuffer("UPDATE contacts SET given_name = ");
|
||||
|
||||
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import org.apache.log4j.*;
|
||||
import com.silverwrist.venice.db.*;
|
||||
import com.silverwrist.venice.core.*;
|
||||
|
||||
class ImageStore implements BinaryData
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public static final short TYPE_USER_PHOTO = 1;
|
||||
public static final short TYPE_SIG_LOGO = 2;
|
||||
|
||||
private static Category logger = Category.getInstance(ImageStore.class);
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private DataPool datapool;
|
||||
private int imgid;
|
||||
private String type;
|
||||
private int length;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected ImageStore(DataPool datapool, int imgid, String type, int length)
|
||||
{
|
||||
this.datapool = datapool;
|
||||
this.imgid = imgid;
|
||||
this.type = type;
|
||||
this.length = length;
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface BinaryData
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return type;
|
||||
|
||||
} // end getMIMEType
|
||||
|
||||
public String getFilename()
|
||||
{
|
||||
return null;
|
||||
|
||||
} // end getFilename
|
||||
|
||||
public int getLength()
|
||||
{
|
||||
return length;
|
||||
|
||||
} // end getLength
|
||||
|
||||
public InputStream getData() throws DataException
|
||||
{
|
||||
Connection conn = null;
|
||||
InputStream rc = null;
|
||||
|
||||
try
|
||||
{ // open up a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// Create the SQL we need to retrieve the image.
|
||||
StringBuffer sql = new StringBuffer("SELECT data FROM imagestore WHERE imgid = ");
|
||||
sql.append(imgid).append(';');
|
||||
|
||||
// Execute the query!
|
||||
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||
if (!(rs.next()))
|
||||
{ // there is no attachment data!
|
||||
logger.error("no image data to get");
|
||||
throw new DataException("There is no image data present.");
|
||||
|
||||
} // end if
|
||||
|
||||
// Since the InputStream we get from JDBC will probably go away when the connection is dropped, we
|
||||
// need to make a temporary copy of it, to a ByteArrayOutputStream.
|
||||
InputStream sqldata = rs.getBinaryStream(1);
|
||||
ByteArrayOutputStream copy = new ByteArrayOutputStream(length);
|
||||
byte[] buffer = new byte[4096];
|
||||
int rd = sqldata.read(buffer);
|
||||
while (rd>=0)
|
||||
{ // write, then read again
|
||||
if (rd>0)
|
||||
copy.write(buffer,0,rd);
|
||||
rd = sqldata.read(buffer);
|
||||
|
||||
} // end while
|
||||
|
||||
// Close both our streams, making sure we create the stream we need for the return value.
|
||||
sqldata.close();
|
||||
rc = new ByteArrayInputStream(copy.toByteArray());
|
||||
copy.close();
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn this into a DataException
|
||||
logger.error("DB error retrieving image: " + e.getMessage(),e);
|
||||
throw new DataException("unable to retrieve image data: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
catch (IOException e)
|
||||
{ // turn this into a DataException too
|
||||
logger.error("I/O error copying image data: " + e.getMessage(),e);
|
||||
throw new DataException("unable to retrieve image data: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure we release the connection before we go
|
||||
if (conn!=null)
|
||||
datapool.releaseConnection(conn);
|
||||
|
||||
} // end finally
|
||||
|
||||
return rc;
|
||||
|
||||
} // end getData
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static ImageStore loadImageByID(DataPool datapool, int id) throws DataException
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("loadImageByID # " + id);
|
||||
|
||||
Connection conn = null; // pooled database connection
|
||||
|
||||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
StringBuffer sql = new StringBuffer("SELECT mimetype, length FROM imagestore WHERE imgid = ");
|
||||
sql.append(id).append(';');
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||
|
||||
if (rs.next()) // create an object reference and return it
|
||||
return new ImageStore(datapool,id,rs.getString(1),rs.getInt(2));
|
||||
|
||||
return null; // no such image
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn SQLException into data exception
|
||||
logger.error("DB error reading image entry: " + e.getMessage(),e);
|
||||
throw new DataException("unable to retrieve image entry: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure we release the connection before we go
|
||||
if (conn!=null)
|
||||
datapool.releaseConnection(conn);
|
||||
|
||||
} // end finally
|
||||
|
||||
} // end loadImageByID
|
||||
|
||||
static int storeNewImage(Connection conn, short type, int owner, String mime, int length, InputStream data)
|
||||
throws SQLException
|
||||
{
|
||||
// Create the SQL statement that inserts the image into the store.
|
||||
StringBuffer sql =
|
||||
new StringBuffer("INSERT INTO imagestore (typecode, ownerid, mimetype, length, data) VALUES (");
|
||||
sql.append(type).append(", ").append(owner).append(", '").append(mime).append("', ").append(length);
|
||||
sql.append(", ?);");
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
|
||||
// Prepare the statement, set the BLOB parameter, and execute it.
|
||||
PreparedStatement stmt = conn.prepareStatement(sql.toString());
|
||||
stmt.setBinaryStream(1,data,length);
|
||||
stmt.executeUpdate();
|
||||
|
||||
// Get the ID of the new image and return it.
|
||||
Statement stmt2 = conn.createStatement();
|
||||
ResultSet rs = stmt2.executeQuery("SELECT LAST_INSERT_ID();");
|
||||
if (!(rs.next()))
|
||||
throw new InternalStateError("storeNewImage(): Unable to get new image ID!");
|
||||
return rs.getInt(1);
|
||||
|
||||
} // end storeNewImage
|
||||
|
||||
static int storeNewImage(DataPool datapool, short type, int owner, String mime, int length, InputStream data)
|
||||
throws DataException
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("storeNewImage: type " + type + ", owner " + owner + ", mime " + mime + ", len " + length);
|
||||
|
||||
Connection conn = null; // pooled database connection
|
||||
|
||||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
return storeNewImage(conn,type,owner,mime,length,data);
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn SQLException into data exception
|
||||
logger.error("DB error storing image entry: " + e.getMessage(),e);
|
||||
throw new DataException("unable to store image entry: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure we release the connection before we go
|
||||
if (conn!=null)
|
||||
datapool.releaseConnection(conn);
|
||||
|
||||
} // end finally
|
||||
|
||||
} // end storeNewImage
|
||||
|
||||
static void replaceImage(Connection conn, int imgid, String mime, int length, InputStream data)
|
||||
throws SQLException
|
||||
{
|
||||
// Create the SQL statement that inserts the image into the store.
|
||||
StringBuffer sql = new StringBuffer("UPDATE imagestore SET mimetype = '");
|
||||
sql.append(mime).append("', length = ").append(length).append(", data = ? WHERE imgid = ").append(imgid);
|
||||
sql.append(';');
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
|
||||
// Prepare the statement, set the BLOB parameter, and execute it.
|
||||
PreparedStatement stmt = conn.prepareStatement(sql.toString());
|
||||
stmt.setBinaryStream(1,data,length);
|
||||
stmt.executeUpdate();
|
||||
|
||||
} // end replaceImage
|
||||
|
||||
static void replaceImage(DataPool datapool, int imgid, String mime, int length, InputStream data)
|
||||
throws DataException
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("replaceImage: imgid " + imgid + ", mime " + mime + ", len " + length);
|
||||
|
||||
Connection conn = null; // pooled database connection
|
||||
|
||||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
replaceImage(conn,imgid,mime,length,data);
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn SQLException into data exception
|
||||
logger.error("DB error storing image entry: " + e.getMessage(),e);
|
||||
throw new DataException("unable to store image entry: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure we release the connection before we go
|
||||
if (conn!=null)
|
||||
datapool.releaseConnection(conn);
|
||||
|
||||
} // end finally
|
||||
|
||||
} // end replaceImage
|
||||
|
||||
} // end class ImageStore
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import org.apache.log4j.*;
|
||||
@@ -388,6 +389,8 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
|
||||
private static final int AUTH_STRING_LEN = 32;
|
||||
|
||||
private static final Dimension DEFAULT_DIM_USERPHOTO = new Dimension(100,100);
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
@@ -1580,6 +1583,18 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
|
||||
|
||||
} // end selectAd
|
||||
|
||||
public BinaryData loadImage(int id) throws DataException
|
||||
{
|
||||
return ImageStore.loadImageByID(datapool,id);
|
||||
|
||||
} // end loadImage
|
||||
|
||||
public Dimension getUserPhotoSize()
|
||||
{
|
||||
return DEFAULT_DIM_USERPHOTO;
|
||||
|
||||
} // end getUserPhotoSize
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface EngineBackend
|
||||
*--------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user