You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2012/04/11 14:23:34 UTC
svn commit: r1324735 - in
/empire-db/trunk/empire-db/src/main/java/org/apache/empire/db:
DBColumn.java DBDatabase.java DBRowSet.java
Author: doebele
Date: Wed Apr 11 12:23:34 2012
New Revision: 1324735
URL: http://svn.apache.org/viewvc?rev=1324735&view=rev
Log:
EMPIREDB-138
Custom serialization and deserialization for DBRowSet and DBColumn objects
Modified:
empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBColumn.java
empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
Modified: empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBColumn.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBColumn.java?rev=1324735&r1=1324734&r2=1324735&view=diff
==============================================================================
--- empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBColumn.java (original)
+++ empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBColumn.java Wed Apr 11 12:23:34 2012
@@ -19,13 +19,22 @@
package org.apache.empire.db;
// Java
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
import java.util.Set;
import org.apache.empire.commons.Options;
+import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.Column;
import org.apache.empire.data.DataType;
import org.apache.empire.db.exceptions.DatabaseNotOpenException;
import org.apache.empire.db.expr.set.DBSetExpr;
+import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.ItemNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
@@ -46,6 +55,8 @@ public abstract class DBColumn extends D
{
private final static long serialVersionUID = 1L;
+ private static final Logger log = LoggerFactory.getLogger(DBColumn.class);
+
// Predefined column attributes
/**
@@ -74,7 +85,7 @@ public abstract class DBColumn extends D
public static final String DBCOLATTR_SINGLEBYTECHARS = "singleByteChars";
// basic data
- protected final DBRowSet rowset;
+ protected final transient DBRowSet rowset;
protected final String name;
protected String comment;
@@ -94,6 +105,105 @@ public abstract class DBColumn extends D
}
/**
+ * Gets an identifier for this RowSet Object
+ * @return the rowset identifier
+ */
+ public String getId()
+ {
+ return rowset.getId()+"."+name;
+ }
+
+ /**
+ * returns a rowset by its identifier
+ * @param rowsetId the id of the rowset
+ * @return the rowset object
+ */
+ public static DBColumn findById(String columnId)
+ {
+ int i = columnId.lastIndexOf('.');
+ if (i<0)
+ throw new InvalidArgumentException("columnId", columnId);
+ // rowset suchen
+ String rsid = columnId.substring(0, i);
+ DBRowSet rset = DBRowSet.findById(rsid);
+ // column suchen
+ String colname = columnId.substring(i+1);
+ DBColumn col = rset.getColumn(colname);
+ if (col==null)
+ throw new ItemNotFoundException(columnId);
+ return col;
+ }
+
+ /**
+ * Custom serialization for transient rowset.
+ */
+ private void writeObject(ObjectOutputStream strm) throws IOException
+ {
+ if (rowset==null)
+ { // No rowset
+ strm.writeObject("");
+ strm.defaultWriteObject();
+ return;
+ }
+ // write dbid and rowset-name
+ String dbid = rowset.getDatabase().getId();
+ String rsname = rowset.getName();
+ strm.writeObject(dbid);
+ strm.writeObject(rsname);
+ if (log.isInfoEnabled())
+ log.info("Serialization: reading DBColumn "+dbid+"."+rsname);
+ strm.defaultWriteObject();
+ }
+
+ /**
+ * Custom serialization for transient rowset.
+ */
+ private void readObject(ObjectInputStream strm) throws IOException, ClassNotFoundException,
+ SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
+ {
+ String dbid = String.valueOf(strm.readObject());
+ if (StringUtils.isNotEmpty(dbid))
+ { // Find Rowset
+ String rsname = String.valueOf(strm.readObject());
+ if (log.isInfoEnabled())
+ log.info("Serialization: reading DBColumn "+dbid+"."+rsname);
+ // find database
+ DBDatabase db = DBDatabase.findById(dbid);
+ if (db==null)
+ throw new ClassNotFoundException(dbid);
+ // find database
+ DBRowSet srs = db.getRowSet(rsname);
+ if (srs==null)
+ throw new ClassNotFoundException(dbid+"."+rsname);
+ // set final field
+ Field f = DBColumn.class.getDeclaredField("rowset");
+ f.setAccessible(true);
+ f.set(this, srs);
+ f.setAccessible(false);
+ }
+ // read the rest
+ strm.defaultReadObject();
+ }
+
+ @Override
+ public boolean equals(Object other)
+ {
+ if (other==this)
+ return true;
+ if (rowset==null)
+ return super.equals(other);
+ if (other instanceof DBColumn)
+ { // Rowset and name must match
+ DBColumn c = (DBColumn) other;
+ if (rowset.equals(c.getRowSet())==false)
+ return false;
+ // check for equal names
+ return name.equalsIgnoreCase(c.getName());
+ }
+ return false;
+ }
+
+ /**
* Returns the size of the column.
*
* @return Returns the size of the column
Modified: empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java?rev=1324735&r1=1324734&r2=1324735&view=diff
==============================================================================
--- empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java (original)
+++ empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java Wed Apr 11 12:23:34 2012
@@ -19,12 +19,14 @@
package org.apache.empire.db;
import java.io.Serializable;
+import java.lang.ref.WeakReference;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import org.apache.empire.commons.ObjectUtils;
@@ -40,6 +42,7 @@ import org.apache.empire.db.expr.column.
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.ItemExistsException;
+import org.apache.empire.exceptions.ItemNotFoundException;
import org.apache.empire.exceptions.MiscellaneousErrorException;
import org.apache.empire.exceptions.PropertyReadOnlyException;
import org.apache.empire.exceptions.UnexpectedReturnValueException;
@@ -87,6 +90,37 @@ public abstract class DBDatabase extends
// Logger
private static final Logger log = LoggerFactory.getLogger(DBDatabase.class);
+
+ /**
+ * global map of all database instances that have been allocated
+ */
+ private static HashMap<String, WeakReference<DBDatabase>> databaseMap = new HashMap<String, WeakReference<DBDatabase>>();
+
+ /**
+ * find a database by id
+ */
+ public static DBDatabase findById(String dbIdent)
+ {
+ if (databaseMap.containsKey(dbIdent)==false)
+ log.warn("Database {} not found!", dbIdent);
+ // get reference
+ WeakReference<DBDatabase> ref = databaseMap.get(dbIdent);
+ return ref.get();
+ }
+
+ /**
+ * find a database by id
+ */
+ public static DBDatabase findByClass(Class<? extends DBDatabase> cls)
+ {
+ for (WeakReference<DBDatabase> ref : databaseMap.values())
+ { // find database by class
+ DBDatabase db = ref.get();
+ if (db!=null && cls.isInstance(db))
+ return db;
+ }
+ throw new ItemNotFoundException(cls.getName());
+ }
/** the database schema * */
protected String schema = null; // database schema name
@@ -95,6 +129,7 @@ public abstract class DBDatabase extends
protected List<DBRelation> relations = new ArrayList<DBRelation>();
protected List<DBView> views = new ArrayList<DBView>();
protected DBDatabaseDriver driver = null;
+ protected String instanceId;
/**
* Property that indicates whether to always use usePreparedStatements (Default is false!)
@@ -104,11 +139,18 @@ public abstract class DBDatabase extends
private boolean preparedStatementsEnabled = false;
/**
- * Constructs a new DBDatabase object set the variable 'schema' = null.
+ * Constructs a new DBDatabase object and sets the specified schema object.
+ *
+ * @param schema the database schema
+ * @param linkName the database link name
*/
- public DBDatabase()
+ public DBDatabase(String schema, String linkName)
{
- this.schema = null;
+ this.schema = schema;
+ this.linkName = linkName;
+
+ // register database in global map
+ register(getClass().getSimpleName());
}
/**
@@ -118,19 +160,48 @@ public abstract class DBDatabase extends
*/
public DBDatabase(String schema)
{
- this.schema = schema;
+ this(schema, null);
}
/**
- * Constructs a new DBDatabase object and sets the specified schema object.
- *
- * @param schema the database schema
- * @param linkName the database link name
+ * Constructs a new DBDatabase object set the variable 'schema' = null.
*/
- public DBDatabase(String schema, String linkName)
+ public DBDatabase()
{
- this.schema = schema;
- this.linkName = linkName;
+ this(null, null);
+ }
+
+ /**
+ * registers the database in the global list of databases
+ * @param dbid
+ */
+ protected void register(String dbid)
+ {
+ // Check if it exists
+ if (databaseMap.containsValue(this))
+ databaseMap.remove(instanceId);
+ // find a unique key
+ int inst=0;
+ for (String key : databaseMap.keySet())
+ {
+ if (key.startsWith(dbid) && databaseMap.get(key).get()!=null)
+ inst++;
+ }
+ if (inst>0)
+ this.instanceId = dbid+":"+String.valueOf(inst+1);
+ else
+ this.instanceId = dbid;
+ // register database in global map
+ databaseMap.put(this.instanceId, new WeakReference<DBDatabase>(this));
+ }
+
+ /**
+ * Returns the database instance id
+ * @return the identifier of the database
+ */
+ public String getId()
+ {
+ return instanceId;
}
// ------------------------------
@@ -457,6 +528,20 @@ public abstract class DBDatabase extends
}
/**
+ * Finds a DBRowSet object (DBTable or DBView) by name.
+ * <P>
+ * @param name the name of the table
+ * @return the located DBTable object
+ */
+ public DBRowSet getRowSet(String name)
+ { // find table by name
+ DBRowSet rset = getTable(name);
+ if (rset==null)
+ rset = getView(name);
+ return rset;
+ }
+
+ /**
* Finds a DBTable object by name.
* <P>
* @param name the name of the table
Modified: empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java?rev=1324735&r1=1324734&r2=1324735&view=diff
==============================================================================
--- empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java (original)
+++ empire-db/trunk/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java Wed Apr 11 12:23:34 2012
@@ -18,6 +18,10 @@
*/
package org.apache.empire.db;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.Timestamp;
import java.util.ArrayList;
@@ -83,7 +87,7 @@ public abstract class DBRowSet extends D
// Logger
protected static final Logger log = LoggerFactory.getLogger(DBRowSet.class);
// Members
- protected final DBDatabase db;
+ protected final transient DBDatabase db;
protected String comment = null;
protected DBIndex primaryKey = null;
protected DBColumn timestampColumn = null; // Use SetUpdateTimestamp!
@@ -100,6 +104,100 @@ public abstract class DBRowSet extends D
this.db = db;
}
+ /**
+ * Gets an identifier for this RowSet Object
+ * @return the rowset identifier
+ */
+ public String getId()
+ {
+ return db.getId()+"."+getName();
+ }
+
+ /**
+ * returns a rowset by its identifier
+ * @param rowsetId the id of the rowset
+ * @return the rowset object
+ */
+ public static DBRowSet findById(String rowsetId)
+ {
+ int i = rowsetId.lastIndexOf('.');
+ if (i<0)
+ throw new InvalidArgumentException("rowsetId", rowsetId);
+ // database suchen
+ String dbid = rowsetId.substring(0, i);
+ DBDatabase db = DBDatabase.findById(dbid);
+ if (db==null)
+ throw new ItemNotFoundException(dbid);
+ // rowset suchen
+ String rsname = rowsetId.substring(i+1);
+ DBRowSet rset = db.getRowSet(rsname);
+ if (rset==null)
+ throw new ItemNotFoundException(rowsetId);
+ return rset;
+ }
+
+ /**
+ * Custom serialization for transient database.
+ */
+ private void writeObject(ObjectOutputStream strm) throws IOException
+ {
+ if (db==null)
+ { // No database
+ strm.writeObject("");
+ strm.defaultWriteObject();
+ return;
+ }
+ String dbid = db.getId();
+ strm.writeObject(dbid);
+ if (log.isInfoEnabled())
+ log.info("Serialization: reading DBRowSet "+dbid);
+ // write the rest
+ strm.defaultWriteObject();
+ }
+
+ /**
+ * Custom deserialization for transient database.
+ */
+ private void readObject(ObjectInputStream strm) throws IOException, ClassNotFoundException,
+ SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
+ {
+ String dbid = String.valueOf(strm.readObject());
+ if (StringUtils.isNotEmpty(dbid))
+ { // Find database
+ if (log.isInfoEnabled())
+ log.info("Serialization: reading DBRowSet "+dbid);
+ // find database
+ DBDatabase sdb = DBDatabase.findById(dbid);
+ if (sdb==null)
+ throw new ClassNotFoundException(dbid);
+ // set final field
+ Field f = DBRowSet.class.getDeclaredField("db");
+ f.setAccessible(true);
+ f.set(this, sdb);
+ f.setAccessible(false);
+ }
+ // read the rest
+ strm.defaultReadObject();
+ }
+
+ @Override
+ public boolean equals(Object other)
+ {
+ if (other==this)
+ return true;
+ if (db==null)
+ return super.equals(other);
+ if (other instanceof DBRowSet)
+ { // Database and name must match
+ DBRowSet r = (DBRowSet) other;
+ if (db.equals(r.getDatabase())==false)
+ return false;
+ // check for equal names
+ return getName().equalsIgnoreCase(r.getName());
+ }
+ return false;
+ }
+
// ------- Abstract Methods -------
public abstract String getName();