diff --git a/build.xml b/build.xml index 9c0d5886..15625912 100644 --- a/build.xml +++ b/build.xml @@ -8,7 +8,7 @@ - + diff --git a/src/helma/main/Server.java b/src/helma/main/Server.java index 70042696..da90daf1 100644 --- a/src/helma/main/Server.java +++ b/src/helma/main/Server.java @@ -38,7 +38,7 @@ import helma.util.ResourceProperties; */ public class Server implements Runnable { // version string - public static final String version = "1.7.0 (__builddate__)"; + public static final String version = "1.7.3 (__builddate__)"; // static server instance private static Server server; diff --git a/src/helma/objectmodel/db/DbSource.java b/src/helma/objectmodel/db/DbSource.java index 2e18179c..33e1dbc8 100644 --- a/src/helma/objectmodel/db/DbSource.java +++ b/src/helma/objectmodel/db/DbSource.java @@ -32,7 +32,7 @@ import java.util.Hashtable; public class DbSource { private static ResourceProperties defaultProps = null; private Properties conProps; - private String name; + private final String name; private ResourceProperties props, subProps; protected String url; private String driver; diff --git a/src/helma/objectmodel/db/Transactor.java b/src/helma/objectmodel/db/Transactor.java index ceb43043..ee6364ea 100644 --- a/src/helma/objectmodel/db/Transactor.java +++ b/src/helma/objectmodel/db/Transactor.java @@ -52,10 +52,10 @@ public class Transactor { protected ITransaction txn; // Transactions for SQL data sources - private Map sqlConnections; + private Map sqlConnections; // Set of SQL connections that already have been verified - private Map testedConnections; + private Map testedConnections; // when did the current transaction start? private long tstart; @@ -81,8 +81,8 @@ public class Transactor { cleanNodes = new HashMap(); parentNodes = new HashSet(); - sqlConnections = new HashMap(); - testedConnections = new HashMap(); + sqlConnections = new HashMap(); + testedConnections = new HashMap(); active = false; killed = false; } @@ -249,14 +249,18 @@ public class Transactor { * @return the connection */ public Connection getConnection(DbSource src) { - Connection con = (Connection) sqlConnections.get(src); - Long tested = (Long) testedConnections.get(src); + Connection con = sqlConnections.get(src); + Long tested = testedConnections.get(src); long now = System.currentTimeMillis(); if (con != null && (tested == null || now - tested.longValue() > 60000)) { // Check if the connection is still alive by executing a simple statement. try { Statement stmt = con.createStatement(); - stmt.execute("SELECT 1"); + if (src.isOracle()) { + stmt.execute("SELECT 1 FROM DUAL"); + } else { + stmt.execute("SELECT 1"); + } stmt.close(); testedConnections.put(src, new Long(now)); } catch (SQLException sx) { diff --git a/src/helma/util/ResourceProperties.java b/src/helma/util/ResourceProperties.java index 9bc78063..07ba9d26 100644 --- a/src/helma/util/ResourceProperties.java +++ b/src/helma/util/ResourceProperties.java @@ -537,4 +537,53 @@ public class ResourceProperties extends Properties { super.clear(); } + /** + * Compares this ResourceProperties instance to the one passed + * as argument. Note that in contrast to Hashtable.equals this method + * isn't synchronized to avoid deadlocks (which can happen in eg. + * DbSource.equals), and the comparison might return a wrong result + * if one of the two instances is modified during this method call. This + * method however doesn't throw a ConcurrentModificationException. + * + * @param o object to be compared for equality with this instance + * @return true if the specified Object is equal to this instance + * @see Hashtable#equals(Object) + */ + public boolean equals(Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof ResourceProperties)) { + return false; + } + ResourceProperties t = (ResourceProperties) o; + if (t.size() != size()) { + return false; + } + + try { + Object[] keys = keySet().toArray(); + for (Object key : keys) { + Object value = get(key); + if (value == null) { + if (!(t.get(key) == null && t.containsKey(key))) { + return false; + } + } else { + if (!value.equals(t.get(key))) { + return false; + } + } + } + } catch (ClassCastException unused) { + return false; + } catch (NullPointerException unused) { + return false; + } + + return true; + } + + }