From 351d6f11a54363419d2d6fd049f17356584dbd55 Mon Sep 17 00:00:00 2001 From: idfx Date: Mon, 1 Oct 2001 23:55:03 +0000 Subject: [PATCH] dupe-protection: user gets message --- source/config.properties-dist | 1 + source/mir/entity/AbstractEntity.java | 364 ++-- source/mir/misc/StringUtil.java | 49 +- source/mir/storage/Database.java | 2078 ++++++++++---------- source/mircoders/entity/EntityComment.java | 63 +- .../mircoders/servlet/ServletModuleOpenIndy.java | 96 +- 6 files changed, 1329 insertions(+), 1322 deletions(-) diff --git a/source/config.properties-dist b/source/config.properties-dist index 25faa0ce..82c6c43d 100755 --- a/source/config.properties-dist +++ b/source/config.properties-dist @@ -229,6 +229,7 @@ ServletModule.OpenIndy.CommentDoneTemplate=open/comment_done.template ServletModule.OpenIndy.CommentDupeTemplate=open/comment_dupe.template ServletModule.OpenIndy.PostingTemplate=open/posting.template ServletModule.OpenIndy.PostingDoneTemplate=open/posting_done.template +ServletModule.OpenIndy.PostingDupeTemplate=open/posting_dupe.template ServletModule.OpenIndy.Logfile=log/openindy.log # diff --git a/source/mir/entity/AbstractEntity.java b/source/mir/entity/AbstractEntity.java index da329764..aed7e859 100755 --- a/source/mir/entity/AbstractEntity.java +++ b/source/mir/entity/AbstractEntity.java @@ -17,197 +17,197 @@ import mir.misc.*; * abstrakte Basisklasse der Entity-Klassen * * @author RK - * @version 29.6.1999 + * @version 29.6.1999 * */ public class AbstractEntity implements Entity { - private boolean changed; - protected HashMap theValuesHash; // tablekey / value - protected StorageObject theStorageObject; - protected static Logfile theLog; - protected ArrayList streamedInput=null; - private static int instances = 0; - static { - theLog = Logfile.getInstance(MirConfig.getProp("Home") + MirConfig.getProp("Entity.Logfile")); - } - - public AbstractEntity() { - this.changed = false; - instances++; - } - - /** - * Konstruktor - */ - public AbstractEntity (StorageObject StorageObject) { - this(); - setStorage(StorageObject); - } - - /* - * Setzt das StorageObject der Entity. - */ - public void setStorage (StorageObject storage) { - this.theStorageObject = storage; - } - - /** - * Setzt die Werte der Entity - * @param theStringValues - */ - - public void setValues(HashMap theStringValues) - { - /** @todo should be synchronized */ - theValuesHash = new HashMap(); - String aKey; - Set set = theStringValues.keySet(); - Iterator it = set.iterator(); - int size = set.size(); - for (int i = 0; i < size; i++) { - aKey = (String)it.next(); - theValuesHash.put(aKey, (String)theStringValues.get(aKey)); - } + private boolean changed; + protected HashMap theValuesHash; // tablekey / value + protected StorageObject theStorageObject; + protected static Logfile theLog; + protected ArrayList streamedInput=null; + private static int instances = 0; + static { + theLog = Logfile.getInstance(MirConfig.getProp("Home") + MirConfig.getProp("Entity.Logfile")); + } + + public AbstractEntity() { + this.changed = false; + instances++; + } + + /** + * Konstruktor + */ + public AbstractEntity (StorageObject StorageObject) { + this(); + setStorage(StorageObject); + } + + /* + * Setzt das StorageObject der Entity. + */ + public void setStorage (StorageObject storage) { + this.theStorageObject = storage; + } + + /** + * Setzt die Werte der Entity + * @param theStringValues + */ + + public void setValues(HashMap theStringValues) + { + /** @todo should be synchronized */ + theValuesHash = new HashMap(); + String aKey; + Set set = theStringValues.keySet(); + Iterator it = set.iterator(); + int size = set.size(); + for (int i = 0; i < size; i++) { + aKey = (String)it.next(); + theValuesHash.put(aKey, (String)theStringValues.get(aKey)); + } } - /** - * Liefert boolschen Wert, ob sich der Inhalt der Entity geändert hat. - * @return true wenn ja, sonst false - */ - public boolean changed () { - return changed; - } - - /** - * Liefert den Primärschluessel der Entity zurueck - * @return String Id - */ - public String getId () { - return (String)getValue(theStorageObject.getIdName()); - } - - /** - * Setzt den Primaerschluessel der Entity - * @param id - */ - public void setId (String id) { - theValuesHash.put(theStorageObject.getIdName(), id); - } - - /** - * Liefert den Wert für einen Feldnamen zurueck - * @param theFieldString - * @return Wert für Feld - */ - public String getValue (String theFieldString) { - return (String)theValuesHash.get(theFieldString); - } - - /** - * Fügt Entity via StorageObject in Datenbank ein. - * @return Primary Key der Entity - * @exception StorageObjectException - */ - public String insert () throws StorageObjectException { - theLog.printDebugInfo("Entity: trying to insert ..."); - if (theStorageObject != null) { - return theStorageObject.insert((Entity)this); - } - else - throw new StorageObjectException("Kein StorageObject gesetzt!"); - } - - /** - * Aktualisiert Aenderungen an der Entity in der Datenbank - * @exception StorageObjectException - */ - public void update () throws StorageObjectException { - theStorageObject.update((Entity)this); - } - - /** - * Setzt den Wert fuer ein Feld - * @param theProp - * @param theValue - * @exception StorageObjectException - */ - public void setValueForProperty (String theProp, String theValue) throws StorageObjectException { - this.changed = true; - if (isField(theProp)) - theValuesHash.put(theProp, theValue); - else - theLog.printWarning("Property not found: " + theProp+theValue); - - } - - /** - * Gibt die Feldnamen der Entity als ArrayList zurueck - * @return ArrayList mit Feldnamen - * @exception StorageObjectException wird geworfen, wenn kein Zugriff auf die Datenbank - * möglich. - */ - public ArrayList getFields () throws StorageObjectException { - return theStorageObject.getFields(); - } - - /** - * Liefert ein int[] mit den Typen der Felder zurueck - * @return int[] mit den Feldtypen - * @exception StorageObjectException - */ - public int[] getTypes () throws StorageObjectException { - return theStorageObject.getTypes(); - } - - /** - * Liefert ArrayListe mit Feldnamen zurueck. - * @return Liste mit Feldnamen - * @exception StorageObjectException - */ - public ArrayList getLabels () throws StorageObjectException { - return theStorageObject.getLabels(); - } - - /** - * Liefert eine Hashmap mit allen Werten der Entity zurueck - * @return HashMap mit Feldname/Wert - */ - public HashMap getValues() { - return theValuesHash; - } - - /** - * Liefert einen ArrayList mit allen Datenbankfeldern, die - * als streamedInput ausgelesen werden muessen. - * Waere automatisierbar ueber die types (blob, etc.) - * Bisher manuell anzulegen in der erbenden Klasse - */ - - public ArrayList streamedInput() { - return streamedInput; - } - - /* Fragt ab, ob fieldName einem Feld entspricht - * @param fieldName - * @return true, wennn ja, sonst false - * @exception StorageObjectException - */ - public boolean isField (String fieldName) throws StorageObjectException { - return theStorageObject.getFields().contains(fieldName); - } - - /** Liefert Anzahl der Instanzen zurück - * @return int - */ - public int getInstances() { + /** + * Liefert boolschen Wert, ob sich der Inhalt der Entity geändert hat. + * @return true wenn ja, sonst false + */ + public boolean changed () { + return changed; + } + + /** + * Liefert den Primärschluessel der Entity zurueck + * @return String Id + */ + public String getId () { + return (String)getValue(theStorageObject.getIdName()); + } + + /** + * Setzt den Primaerschluessel der Entity + * @param id + */ + public void setId (String id) { + theValuesHash.put(theStorageObject.getIdName(), id); + } + + /** + * Liefert den Wert für einen Feldnamen zurueck + * @param theFieldString + * @return Wert für Feld + */ + public String getValue (String theFieldString) { + return (String)theValuesHash.get(theFieldString); + } + + /** + * Fügt Entity via StorageObject in Datenbank ein. + * @return Primary Key der Entity + * @exception StorageObjectException + */ + public String insert () throws StorageObjectException { + theLog.printDebugInfo("Entity: trying to insert ..."); + if (theStorageObject != null) { + return theStorageObject.insert((Entity)this); + } + else + throw new StorageObjectException("Kein StorageObject gesetzt!"); + } + + /** + * Aktualisiert Aenderungen an der Entity in der Datenbank + * @exception StorageObjectException + */ + public void update () throws StorageObjectException { + theStorageObject.update((Entity)this); + } + + /** + * Setzt den Wert fuer ein Feld + * @param theProp + * @param theValue + * @exception StorageObjectException + */ + public void setValueForProperty (String theProp, String theValue) throws StorageObjectException { + this.changed = true; + if (isField(theProp)) + theValuesHash.put(theProp, theValue); + else + theLog.printWarning("Property not found: " + theProp+theValue); + + } + + /** + * Gibt die Feldnamen der Entity als ArrayList zurueck + * @return ArrayList mit Feldnamen + * @exception StorageObjectException wird geworfen, wenn kein Zugriff auf die Datenbank + * möglich. + */ + public ArrayList getFields () throws StorageObjectException { + return theStorageObject.getFields(); + } + + /** + * Liefert ein int[] mit den Typen der Felder zurueck + * @return int[] mit den Feldtypen + * @exception StorageObjectException + */ + public int[] getTypes () throws StorageObjectException { + return theStorageObject.getTypes(); + } + + /** + * Liefert ArrayListe mit Feldnamen zurueck. + * @return Liste mit Feldnamen + * @exception StorageObjectException + */ + public ArrayList getLabels () throws StorageObjectException { + return theStorageObject.getLabels(); + } + + /** + * Liefert eine Hashmap mit allen Werten der Entity zurueck + * @return HashMap mit Feldname/Wert + */ + public HashMap getValues() { + return theValuesHash; + } + + /** + * Liefert einen ArrayList mit allen Datenbankfeldern, die + * als streamedInput ausgelesen werden muessen. + * Waere automatisierbar ueber die types (blob, etc.) + * Bisher manuell anzulegen in der erbenden Klasse + */ + + public ArrayList streamedInput() { + return streamedInput; + } + + /* Fragt ab, ob fieldName einem Feld entspricht + * @param fieldName + * @return true, wennn ja, sonst false + * @exception StorageObjectException + */ + public boolean isField (String fieldName) throws StorageObjectException { + return theStorageObject.getFields().contains(fieldName); + } + + /** Liefert Anzahl der Instanzen zurück + * @return int + */ + public int getInstances() { return instances; } - /** - * Gibt eine Instanz frei - */ - public void finalize () { + /** + * Gibt eine Instanz frei + */ + public void finalize () { instances--; try { super.finalize(); diff --git a/source/mir/misc/StringUtil.java b/source/mir/misc/StringUtil.java index 09a4b7c8..2b700115 100755 --- a/source/mir/misc/StringUtil.java +++ b/source/mir/misc/StringUtil.java @@ -904,32 +904,32 @@ try { public static String approveHTMLTags(String haystack){ - try { - String approvedTags="a|img|h1|h2|h3|h4|h5|h6|br|b|i|strong|p"; - String badAttributes="onAbort|onBlur|onChange|onClick|onDblClick|onDragDrop|onError|onFocus|onKeyDown|onKeyPress|onKeyUp|onLoad|onMouseDown|onMouseMove|onMouseOut|onMouseOver|onMouseUp|onMove|onReset|onResize|onSelect|onSubmit|onUnload"; - String approvedProtocols="rtsp|http|ftp|https|freenet|mailto"; + try { + String approvedTags="a|img|h1|h2|h3|h4|h5|h6|br|b|i|strong|p"; + String badAttributes="onAbort|onBlur|onChange|onClick|onDblClick|onDragDrop|onError|onFocus|onKeyDown|onKeyPress|onKeyUp|onLoad|onMouseDown|onMouseMove|onMouseOut|onMouseOver|onMouseUp|onMove|onReset|onResize|onSelect|onSubmit|onUnload"; + String approvedProtocols="rtsp|http|ftp|https|freenet|mailto"; - // kill all the bad tags that have attributes - - RE regex = new RE("<\\s*/?\\s*(?!(("+approvedTags+")\\s))\\w+\\s[^>]*>",RE.REG_ICASE); - haystack = regex.substituteAll(haystack,""); - - // kill all the bad tags that are attributeless - regex = new RE("<\\s*/?\\s*(?!(("+approvedTags+")\\s*>))\\w+\\s*>",RE.REG_ICASE); - haystack = regex.substituteAll(haystack,""); - - // kill all the tags which have a javascript attribute like onLoad - regex = new RE("<[^>]*("+badAttributes+")[^>]*>",RE.REG_ICASE); - haystack = regex.substituteAll(haystack,""); - - // kill all the tags which include a url to an unacceptable protocol - regex = new RE("<\\s*a\\s+[^>]*href=(?!(\'|\")?("+approvedProtocols+"))[^>]*>",RE.REG_ICASE); - haystack = regex.substituteAll(haystack,""); - - return haystack; + // kill all the bad tags that have attributes + String s = "<\\s*/?\\s*(?!(("+approvedTags+")\\s))\\w+\\s[^>]*>"; + RE regex = new RE(s,RE.REG_ICASE); + haystack = regex.substituteAll(haystack,""); + + // kill all the bad tags that are attributeless + regex = new RE("<\\s*/?\\s*(?!(("+approvedTags+")\\s*>))\\w+\\s*>",RE.REG_ICASE); + haystack = regex.substituteAll(haystack,""); + + // kill all the tags which have a javascript attribute like onLoad + regex = new RE("<[^>]*("+badAttributes+")[^>]*>",RE.REG_ICASE); + haystack = regex.substituteAll(haystack,""); + + // kill all the tags which include a url to an unacceptable protocol + regex = new RE("<\\s*a\\s+[^>]*href=(?!(\'|\")?("+approvedProtocols+"))[^>]*>",RE.REG_ICASE); + haystack = regex.substituteAll(haystack,""); + + return haystack; } catch(REException ex){ - //return ex.toString(); - return null; + ex.printStackTrace(); + return null; } @@ -961,3 +961,4 @@ try { } } + diff --git a/source/mir/storage/Database.java b/source/mir/storage/Database.java index 9758d683..dbfe1372 100755 --- a/source/mir/storage/Database.java +++ b/source/mir/storage/Database.java @@ -27,252 +27,252 @@ import mir.misc.*; */ public class Database implements StorageObject { - protected DbConnectionBroker myBroker; - protected String theTable; - protected String theCoreTable=null; - protected String thePKeyName="id"; - protected int thePKeyType; - protected boolean evaluatedMetaData=false; - protected ArrayList metadataFields,metadataLabels,metadataNotNullFields; - protected int[] metadataTypes; - protected Class theEntityClass; - protected StorageObject myselfDatabase; - protected HashMap cache; - protected SimpleList popupCache=null; - protected boolean hasPopupCache = false; - protected SimpleHash hashCache=null; - protected boolean hasTimestamp=true; - private String database_driver; - private String database_url; - private int defaultLimit; - private DatabaseAdaptor theAdaptor; - protected Logfile theLog; - protected Connection con; - - /** - * Kontruktor bekommt den Filenamen des Konfigurationsfiles übergeben. - * Aus diesem file werden Database.Logfile, - * Database.Username,Database.Password, - * Database.Host und Database.Adaptor - * ausgelesen und ein Broker für die Verbindugen zur Datenbank - * erzeugt. - * - * @param String confFilename Dateiname der Konfigurationsdatei - */ - public Database() { - theLog = Logfile.getInstance(MirConfig.getProp("Home") + MirConfig.getProp("Database.Logfile")); - String database_username=MirConfig.getProp("Database.Username"); - String database_password=MirConfig.getProp("Database.Password"); - String database_host=MirConfig.getProp("Database.Host"); - String theAdaptorName=MirConfig.getProp("Database.Adaptor"); - try { - theEntityClass = Class.forName("mir.entity.GenericEntity"); - theAdaptor = (DatabaseAdaptor)Class.forName(theAdaptorName).newInstance(); - defaultLimit = Integer.parseInt(MirConfig.getProp("Database.Limit")); - database_driver=theAdaptor.getDriver(); - database_url=theAdaptor.getURL(database_username,database_password,database_host); - theLog.printDebugInfo("adding Broker with: " +database_driver+":"+database_url ); - MirConfig.addBroker(database_driver,database_url); - myBroker=MirConfig.getBroker(); - } - catch (Exception e){ - theLog.printError("Bei Konstruktion von Database() with " + theAdaptorName + " -- " +e.toString()); - } - } - - /** - * Liefert die Entity-Klasse zurück, in der eine Datenbankzeile gewrappt - * wird. Wird die Entity-Klasse durch die erbende Klasse nicht überschrieben, - * wird eine mir.entity.GenericEntity erzeugt. - * - * @return Class-Objekt der Entity - */ - public java.lang.Class getEntityClass () { - return theEntityClass; - } - - /** - * Liefert die Standardbeschränkung von select-Statements zurück, also - * wieviel Datensätze per Default selektiert werden. - * - * @return Standard-Anzahl der Datensätze - */ - public int getLimit () { - return defaultLimit; - } - - /** - * Liefert den Namen des Primary-Keys zurück. Wird die Variable nicht von - * der erbenden Klasse überschrieben, so ist der Wert PKEY - * @return Name des Primary-Keys - */ - public String getIdName () { - return thePKeyName; - } - - /** - * Liefert den Namen der Tabelle, auf das sich das Datenbankobjekt bezieht. - * - * @return Name der Tabelle - */ - public String getTableName () { - return theTable; - } - - /* - * Dient dazu vererbte Tabellen bei objectrelationalen DBMS - * zu speichern, wenn die id einer Tabelle in der parenttabelle verwaltet wird. - * @return liefert theCoreTabel als String zurueck, wenn gesetzt, sonst - * the Table - */ - - public String getCoreTable(){ - if (theCoreTable!=null) return theCoreTable; - else return theTable; - } - - /** - * Liefert Feldtypen der Felder der Tabelle zurueck (s.a. java.sql.Types) - * @return int-Array mit den Typen der Felder - * @exception StorageObjectException - */ - public int[] getTypes () throws StorageObjectException { - if (metadataTypes == null) - get_meta_data(); - return metadataTypes; - } - - /** - * Liefert eine Liste der Labels der Tabellenfelder - * @return ArrayListe mit Labeln - * @exception StorageObjectException - */ - public ArrayList getLabels () throws StorageObjectException { - if (metadataLabels == null) - get_meta_data(); - return metadataLabels; - } - - /** - * Liefert eine Liste der Felder der Tabelle - * @return ArrayList mit Feldern - * @exception StorageObjectException - */ - public ArrayList getFields () throws StorageObjectException { - if (metadataFields == null) - get_meta_data(); - return metadataFields; - } - - - /* - * Gets value out of ResultSet according to type and converts to String - * @param inValue Wert aus ResultSet. - * @param aType Datenbanktyp. - * @return liefert den Wert als String zurueck. Wenn keine Umwandlung moeglich - * dann /unsupported value/ - */ - private String getValueAsString (ResultSet rs, int valueIndex, int aType) throws StorageObjectException { - String outValue = null; - if (rs != null) { - try { - switch (aType) { - case java.sql.Types.BIT: - outValue = (rs.getBoolean(valueIndex) == true) ? "1" : "0"; - break; - case java.sql.Types.INTEGER:case java.sql.Types.SMALLINT:case java.sql.Types.TINYINT:case java.sql.Types.BIGINT: - int out = rs.getInt(valueIndex); - if (!rs.wasNull()) - outValue = new Integer(out).toString(); - break; - case java.sql.Types.NUMERIC: - long outl = rs.getLong(valueIndex); - if (!rs.wasNull()) - outValue = new Long(outl).toString(); - break; - case java.sql.Types.REAL: - float tempf = rs.getFloat(valueIndex); - if (!rs.wasNull()) { - tempf *= 10; - tempf += 0.5; - int tempf_int = (int)tempf; - tempf = (float)tempf_int; - tempf /= 10; - outValue = "" + tempf; - outValue = outValue.replace('.', ','); - } - break; - case java.sql.Types.DOUBLE: - double tempd = rs.getDouble(valueIndex); - if (!rs.wasNull()) { - tempd *= 10; - tempd += 0.5; - int tempd_int = (int)tempd; - tempd = (double)tempd_int; - tempd /= 10; - outValue = "" + tempd; - outValue = outValue.replace('.', ','); - } - break; - case java.sql.Types.CHAR:case java.sql.Types.VARCHAR:case java.sql.Types.LONGVARCHAR: - outValue = rs.getString(valueIndex); - if (outValue != null) - outValue = StringUtil.encodeHtml(StringUtil.unquote(outValue)); - break; - case java.sql.Types.LONGVARBINARY: - outValue = rs.getString(valueIndex); - if (outValue != null) - outValue = StringUtil.encodeHtml(StringUtil.unquote(outValue)); - break; - case java.sql.Types.TIMESTAMP: - Timestamp timestamp = (rs.getTimestamp(valueIndex)); - if (!rs.wasNull()) { - outValue = timestamp.toString(); - } - break; - default: - outValue = ""; - theLog.printWarning("Unsupported Datatype: at " + valueIndex + - " (" + aType + ")"); - } - } catch (SQLException e) { - throw new StorageObjectException("Could not get Value out of Resultset -- " - + e.toString()); - } - } - return outValue; - } - - /* - * select-Operator um einen Datensatz zu bekommen. - * @param id Primaerschluessel des Datensatzes. - * @return liefert EntityObject des gefundenen Datensatzes oder null. - */ - public Entity selectById(String id) + protected DbConnectionBroker myBroker; + protected String theTable; + protected String theCoreTable=null; + protected String thePKeyName="id"; + protected int thePKeyType; + protected boolean evaluatedMetaData=false; + protected ArrayList metadataFields,metadataLabels,metadataNotNullFields; + protected int[] metadataTypes; + protected Class theEntityClass; + protected StorageObject myselfDatabase; + protected HashMap cache; + protected SimpleList popupCache=null; + protected boolean hasPopupCache = false; + protected SimpleHash hashCache=null; + protected boolean hasTimestamp=true; + private String database_driver; + private String database_url; + private int defaultLimit; + private DatabaseAdaptor theAdaptor; + protected Logfile theLog; + protected Connection con; + + /** + * Kontruktor bekommt den Filenamen des Konfigurationsfiles übergeben. + * Aus diesem file werden Database.Logfile, + * Database.Username,Database.Password, + * Database.Host und Database.Adaptor + * ausgelesen und ein Broker für die Verbindugen zur Datenbank + * erzeugt. + * + * @param String confFilename Dateiname der Konfigurationsdatei + */ + public Database() { + theLog = Logfile.getInstance(MirConfig.getProp("Home") + MirConfig.getProp("Database.Logfile")); + String database_username=MirConfig.getProp("Database.Username"); + String database_password=MirConfig.getProp("Database.Password"); + String database_host=MirConfig.getProp("Database.Host"); + String theAdaptorName=MirConfig.getProp("Database.Adaptor"); + try { + theEntityClass = Class.forName("mir.entity.GenericEntity"); + theAdaptor = (DatabaseAdaptor)Class.forName(theAdaptorName).newInstance(); + defaultLimit = Integer.parseInt(MirConfig.getProp("Database.Limit")); + database_driver=theAdaptor.getDriver(); + database_url=theAdaptor.getURL(database_username,database_password,database_host); + theLog.printDebugInfo("adding Broker with: " +database_driver+":"+database_url ); + MirConfig.addBroker(database_driver,database_url); + myBroker=MirConfig.getBroker(); + } + catch (Exception e){ + theLog.printError("Bei Konstruktion von Database() with " + theAdaptorName + " -- " +e.toString()); + } + } + + /** + * Liefert die Entity-Klasse zurück, in der eine Datenbankzeile gewrappt + * wird. Wird die Entity-Klasse durch die erbende Klasse nicht überschrieben, + * wird eine mir.entity.GenericEntity erzeugt. + * + * @return Class-Objekt der Entity + */ + public java.lang.Class getEntityClass () { + return theEntityClass; + } + + /** + * Liefert die Standardbeschränkung von select-Statements zurück, also + * wieviel Datensätze per Default selektiert werden. + * + * @return Standard-Anzahl der Datensätze + */ + public int getLimit () { + return defaultLimit; + } + + /** + * Liefert den Namen des Primary-Keys zurück. Wird die Variable nicht von + * der erbenden Klasse überschrieben, so ist der Wert PKEY + * @return Name des Primary-Keys + */ + public String getIdName () { + return thePKeyName; + } + + /** + * Liefert den Namen der Tabelle, auf das sich das Datenbankobjekt bezieht. + * + * @return Name der Tabelle + */ + public String getTableName () { + return theTable; + } + + /* + * Dient dazu vererbte Tabellen bei objectrelationalen DBMS + * zu speichern, wenn die id einer Tabelle in der parenttabelle verwaltet wird. + * @return liefert theCoreTabel als String zurueck, wenn gesetzt, sonst + * the Table + */ + + public String getCoreTable(){ + if (theCoreTable!=null) return theCoreTable; + else return theTable; + } + + /** + * Liefert Feldtypen der Felder der Tabelle zurueck (s.a. java.sql.Types) + * @return int-Array mit den Typen der Felder + * @exception StorageObjectException + */ + public int[] getTypes () throws StorageObjectException { + if (metadataTypes == null) + get_meta_data(); + return metadataTypes; + } + + /** + * Liefert eine Liste der Labels der Tabellenfelder + * @return ArrayListe mit Labeln + * @exception StorageObjectException + */ + public ArrayList getLabels () throws StorageObjectException { + if (metadataLabels == null) + get_meta_data(); + return metadataLabels; + } + + /** + * Liefert eine Liste der Felder der Tabelle + * @return ArrayList mit Feldern + * @exception StorageObjectException + */ + public ArrayList getFields () throws StorageObjectException { + if (metadataFields == null) + get_meta_data(); + return metadataFields; + } + + + /* + * Gets value out of ResultSet according to type and converts to String + * @param inValue Wert aus ResultSet. + * @param aType Datenbanktyp. + * @return liefert den Wert als String zurueck. Wenn keine Umwandlung moeglich + * dann /unsupported value/ + */ + private String getValueAsString (ResultSet rs, int valueIndex, int aType) throws StorageObjectException { + String outValue = null; + if (rs != null) { + try { + switch (aType) { + case java.sql.Types.BIT: + outValue = (rs.getBoolean(valueIndex) == true) ? "1" : "0"; + break; + case java.sql.Types.INTEGER:case java.sql.Types.SMALLINT:case java.sql.Types.TINYINT:case java.sql.Types.BIGINT: + int out = rs.getInt(valueIndex); + if (!rs.wasNull()) + outValue = new Integer(out).toString(); + break; + case java.sql.Types.NUMERIC: + long outl = rs.getLong(valueIndex); + if (!rs.wasNull()) + outValue = new Long(outl).toString(); + break; + case java.sql.Types.REAL: + float tempf = rs.getFloat(valueIndex); + if (!rs.wasNull()) { + tempf *= 10; + tempf += 0.5; + int tempf_int = (int)tempf; + tempf = (float)tempf_int; + tempf /= 10; + outValue = "" + tempf; + outValue = outValue.replace('.', ','); + } + break; + case java.sql.Types.DOUBLE: + double tempd = rs.getDouble(valueIndex); + if (!rs.wasNull()) { + tempd *= 10; + tempd += 0.5; + int tempd_int = (int)tempd; + tempd = (double)tempd_int; + tempd /= 10; + outValue = "" + tempd; + outValue = outValue.replace('.', ','); + } + break; + case java.sql.Types.CHAR:case java.sql.Types.VARCHAR:case java.sql.Types.LONGVARCHAR: + outValue = rs.getString(valueIndex); + if (outValue != null) + outValue = StringUtil.encodeHtml(StringUtil.unquote(outValue)); + break; + case java.sql.Types.LONGVARBINARY: + outValue = rs.getString(valueIndex); + if (outValue != null) + outValue = StringUtil.encodeHtml(StringUtil.unquote(outValue)); + break; + case java.sql.Types.TIMESTAMP: + Timestamp timestamp = (rs.getTimestamp(valueIndex)); + if (!rs.wasNull()) { + outValue = timestamp.toString(); + } + break; + default: + outValue = ""; + theLog.printWarning("Unsupported Datatype: at " + valueIndex + + " (" + aType + ")"); + } + } catch (SQLException e) { + throw new StorageObjectException("Could not get Value out of Resultset -- " + + e.toString()); + } + } + return outValue; + } + + /* + * select-Operator um einen Datensatz zu bekommen. + * @param id Primaerschluessel des Datensatzes. + * @return liefert EntityObject des gefundenen Datensatzes oder null. + */ + public Entity selectById(String id) throws StorageObjectException { - if (id==null||id.equals("")) + if (id==null||id.equals("")) throw new StorageObjectException("id war null"); - if (cache != null && cache.containsKey(id)) - return (Entity)cache.get(id); // wenn cache gesetzt, evtl. kein roundtrip zur Datenbank - - Statement stmt=null;Connection con=getPooledCon(); - Entity returnEntity=null; - try { - ResultSet rs; - String selectSql = "select * from " + theTable + " where " + thePKeyName + "=" + id; - stmt = con.createStatement(); - rs = executeSql(stmt, selectSql); - if (rs != null) { - if (evaluatedMetaData==false) evalMetaData(rs.getMetaData()); - if (rs.next()) - returnEntity = makeEntityFromResultSet(rs); - else theLog.printDebugInfo("Keine daten fuer id: " + id + "in Tabelle" + theTable); - rs.close(); - } else { + if (cache != null && cache.containsKey(id)) + return (Entity)cache.get(id); // wenn cache gesetzt, evtl. kein roundtrip zur Datenbank + + Statement stmt=null;Connection con=getPooledCon(); + Entity returnEntity=null; + try { + ResultSet rs; + String selectSql = "select * from " + theTable + " where " + thePKeyName + "=" + id; + stmt = con.createStatement(); + rs = executeSql(stmt, selectSql); + if (rs != null) { + if (evaluatedMetaData==false) evalMetaData(rs.getMetaData()); + if (rs.next()) + returnEntity = makeEntityFromResultSet(rs); + else theLog.printDebugInfo("Keine daten fuer id: " + id + "in Tabelle" + theTable); + rs.close(); + } else { theLog.printDebugInfo("No Data for Id " + id + " in Table " + theTable); } - } catch (SQLException sqe){ + } catch (SQLException sqe){ throwSQLException(sqe,"selectById"); return null; } catch (NumberFormatException e) { theLog.printError("ID ist keine Zahl: " + id); @@ -280,803 +280,807 @@ public class Database implements StorageObject { freeConnection(con,stmt); } - return returnEntity; - } - - /** - * select-Operator um Datensaetze zu bekommen, die key = value erfuellen. - * @param key Datenbankfeld der Bedingung. - * @param value Wert die der key anehmen muss. - * @return EntityList mit den gematchten Entities - */ - - public EntityList selectByFieldValue(String aField, String aValue) - throws StorageObjectException { - - return selectByFieldValue(aField, aValue, 0); - } - - /** - * select-Operator um Datensaetze zu bekommen, die key = value erfuellen. - * @param key Datenbankfeld der Bedingung. - * @param value Wert die der key anehmen muss. - * @param offset Gibt an ab welchem Datensatz angezeigt werden soll. - * @return EntityList mit den gematchten Entities - */ - - public EntityList selectByFieldValue(String aField, String aValue, int offset) - throws StorageObjectException { - - return selectByWhereClause(aField + "=" + aValue, offset); - } - - - /** - * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. - * Also offset wird der erste Datensatz genommen. - * - * @param wc where-Clause - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - public EntityList selectByWhereClause(String where) - throws StorageObjectException { - - return selectByWhereClause(where, 0); - } - - - /** - * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. - * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. - * - * @param wc where-Clause - * @param offset ab welchem Datensatz. - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - public EntityList selectByWhereClause(String whereClause, int offset) - throws StorageObjectException { - - return selectByWhereClause(whereClause, null, offset); - } - - /** - * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. - * Also offset wird der erste Datensatz genommen. - * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. - * - * @param wc where-Clause - * @param ob orderBy-Clause - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - - public EntityList selectByWhereClause(String where, String order) - throws StorageObjectException { - - return selectByWhereClause(where, order, 0); - } - /** - * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. - * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. - * - * @param wc where-Clause - * @param ob orderBy-Clause - * @param offset ab welchem Datensatz - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - - public EntityList selectByWhereClause(String whereClause, String orderBy, int offset) - throws StorageObjectException { - - return selectByWhereClause(whereClause, orderBy, offset, defaultLimit); - } - - - /** - * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. - * @param wc where-Clause - * @param ob orderBy-Clause - * @param offset ab welchem Datensatz - * @param limit wieviele Datensätze - * @return EntityList mit den gematchten Entities - * @exception StorageObjectException - */ - - public EntityList selectByWhereClause(String wc, String ob, int offset, int limit) - throws StorageObjectException { - - // local - EntityList theReturnList=null; - Connection con=null; - Statement stmt=null; - ResultSet rs; - int offsetCount = 0; - int count=0; - - - // build sql-statement - if (wc != null && wc.length() == 0) { - wc = null; - } - StringBuffer countSql = new StringBuffer("select count(*) from ").append(theTable); - StringBuffer selectSql = new StringBuffer("select * from ").append(theTable); - if (wc != null) { - selectSql.append(" where ").append(wc); - countSql.append(" where ").append(wc); - } - if (ob != null && !(ob.length() == 0)) { - selectSql.append(" order by ").append(ob); - } - if (theAdaptor.hasLimit()) { - if (limit > -1 && offset > -1) { - selectSql.append(" limit "); - if (theAdaptor.reverseLimit()) { - selectSql.append(limit).append(",").append(offset); - } - else { - selectSql.append(offset).append(",").append(limit); - } - } - } - - // execute sql - try { - con = getPooledCon(); - stmt = con.createStatement(); - // counting rows - if (theAdaptor.hasLimit()) { - rs = executeSql(stmt, countSql.toString()); - if (rs != null) { - if (rs.next()) - count = rs.getInt(1); - rs.close(); - } - else - theLog.printError("Mh. Konnte nicht zaehlen: " + countSql); - } - // hier select - rs = executeSql(stmt, selectSql.toString()); - if (rs != null) { - theReturnList = new EntityList(); - if (evaluatedMetaData == false) { - evalMetaData(rs.getMetaData()); - } - Entity theResultEntity; - while (rs.next()) { - theResultEntity = makeEntityFromResultSet(rs); - theReturnList.add(theResultEntity); - offsetCount++; - } - rs.close(); - } - // making entitylist - if (!(theAdaptor.hasLimit())) - count = offsetCount; - if (theReturnList != null) { - theReturnList.setCount(count); - theReturnList.setOffset(offset); - theReturnList.setWhere(wc); - theReturnList.setOrder(ob); - if (offset >= limit) { - theReturnList.setPrevBatch(offset - limit); - } - if (offset + offsetCount < count) { - theReturnList.setNextBatch(offset + limit); - } - } - } catch (SQLException sqe) { - throwSQLException(sqe, "selectByWhereClause"); - } finally { - freeConnection(con, stmt); - } - return theReturnList; - } - - /** - * Bastelt aus einer Zeile der Datenbank ein EntityObjekt. - * - * @param rs Das ResultSetObjekt. - * @return Entity Die Entity. - */ - - public Entity makeEntityFromResultSet (ResultSet rs) throws StorageObjectException { - HashMap theResultHash = new HashMap(); - String theResult = null; - int theType; - Entity returnEntity = null; - try { - int size = metadataFields.size(); - for (int i = 0; i < size; i++) { - // alle durchlaufen bis nix mehr da - theType = metadataTypes[i]; - if (theType == java.sql.Types.LONGVARBINARY) { - InputStream us = rs.getAsciiStream(i + 1); - if (us != null) { - InputStreamReader is = new InputStreamReader(us); - char[] data = new char[32768]; - StringBuffer theResultString = new StringBuffer(); - int len; - while ((len = is.read(data)) > 0) { - theResultString.append(data, 0, len); - } - is.close(); - theResult = theResultString.toString(); - } - else { - theResult = null; - } - } - else { - theResult = getValueAsString(rs, (i + 1), theType); - } - if (theResult != null) { - theResultHash.put(metadataFields.get(i), theResult); - } - } - if (cache != null && theResultHash.containsKey(thePKeyName) && cache.containsKey((String)theResultHash.get(thePKeyName))) { - //theLog.printDebugInfo("CACHE: (out) "+ theResultHash.get(thePKeyName)+ " :"+theTable); - returnEntity = (Entity)cache.get((String)theResultHash.get(thePKeyName)); - } - else { - if (theEntityClass != null) { - returnEntity = (Entity)theEntityClass.newInstance(); - returnEntity.setValues(theResultHash); - returnEntity.setStorage(myselfDatabase); - if (cache != null) { - //theLog.printDebugInfo("CACHE: ( in) " + returnEntity.getId() + " :"+theTable); - cache.put(returnEntity.getId(), returnEntity); - } - } - else { - throwStorageObjectException("Interner Fehler theEntityClass nicht gesetzt!"); - } - } - } // try - catch (IllegalAccessException e) { - throwStorageObjectException("Kein Zugriff! -- " + e.toString()); - } catch (IOException e) { - throwStorageObjectException("IOException! -- " + e.toString()); - } catch (InstantiationException e) { - throwStorageObjectException("Keine Instantiiierung! -- " + e.toString()); - } catch (SQLException sqe) { - throwSQLException(sqe, "makeEntityFromResultSet"); - return null; - } - return returnEntity; - } - - /** - * insert-Operator: fügt eine Entity in die Tabelle ein. Eine Spalte WEBDB_CREATE - * wird automatisch mit dem aktuellen Datum gefuellt. - * - * @param theEntity - * @return der Wert des Primary-keys der eingefügten Entity - */ - public String insert (Entity theEntity) throws StorageObjectException { - String returnId = "0"; - Connection con = null; - PreparedStatement pstmt = null; - //cache - invalidatePopupCache(); - try { - HashMap theEntityValues = theEntity.getValues(); - ArrayList streamedInput = theEntity.streamedInput(); - StringBuffer f = new StringBuffer(); - StringBuffer v = new StringBuffer(); - String aField, aValue; - boolean firstField = true; - // make sql-string - for (int i = 0; i < getFields().size(); i++) { - aField = (String)getFields().get(i); - if (!aField.equals(thePKeyName)) { - aValue = null; - // sonderfaelle - if (aField.equals("webdb_create")) { - aValue = "NOW()"; - } - else { - if (streamedInput != null && streamedInput.contains(aField)) { - aValue = "?"; - } - else { - if (theEntityValues.containsKey(aField)) { - aValue = "'" + StringUtil.quote((String)theEntityValues.get(aField)) - + "'"; - } - } - } - // wenn Wert gegeben, dann einbauen - if (aValue != null) { - if (firstField == false) { - f.append(","); - v.append(","); - } - else { - firstField = false; - } - f.append(aField); - v.append(aValue); - } - } - } // end for - // insert into db - StringBuffer sqlBuf = new StringBuffer("insert into ").append(theTable).append("(").append(f).append(") values (").append(v).append(")"); - String sql = sqlBuf.toString(); - theLog.printInfo("INSERT: " + sql); - con = getPooledCon(); - con.setAutoCommit(false); - pstmt = con.prepareStatement(sql); - if (streamedInput != null) { - for (int i = 0; i < streamedInput.size(); i++) { - String inputString = (String)theEntityValues.get(streamedInput.get(i)); - pstmt.setBytes(i + 1, inputString.getBytes()); - } - } - pstmt.execute(); - pstmt = con.prepareStatement(theAdaptor.getLastInsertSQL((Database)myselfDatabase)); - ResultSet rs = pstmt.executeQuery(); - rs.next(); - returnId = rs.getString(1); - theEntity.setId(returnId); - } catch (SQLException sqe) { - throwSQLException(sqe, "insert"); - } finally { - try { - con.setAutoCommit(true); - } catch (Exception e) { - ; - } - freeConnection(con, pstmt); - } - return returnId; - } - - /** - * update-Operator: aktualisiert eine Entity. Eine Spalte WEBDB_LASTCHANGE - * wird automatisch mit dem aktuellen Datum gefuellt. - * - * @param theEntity - */ - public void update (Entity theEntity) throws StorageObjectException { - Connection con = null; - PreparedStatement pstmt = null; - ArrayList streamedInput = theEntity.streamedInput(); - HashMap theEntityValues = theEntity.getValues(); - String id = theEntity.getId(); - String aField; - StringBuffer fv = new StringBuffer(); - boolean firstField = true; - //cache - invalidatePopupCache(); - // build sql statement - for (int i = 0; i < getFields().size(); i++) { - aField = (String)metadataFields.get(i); - // only normal cases - if (!(aField.equals(thePKeyName) || aField.equals("webdb_create") || - aField.equals("webdb_lastchange") || (streamedInput != null && streamedInput.contains(aField)))) { - if (theEntityValues.containsKey(aField)) { - if (firstField == false) { - fv.append(", "); - } - else { - firstField = false; - } - fv.append(aField).append("='").append(StringUtil.quote((String)theEntityValues.get(aField))).append("'"); - } - } - } - StringBuffer sql = new StringBuffer("update ").append(theTable).append(" set ").append(fv); - // exceptions - if (metadataFields.contains("webdb_lastchange")) { - sql.append(",webdb_lastchange=NOW()"); - } - if (streamedInput != null) { - for (int i = 0; i < streamedInput.size(); i++) { - sql.append(",").append(streamedInput.get(i)).append("=?"); - } - } - sql.append(" where id=").append(id); - theLog.printInfo("UPDATE: " + sql); - // execute sql - try { - con = getPooledCon(); - con.setAutoCommit(false); - pstmt = con.prepareStatement(sql.toString()); - if (streamedInput != null) { - for (int i = 0; i < streamedInput.size(); i++) { - String inputString = (String)theEntityValues.get(streamedInput.get(i)); - pstmt.setBytes(i + 1, inputString.getBytes()); - } - } - pstmt.executeUpdate(); - } catch (SQLException sqe) { - throwSQLException(sqe, "update"); - } finally { - try { - con.setAutoCommit(true); - } catch (Exception e) { - ; - } - freeConnection(con, pstmt); - } - } - - /* - * delete-Operator - * @param id des zu loeschenden Datensatzes - * @return boolean liefert true zurueck, wenn loeschen erfolgreich war. - */ - public boolean delete (String id) throws StorageObjectException { - Statement stmt = null; - Connection con = null; - String sql; - int res = 0; - // loeschen des caches - invalidatePopupCache(); - sql = "delete from " + theTable + " where " + thePKeyName + "='" + id + - "'"; - theLog.printInfo("DELETE " + sql); - try { - con = getPooledCon(); - stmt = con.createStatement(); - res = stmt.executeUpdate(sql); - } catch (SQLException sqe) { - throwSQLException(sqe, "delete"); - } finally { - freeConnection(con, stmt); - } - if (cache != null) { - theLog.printInfo("CACHE: deleted " + id); - cache.remove(id); - } - return (res > 0) ? true : false; - } - - /* noch nicht implementiert. - * @return immer false - */ - public boolean delete (EntityList theEntityList) { - invalidatePopupCache(); - return false; - } - - /** - * Diese Methode sollte ueberschrieben werden, wenn fuer die abgeleitete Database-Klasse - * eine SimpleList mit Standard-Popupdaten erzeugt werden koennen soll. - * @return null - */ - public SimpleList getPopupData () { - return null; - } - - /** - * Holt Daten fuer Popups. - * @param name Name des Feldes. - * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. - * @return SimpleList Gibt freemarker.template.SimpleList zurueck. - */ - public SimpleList getPopupData (String name, boolean hasNullValue) { - return getPopupData(name, hasNullValue, null); - } - - /** - * Holt Daten fuer Popups. - * @param name Name des Feldes. - * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. - * @param where Schraenkt die Selektion der Datensaetze ein. - * @return SimpleList Gibt freemarker.template.SimpleList zurueck. - */ - public SimpleList getPopupData (String name, boolean hasNullValue, String where) { - return getPopupData(name, hasNullValue, where, null); - } - - /** - * Holt Daten fuer Popups. - * @param name Name des Feldes. - * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. - * @param where Schraenkt die Selektion der Datensaetze ein. - * @param order Gibt ein Feld als Sortierkriterium an. - * @return SimpleList Gibt freemarker.template.SimpleList zurueck. - */ - public SimpleList getPopupData (String name, boolean hasNullValue, String where, - String order) { - // caching - if (hasPopupCache && popupCache != null) - return popupCache; - SimpleList simpleList = null; - Connection con = null; - Statement stmt = null; - // build sql - StringBuffer sql = new StringBuffer("select ").append(thePKeyName).append(",").append(name).append(" from ").append(theTable); - if (where != null && !(where.length() == 0)) - sql.append(" where ").append(where); - sql.append(" order by "); - if (order != null && !(order.length() == 0)) - sql.append(order); - else - sql.append(name); - // execute sql - try { - con = getPooledCon(); - stmt = con.createStatement(); - ResultSet rs = executeSql(stmt, sql.toString()); - if (rs != null) { - if (evaluatedMetaData == false) - get_meta_data(); - simpleList = new SimpleList(); - SimpleHash popupDict; - if (hasNullValue) { - popupDict = new SimpleHash(); - popupDict.put("key", ""); - popupDict.put("value", "--"); - simpleList.add(popupDict); - } - while (rs.next()) { - popupDict = new SimpleHash(); - popupDict.put("key", getValueAsString(rs, 1, thePKeyType)); - popupDict.put("value", rs.getString(2)); - simpleList.add(popupDict); - } - rs.close(); - } - } catch (Exception e) { - theLog.printDebugInfo(e.toString()); - } finally { - freeConnection(con, stmt); - } - if (hasPopupCache) { - popupCache = simpleList; - } - return simpleList; - } - - /** - * Liefert alle Daten der Tabelle als SimpleHash zurueck. Dies wird verwandt, - * wenn in den Templates ein Lookup-Table benoetigt wird. Sollte nur bei kleinen - * Tabellen Verwendung finden. - * @return SimpleHash mit den Tabellezeilen. - */ - public SimpleHash getHashData () { - if (hashCache == null) { - try { - hashCache = HTMLTemplateProcessor.makeSimpleHash(selectByWhereClause("", - -1)); - } catch (StorageObjectException e) { - theLog.printDebugInfo(e.toString()); - } - } - return hashCache; - } - - /* invalidates the popupCache - */ - private void invalidatePopupCache () { - - /** @todo invalidates toooo much */ - popupCache = null; - hashCache = null; - } - - /** - * Diese Methode fuehrt den Sqlstring sql aus und timed im Logfile. - * @param stmt Statemnt - * @param sql Sql-String - * @return ResultSet - * @exception StorageObjectException, SQLException - */ - public ResultSet executeSql (Statement stmt, String sql) throws StorageObjectException, - SQLException { - long startTime = (new java.util.Date()).getTime(); - ResultSet rs = stmt.executeQuery(sql); - theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " - + sql); - return rs; - } - - /** - * Fuehrt Statement stmt aus und liefert Resultset zurueck. Das SQL-Statment wird - * getimed und geloggt. - * @param stmt PreparedStatement mit der SQL-Anweisung - * @return Liefert ResultSet des Statements zurueck. - * @exception StorageObjectException, SQLException - */ - public ResultSet executeSql (PreparedStatement stmt) throws StorageObjectException, - SQLException { - long startTime = (new java.util.Date()).getTime(); - ResultSet rs = stmt.executeQuery(); - theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms."); - return rs; - } - - /** - * returns the number of rows in the table - */ - public int getSize(String where) - throws SQLException,StorageObjectException - { - long startTime = (new java.util.Date()).getTime(); - String sql = "SELECT count(*) FROM "+ theTable + " where " + where; - //theLog.printDebugInfo("trying: "+ sql); - Connection con = null; - Statement stmt = null; - int result = 0; - - try { - con = getPooledCon(); - stmt = con.createStatement(); - ResultSet rs = executeSql(stmt,sql); - while(rs.next()){ - result = rs.getInt(1); - } - } catch (SQLException e) { - theLog.printError(e.toString()); - } finally { - freeConnection(con,stmt); - } - theLog.printInfo(theTable + " has "+ result +" rows where " + where); - theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); - return result; - } - - public int executeUpdate(Statement stmt, String sql) - throws StorageObjectException, SQLException - { - long startTime = (new java.util.Date()).getTime(); - //theLog.printDebugInfo("trying: "+ sql); - int rs = stmt.executeUpdate(sql); - theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); - return rs; - } - - public int executeUpdate(String sql) - throws StorageObjectException, SQLException - { - int result=-1; - long startTime = (new java.util.Date()).getTime(); - Connection con=null;PreparedStatement pstmt=null; - try { - con=getPooledCon(); - pstmt = con.prepareStatement(sql); - result = pstmt.executeUpdate(); - } - catch (Exception e) {theLog.printDebugInfo("settimage :: setImage gescheitert: "+e.toString());} - finally { freeConnection(con,pstmt); } - theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); - return result; - } - - /** - * Wertet ResultSetMetaData aus und setzt interne Daten entsprechend - * @param md ResultSetMetaData - * @exception StorageObjectException - */ - private void evalMetaData (ResultSetMetaData md) throws StorageObjectException { - this.evaluatedMetaData = true; - this.metadataFields = new ArrayList(); - this.metadataLabels = new ArrayList(); - this.metadataNotNullFields = new ArrayList(); - try { - int numFields = md.getColumnCount(); - this.metadataTypes = new int[numFields]; - String aField; - int aType; - for (int i = 1; i <= numFields; i++) { - aField = md.getColumnName(i); - metadataFields.add(aField); - metadataLabels.add(md.getColumnLabel(i)); - aType = md.getColumnType(i); - metadataTypes[i - 1] = aType; - if (aField.equals(thePKeyName)) { - thePKeyType = aType; - } - if (md.isNullable(i) == md.columnNullable) { - metadataNotNullFields.add(aField); - } - } - } catch (SQLException e) { - throwSQLException(e, "evalMetaData"); - } - } - - /** - * Wertet die Metadaten eines Resultsets fuer eine Tabelle aus, - * um die alle Columns und Typen einer Tabelle zu ermitteln. - */ - private void get_meta_data () throws StorageObjectException { - Connection con = null; - PreparedStatement pstmt = null; - String sql = "select * from " + theTable + " where 0=1"; - try { - con = getPooledCon(); - pstmt = con.prepareStatement(sql); - theLog.printInfo("METADATA: " + sql); - ResultSet rs = pstmt.executeQuery(); - evalMetaData(rs.getMetaData()); - rs.close(); - } catch (SQLException e) { - throwSQLException(e, "get_meta_data"); - } finally { - freeConnection(con, pstmt); - } - } - - /** - * Datenbankverbindung wird geschlossen - */ - public void disconnectPool () { - try { - myBroker.destroy(100); - } catch (SQLException sqe) { - ; - } - } - - /** - * Returns Connection-Object out of the PoolBroker. + return returnEntity; + } + + /** + * select-Operator um Datensaetze zu bekommen, die key = value erfuellen. + * @param key Datenbankfeld der Bedingung. + * @param value Wert die der key anehmen muss. + * @return EntityList mit den gematchten Entities + */ + + public EntityList selectByFieldValue(String aField, String aValue) + throws StorageObjectException { + + return selectByFieldValue(aField, aValue, 0); + } + + /** + * select-Operator um Datensaetze zu bekommen, die key = value erfuellen. + * @param key Datenbankfeld der Bedingung. + * @param value Wert die der key anehmen muss. + * @param offset Gibt an ab welchem Datensatz angezeigt werden soll. + * @return EntityList mit den gematchten Entities + */ + + public EntityList selectByFieldValue(String aField, String aValue, int offset) + throws StorageObjectException { + + return selectByWhereClause(aField + "=" + aValue, offset); + } + + + /** + * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. + * Also offset wird der erste Datensatz genommen. + * + * @param wc where-Clause + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + public EntityList selectByWhereClause(String where) + throws StorageObjectException { + + return selectByWhereClause(where, 0); + } + + + /** + * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. + * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. + * + * @param wc where-Clause + * @param offset ab welchem Datensatz. + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + public EntityList selectByWhereClause(String whereClause, int offset) + throws StorageObjectException { + + return selectByWhereClause(whereClause, null, offset); + } + + /** + * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. + * Also offset wird der erste Datensatz genommen. + * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. + * + * @param wc where-Clause + * @param ob orderBy-Clause + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + + public EntityList selectByWhereClause(String where, String order) + throws StorageObjectException { + + return selectByWhereClause(where, order, 0); + } + /** + * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. + * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. * - * @return Connection Object. - */ - public Connection getPooledCon () throws StorageObjectException { - if (myBroker != null) { - Connection con = myBroker.getConnection(); - if (con != null) - return con; - } - throw new StorageObjectException("No connection to database!"); - } - - /** - * Connection und StatementObjekt werden geschlossen und an den Connectionpool - * zurückgeben - * @param con Connection zur Datenbank - * @param stmt Statement-Objekt - */ - public void freeConnection (Connection con, Statement stmt) { - try { - if (stmt != null) - stmt.close(); - } catch (SQLException e1) { - theLog.printDebugInfo(e1.toString()); - } - if (con != null) - myBroker.freeConnection(con); - else - theLog.printDebugInfo("Con was null!"); - } - - /** - * Wertet SQLException aus und wirft dannach eine StorageObjectException - * @param sqe SQLException - * @param wo Funktonsname, in der die SQLException geworfen wurde - * @exception StorageObjectException - */ - void throwSQLException (SQLException sqe, String wo) throws StorageObjectException { - String state = ""; - String message = ""; - int vendor = 0; - if (sqe != null) { - state = sqe.getSQLState(); - message = sqe.getMessage(); - vendor = sqe.getErrorCode(); - } - theLog.printError(state + ": " + vendor + " : " + message + " Funktion: " - + wo); - throw new StorageObjectException((sqe == null) ? "undefined sql exception" : - sqe.toString()); - } - - /** - * Loggt Fehlermeldung mit dem Parameter Message und wirft dannach eine StorageObjectException - * @param message Nachricht mit dem Fehler - * @exception StorageObjectException - */ - void throwStorageObjectException (String message) throws StorageObjectException { - theLog.printError(message); - throw new StorageObjectException(message); - } + * @param wc where-Clause + * @param ob orderBy-Clause + * @param offset ab welchem Datensatz + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + + public EntityList selectByWhereClause(String whereClause, String orderBy, int offset) + throws StorageObjectException { + + return selectByWhereClause(whereClause, orderBy, offset, defaultLimit); + } + + + /** + * select-Operator liefert eine EntityListe mit den gematchten Datensätzen zurück. + * @param wc where-Clause + * @param ob orderBy-Clause + * @param offset ab welchem Datensatz + * @param limit wieviele Datensätze + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + + public EntityList selectByWhereClause(String wc, String ob, int offset, int limit) + throws StorageObjectException { + + // local + EntityList theReturnList=null; + Connection con=null; + Statement stmt=null; + ResultSet rs; + int offsetCount = 0; + int count=0; + + + // build sql-statement + if (wc != null && wc.length() == 0) { + wc = null; + } + StringBuffer countSql = new StringBuffer("select count(*) from ").append(theTable); + StringBuffer selectSql = new StringBuffer("select * from ").append(theTable); + if (wc != null) { + selectSql.append(" where ").append(wc); + countSql.append(" where ").append(wc); + } + if (ob != null && !(ob.length() == 0)) { + selectSql.append(" order by ").append(ob); + } + if (theAdaptor.hasLimit()) { + if (limit > -1 && offset > -1) { + selectSql.append(" limit "); + if (theAdaptor.reverseLimit()) { + selectSql.append(limit).append(",").append(offset); + } + else { + selectSql.append(offset).append(",").append(limit); + } + } + } + + // execute sql + try { + con = getPooledCon(); + stmt = con.createStatement(); + // counting rows + if (theAdaptor.hasLimit()) { + rs = executeSql(stmt, countSql.toString()); + if (rs != null) { + if (rs.next()) + count = rs.getInt(1); + rs.close(); + } + else + theLog.printError("Mh. Konnte nicht zaehlen: " + countSql); + } + // hier select + rs = executeSql(stmt, selectSql.toString()); + if (rs != null) { + theReturnList = new EntityList(); + if (evaluatedMetaData == false) { + evalMetaData(rs.getMetaData()); + } + Entity theResultEntity; + while (rs.next()) { + theResultEntity = makeEntityFromResultSet(rs); + theReturnList.add(theResultEntity); + offsetCount++; + } + rs.close(); + } + // making entitylist + if (!(theAdaptor.hasLimit())) + count = offsetCount; + if (theReturnList != null) { + theReturnList.setCount(count); + theReturnList.setOffset(offset); + theReturnList.setWhere(wc); + theReturnList.setOrder(ob); + if (offset >= limit) { + theReturnList.setPrevBatch(offset - limit); + } + if (offset + offsetCount < count) { + theReturnList.setNextBatch(offset + limit); + } + } + } catch (SQLException sqe) { + throwSQLException(sqe, "selectByWhereClause"); + } finally { + freeConnection(con, stmt); + } + return theReturnList; + } + + /** + * Bastelt aus einer Zeile der Datenbank ein EntityObjekt. + * + * @param rs Das ResultSetObjekt. + * @return Entity Die Entity. + */ + + public Entity makeEntityFromResultSet (ResultSet rs) throws StorageObjectException { + HashMap theResultHash = new HashMap(); + String theResult = null; + int theType; + Entity returnEntity = null; + try { + int size = metadataFields.size(); + for (int i = 0; i < size; i++) { + // alle durchlaufen bis nix mehr da + theType = metadataTypes[i]; + if (theType == java.sql.Types.LONGVARBINARY) { + InputStream us = rs.getAsciiStream(i + 1); + if (us != null) { + InputStreamReader is = new InputStreamReader(us); + char[] data = new char[32768]; + StringBuffer theResultString = new StringBuffer(); + int len; + while ((len = is.read(data)) > 0) { + theResultString.append(data, 0, len); + } + is.close(); + theResult = theResultString.toString(); + } + else { + theResult = null; + } + } + else { + theResult = getValueAsString(rs, (i + 1), theType); + } + if (theResult != null) { + theResultHash.put(metadataFields.get(i), theResult); + } + } + if (cache != null && theResultHash.containsKey(thePKeyName) && cache.containsKey((String)theResultHash.get(thePKeyName))) { + //theLog.printDebugInfo("CACHE: (out) "+ theResultHash.get(thePKeyName)+ " :"+theTable); + returnEntity = (Entity)cache.get((String)theResultHash.get(thePKeyName)); + } + else { + if (theEntityClass != null) { + returnEntity = (Entity)theEntityClass.newInstance(); + returnEntity.setValues(theResultHash); + returnEntity.setStorage(myselfDatabase); + if (cache != null) { + //theLog.printDebugInfo("CACHE: ( in) " + returnEntity.getId() + " :"+theTable); + cache.put(returnEntity.getId(), returnEntity); + } + } + else { + throwStorageObjectException("Interner Fehler theEntityClass nicht gesetzt!"); + } + } + } // try + catch (IllegalAccessException e) { + throwStorageObjectException("Kein Zugriff! -- " + e.toString()); + } catch (IOException e) { + throwStorageObjectException("IOException! -- " + e.toString()); + } catch (InstantiationException e) { + throwStorageObjectException("Keine Instantiiierung! -- " + e.toString()); + } catch (SQLException sqe) { + throwSQLException(sqe, "makeEntityFromResultSet"); + return null; + } + return returnEntity; + } + + /** + * insert-Operator: fügt eine Entity in die Tabelle ein. Eine Spalte WEBDB_CREATE + * wird automatisch mit dem aktuellen Datum gefuellt. + * + * @param theEntity + * @return der Wert des Primary-keys der eingefügten Entity + */ + public String insert (Entity theEntity) throws StorageObjectException { + String returnId = null; + Connection con = null; + PreparedStatement pstmt = null; + //cache + invalidatePopupCache(); + try { + HashMap theEntityValues = theEntity.getValues(); + ArrayList streamedInput = theEntity.streamedInput(); + StringBuffer f = new StringBuffer(); + StringBuffer v = new StringBuffer(); + String aField, aValue; + boolean firstField = true; + // make sql-string + for (int i = 0; i < getFields().size(); i++) { + aField = (String)getFields().get(i); + if (!aField.equals(thePKeyName)) { + aValue = null; + // sonderfaelle + if (aField.equals("webdb_create")) { + aValue = "NOW()"; + } + else { + if (streamedInput != null && streamedInput.contains(aField)) { + aValue = "?"; + } + else { + if (theEntityValues.containsKey(aField)) { + aValue = "'" + StringUtil.quote((String)theEntityValues.get(aField)) + + "'"; + } + } + } + // wenn Wert gegeben, dann einbauen + if (aValue != null) { + if (firstField == false) { + f.append(","); + v.append(","); + } + else { + firstField = false; + } + f.append(aField); + v.append(aValue); + } + } + } // end for + // insert into db + StringBuffer sqlBuf = new StringBuffer("insert into ").append(theTable).append("(").append(f).append(") values (").append(v).append(")"); + String sql = sqlBuf.toString(); + theLog.printInfo("INSERT: " + sql); + con = getPooledCon(); + con.setAutoCommit(false); + pstmt = con.prepareStatement(sql); + if (streamedInput != null) { + for (int i = 0; i < streamedInput.size(); i++) { + String inputString = (String)theEntityValues.get(streamedInput.get(i)); + pstmt.setBytes(i + 1, inputString.getBytes()); + } + } + int ret = pstmt.executeUpdate(); + if(ret == 0){ + //insert failed + return null; + } + pstmt = con.prepareStatement(theAdaptor.getLastInsertSQL((Database)myselfDatabase)); + ResultSet rs = pstmt.executeQuery(); + rs.next(); + returnId = rs.getString(1); + theEntity.setId(returnId); + } catch (SQLException sqe) { + throwSQLException(sqe, "insert"); + } finally { + try { + con.setAutoCommit(true); + } catch (Exception e) { + ; + } + freeConnection(con, pstmt); + } + return returnId; + } + + /** + * update-Operator: aktualisiert eine Entity. Eine Spalte WEBDB_LASTCHANGE + * wird automatisch mit dem aktuellen Datum gefuellt. + * + * @param theEntity + */ + public void update (Entity theEntity) throws StorageObjectException { + Connection con = null; + PreparedStatement pstmt = null; + ArrayList streamedInput = theEntity.streamedInput(); + HashMap theEntityValues = theEntity.getValues(); + String id = theEntity.getId(); + String aField; + StringBuffer fv = new StringBuffer(); + boolean firstField = true; + //cache + invalidatePopupCache(); + // build sql statement + for (int i = 0; i < getFields().size(); i++) { + aField = (String)metadataFields.get(i); + // only normal cases + if (!(aField.equals(thePKeyName) || aField.equals("webdb_create") || + aField.equals("webdb_lastchange") || (streamedInput != null && streamedInput.contains(aField)))) { + if (theEntityValues.containsKey(aField)) { + if (firstField == false) { + fv.append(", "); + } + else { + firstField = false; + } + fv.append(aField).append("='").append(StringUtil.quote((String)theEntityValues.get(aField))).append("'"); + } + } + } + StringBuffer sql = new StringBuffer("update ").append(theTable).append(" set ").append(fv); + // exceptions + if (metadataFields.contains("webdb_lastchange")) { + sql.append(",webdb_lastchange=NOW()"); + } + if (streamedInput != null) { + for (int i = 0; i < streamedInput.size(); i++) { + sql.append(",").append(streamedInput.get(i)).append("=?"); + } + } + sql.append(" where id=").append(id); + theLog.printInfo("UPDATE: " + sql); + // execute sql + try { + con = getPooledCon(); + con.setAutoCommit(false); + pstmt = con.prepareStatement(sql.toString()); + if (streamedInput != null) { + for (int i = 0; i < streamedInput.size(); i++) { + String inputString = (String)theEntityValues.get(streamedInput.get(i)); + pstmt.setBytes(i + 1, inputString.getBytes()); + } + } + pstmt.executeUpdate(); + } catch (SQLException sqe) { + throwSQLException(sqe, "update"); + } finally { + try { + con.setAutoCommit(true); + } catch (Exception e) { + ; + } + freeConnection(con, pstmt); + } + } + + /* + * delete-Operator + * @param id des zu loeschenden Datensatzes + * @return boolean liefert true zurueck, wenn loeschen erfolgreich war. + */ + public boolean delete (String id) throws StorageObjectException { + Statement stmt = null; + Connection con = null; + String sql; + int res = 0; + // loeschen des caches + invalidatePopupCache(); + sql = "delete from " + theTable + " where " + thePKeyName + "='" + id + + "'"; + theLog.printInfo("DELETE " + sql); + try { + con = getPooledCon(); + stmt = con.createStatement(); + res = stmt.executeUpdate(sql); + } catch (SQLException sqe) { + throwSQLException(sqe, "delete"); + } finally { + freeConnection(con, stmt); + } + if (cache != null) { + theLog.printInfo("CACHE: deleted " + id); + cache.remove(id); + } + return (res > 0) ? true : false; + } + + /* noch nicht implementiert. + * @return immer false + */ + public boolean delete (EntityList theEntityList) { + invalidatePopupCache(); + return false; + } + + /** + * Diese Methode sollte ueberschrieben werden, wenn fuer die abgeleitete Database-Klasse + * eine SimpleList mit Standard-Popupdaten erzeugt werden koennen soll. + * @return null + */ + public SimpleList getPopupData () { + return null; + } + + /** + * Holt Daten fuer Popups. + * @param name Name des Feldes. + * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. + * @return SimpleList Gibt freemarker.template.SimpleList zurueck. + */ + public SimpleList getPopupData (String name, boolean hasNullValue) { + return getPopupData(name, hasNullValue, null); + } + + /** + * Holt Daten fuer Popups. + * @param name Name des Feldes. + * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. + * @param where Schraenkt die Selektion der Datensaetze ein. + * @return SimpleList Gibt freemarker.template.SimpleList zurueck. + */ + public SimpleList getPopupData (String name, boolean hasNullValue, String where) { + return getPopupData(name, hasNullValue, where, null); + } + + /** + * Holt Daten fuer Popups. + * @param name Name des Feldes. + * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. + * @param where Schraenkt die Selektion der Datensaetze ein. + * @param order Gibt ein Feld als Sortierkriterium an. + * @return SimpleList Gibt freemarker.template.SimpleList zurueck. + */ + public SimpleList getPopupData (String name, boolean hasNullValue, String where, + String order) { + // caching + if (hasPopupCache && popupCache != null) + return popupCache; + SimpleList simpleList = null; + Connection con = null; + Statement stmt = null; + // build sql + StringBuffer sql = new StringBuffer("select ").append(thePKeyName).append(",").append(name).append(" from ").append(theTable); + if (where != null && !(where.length() == 0)) + sql.append(" where ").append(where); + sql.append(" order by "); + if (order != null && !(order.length() == 0)) + sql.append(order); + else + sql.append(name); + // execute sql + try { + con = getPooledCon(); + stmt = con.createStatement(); + ResultSet rs = executeSql(stmt, sql.toString()); + if (rs != null) { + if (evaluatedMetaData == false) + get_meta_data(); + simpleList = new SimpleList(); + SimpleHash popupDict; + if (hasNullValue) { + popupDict = new SimpleHash(); + popupDict.put("key", ""); + popupDict.put("value", "--"); + simpleList.add(popupDict); + } + while (rs.next()) { + popupDict = new SimpleHash(); + popupDict.put("key", getValueAsString(rs, 1, thePKeyType)); + popupDict.put("value", rs.getString(2)); + simpleList.add(popupDict); + } + rs.close(); + } + } catch (Exception e) { + theLog.printDebugInfo(e.toString()); + } finally { + freeConnection(con, stmt); + } + if (hasPopupCache) { + popupCache = simpleList; + } + return simpleList; + } + + /** + * Liefert alle Daten der Tabelle als SimpleHash zurueck. Dies wird verwandt, + * wenn in den Templates ein Lookup-Table benoetigt wird. Sollte nur bei kleinen + * Tabellen Verwendung finden. + * @return SimpleHash mit den Tabellezeilen. + */ + public SimpleHash getHashData () { + if (hashCache == null) { + try { + hashCache = HTMLTemplateProcessor.makeSimpleHash(selectByWhereClause("", + -1)); + } catch (StorageObjectException e) { + theLog.printDebugInfo(e.toString()); + } + } + return hashCache; + } + + /* invalidates the popupCache + */ + private void invalidatePopupCache () { + + /** @todo invalidates toooo much */ + popupCache = null; + hashCache = null; + } + + /** + * Diese Methode fuehrt den Sqlstring sql aus und timed im Logfile. + * @param stmt Statemnt + * @param sql Sql-String + * @return ResultSet + * @exception StorageObjectException, SQLException + */ + public ResultSet executeSql (Statement stmt, String sql) throws StorageObjectException, + SQLException { + long startTime = (new java.util.Date()).getTime(); + ResultSet rs = stmt.executeQuery(sql); + theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + + sql); + return rs; + } + + /** + * Fuehrt Statement stmt aus und liefert Resultset zurueck. Das SQL-Statment wird + * getimed und geloggt. + * @param stmt PreparedStatement mit der SQL-Anweisung + * @return Liefert ResultSet des Statements zurueck. + * @exception StorageObjectException, SQLException + */ + public ResultSet executeSql (PreparedStatement stmt) throws StorageObjectException, + SQLException { + long startTime = (new java.util.Date()).getTime(); + ResultSet rs = stmt.executeQuery(); + theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms."); + return rs; + } + + /** + * returns the number of rows in the table + */ + public int getSize(String where) + throws SQLException,StorageObjectException + { + long startTime = (new java.util.Date()).getTime(); + String sql = "SELECT count(*) FROM "+ theTable + " where " + where; + //theLog.printDebugInfo("trying: "+ sql); + Connection con = null; + Statement stmt = null; + int result = 0; + + try { + con = getPooledCon(); + stmt = con.createStatement(); + ResultSet rs = executeSql(stmt,sql); + while(rs.next()){ + result = rs.getInt(1); + } + } catch (SQLException e) { + theLog.printError(e.toString()); + } finally { + freeConnection(con,stmt); + } + theLog.printInfo(theTable + " has "+ result +" rows where " + where); + theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); + return result; + } + + public int executeUpdate(Statement stmt, String sql) + throws StorageObjectException, SQLException + { + long startTime = (new java.util.Date()).getTime(); + //theLog.printDebugInfo("trying: "+ sql); + int rs = stmt.executeUpdate(sql); + theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); + return rs; + } + + public int executeUpdate(String sql) + throws StorageObjectException, SQLException + { + int result=-1; + long startTime = (new java.util.Date()).getTime(); + Connection con=null;PreparedStatement pstmt=null; + try { + con=getPooledCon(); + pstmt = con.prepareStatement(sql); + result = pstmt.executeUpdate(); + } + catch (Exception e) {theLog.printDebugInfo("settimage :: setImage gescheitert: "+e.toString());} + finally { freeConnection(con,pstmt); } + theLog.printInfo((new java.util.Date().getTime() - startTime) + "ms. for: " + sql); + return result; + } + + /** + * Wertet ResultSetMetaData aus und setzt interne Daten entsprechend + * @param md ResultSetMetaData + * @exception StorageObjectException + */ + private void evalMetaData (ResultSetMetaData md) throws StorageObjectException { + this.evaluatedMetaData = true; + this.metadataFields = new ArrayList(); + this.metadataLabels = new ArrayList(); + this.metadataNotNullFields = new ArrayList(); + try { + int numFields = md.getColumnCount(); + this.metadataTypes = new int[numFields]; + String aField; + int aType; + for (int i = 1; i <= numFields; i++) { + aField = md.getColumnName(i); + metadataFields.add(aField); + metadataLabels.add(md.getColumnLabel(i)); + aType = md.getColumnType(i); + metadataTypes[i - 1] = aType; + if (aField.equals(thePKeyName)) { + thePKeyType = aType; + } + if (md.isNullable(i) == md.columnNullable) { + metadataNotNullFields.add(aField); + } + } + } catch (SQLException e) { + throwSQLException(e, "evalMetaData"); + } + } + + /** + * Wertet die Metadaten eines Resultsets fuer eine Tabelle aus, + * um die alle Columns und Typen einer Tabelle zu ermitteln. + */ + private void get_meta_data () throws StorageObjectException { + Connection con = null; + PreparedStatement pstmt = null; + String sql = "select * from " + theTable + " where 0=1"; + try { + con = getPooledCon(); + pstmt = con.prepareStatement(sql); + theLog.printInfo("METADATA: " + sql); + ResultSet rs = pstmt.executeQuery(); + evalMetaData(rs.getMetaData()); + rs.close(); + } catch (SQLException e) { + throwSQLException(e, "get_meta_data"); + } finally { + freeConnection(con, pstmt); + } + } + + /** + * Datenbankverbindung wird geschlossen + */ + public void disconnectPool () { + try { + myBroker.destroy(100); + } catch (SQLException sqe) { + ; + } + } + + /** + * Returns Connection-Object out of the PoolBroker. + * + * @return Connection Object. + */ + public Connection getPooledCon () throws StorageObjectException { + if (myBroker != null) { + Connection con = myBroker.getConnection(); + if (con != null) + return con; + } + throw new StorageObjectException("No connection to database!"); + } + + /** + * Connection und StatementObjekt werden geschlossen und an den Connectionpool + * zurückgeben + * @param con Connection zur Datenbank + * @param stmt Statement-Objekt + */ + public void freeConnection (Connection con, Statement stmt) { + try { + if (stmt != null) + stmt.close(); + } catch (SQLException e1) { + theLog.printDebugInfo(e1.toString()); + } + if (con != null) + myBroker.freeConnection(con); + else + theLog.printDebugInfo("Con was null!"); + } + + /** + * Wertet SQLException aus und wirft dannach eine StorageObjectException + * @param sqe SQLException + * @param wo Funktonsname, in der die SQLException geworfen wurde + * @exception StorageObjectException + */ + void throwSQLException (SQLException sqe, String wo) throws StorageObjectException { + String state = ""; + String message = ""; + int vendor = 0; + if (sqe != null) { + state = sqe.getSQLState(); + message = sqe.getMessage(); + vendor = sqe.getErrorCode(); + } + theLog.printError(state + ": " + vendor + " : " + message + " Funktion: " + + wo); + throw new StorageObjectException((sqe == null) ? "undefined sql exception" : + sqe.toString()); + } + + /** + * Loggt Fehlermeldung mit dem Parameter Message und wirft dannach eine StorageObjectException + * @param message Nachricht mit dem Fehler + * @exception StorageObjectException + */ + void throwStorageObjectException (String message) throws StorageObjectException { + theLog.printError(message); + throw new StorageObjectException(message); + } } diff --git a/source/mircoders/entity/EntityComment.java b/source/mircoders/entity/EntityComment.java index 4e5aa035..1bbe80bf 100755 --- a/source/mircoders/entity/EntityComment.java +++ b/source/mircoders/entity/EntityComment.java @@ -21,48 +21,47 @@ import mir.storage.*; public class EntityComment extends AbstractEntity implements Entity { - private static int instances; + private static int instances; - public EntityComment() - { - super(); - instances++; - } - - public EntityComment(StorageObject theStorage) { - this(); - setStorage(theStorage); - } + public EntityComment() + { + super(); + instances++; + } - public HashMap getValues() { - HashMap returnHash = super.getValues(); - String create = (String)returnHash.get("webdb_create"); - returnHash.put("date",StringUtil.dateToReadableDate(create)); + public EntityComment(StorageObject theStorage) { + this(); + setStorage(theStorage); + } - return returnHash; - } + public HashMap getValues() { + HashMap returnHash = super.getValues(); + String create = (String)returnHash.get("webdb_create"); + returnHash.put("date",StringUtil.dateToReadableDate(create)); -/** - * overridden method setValues to patch creator_main_url - */ + return returnHash; + } - public void setValues(HashMap theStringValues) - { - if (theStringValues != null) { - if (!theStringValues.containsKey("is_published")) - theStringValues.put("is_published","0"); - if (theStringValues.containsKey("main_url")) - if (((String)theStringValues.get("main_url")).equalsIgnoreCase("http://")) { - theStringValues.remove("main_url"); + /** + * overridden method setValues to patch creator_main_url + */ + public void setValues(HashMap theStringValues) + { + if (theStringValues != null) { + if (!theStringValues.containsKey("is_published")) + theStringValues.put("is_published","0"); + if (theStringValues.containsKey("main_url")) + if (((String)theStringValues.get("main_url")).equalsIgnoreCase("http://")) { + theStringValues.remove("main_url"); } else if (!((String)theStringValues.get("main_url")).startsWith("http://")){ theStringValues.put("main_url","http://"+((String)theStringValues.get("main_url"))); } - } - super.setValues(theStringValues); - } + } + super.setValues(theStringValues); + } - public void finalize() { + public void finalize() { instances--; super.finalize(); } diff --git a/source/mircoders/servlet/ServletModuleOpenIndy.java b/source/mircoders/servlet/ServletModuleOpenIndy.java index 176908a1..2e0d8292 100755 --- a/source/mircoders/servlet/ServletModuleOpenIndy.java +++ b/source/mircoders/servlet/ServletModuleOpenIndy.java @@ -37,10 +37,10 @@ public class ServletModuleOpenIndy extends ServletModule { private String commentFormTemplate, commentFormDoneTemplate, commentFormDupeTemplate; - private String postingFormTemplate, postingFormDoneTemplate; + private String postingFormTemplate, postingFormDoneTemplate, postingFormDupeTemplate; private ModuleContent contentModule; private ModuleImages imageModule; - private ModuleTopics themenModule; + private ModuleTopics themenModule; private String directOp ="yes"; // Singelton / Kontruktor @@ -55,6 +55,7 @@ public class ServletModuleOpenIndy extends ServletModule commentFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.CommentDupeTemplate"); postingFormTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingTemplate"); postingFormDoneTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDoneTemplate"); + postingFormDupeTemplate = MirConfig.getProp("ServletModule.OpenIndy.PostingDupeTemplate"); directOp = MirConfig.getProp("DirectOpenposting").toLowerCase(); mainModule = new ModuleComment(DatabaseComment.getInstance()); contentModule = new ModuleContent(DatabaseContent.getInstance()); @@ -97,40 +98,36 @@ public class ServletModuleOpenIndy extends ServletModule { // ok, collecting data from form try { - HashMap withValues = getIntersectingValues(req, DatabaseComment.getInstance()); - - //no html in comments(for now) - for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){ - String k=(String)i.next(); - String v=(String)withValues.get(k); - - withValues.put(k,StringUtil.removeHTMLTags(v)); - } - + HashMap withValues = getIntersectingValues(req, DatabaseComment.getInstance()); + + //no html in comments(for now) + for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){ + String k=(String)i.next(); + String v=(String)withValues.get(k); + + withValues.put(k,StringUtil.removeHTMLTags(v)); + } withValues.put("is_published","1"); - // Dupe detection -// EntityList com = mainModule.getByWhereClause("description='"+req.getParameter("description")+"' AND to_media='"+aid+"' AND creator='"+req.getParameter("creator")+"'", 0); -// if (com.getCount() > 0) { -// theLog.printDebugInfo("Comment dupe dropped for article "+aid); -// deliver(req, res, (TemplateModelRoot) null, commentFormDupeTemplate); -// } else { - - // inserting into database - String id = mainModule.add(withValues); - - // producing new page - new ProducerContent().handle(null, null, true, false, aid); - - // sync the server - int exitValue = Helper.rsync(); - theLog.printDebugInfo("rsync:"+exitValue); - - // redirecting to url - // should implement back to article - SimpleHash mergeData = new SimpleHash(); - deliver(req, res, mergeData, commentFormDoneTemplate); -// } + // inserting into database + String id = mainModule.add(withValues); + theLog.printDebugInfo("id: "+id); + //insert was not successfull + if(id==null){ + deliver(req, res, new SimpleHash(), commentFormDupeTemplate); + } + + // producing new page + new ProducerContent().handle(null, null, true, false, aid); + + // sync the server + int exitValue = Helper.rsync(); + theLog.printDebugInfo("rsync:"+exitValue); + + // redirecting to url + // should implement back to article + SimpleHash mergeData = new SimpleHash(); + deliver(req, res, mergeData, commentFormDoneTemplate); } catch (StorageObjectException e) { throw new ServletModuleException(e.toString());} catch (ModuleException e) { throw new ServletModuleException(e.toString());} @@ -191,18 +188,17 @@ public class ServletModuleOpenIndy extends ServletModule // call the routines that escape html for (Iterator i=withValues.keySet().iterator(); i.hasNext(); ){ - String k=(String)i.next(); - String v=(String)withValues.get(k); - - if (k.equals("content_data")){ - //this doesn't quite work yet, so for now, all html goes - // withValues.put(k,StringUtil.approveHTMLTags(v)); - withValues.put(k,StringUtil.removeHTMLTags(v)); - } - else{ - withValues.put(k,StringUtil.removeHTMLTags(v)); - } - + String k=(String)i.next(); + String v=(String)withValues.get(k); + + if (k.equals("content_data")){ + //this doesn't quite work yet, so for now, all html goes + withValues.put(k,StringUtil.approveHTMLTags(v)); + //withValues.put(k,StringUtil.removeHTMLTags(v)); + } else { + withValues.put(k,StringUtil.removeHTMLTags(v)); + } + } withValues.put("date", StringUtil.date2webdbDate(new GregorianCalendar())); @@ -220,8 +216,13 @@ public class ServletModuleOpenIndy extends ServletModule // inserting content into database String cid = contentModule.add(withValues); + theLog.printDebugInfo("id: "+cid); + //insert was not successfull + if(cid==null){ + deliver(req, res, mergeData, postingFormDupeTemplate); + } - String[] to_topicsArr = mp.getParameterValues("to_topic"); + String[] to_topicsArr = mp.getParameterValues("to_topic"); if (to_topicsArr != null && to_topicsArr.length > 0) { try{ DatabaseContentToTopics.getInstance().setTopics(cid,to_topicsArr); @@ -333,3 +334,4 @@ public class ServletModuleOpenIndy extends ServletModule } + -- 2.11.0