summaryrefslogtreecommitdiffstats
path: root/java/rasj/odmg
diff options
context:
space:
mode:
authorConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
committerConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
commit8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 (patch)
treebd328a4dd4f92d32202241b5e3a7f36177792c5f /java/rasj/odmg
downloadrasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip
Initial commitv8.0
Diffstat (limited to 'java/rasj/odmg')
-rw-r--r--java/rasj/odmg/MD5.classbin0 -> 7551 bytes
-rw-r--r--java/rasj/odmg/MD5State.classbin0 -> 1048 bytes
-rw-r--r--java/rasj/odmg/Makefile59
-rw-r--r--java/rasj/odmg/Makefile.dep0
-rw-r--r--java/rasj/odmg/RasBag.classbin0 -> 3170 bytes
-rw-r--r--java/rasj/odmg/RasBag.java178
-rw-r--r--java/rasj/odmg/RasCollection.classbin0 -> 1287 bytes
-rw-r--r--java/rasj/odmg/RasCollection.java105
-rw-r--r--java/rasj/odmg/RasDatabase.classbin0 -> 2477 bytes
-rw-r--r--java/rasj/odmg/RasDatabase.java133
-rw-r--r--java/rasj/odmg/RasList.classbin0 -> 2594 bytes
-rw-r--r--java/rasj/odmg/RasList.java183
-rw-r--r--java/rasj/odmg/RasODMGGlobal.classbin0 -> 663 bytes
-rw-r--r--java/rasj/odmg/RasODMGGlobal.java60
-rw-r--r--java/rasj/odmg/RasODMGImplementation.classbin0 -> 20240 bytes
-rw-r--r--java/rasj/odmg/RasODMGImplementation.java1366
-rw-r--r--java/rasj/odmg/RasODMGImplementation.java.BEFORE_Connection1344
-rw-r--r--java/rasj/odmg/RasODMGImplementation.java.getFreeServer_beginTA1361
-rw-r--r--java/rasj/odmg/RasOID.classbin0 -> 2119 bytes
-rw-r--r--java/rasj/odmg/RasOID.java153
-rw-r--r--java/rasj/odmg/RasOQLQuery.classbin0 -> 5925 bytes
-rw-r--r--java/rasj/odmg/RasOQLQuery.java425
-rw-r--r--java/rasj/odmg/RasObject.classbin0 -> 3229 bytes
-rw-r--r--java/rasj/odmg/RasObject.java244
-rw-r--r--java/rasj/odmg/RasSet.classbin0 -> 2087 bytes
-rw-r--r--java/rasj/odmg/RasSet.java172
-rw-r--r--java/rasj/odmg/RasTransaction.LOCAL_isOpenTA173
-rw-r--r--java/rasj/odmg/RasTransaction.classbin0 -> 2617 bytes
-rw-r--r--java/rasj/odmg/RasTransaction.java173
-rw-r--r--java/rasj/odmg/RasTransaction.java.ORIG146
-rw-r--r--java/rasj/odmg/utils.classbin0 -> 5118 bytes
31 files changed, 6275 insertions, 0 deletions
diff --git a/java/rasj/odmg/MD5.class b/java/rasj/odmg/MD5.class
new file mode 100644
index 0000000..00f1f09
--- /dev/null
+++ b/java/rasj/odmg/MD5.class
Binary files differ
diff --git a/java/rasj/odmg/MD5State.class b/java/rasj/odmg/MD5State.class
new file mode 100644
index 0000000..07ab66a
--- /dev/null
+++ b/java/rasj/odmg/MD5State.class
Binary files differ
diff --git a/java/rasj/odmg/Makefile b/java/rasj/odmg/Makefile
new file mode 100644
index 0000000..6c768a7
--- /dev/null
+++ b/java/rasj/odmg/Makefile
@@ -0,0 +1,59 @@
+# -*-Makefile-*- (for Emacs)
+#
+# This file is part of rasdaman community.
+#
+# Rasdaman community is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Rasdaman community is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+# rasdaman GmbH.
+#
+# For more information please see <http://www.rasdaman.org>
+# or contact Peter Baumann via <baumann@rasdaman.com>. # Top Level makefile. This points to the various modules that have to be build
+# and/or deployed
+#
+# MAKEFILE FOR:
+# package rasj/odmg
+#
+# COMMENTS:
+#
+##################################################################
+######################### Definitions ############################
+
+# standard include with general options
+include $(RMANBASE)/Makefile.inc
+
+SRCS = RasBag.java RasCollection.java RasDatabase.java RasList.java \
+ RasODMGGlobal.java RasODMGImplementation.java RasOID.java \
+ RasOQLQuery.java RasObject.java RasSet.java RasTransaction.java
+OBJS = ${SRCS:%.java=%.class}
+MISCCLEAN = *.class
+
+# directory where HTML documentation is created
+DOCDIR := $(DOCBASE)/java/rasj/odmg
+
+########################### Targets ##############################
+
+# compile everything
+.PHONY : all
+all: $(OBJS)
+
+# delete all files
+empty:
+ -rm -f $(SRCS) $(MISCCLEAN)
+
+############################ Dependencies #######################
+
+# general rules
+include $(RMANBASE)/Makefile.rel
+
diff --git a/java/rasj/odmg/Makefile.dep b/java/rasj/odmg/Makefile.dep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/java/rasj/odmg/Makefile.dep
diff --git a/java/rasj/odmg/RasBag.class b/java/rasj/odmg/RasBag.class
new file mode 100644
index 0000000..9d443fa
--- /dev/null
+++ b/java/rasj/odmg/RasBag.class
Binary files differ
diff --git a/java/rasj/odmg/RasBag.java b/java/rasj/odmg/RasBag.java
new file mode 100644
index 0000000..5ed1843
--- /dev/null
+++ b/java/rasj/odmg/RasBag.java
@@ -0,0 +1,178 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+
+package rasj.odmg;
+
+import org.odmg.*;
+import rasj.global.*;
+import java.util.*;
+
+/**
+ * This class implements the ODMG DBag interface.
+ * @version $Revision: 1.3 $
+ */
+public class RasBag extends RasCollection implements DBag
+ {
+ static final String rcsid = "@(#)Package rasj.odmg, class RasBag: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/odmg/RasBag.java,v 1.3 2003/12/19 15:42:56 rasdev Exp $";
+
+ List content;
+
+ /**
+ * constructor
+ */
+ public RasBag()
+ {
+ Debug.enterVerbose( "RasBag.constructor start." );
+ content = new ArrayList();
+ Debug.leaveVerbose( "RasBag.constructor done." );
+ }
+
+ /**
+ * Appends the specified element to this Bag.
+ */
+ public boolean add(Object o)
+ {
+ boolean result = content.add(o);
+ Debug.talkVerbose( "RasBag.add: result=" + result );
+ return result;
+ }
+
+ /**
+ * This method returns the number of occurrences of the object obj in the DBag collection.
+ */
+ public int occurrences(java.lang.Object obj)
+ {
+ Debug.enterVerbose( "RasBag.occurrences start." );
+
+ DBag tmpBag = new RasBag();
+ tmpBag.addAll(content);
+ int count = 0;
+ while(tmpBag.contains(obj))
+ {
+ count++;
+ tmpBag.remove(obj);
+ }
+
+ Debug.leaveVerbose( "RasBag.occurrences done. count=" + count );
+ return count;
+ }
+
+ /**
+ * A new DBag instance is created that contains the difference of this object and the DBag instance referenced by otherBag.
+ */
+ public DBag difference(DBag otherBag)
+ {
+ Debug.enterVerbose( "RasBag.difference start." );
+
+ DBag diffBag = new RasBag();
+ diffBag.addAll(otherBag);
+ DBag retBag = new RasBag();
+ Iterator it = content.iterator();
+ Object tmp;
+ while(it.hasNext())
+ {
+ tmp = it.next();
+ if(!diffBag.contains(tmp))
+ retBag.add(tmp);
+ else
+ diffBag.remove(tmp);
+ }
+ retBag.addAll(diffBag);
+
+ Debug.leaveVerbose( "RasBag.difference done." );
+ return retBag;
+ }
+
+ /**
+ * A new DBag instance is created that contains the intersection of this object and the DBag referenced by otherBag.
+ */
+ public DBag intersection(DBag otherBag)
+ {
+ Debug.enterVerbose( "RasBag.intersection start." );
+
+ DBag intBag = new RasBag();
+ intBag.addAll(otherBag);
+ DBag retBag = new RasBag();
+ Iterator it = content.iterator();
+ Object tmp;
+ while(it.hasNext())
+ {
+ tmp = it.next();
+ if(intBag.contains(tmp))
+ {
+ retBag.add(tmp);
+ intBag.remove(tmp);
+ }
+ }
+
+ Debug.leaveVerbose( "RasBag.intersection done." );
+ return retBag;
+ }
+
+ /**
+ * A new DBag instance is created that is the union of this object and otherBag.
+ */
+ public DBag union(DBag otherBag)
+ {
+ Debug.enterVerbose( "RasBag.union start." );
+
+ DBag retBag = new RasBag();
+ retBag.addAll(content);
+ retBag.addAll(otherBag);
+
+ Debug.leaveVerbose( "RasBag.union done." );
+ return retBag;
+ }
+
+ /**
+ * Returns an iterator over the elements in this Bag in proper sequence.
+ */
+ public Iterator iterator()
+ {
+ Debug.talkVerbose( "RasBag.iterator." );
+ return content.iterator();
+ }
+
+ /**
+ * Returns the number of elements in this Bag.
+ */
+ public int size()
+ {
+ int result = content.size();
+ Debug.talkVerbose( "RasBag.size: size=" + result );
+ return result;
+ }
+
+} // RasBag
+
diff --git a/java/rasj/odmg/RasCollection.class b/java/rasj/odmg/RasCollection.class
new file mode 100644
index 0000000..de260fc
--- /dev/null
+++ b/java/rasj/odmg/RasCollection.class
Binary files differ
diff --git a/java/rasj/odmg/RasCollection.java b/java/rasj/odmg/RasCollection.java
new file mode 100644
index 0000000..f782c94
--- /dev/null
+++ b/java/rasj/odmg/RasCollection.java
@@ -0,0 +1,105 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+
+package rasj.odmg;
+
+import org.odmg.*;
+import java.util.*;
+
+/**
+ * This abstract class should implement the ODMG DCollection interface but is not implemented yet,
+ * please use subclass RasBag
+ * @version $Revision: 1.5 $
+ */
+public abstract class RasCollection extends AbstractCollection implements DCollection //extends RasObject
+
+{
+ static final String rcsid = "@(#)Package rasj.odmg, class RasCollection: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/odmg/RasCollection.java,v 1.5 2003/12/19 15:42:56 rasdev Exp $";
+
+ public RasCollection()
+ {
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DCollection query(String predicate)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public Iterator select(String predicate)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public boolean existsElement(String predicate)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public Object selectElement(String predicate)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public int size()
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public Iterator iterator()
+ {
+ throw new NotImplementedException();
+ }
+
+}
+
+
+
diff --git a/java/rasj/odmg/RasDatabase.class b/java/rasj/odmg/RasDatabase.class
new file mode 100644
index 0000000..287b753
--- /dev/null
+++ b/java/rasj/odmg/RasDatabase.class
Binary files differ
diff --git a/java/rasj/odmg/RasDatabase.java b/java/rasj/odmg/RasDatabase.java
new file mode 100644
index 0000000..d494b37
--- /dev/null
+++ b/java/rasj/odmg/RasDatabase.java
@@ -0,0 +1,133 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+package rasj.odmg;
+
+import org.odmg.*;
+import rasj.global.*;
+import rasj.*;
+
+/**
+ * This class implements the ODMG Database interface.
+ *
+ * @version 1.0 (07-Apr-2000)
+ *
+ * @author Peter Zoller
+ */
+public class RasDatabase implements Database
+{
+ /**
+ * This variable holds a reference to the RasODMGImplementation object which created
+ * this RasDatabase object
+ */
+ //private RasODMGImplementation rasImplementation=null;
+ private RasImplementationInterface rasImplementation=null;
+
+ public RasDatabase(RasImplementationInterface imp)
+ {
+ Debug.enterVerbose( "RasDatabase.constructor start." );
+ rasImplementation=imp;
+ Debug.leaveVerbose( "RasDatabase.constructor done." );
+ }
+
+ /**
+ * Opens a database on the RasDaMan server ( which has been specified when the
+ * RasODMG bootstrap object has been initialized).
+ *
+ * @param name Name of the database
+ * @param accessMode access mode. Available options: OPEN_READ_ONLY, OPEN_READ_WRITE, OPEN_EXCLUSIVE
+ */
+ public void open(String name, int accessMode) throws ODMGException
+ {
+ Debug.enterVerbose( "RasDatabase.open start. name=" + name + ", accessmode=" + accessMode + "." );
+ rasImplementation.openDB(name,accessMode);
+ Debug.leaveVerbose( "RasDatabase.open done." );
+ }
+
+ /**
+ * Closes an open database. At the moment, only one database can be open at
+ * a given time and thus no parameter "database" is necessary here.
+ */
+ public void close() throws ODMGException
+ {
+ Debug.enterVerbose( "RasDatabase.close start." );
+ rasImplementation.closeDB();
+ Debug.leaveVerbose( "RasDatabase.close done." );
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void bind(Object object, String name) throws ObjectNameNotUniqueException
+ {
+ Debug.talkCritical( "RasDatabase.bind: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public Object lookup(String name) throws ObjectNameNotFoundException
+ {
+ Debug.talkCritical( "RasDatabase.lookup: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void unbind(String name) throws ObjectNameNotFoundException
+ {
+ Debug.talkCritical( "RasDatabase.unbind: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void makePersistent(Object object)
+ {
+ Debug.talkCritical( "RasDatabase.makePersistent: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void deletePersistent(Object object)
+ {
+ Debug.talkCritical( "RasDatabase.deletePersistent: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+}
+
diff --git a/java/rasj/odmg/RasList.class b/java/rasj/odmg/RasList.class
new file mode 100644
index 0000000..e43cbba
--- /dev/null
+++ b/java/rasj/odmg/RasList.class
Binary files differ
diff --git a/java/rasj/odmg/RasList.java b/java/rasj/odmg/RasList.java
new file mode 100644
index 0000000..210daf0
--- /dev/null
+++ b/java/rasj/odmg/RasList.java
@@ -0,0 +1,183 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+
+package rasj.odmg;
+
+import org.odmg.*;
+import java.util.*;
+
+/**
+ * This class implements the ODMG DList interface.
+ * @version $Revision: 1.3 $
+ */
+public class RasList extends RasCollection implements DList
+
+{
+ static final String rcsid = "@(#)Package rasj.odmg, class RasList: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/odmg/RasList.java,v 1.3 2003/12/19 15:42:56 rasdev Exp $";
+
+ List content;
+
+ /**
+ * constructor
+ */
+ public RasList()
+ {
+ content = new ArrayList();
+ }
+
+ /**
+ * Creates a new DList object that contains the contents of this DList object concatenated with the contents of the otherList object.
+ */
+ public DList concat(DList otherList)
+ {
+ for(int i=0; i<otherList.size(); i++)
+ {
+ content.add(otherList.get(i));
+ }
+ return this;
+ }
+
+ /**
+ * Returns a view of the portion of this list between fromIndex, inclusive, and toIndex, exclusive.
+ */
+ public List subList(int fromIndex, int toIndex)
+ {
+ List l = new RasList();
+ for(int j=fromIndex; j<toIndex; j++)
+ {
+ l.add(content.get(j));
+ }
+ return l;
+ }
+
+ /**
+ * Returns a list iterator of the elements in this list (in proper sequence).
+ */
+ public ListIterator listIterator()
+ {
+ return content.listIterator();
+ }
+
+ /**
+ * Returns an iterator over the elements in this list in proper sequence.
+ */
+ public Iterator iterator()
+ {
+ return content.iterator();
+ }
+
+
+ /**
+ * Returns a list iterator of the elements in this list (in proper sequence), starting at the specified position in the list.
+ */
+ public ListIterator listIterator(int index)
+ {
+ return content.listIterator(index);
+ }
+
+ /**
+ * Returns the index in this list of the last occurence of the specified element, or -1 if the list does not contain this element.
+ */
+ public int lastIndexOf(Object o)
+ {
+ return content.lastIndexOf(o);
+ }
+
+
+ /**
+ * Returns the index in this list of the first occurence of the specified element, or -1 if the list does not contain this element.
+ */
+ public int indexOf(Object o)
+ {
+ return content.indexOf(o);
+ }
+
+ /**
+ * Removes the element at the specified position in this list.
+ */
+ public Object remove(int index)
+ {
+ return content.remove(index);
+ }
+
+ /**
+ * Appends the specified element to the end of this List.
+ */
+ public boolean add(Object o)
+ {
+ return content.add(o);
+ }
+
+ /**
+ * Inserts the specified element at the specified position in this list.
+ */
+ public void add(int index, Object element)
+ {
+ content.add(index, element);
+ }
+
+ /**
+ * Replaces the element at the specified position in this list with the specified element.
+ */
+ public Object set(int index, Object element)
+ {
+ return content.set(index, element);
+ }
+
+ /**
+ * Returns the element at the specified position in this list.
+ */
+ public Object get(int index)
+ {
+ return content.get(index);
+ }
+
+ /**
+ * Inserts all of the elements in the specified collection into this list at the specified position.
+ */
+ public boolean addAll(int index, Collection c)
+ {
+ return content.addAll(index, c);
+ }
+
+ /**
+ * Returns the number of elements in this List.
+ */
+ public int size()
+ {
+ return content.size();
+ }
+
+}
+
diff --git a/java/rasj/odmg/RasODMGGlobal.class b/java/rasj/odmg/RasODMGGlobal.class
new file mode 100644
index 0000000..7ddf33e
--- /dev/null
+++ b/java/rasj/odmg/RasODMGGlobal.class
Binary files differ
diff --git a/java/rasj/odmg/RasODMGGlobal.java b/java/rasj/odmg/RasODMGGlobal.java
new file mode 100644
index 0000000..431cefc
--- /dev/null
+++ b/java/rasj/odmg/RasODMGGlobal.java
@@ -0,0 +1,60 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE: Stores Global information for the RasODMGInterface
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+package rasj.odmg;
+
+/**
+ * This class provides some global defines and variables needed for the
+ * ODMG implementation of the RasDaMan httpserver. This information is
+ * only used for internal purposes and not visible to the user of the
+ * ODMG interface.
+ *
+ * @version 1.0 (07-Apr-2000)
+ *
+ * @author Peter Zoller
+ */
+public abstract class RasODMGGlobal
+{
+ // client requests allowed
+ public static final int commOpenDB = 1;
+ public static final int commCloseDB = 2;
+ public static final int commBTreadOnly = 3;
+ public static final int commBTreadWrite = 4;
+ public static final int commCT = 5;
+ public static final int commAT = 6;
+ public static final int commIsOpenTA = 7;
+ public static final int commQueryExec = 8;
+ public static final int commUpdateQueryExec = 9;
+ public static final int commGetNewOID = 10;
+}
+
+
diff --git a/java/rasj/odmg/RasODMGImplementation.class b/java/rasj/odmg/RasODMGImplementation.class
new file mode 100644
index 0000000..f8b6fa5
--- /dev/null
+++ b/java/rasj/odmg/RasODMGImplementation.class
Binary files differ
diff --git a/java/rasj/odmg/RasODMGImplementation.java b/java/rasj/odmg/RasODMGImplementation.java
new file mode 100644
index 0000000..cc6a569
--- /dev/null
+++ b/java/rasj/odmg/RasODMGImplementation.java
@@ -0,0 +1,1366 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE: ODMG Implementation Bootstrap Object
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+package rasj.odmg;
+
+import rasj.*;
+import rasj.global.*;
+import rasj.clientcommhttp.*;
+import org.odmg.*;
+
+import java.io.*;
+import java.net.*;
+import java.lang.*;
+import java.util.*;
+
+
+/**
+ * This class implements the internal ODMG Bootstrap Object used by the rasj.odmg package.
+ * Because it contains a lot of functionality for internal purposes (e.g. methods for
+ * the RasManager), this class is not the official Implementation object the user works
+ * with, it is only used by the rasj.odmg package.
+ * <P>
+ * The public Implementation object is the class
+ * {@link rasj.RasImplementation rasj.RasImplementation}, which internally works with a
+ * RasODMGImplementation object.
+ *
+ * @see rasj.RasImplementation
+ */
+
+public class RasODMGImplementation implements RasImplementationInterface,RasCommDefs//implements Implementation
+ {
+
+ private String rasServer = "";
+ private String rasMgr = "";
+ private int rasMgrPort= RasGlobalDefs.RASMGRPORT_DEFAULT;
+ private String userIdentification = RasGlobalDefs.GUESTIDENT_DEFAULT;
+ private String databaseName = "";
+ private String capability = "dummy";
+ private int maxRetry = RasGlobalDefs.MAX_GETFREESERVER_ATTEMPTS;
+
+ /**
+ * current state of transaction
+ **/
+ private boolean isOpenTA = false;
+
+ /**
+ /**
+ * This variable holds the current RasTransaction object.
+ */
+ private RasTransaction transaction = null;
+
+ /**
+ * This variable holds the current Rasdatabase object.
+ */
+ private RasDatabase database = null;
+
+ /**
+ * This variable holds the current RasOQLQuery object.
+ */
+ private RasOQLQuery query = null;
+
+ /**
+ * The standard ODMG implementation sets the access mode when the database
+ * is opened, whereas the RasDaMan server expects this information when a
+ * transaction is started. Therefore it is saved in this variable.
+ *
+ * Available modes:
+ * OPEN_READ_ONLY = 1
+ * OPEN_READ_WRITE = 2
+ * OPEN_EXCLUSIVE = 3
+ */
+ private int accessMode = 0;
+
+ /**
+ * Since ODMG does not specify a "isDatabaseOpen" method but provides a
+ * DatabaseClosedException, this variable is set to 1 if an openDB command is
+ * executed (closeDB sets it back to 0).
+ */
+ private int dbIsOpen = 0;
+
+ /**
+ * This value is set to 1 if a transaction has been opened. Commiting or aborting
+ * a transaction sets it back to 0.
+ */
+ private int taIsOpen = 0;
+
+ private int clientID = 0;
+
+ /**
+ * This value is used to store possible error messages of exceptions occuring
+ * when opening or closing transactions.
+ * The ODMG specification does not allow these operations to throw
+ * any exceptions, but our implementation could produce exceptions when connecting
+ * to the RasDaMan httpserver. In order to not get lost, these exception messages
+ * are stored in this variable.
+ */
+ private String errorStatus = "";
+ // later: private String strUserAndPasswd = "anonymous:anonymouspasswd";
+
+ /**
+ * Standard constructor.
+ * @param server Complete URL of the RasDaMan httpserver (including port number)
+ */
+ public RasODMGImplementation(String server)
+ {
+ Debug.enterVerbose( "RasODMGImplementation.constructor: start, server=" + server + "." );
+ try
+ {
+ // server address is http://server:port, we need server and port
+ StringTokenizer t=new StringTokenizer (server,"/");
+ String xxx=t.nextToken();
+ rasMgr =t.nextToken("/:");
+ String portStr = t.nextToken(":");
+ rasMgrPort = Integer.parseInt(portStr);
+ }
+ catch(NoSuchElementException e)
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.constructor: done. server URL format error." );
+ throw new RasConnectionFailedException(RasGlobalDefs.URL_FORMAT_ERROR, server);
+ }
+
+ isOpenTA = false;
+
+ Debug.leaveVerbose( "RasODMGImplementation.constructor: done. ok." );
+ }
+
+ /**
+ * Gets the name of the actual server.
+ * @return the name of the RasDaMan server used
+ */
+ public String getRasServer()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getRasServer: server=" + rasServer + "." );
+ return rasServer;
+ }
+
+ /**
+ * Tells whether database is open.
+ * @return open status of database
+ */
+ public int dbIsOpen()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.dbIsOpen: dbIsOpen=" + dbIsOpen + "." );
+ return dbIsOpen;
+ }
+
+ /**
+ * Gets the client ID
+ * @return ID of this client
+ */
+ public int getClientID()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getClientID: clientID=" + clientID + "." );
+ return clientID;
+ }
+
+ /**
+ * Gets the database access mode
+ * @return accessMode code: OPEN_READ_ONLY = 1; OPEN_READ_WRITE = 2; OPEN_EXCLUSIVE = 3
+ */
+ public int getAccessMode()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getAccessMode: accessMode=" + accessMode + "." );
+ return accessMode;
+ }
+
+ /**
+ * Gets the current error status
+ * @return error status string
+ */
+ public String getErrorStatus()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getErrorStatus: errorStatus=" + errorStatus + "." );
+ return errorStatus;
+ }
+
+
+ /**
+ * Create a new transaction object and associate it with the current thread.
+ */
+ public Transaction newTransaction()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.newTransaction: start." );
+ transaction= new RasTransaction(this);
+ Debug.leaveVerbose( "RasODMGImplementation.newTransaction: done." );
+ return transaction;
+ }
+
+ /**
+ * Get current transaction for thread, or NULL if none.
+ */
+ public Transaction currentTransaction()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.currentTransaction." );
+ return transaction;
+ }
+
+ /**
+ * Create a new database object.
+ */
+ public Database newDatabase()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.newDatabase: start." );
+ database = new RasDatabase(this);
+ Debug.leaveVerbose( "RasODMGImplementation.newDatabase: done." );
+ return database;
+ }
+
+ /**
+ * Create a new query object.
+ */
+ public OQLQuery newOQLQuery()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.newOQLQuery: start." );
+ query = new RasOQLQuery(this);
+ Debug.leaveVerbose( "RasODMGImplementation.newOQLQuery: done." );
+ return query;
+ }
+
+ /**
+ * Create a new DList object.
+ */
+ public DList newDList()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.newDList." );
+ return new RasList();
+ }
+
+ /**
+ * Create a new DBag object.
+ */
+ public DBag newDBag()
+ {
+ return new RasBag();
+ }
+
+ /**
+ * Create a new DSet object.
+ */
+ public DSet newDSet()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.newDSet." );
+ return new RasSet();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DArray newDArray()
+ {
+ Debug.talkWarning( "RasODMGImplementation.newDArray: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DMap newDMap()
+ {
+ Debug.talkWarning( "RasODMGImplementation.newDMap: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Get a String representation of the object's identifier.
+ * @returns: OID string on success, null otherwise
+ */
+ public String getObjectId(Object obj)
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getObjectId: start." );
+
+ if( ! (obj instanceof RasObject) ) // currently all must be derived from RasObject
+ {
+ Debug.leaveWarning( "RasODMGImplementation.getObjectId: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ // if we come here: yes, we are derived from RasObject, let's proceed
+ RasOID roid = ((RasObject)obj).getOID();
+ String oid = roid.toString();
+ DBag resultBag = null;
+ if(!((RasObject)obj).getOID().isValid()) // OID of our object is not valid -> get one
+ {
+ Debug.talkWarning( "RasODMGImplementation.getObjectId: OID not Valid: " + roid + "." );
+ String params = "ClientID=" + clientID + "&Command=10";
+ RasHttpRequest request = new RasHttpRequest();
+ if(((RasTransaction)this.currentTransaction()).isOpenLocally()) // TA is open, we can proceed
+ // (decide w/o asking server -- PB 2003-jun-25)
+ {
+ // get new oid
+ try
+ {
+ request.execute(rasServer,params); // get it from server
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkCritical( "RasODMGImplementation.getObjectId: query execution failed: " + e.getMessage() );
+ }
+ }
+ else // TA is not open, so we do an open here
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: db not open, opening: " + databaseName + "." );
+ boolean openedDbHere = false; // did we open a db locally?
+ boolean openedTaHere = false; // did we open a db locally?
+ Database d = null;
+ Transaction t = null;
+ try
+ {
+ if(this.dbIsOpen == Database.NOT_OPEN) // we even open the db if not done already
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: db not open, opening: " + databaseName + "." );
+ d = this.newDatabase();
+ d.open( databaseName, Database.OPEN_READ_WRITE);
+ // fix: was: "RASBASE"; now: take name of last opened db. not good, but better maybe -- PB 2003-jun-13
+ // FIXME: r/w open not good, do we have info at this point? Maybe getOid needs r/w
+ openedDbHere = true;
+ }
+ t = this.newTransaction();
+ t.begin();
+ openedTaHere = true; // we know now we have an open TA
+ // get new oid
+ request.execute(rasServer,params); // get it from server
+ t.commit();
+ if(openedDbHere)
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: closing locally opened DB. " );
+ d.close();
+ openedDbHere = false; // no more locally opened DB to close
+ }
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getObjectId: failed: " + e.getMessage() );
+ try
+ {
+ if (openedTaHere)
+ t.abort();
+ if(openedDbHere)
+ d.close();
+ }
+ catch (ODMGException e3)
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: error closing locally opened DB (ignored): " + e3.getMessage() );
+ }
+ }
+ } // if (TA open)
+
+ resultBag = (DBag)request.getResult(); // if all went fine we now have OID in result
+ if(resultBag != null)
+ {
+ Iterator iter = resultBag.iterator();
+ if(iter.hasNext())
+ roid = (RasOID)iter.next();
+ oid = roid.toString();
+ ((RasObject)obj).setOID(roid);
+ }
+ else
+ {
+ Debug.talkCritical( "RasODMGImplementation.getObjectId: empty query result, cannot fetch OID." );
+ oid = null;
+ }
+ } // valid OID
+
+ Debug.leaveVerbose( "RasODMGImplementation.getObjectId: done. oid=" + oid + "." );
+ return oid;
+ } // getObjectId()
+
+ /**
+ * Not implemented yet.
+ */
+ public Database getDatabase(Object obj)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getDatabase: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Open database
+ */
+ public void openDB(String name, int accessMode) throws ODMGException, ODMGRuntimeException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.openDB: start, db=" + name + ", accessMode=" + accessMode );
+
+ databaseName = name;
+ this.accessMode = accessMode;
+
+ try
+ {
+ getFreeServer(); // sets rasServer
+ executeOpenDB(databaseName,accessMode);
+ // executeCloseDB(); // does nothing, so clean away -- PB 2003-jun-25
+ dbIsOpen = 1;
+ }
+ catch (ODMGException e) // catch just for logging, then rethrow immediately
+ {
+ Debug.leaveCritical( "RasODMGImplementation.openDB: done. Exception: " + e.getMessage() );
+ throw new ODMGException( e.getMessage() );
+ }
+ catch (ODMGRuntimeException x) // catch just for logging, then rethrow immediately
+ {
+ Debug.leaveCritical( "RasODMGImplementation.openDB: done. ODMGRuntimeException: " + x.getMessage() );
+ throw new ODMGException( x.getMessage() );
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.openDB: done. OK." );
+ }
+
+ private void executeOpenDB(String name, int accessMode) throws ODMGException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.executeOpenDB: start, name=" + name + ", accessMode=" + accessMode );
+ String params = "Command=" + RasODMGGlobal.commOpenDB + "&Database=" + name + "&Capability=" + capability;
+ RasHttpRequest request = new RasHttpRequest();
+ request.execute(rasServer,params);
+ // Later, the client ID is determined here
+ clientID = 1; // not used anymore
+ Debug.leaveVerbose( "RasODMGImplementation.executeOpenDB: done." );
+ }
+
+ /**
+ * Closes an open database. At the moment, only one database can be open at
+ * a given time and thus no parameter "database" is necessary here.
+ */
+ public void closeDB() throws ODMGException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.closeDB start." );
+
+ // not necessary, others do close already
+ // PB: this is due to an old bug in O2 which needed a closeDB in order to free objects, hence we do this in commitTA/abortTA
+
+ dbIsOpen = 0;
+ Debug.leaveVerbose( "RasODMGImplementation.closeDB done." );
+ }
+
+ private void executeCloseDB() throws ODMGException
+ {
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commCloseDB;
+ RasHttpRequest request = new RasHttpRequest();
+ request.execute(rasServer,params);
+ }
+
+ /**
+ * Begin a transaction.
+ */
+ public void beginTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.beginTA start." );
+
+ // exception handling deactivated, as not thrown any longer -- PB 2004-jul-03
+ // try
+ // {
+ // this hurts in several ways, so deactivated it: -- PB 2004-jul-03
+ // - "getFreeServer();executeOpenDB();" done in openDB(). ODMG says: to begin a TA DB must be open
+ // - this sucks up an additional server process for clean clients doing "openDB();beginTA()"
+ // getFreeServer();
+ // executeOpenDB(databaseName,accessMode);
+ executeBeginTA();
+ // }
+ // catch(ODMGException e)
+ // {
+ // Debug.talkWarning( "RasODMGImplementation.beginTA: " + e.getMessage() );
+ // errorStatus = e.getMessage();
+ // }
+ Debug.leaveVerbose( "RasODMGImplementation.beginTA done." );
+ }
+
+ private void executeBeginTA()
+ {
+ String errorMsg = "Could not open transaction: ";
+ if(dbIsOpen == 0)
+ throw new DatabaseClosedException(errorMsg + "database not open");
+
+ String params = "ClientID=" + clientID + "&Command=";
+ // Is the database opened READ_ONLY or READ_WRITE ?
+ if(accessMode == Database.OPEN_READ_ONLY)
+ params = params + RasODMGGlobal.commBTreadOnly;
+ else
+ params = params + RasODMGGlobal.commBTreadWrite;
+ params = params + "&Capability=" + capability;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.executeBeginTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ }
+
+ /**
+ * Returns TRUE if a transaction is currently open.
+ * This method MUST be sincere in that it asks the server about its state! (some apps use it to override timeout)
+ */
+ public boolean isOpenTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.isOpenTA start." );
+ boolean result = false;
+
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commIsOpenTA;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);
+ result= (request.getResultType() == 99) ? true : false;
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.isOpenTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ result = false;
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.isOpenTA done. result=" + result );
+ return result;
+ }
+
+ /**
+ * Commit a transaction.
+ */
+ public void commitTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.commitTA start." );
+
+ try
+ {
+ executeCommitTA();
+ executeCloseDB(); // FIXME: why close here??? -- PB 2003-jun-13
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkWarning( "RasODMGImplementation.commitTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.commitTA done." );
+ }
+
+ private void executeCommitTA()
+ {
+ String errorMsg = "Could not commit transaction: ";
+ if(dbIsOpen == 0)
+ throw new DatabaseClosedException(errorMsg + "database not open");
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commCT;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);//RasODMGGlobal.getRasServer(),params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.executeCommitTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ }
+
+ /**
+ * Abort a transaction.
+ */
+ public void abortTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.abortTA start." );
+
+ try
+ {
+ executeAbortTA();
+ executeCloseDB();
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkWarning( "RasODMGImplementation.abortTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.abortTA done." );
+ }
+
+ private void executeAbortTA()
+ {
+ String errorMsg = "Cannot abort transaction: ";
+ if(dbIsOpen == 0)
+ throw new DatabaseClosedException(errorMsg + "database not open");
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commAT;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.executeAbortTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ }
+
+ /**
+ * Set the maximum retry parameter
+ */
+ public void setMaxRetry(int newRetry)
+ {
+ Debug.talkVerbose( "RasODMGImplementation.setMaxRetry to " + newRetry + "." );
+ maxRetry = newRetry;
+ }
+
+ /**
+ * Get the maximum retry parameter
+ */
+ public int getMaxRetry()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getMaxRetry: maxRetry=" + maxRetry + "." );
+ return maxRetry;
+ }
+
+ /**
+ * Requests a free server and retry's
+ */
+ //private void getFreeServer( )
+ public void getFreeServer( )
+ throws RasQueryExecutionFailedException, RasConnectionFailedException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getFreeServer: start." );
+
+ String uniqueID = uniqueRequestID();
+
+ int millisec = RasGlobalDefs.GETFREESERVER_WAIT_INITIAL;
+ for (int retryCount = 1; retryCount <= maxRetry; retryCount++)
+ {
+ try
+ {
+ executeGetFreeServer(uniqueID);
+ // if no error, we have the server, so break
+ break;
+ }
+ catch(RasConnectionFailedException e)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getFreeServer: cannot obtain a free server:" + e.getMessage() );
+ // the following errors justify that we try again, maybe we get a free server a little later
+ int errno = e.getErrorNo();
+ if (errno==RasGlobalDefs.MANAGER_BUSY
+ /* || errno==RasGlobalDefs.NO_ACTIVE_SERVERS */ // if no such server is started, waiting won't help
+ || errno==RasGlobalDefs.WRITE_TRANS_IN_PROGRESS)
+ {
+ // retry, but with increasing wait period
+ millisec = millisec * RasGlobalDefs.GETFREESERVER_WAIT_INCREMENT;
+
+ Debug.talkCritical( "RasODMGImplementation.getFreeServer: no free server available, errno=" + errno + ", retry #" + retryCount + " of " + maxRetry + " after " + millisec + " msecs." );
+ try
+ {
+ Thread.sleep(millisec);
+ }
+ catch(InterruptedException intex)
+ { // wake up
+ }
+ }
+ else
+ {
+ Debug.talkCritical( "RasODMGImplementation.getFreeServer: giving up, cannot obtain free server. marking connection as closed." );
+ Debug.leaveVerbose( "RasODMGImplementation.getFreeServer: done." );
+
+ // reset ta & db
+ isOpenTA = false;
+ dbIsOpen = 0;
+ throw(e); // we give up, or we shouldn't retry with this kind of error
+ }
+ }
+ } // for
+
+ Debug.leaveVerbose( "RasODMGImplementation.getFreeServer: done." );
+ }
+
+ /**
+ * Requests a free server from rasmgr
+ */
+
+ private void executeGetFreeServer( String uniqueID ) throws RasQueryExecutionFailedException, RasConnectionFailedException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.executeGetFreeServer: enter, uniqueID=" + uniqueID );
+
+ try
+ {
+ Socket soclu = new Socket(rasMgr,rasMgrPort); // FIXME: where is this socket closed ??? PB
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: socket=" + soclu );
+ PrintStream ps = new PrintStream(soclu.getOutputStream());
+ String body = databaseName + " HTTP " + (accessMode == Database.OPEN_READ_ONLY ? "ro":"rw") + " " + uniqueID + " \0";
+ ps.print("POST getfreeserver HTTP/1.1\r\nAccept: text/plain\r\nContent-type: text/plain\r\n"
+ + "User-Agent: RasDaMan Java Client1.0\r\nAuthorization: ras " + userIdentification
+ + "\r\nContent length: " + body.length()+"\r\n\r\n" + body);
+ ps.flush();
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: sent body=" + body );
+
+ BufferedReader ds = new BufferedReader(new InputStreamReader(soclu.getInputStream()));
+ int resultCode = getResultCode(ds);
+ String bodyLine = getBodyLine(ds);
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: received result code=" + resultCode + ", bodyLine=" + bodyLine );
+
+ ps.close();
+ ds.close();
+ soclu.close(); // this one was missing all the time -- PB
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: socket closed: " + soclu );
+
+ if(resultCode==200)
+ {
+ StringTokenizer t=new StringTokenizer(bodyLine," ");
+ String host=t.nextToken();
+ String port=t.nextToken(" ");
+ capability=t.nextToken(" \t\r\n\0");
+ rasServer="http://" + host + ":" + port;
+ }
+ else
+ {
+ // if error =>bodyLine: errorCode someText
+ Debug.talkSparse( "RasODMGImplementation.executeGetFreeServer: bodyLine=" + bodyLine);
+ StringTokenizer t=new StringTokenizer(bodyLine," ");
+ String errorStr = t.nextToken();
+ int errorCode = Integer.parseInt(errorStr);
+ if( resultCode < 1000 )
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done. connection failed, code=" + errorCode );
+ throw new RasConnectionFailedException(errorCode,null);
+ }
+ else
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done. request format error, code=" + errorCode );
+ throw new RasConnectionFailedException(RasGlobalDefs.REQUEST_FORMAT_ERROR," code=" + errorCode);
+ }
+ }
+ }
+ catch( MalformedURLException e )
+ {
+ Debug.talkCritical( "RasODMGImplementation.executeGetFreeServer: malformed URL exception: " + e.getMessage() );
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done with exception: " + e.getMessage() );
+ throw new RasConnectionFailedException(RasGlobalDefs.MANAGER_CONN_FAILED,rasMgr);
+ }
+ catch( IOException e )
+ {
+ Debug.talkCritical( "RasODMGImplementation.executeGetFreeServer: IO exception: " + e.getMessage() );
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done with exception: " + e.getMessage() );
+ throw new RasClientInternalException( "RasODMGImplementation","executeGetFreeServer()", e.getMessage() );
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done." );
+ } // executeGetFreeServer()
+
+ public Object queryRequest(String parameters) throws RasQueryExecutionFailedException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.queryRequest start. parameters=" + parameters + "." );
+
+ BenchmarkTimer qTimer = new BenchmarkTimer("queryRequest");
+ qTimer.startTimer();
+
+ RasHttpRequest request= new RasHttpRequest();
+ request.execute(rasServer,parameters);
+
+ qTimer.stopTimer();
+ qTimer.print();
+
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer done." );
+ return request.getResult();
+ }
+
+
+ //private int getResultCode(BufferedReader ds) throws IOException
+ public int getResultCode(BufferedReader ds) throws IOException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getResultCode start." );
+
+ String s = ds.readLine();
+ StringTokenizer t = new StringTokenizer(s," ");
+ String http = t.nextToken();
+ String resultString = t.nextToken(" ");
+ int result = Integer.parseInt(resultString);
+
+ Debug.leaveVerbose( "RasODMGImplementation.getResultCode done. result=" + result + "." );
+ return result;
+ }
+
+ //private String getBodyLine(BufferedReader ds) throws IOException
+ public String getBodyLine(BufferedReader ds) throws IOException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getBodyLine start." );
+
+ String s;
+ do // was a "for(;;)" loop, cleaned it -- PB 2003-jun-13
+ {
+ s = ds.readLine();
+ if(s==null)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getBodyLine: Unexpected EOF in rasmgr answer." );
+ throw new IOException("Unexpected EOF in rasmgr answer.");
+ }
+ }
+ while (s.length() != 0);
+
+ String result = ds.readLine();
+ Debug.leaveVerbose( "RasODMGImplementation.getBodyLine done. result=" + result + "." );
+ return result;
+ }
+
+ public void setUserIdentification(String userName, String plainPass)
+ {
+ Debug.enterVerbose( "RasODMGImplementation.setUserIdentification start." );
+
+ MD5 md5 = new MD5();
+ String hex;
+ md5.Init();
+ md5.Update(plainPass);
+ hex = md5.asHex();
+ userIdentification= userName + ":" + hex;
+
+ Debug.leaveVerbose( "RasODMGImplementation.setUserIdentification done." );
+ }
+
+ private String strHostID = null;
+ static private int idcounter = 0;
+
+ private String uniqueRequestID()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.uniqueRequestID start." );
+
+ if(strHostID == null)
+ {
+ long hostid = 0;
+ try
+ {
+ InetAddress addr = InetAddress.getLocalHost();
+ // Get IP Address
+ byte[] ipAddr = addr.getAddress();
+
+ for(int i=0;i<ipAddr.length; i++)
+ {
+ int ss = (int)ipAddr[i];
+ if(ss<0)
+ ss = 256 + ss;
+ hostid = hostid * 256 + ss;
+ }
+ }
+ catch (UnknownHostException e)
+ {
+ Random random = new Random();
+ hostid = random.nextInt();
+ }
+ idcounter = (idcounter + 1) & 0xF;
+ // it's unique enough, we don't need such a huge number
+ strHostID = "" + hostid + ':' + (System.currentTimeMillis() & 0xFFFFFFF0) + idcounter;
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.uniqueRequestID done. strHostID=" + strHostID + "." );
+ return strHostID;
+ }
+
+}
+
+//##################################################################################
+/**
+ * Contains internal state of the MD5 class
+ */
+
+class MD5State
+ {
+ /**
+ * 128-byte state
+ */
+ int state[];
+
+ /**
+ * 64-bit character count (could be true Java long?)
+ */
+ int count[];
+
+ /**
+ * 64-byte buffer (512 bits) for storing to-be-hashed characters
+ */
+ byte buffer[];
+
+ public MD5State()
+ {
+ Debug.enterVerbose( "MD5State.constructor start." );
+
+ buffer = new byte[64];
+ count = new int[2];
+ state = new int[4];
+
+ state[0] = 0x67452301;
+ state[1] = 0xefcdab89;
+ state[2] = 0x98badcfe;
+ state[3] = 0x10325476;
+
+ count[0] = count[1] = 0;
+
+ Debug.leaveVerbose( "MD5State.constructor done." );
+ }
+
+ /**
+ Create this State as a copy of another state
+ **/
+ public MD5State (MD5State from)
+ {
+ this();
+
+ Debug.enterVerbose( "MD5State.cloner start." );
+
+ int i;
+
+ for (i = 0; i < buffer.length; i++)
+ this.buffer[i] = from.buffer[i];
+
+ for (i = 0; i < state.length; i++)
+ this.state[i] = from.state[i];
+
+ for (i = 0; i < count.length; i++)
+ this.count[i] = from.count[i];
+
+ Debug.leaveVerbose( "MD5State.cloner done." );
+ }
+
+ }; // MD5State
+
+/**
+ * Implementation of RSA's MD5 hash generator
+ *
+ * @version $Revision: 1.25 $
+ * @author Santeri Paavolainen <sjpaavol@cc.helsinki.fi>
+ */
+
+class MD5
+{
+ /**
+ * MD5 state
+ */
+ MD5State state;
+
+ /**
+ * If Final() has been called, finals is set to the current finals
+ * state. Any Update() causes this to be set to null.
+ */
+ MD5State finals;
+
+ /**
+ * Padding for Final()
+ */
+ static byte padding[] = {
+ (byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ /**
+ * Initialize MD5 internal state (object can be reused just by
+ * calling Init() after every Final()
+ */
+ public synchronized void Init () {
+ state = new MD5State();
+ finals = null;
+ }
+
+ /**
+ * Class constructor
+ */
+ public MD5 () {
+ this.Init();
+ }
+
+ /**
+ * Initialize class, and update hash with ob.toString()
+ *
+ * @param ob Object, ob.toString() is used to update hash
+ * after initialization
+ */
+ public MD5 (Object ob) {
+ this();
+ Update(ob.toString());
+ }
+
+ private int rotate_left (int x, int n) {
+ return (x << n) | (x >>> (32 - n));
+ }
+
+ /* I wonder how many loops and hoops you'll have to go through to
+ get unsigned add for longs in java */
+
+ private int uadd (int a, int b) {
+ long aa, bb;
+ aa = ((long) a) & 0xffffffffL;
+ bb = ((long) b) & 0xffffffffL;
+
+ aa += bb;
+
+ return (int) (aa & 0xffffffffL);
+ }
+
+ private int uadd (int a, int b, int c) {
+ return uadd(uadd(a, b), c);
+ }
+
+ private int uadd (int a, int b, int c, int d) {
+ return uadd(uadd(a, b, c), d);
+ }
+
+ private int FF (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, ((b & c) | (~b & d)), x, ac);
+ return uadd(rotate_left(a, s), b);
+ }
+
+ private int GG (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, ((b & d) | (c & ~d)), x, ac);
+ return uadd(rotate_left(a, s), b);
+ }
+
+ private int HH (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, (b ^ c ^ d), x, ac);
+ return uadd(rotate_left(a, s) , b);
+ }
+
+ private int II (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, (c ^ (b | ~d)), x, ac);
+ return uadd(rotate_left(a, s), b);
+ }
+
+ private int[] Decode (byte buffer[], int len, int shift) {
+ int out[];
+ int i, j;
+
+ out = new int[16];
+
+ for (i = j = 0; j < len; i++, j += 4) {
+ out[i] = ((int) (buffer[j + shift] & 0xff)) |
+ (((int) (buffer[j + 1 + shift] & 0xff)) << 8) |
+ (((int) (buffer[j + 2 + shift] & 0xff)) << 16) |
+ (((int) (buffer[j + 3 + shift] & 0xff)) << 24);
+
+/* System.out.println("out[" + i + "] = \t" +
+ ((int) buffer[j + 0 + shift] & 0xff) + "\t|\t" +
+ ((int) buffer[j + 1 + shift] & 0xff) + "\t|\t" +
+ ((int) buffer[j + 2 + shift] & 0xff) + "\t|\t" +
+ ((int) buffer[j + 3 + shift] & 0xff));*/
+ }
+
+ return out;
+ }
+
+ private void Transform (MD5State state, byte buffer[], int shift) {
+ int
+ a = state.state[0],
+ b = state.state[1],
+ c = state.state[2],
+ d = state.state[3],
+ x[];
+
+ x = Decode(buffer, 64, shift);
+
+ /* Round 1 */
+ a = FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
+ d = FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
+ c = FF (c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
+ b = FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
+ a = FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
+ d = FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
+ c = FF (c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
+ b = FF (b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
+ a = FF (a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
+ d = FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
+ c = FF (c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
+ b = FF (b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
+ a = FF (a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
+ d = FF (d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
+ c = FF (c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
+ b = FF (b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ a = GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
+ d = GG (d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
+ c = GG (c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
+ b = GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
+ a = GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
+ d = GG (d, a, b, c, x[10], 9, 0x2441453); /* 22 */
+ c = GG (c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
+ b = GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
+ a = GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
+ d = GG (d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
+ c = GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
+ b = GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
+ a = GG (a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
+ d = GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
+ c = GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
+ b = GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ a = HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
+ d = HH (d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
+ c = HH (c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
+ b = HH (b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
+ a = HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
+ d = HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
+ c = HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
+ b = HH (b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
+ a = HH (a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
+ d = HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
+ c = HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
+ b = HH (b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
+ a = HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
+ d = HH (d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
+ c = HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
+ b = HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ a = II (a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
+ d = II (d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
+ c = II (c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
+ b = II (b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
+ a = II (a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
+ d = II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
+ c = II (c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
+ b = II (b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
+ a = II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
+ d = II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
+ c = II (c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
+ b = II (b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
+ a = II (a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
+ d = II (d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
+ c = II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
+ b = II (b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
+
+ state.state[0] += a;
+ state.state[1] += b;
+ state.state[2] += c;
+ state.state[3] += d;
+ }
+
+ /**
+ * Updates hash with the bytebuffer given (using at maximum length bytes from
+ * that buffer)
+ *
+ * @param state Which state is updated
+ * @param buffer Array of bytes to be hashed
+ * @param offset Offset to buffer array
+ * @param length Use at maximum `length' bytes (absolute
+ * maximum is buffer.length)
+ */
+ public void Update (MD5State stat, byte buffer[], int offset, int length) {
+ int index, partlen, i, start;
+
+/* System.out.print("Offset = " + offset + "\tLength = " + length + "\t");
+ System.out.print("Buffer = ");
+ for (i = 0; i < buffer.length; i++)
+ System.out.print((int) (buffer[i] & 0xff) + " ");
+ System.out.print("\n");*/
+
+ finals = null;
+
+ /* Length can be told to be shorter, but not inter */
+ if ((length - offset)> buffer.length)
+ length = buffer.length - offset;
+
+ /* compute number of bytes mod 64 */
+ index = (int) (stat.count[0] >>> 3) & 0x3f;
+
+ if ((stat.count[0] += (length << 3)) <
+ (length << 3))
+ stat.count[1]++;
+
+ stat.count[1] += length >>> 29;
+
+ partlen = 64 - index;
+
+ if (length >= partlen) {
+ for (i = 0; i < partlen; i++)
+ stat.buffer[i + index] = buffer[i + offset];
+
+ Transform(stat, stat.buffer, 0);
+
+ for (i = partlen; (i + 63) < length; i+= 64)
+ Transform(stat, buffer, i);
+
+ index = 0;
+ } else
+ i = 0;
+
+ /* buffer remaining input */
+ if (i < length) {
+ start = i;
+ for (; i < length; i++)
+ stat.buffer[index + i - start] = buffer[i + offset];
+ }
+ }
+
+ /*
+ * Update()s for other datatypes than byte[] also. Update(byte[], int)
+ * is only the main driver.
+ */
+
+ /**
+ * Plain update, updates this object
+ */
+
+ public void Update (byte buffer[], int offset, int length) {
+ Update(this.state, buffer, offset, length);
+ }
+
+ public void Update (byte buffer[], int length) {
+ Update(this.state, buffer, 0, length);
+ }
+
+ /**
+ * Updates hash with given array of bytes
+ *
+ * @param buffer Array of bytes to use for updating the hash
+ */
+ public void Update (byte buffer[]) {
+ Update(buffer, 0, buffer.length);
+ }
+
+ /**
+ * Updates hash with a single byte
+ *
+ * @param b Single byte to update the hash
+ */
+ public void Update (byte b) {
+ byte buffer[] = new byte[1];
+ buffer[0] = b;
+
+ Update(buffer, 1);
+ }
+
+ /**
+ * Update buffer with given string.
+ *
+ * @param s String to be update to hash (is used as
+ * s.getBytes())
+ */
+ public void Update (String s) {
+ byte chars[];
+
+ /* deprecated chars = new byte[s.length()];
+ s.getBytes(0, s.length(), chars, 0);
+ */
+ chars = s.getBytes();
+
+ Update(chars, chars.length);
+ }
+
+ /**
+ * Update buffer with a single integer (only & 0xff part is used,
+ * as a byte)
+ *
+ * @param i Integer value, which is then converted to
+ * byte as i & 0xff
+ */
+
+ public void Update (int i) {
+ Update((byte) (i & 0xff));
+ }
+
+ private byte[] Encode (int input[], int len) {
+ int i, j;
+ byte out[];
+
+ out = new byte[len];
+
+ for (i = j = 0; j < len; i++, j += 4) {
+ out[j] = (byte) (input[i] & 0xff);
+ out[j + 1] = (byte) ((input[i] >>> 8) & 0xff);
+ out[j + 2] = (byte) ((input[i] >>> 16) & 0xff);
+ out[j + 3] = (byte) ((input[i] >>> 24) & 0xff);
+ }
+
+ return out;
+ }
+
+ /**
+ * Returns array of bytes (16 bytes) representing hash as of the
+ * current state of this object. Note: getting a hash does not
+ * invalidate the hash object, it only creates a copy of the real
+ * state which is finalized.
+ *
+ * @return Array of 16 bytes, the hash of all updated bytes
+ */
+ public synchronized byte[] Final () {
+ byte bits[];
+ int index, padlen;
+ MD5State fin;
+
+ if (finals == null) {
+ fin = new MD5State(state);
+
+ bits = Encode(fin.count, 8);
+
+ index = (int) ((fin.count[0] >>> 3) & 0x3f);
+ padlen = (index < 56) ? (56 - index) : (120 - index);
+
+ Update(fin, padding, 0, padlen);
+ /**/
+ Update(fin, bits, 0, 8);
+
+ /* Update() sets finalds to null */
+ finals = fin;
+ }
+
+ return Encode(finals.state, 16);
+ }
+
+ /**
+ * Turns array of bytes into string representing each byte as
+ * unsigned hex number.
+ *
+ * @param hash Array of bytes to convert to hex-string
+ * @return Generated hex string
+ */
+ public static String asHex (byte hash[]) {
+ StringBuffer buf = new StringBuffer(hash.length * 2);
+ int i;
+
+ for (i = 0; i < hash.length; i++) {
+ if (((int) hash[i] & 0xff) < 0x10)
+ buf.append("0");
+
+ buf.append(Long.toString((int) hash[i] & 0xff, 16));
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Returns 32-character hex representation of this objects hash
+ *
+ * @return String of this object's hash
+ */
+ public String asHex () {
+ return asHex(this.Final());
+ }
+
+} // MD5
+
diff --git a/java/rasj/odmg/RasODMGImplementation.java.BEFORE_Connection b/java/rasj/odmg/RasODMGImplementation.java.BEFORE_Connection
new file mode 100644
index 0000000..4d7f76d
--- /dev/null
+++ b/java/rasj/odmg/RasODMGImplementation.java.BEFORE_Connection
@@ -0,0 +1,1344 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE: ODMG Implementation Bootstrap Object
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+package rasj.odmg;
+
+import rasj.*;
+import rasj.global.*;
+import rasj.clientcommhttp.*;
+import org.odmg.*;
+
+import java.io.*;
+import java.net.*;
+import java.lang.*;
+import java.util.*;
+
+
+/**
+ * This class implements the internal ODMG Bootstrap Object used by the rasj.odmg package.
+ * Because it contains a lot of functionality for internal purposes (e.g. methods for
+ * the RasManager), this class is not the official Implementation object the user works
+ * with, it is only used by the rasj.odmg package.
+ * <P>
+ * The public Implementation object is the class
+ * {@link rasj.RasImplementation rasj.RasImplementation}, which internally works with a
+ * RasODMGImplementation object.
+ *
+ * @see rasj.RasImplementation
+ */
+
+public class RasODMGImplementation implements RasImplementationInterface,RasCommDefs//implements Implementation
+ {
+
+ private String rasServer = "";
+ private String rasMgr = "";
+ private int rasMgrPort=7001;
+ private String userIdentification = "rasguest:8e70a429be359b6dace8b5b2500dedb0";
+ private String databaseName = "";
+ private String capability = "dummy";
+ private int maxRetry = RasGlobalDefs.MAX_GETFREESERVER_ATTEMPTS;
+
+ /**
+ * This variable holds the current RasTransaction object.
+ */
+ private RasTransaction transaction = null;
+
+ /**
+ * This variable holds the current Rasdatabase object.
+ */
+ private RasDatabase database = null;
+
+ /**
+ * This variable holds the current RasOQLQuery object.
+ */
+ private RasOQLQuery query = null;
+
+ /**
+ * The standard ODMG implementation sets the access mode when the database
+ * is opened, whereas the RasDaMan server expects this information when a
+ * transaction is started. Therefore it is saved in this variable.
+ *
+ * Available modes:
+ * OPEN_READ_ONLY = 1
+ * OPEN_READ_WRITE = 2
+ * OPEN_EXCLUSIVE = 3
+ */
+ private int accessMode = 0;
+
+ /**
+ * Since ODMG does not specify a "isDatabaseOpen" method but provides a
+ * DatabaseClosedException, this variable is set to 1 if an openDB command is
+ * executed (closeDB sets it back to 0).
+ */
+ private int dbIsOpen = 0;
+
+ /**
+ * This value is set to 1 if a transaction has been opened. Commiting or aborting
+ * a transaction sets it back to 0.
+ */
+ private int taIsOpen = 0;
+
+ private int clientID = 0;
+
+ /**
+ * This value is used to store possible error messages of exceptions occuring
+ * when opening or closing transactions.
+ * The ODMG specification does not allow these operations to throw
+ * any exceptions, but our implementation could produce exceptions when connecting
+ * to the RasDaMan httpserver. In order to not get lost, these exception messages
+ * are stored in this variable.
+ */
+ private String errorStatus = "";
+ // later: private String strUserAndPasswd = "anonymous:anonymouspasswd";
+
+ /**
+ * Standard constructor.
+ * @param server Complete URL of the RasDaMan httpserver (including port number)
+ */
+ public RasODMGImplementation(String server)
+ {
+ Debug.enterVerbose( "RasODMGImplementation.constructor: start, server=" + server + "." );
+ try
+ {
+ // server address is http://server:port, we need server and port
+ StringTokenizer t=new StringTokenizer (server,"/");
+ String xxx=t.nextToken();
+ rasMgr =t.nextToken("/:");
+ String portStr = t.nextToken(":");
+ rasMgrPort = Integer.parseInt(portStr);
+ }
+ catch(NoSuchElementException e)
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.constructor: done. server URL format error." );
+ throw new RasConnectionFailedException(RasGlobalDefs.URL_FORMAT_ERROR, server);
+ }
+ Debug.leaveVerbose( "RasODMGImplementation.constructor: done. ok." );
+ }
+
+ /**
+ * Gets the name of the actual server.
+ * @return the name of the RasDaMan server used
+ */
+ public String getRasServer()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getRasServer: server=" + rasServer + "." );
+ return rasServer;
+ }
+
+ /**
+ * Tells whether database is open.
+ * @return open status of database
+ */
+ public int dbIsOpen()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.dbIsOpen: dbIsOpen=" + dbIsOpen + "." );
+ return dbIsOpen;
+ }
+
+ /**
+ * Gets the client ID
+ * @return ID of this client
+ */
+ public int getClientID()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getClientID: clientID=" + clientID + "." );
+ return clientID;
+ }
+
+ /**
+ * Gets the database access mode
+ * @return accessMode code: OPEN_READ_ONLY = 1; OPEN_READ_WRITE = 2; OPEN_EXCLUSIVE = 3
+ */
+ public int getAccessMode()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getAccessMode: accessMode=" + accessMode + "." );
+ return accessMode;
+ }
+
+ /**
+ * Gets the current error status
+ * @return error status string
+ */
+ public String getErrorStatus()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getErrorStatus: errorStatus=" + errorStatus + "." );
+ return errorStatus;
+ }
+
+
+ /**
+ * Create a new transaction object and associate it with the current thread.
+ */
+ public Transaction newTransaction()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.newTransaction: enter." );
+ transaction= new RasTransaction(this);
+ Debug.leaveVerbose( "RasODMGImplementation.newTransaction: done." );
+ return transaction;
+ }
+
+ /**
+ * Get current transaction for thread, or NULL if none.
+ */
+ public Transaction currentTransaction()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.currentTransaction." );
+ return transaction;
+ }
+
+ /**
+ * Create a new database object.
+ */
+ public Database newDatabase()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.newDatabase: enter." );
+ database = new RasDatabase(this);
+ Debug.leaveVerbose( "RasODMGImplementation.newDatabase: done." );
+ return database;
+ }
+
+ /**
+ * Create a new query object.
+ */
+ public OQLQuery newOQLQuery()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.newOQLQuery: enter." );
+ query = new RasOQLQuery(this);
+ Debug.leaveVerbose( "RasODMGImplementation.newOQLQuery: done." );
+ return query;
+ }
+
+ /**
+ * Create a new DList object.
+ */
+ public DList newDList()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.newDList." );
+ return new RasList();
+ }
+
+ /**
+ * Create a new DBag object.
+ */
+ public DBag newDBag()
+ {
+ return new RasBag();
+ }
+
+ /**
+ * Create a new DSet object.
+ */
+ public DSet newDSet()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.newDSet." );
+ return new RasSet();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DArray newDArray()
+ {
+ Debug.talkWarning( "RasODMGImplementation.newDArray: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DMap newDMap()
+ {
+ Debug.talkWarning( "RasODMGImplementation.newDMap: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Get a String representation of the object's identifier.
+ * @returns: OID string on success, null otherwise
+ */
+ public String getObjectId(Object obj)
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getObjectId: enter." );
+
+ if( ! (obj instanceof RasObject) ) // currently all must be derived from RasObject
+ {
+ Debug.leaveWarning( "RasODMGImplementation.getObjectId: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ // if we come here: yes, we are derived from RasObject, let's proceed
+ RasOID roid = ((RasObject)obj).getOID();
+ String oid = roid.toString();
+ DBag resultBag = null;
+ if(!((RasObject)obj).getOID().isValid()) // OID of our object is not valid -> get one
+ {
+ Debug.talkWarning( "RasODMGImplementation.getObjectId: OID not Valid: " + roid + "." );
+ String params = "ClientID=" + clientID + "&Command=10";
+ RasHttpRequest request = new RasHttpRequest();
+ if(this.currentTransaction().isOpen()) // TA is open, we can proceed
+ {
+ // get new oid
+ try
+ {
+ request.execute(rasServer,params); // get it from server
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkCritical( "RasODMGImplementation.getObjectId: query execution failed: " + e.getMessage() );
+ }
+ }
+ else // TA is not open, so we do an open here
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: db not open, opening: " + databaseName + "." );
+ boolean openedDbHere = false; // did we open a db locally?
+ boolean openedTaHere = false; // did we open a db locally?
+ Database d = null;
+ Transaction t = null;
+ try
+ {
+ if(this.dbIsOpen == Database.NOT_OPEN) // we even open the db if not done already
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: db not open, opening: " + databaseName + "." );
+ d = this.newDatabase();
+ d.open( databaseName, Database.OPEN_READ_WRITE);
+ // fix: was: "RASBASE"; now: take name of last opened db. not good, but better maybe -- PB 2003-jun-13
+ // FIXME: r/w open not good, do we have info at this point? Maybe getOid needs r/w
+ openedDbHere = true;
+ }
+ t = this.newTransaction();
+ t.begin();
+ openedTaHere = true; // we know now we have an open TA
+ // get new oid
+ request.execute(rasServer,params); // get it from server
+ t.commit();
+ if(openedDbHere)
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: closing locally opened DB. " );
+ d.close();
+ openedDbHere = false; // no more locally opened DB to close
+ }
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getObjectId: failed: " + e.getMessage() );
+ try
+ {
+ if (openedTaHere)
+ t.abort();
+ if(openedDbHere)
+ d.close();
+ }
+ catch (ODMGException e3)
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: error closing locally opened DB (ignored): " + e3.getMessage() );
+ }
+ }
+ } // if (TA open)
+
+ resultBag = (DBag)request.getResult(); // if all went fine we now have OID in result
+ if(resultBag != null)
+ {
+ Iterator iter = resultBag.iterator();
+ if(iter.hasNext())
+ roid = (RasOID)iter.next();
+ oid = roid.toString();
+ ((RasObject)obj).setOID(roid);
+ }
+ else
+ {
+ Debug.talkCritical( "RasODMGImplementation.getObjectId: empty query result, cannot fetch OID." );
+ oid = null;
+ }
+ } // valid OID
+
+ Debug.leaveVerbose( "RasODMGImplementation.getObjectId: done. oid=" + oid + "." );
+ return oid;
+ } // getObjectId()
+
+ /**
+ * Not implemented yet.
+ */
+ public Database getDatabase(Object obj)
+ {
+ Debug.talkWarning( "RasODMGImplementation.getDatabase: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Open database
+ */
+ public void openDB(String name, int accessMode) throws ODMGException, ODMGRuntimeException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.openDB: start, db=" + name + ", accessMode=" + accessMode );
+
+ databaseName = name;
+ this.accessMode = accessMode;
+ try
+ {
+ openConnection( serverURL ); // establish connection to database -- PB 2003-jun-13
+ getFreeServer();
+ executeOpenDB(databaseName,accessMode);
+ executeCloseDB(); // FIXME: why in heaven do we close the db??? -- PB 2003-jun-06
+ dbIsOpen = 1;
+ }
+ catch (ODMGException e) // catch just for logging, then rethrow immediately
+ {
+ Debug.leaveCritical( "RasODMGImplementation.openDB: done. Exception: " + e.getMessage() );
+ throw new ODMGException( e.getMessage() );
+ }
+ catch (ODMGRuntimeException x) // catch just for logging, then rethrow immediately
+ {
+ Debug.leaveCritical( "RasODMGImplementation.openDB: done. ODMGRuntimeException: " + x.getMessage() );
+ throw new ODMGException( x.getMessage() );
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.openDB: done. OK." );
+ }
+
+ private void executeOpenDB(String name, int accessMode) throws ODMGException
+ {
+ String params = "Command=" + RasODMGGlobal.commOpenDB + "&Database=" + name + "&Capability=" + capability;
+ RasHttpRequest request = new RasHttpRequest();
+ request.execute(rasServer,params);
+ // Later, the client ID is determined here
+ clientID = 1; // not used anymore
+ }
+
+ /**
+ * Closes an open database. At the moment, only one database can be open at
+ * a given time and thus no parameter "database" is necessary here.
+ */
+ public void closeDB() throws ODMGException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.closeDB start." );
+
+ // not necessary, others do close already
+ // PB: this is due to an old bug in O2 which needed a closeDB in order to free objects, hence we do this in commitTA/abortTA
+
+ // close connection to server -- PB 2003-jun-13
+ closeConnection();
+
+ dbIsOpen = 0;
+ Debug.leaveVerbose( "RasODMGImplementation.closeDB done." );
+ }
+
+ private void executeCloseDB() throws ODMGException
+ {
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commCloseDB;
+ RasHttpRequest request = new RasHttpRequest();
+ request.execute(rasServer,params);
+ }
+
+ /**
+ * Begin a transaction.
+ */
+ public void beginTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.beginTA start." );
+ try
+ {
+ getFreeServer();
+ executeOpenDB(databaseName,accessMode);
+ executeBeginTA();
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkWarning( "RasODMGImplementation.beginTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ Debug.leaveVerbose( "RasODMGImplementation.beginTA done." );
+ }
+
+ private void executeBeginTA()
+ {
+ String errorMsg = "Could not open transaction: ";
+ if(dbIsOpen == 0)
+ throw new DatabaseClosedException(errorMsg + "database not open");
+
+ String params = "ClientID=" + clientID + "&Command=";
+ // Is the database opened READ_ONLY or READ_WRITE ?
+ if(accessMode == Database.OPEN_READ_ONLY)
+ params = params + RasODMGGlobal.commBTreadOnly;
+ else
+ params = params + RasODMGGlobal.commBTreadWrite;
+ params = params + "&Capability=" + capability;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.executeBeginTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ }
+
+ /**
+ * Returns TRUE if a transaction is currently open.
+ */
+ public boolean isOpenTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.isOpenTA start." );
+ boolean result = false;
+
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commIsOpenTA;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);
+ result= (request.getResultType() == 99) ? true : false;
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.isOpenTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ result = false;
+ }
+ Debug.leaveVerbose( "RasODMGImplementation.isOpenTA done. result=" + result );
+ return result;
+ }
+
+ /**
+ * Commit a transaction.
+ */
+ public void commitTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.commitTA start." );
+
+ try
+ {
+ executeCommitTA();
+ executeCloseDB(); // FIXME: why close here??? -- PB 2003-jun-13
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkWarning( "RasODMGImplementation.commitTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.commitTA done." );
+ }
+
+ private void executeCommitTA()
+ {
+ String errorMsg = "Could not commit transaction: ";
+ if(dbIsOpen == 0)
+ throw new DatabaseClosedException(errorMsg + "database not open");
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commCT;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);//RasODMGGlobal.getRasServer(),params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.executeCommitTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ }
+
+ /**
+ * Abort a transaction.
+ */
+ public void abortTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.abortTA start." );
+
+ try
+ {
+ executeAbortTA();
+ executeCloseDB();
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkWarning( "RasODMGImplementation.abortTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.abortTA done." );
+ }
+
+ private void executeAbortTA()
+ {
+ String errorMsg = "Cannot abort transaction: ";
+ if(dbIsOpen == 0)
+ throw new DatabaseClosedException(errorMsg + "database not open");
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commAT;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.executeAbortTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ }
+
+ /**
+ * Set the maximum retry parameter
+ */
+ public void setMaxRetry(int newRetry)
+ {
+ Debug.talkVerbose( "RasODMGImplementation.setMaxRetry to " + newRetry + "." );
+ maxRetry = newRetry;
+ }
+
+ /**
+ * Get the maximum retry parameter
+ */
+ public int getMaxRetry()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getMaxRetry: maxRetry=" + maxRetry + "." );
+ return maxRetry;
+ }
+
+ /**
+ * Requests a free server and retry's
+ */
+ //private void getFreeServer( )
+ public void getFreeServer( )
+ throws RasQueryExecutionFailedException, RasConnectionFailedException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getFreeServer: enter." );
+
+ String uniqueID = uniqueRequestID();
+
+ int millisec = RasGlobalDefs.GETFREESERVER_WAIT_INITIAL;
+ for (int retryCount = 1; retryCount <= maxRetry; retryCount++)
+ {
+ try
+ {
+ executeGetFreeServer(uniqueID);
+ // if no error, we have the server, so break
+ break;
+ }
+ catch(RasConnectionFailedException e)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getFreeServer: cannot obtain a free server:" + e.getMessage() );
+ // the following errors justify that we try again, maybe we get a free server a little later
+ int errno = e.getErrorNo();
+ if (errno==RasGlobalDefs.MANAGER_BUSY
+ /* || errno==RasGlobalDefs.NO_ACTIVE_SERVERS */ // if no such server is started, waiting won't help
+ || errno==RasGlobalDefs.WRITE_TRANS_IN_PROGRESS)
+ {
+ // retry, but with increasing wait period
+ millisec = millisec * RasGlobalDefs.GETFREESERVER_WAIT_INCREMENT;
+
+ Debug.talkCritical( "RasODMGImplementation.getFreeServer: no free server available, errno=" + errno + ", retry #" + retryCount + " of " + maxRetry + " after " + millisec + " msecs." );
+ try
+ {
+ Thread.sleep(millisec);
+ }
+ catch(InterruptedException intex)
+ {
+ }
+ }
+ else
+ {
+ Debug.leaveCritical( "RasODMGImplementation.getFreeServer: giving up, cannot obtain free server." );
+ throw(e); // we give up, or we shouldn't retry with this kind of error
+ }
+ }
+ } // for
+
+ Debug.leaveVerbose( "RasODMGImplementation.getFreeServer: done." );
+ }
+
+ /**
+ * Requests a free server
+ */
+
+ private void executeGetFreeServer( String uniqueID ) throws RasQueryExecutionFailedException, RasConnectionFailedException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.executeGetFreeServer: enter, uniqueID=" + uniqueID );
+
+ try
+ {
+ Socket soclu = new Socket(rasMgr,rasMgrPort); // FIXME: where is this socket closed ??? PB
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: socket=" + soclu );
+ PrintStream ps = new PrintStream(soclu.getOutputStream());
+ String body = databaseName + " HTTP " + (accessMode == Database.OPEN_READ_ONLY ? "ro":"rw") + " " + uniqueID + " \0";
+ ps.print("POST getfreeserver HTTP/1.1\r\nAccept: text/plain\r\nContent-type: text/plain\r\n"
+ + "User-Agent: RasDaMan Java Client1.0\r\nAuthorization: ras " + userIdentification
+ + "\r\nContent length: " + body.length()+"\r\n\r\n" + body);
+ ps.flush();
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: sent body=" + body );
+
+ BufferedReader ds = new BufferedReader(new InputStreamReader(soclu.getInputStream()));
+ int resultCode = getResultCode(ds);
+ String bodyLine = getBodyLine(ds);
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: received result code=" + resultCode + ", bodyLine=" + bodyLine );
+
+ ps.close();
+ ds.close();
+ soclu.close(); // this one was missing all the time -- PB
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: socket closed: " + soclu );
+
+ if(resultCode==200)
+ {
+ StringTokenizer t=new StringTokenizer(bodyLine," ");
+ String host=t.nextToken();
+ String port=t.nextToken(" ");
+ capability=t.nextToken(" \t\r\n\0");
+ rasServer="http://" + host + ":" + port;
+ }
+ else
+ {
+ // if error =>bodyLine: errorCode someText
+ Debug.talkSparse( "RasODMGImplementation.executeGetFreeServer: bodyLine=" + bodyLine);
+ StringTokenizer t=new StringTokenizer(bodyLine," ");
+ String errorStr = t.nextToken();
+ int errorCode = Integer.parseInt(errorStr);
+ if( resultCode < 1000 )
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done. connection failed, code=" + errorCode );
+ throw new RasConnectionFailedException(errorCode,null);
+ }
+ else
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done. request format error, code=" + errorCode );
+ throw new RasConnectionFailedException(RasGlobalDefs.REQUEST_FORMAT_ERROR," code=" + errorCode);
+ }
+ }
+ }
+ catch( MalformedURLException e )
+ {
+ Debug.talkCritical( "RasODMGImplementation.executeGetFreeServer: malformed URL exception: " + e.getMessage() );
+ throw new RasConnectionFailedException(RasGlobalDefs.MANAGER_CONN_FAILED,rasMgr);
+ }
+ catch( IOException e )
+ {
+ Debug.talkCritical( "RasODMGImplementation.executeGetFreeServer: IO exception: " + e.getMessage() );
+ throw new RasClientInternalException( "RasODMGImplementation","executeGetFreeServer()", e.getMessage() );
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done." );
+ } // executeGetFreeServer()
+
+
+ public Object queryRequest(String parameters) throws RasQueryExecutionFailedException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.queryRequest start. parameters=" + parameters + "." );
+
+ BenchmarkTimer qTimer = new BenchmarkTimer("queryRequest");
+ qTimer.startTimer();
+
+ RasHttpRequest request= new RasHttpRequest();
+ request.execute(getRasServer(),parameters);
+
+ qTimer.stopTimer();
+ qTimer.print();
+
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer done." );
+ return request.getResult();
+ }
+
+
+ //private int getResultCode(BufferedReader ds) throws IOException
+ public int getResultCode(BufferedReader ds) throws IOException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getResultCode start." );
+
+ String s = ds.readLine();
+ StringTokenizer t = new StringTokenizer(s," ");
+ String http = t.nextToken();
+ String resultString = t.nextToken(" ");
+ int result = Integer.parseInt(resultString);
+
+ Debug.leaveVerbose( "RasODMGImplementation.getResultCode done. result=" + result + "." );
+ return result;
+ }
+
+ //private String getBodyLine(BufferedReader ds) throws IOException
+ public String getBodyLine(BufferedReader ds) throws IOException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getBodyLine start." );
+
+ String s;
+ do // was a "for(;;)" loop, cleaned it -- PB 2003-jun-13
+ {
+ s = ds.readLine();
+ if(s==null)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getBodyLine: Unexpected EOF in rasmgr answer." );
+ throw new IOException("Unexpected EOF in rasmgr answer.");
+ }
+ }
+ while (s.length() != 0);
+
+ String result = ds.readLine();
+ Debug.leaveVerbose( "RasODMGImplementation.getBodyLine done. result=" + result + "." );
+ return result;
+ }
+
+ public void setUserIdentification(String userName, String plainPass)
+ {
+ Debug.enterVerbose( "RasODMGImplementation.setUserIdentification start." );
+
+ MD5 md5 = new MD5();
+ String hex;
+ md5.Init();
+ md5.Update(plainPass);
+ hex = md5.asHex();
+ userIdentification= userName + ":" + hex;
+
+ Debug.leaveVerbose( "RasODMGImplementation.setUserIdentification done." );
+ }
+
+ private String strHostID = null;
+ static private int idcounter = 0;
+
+ private String uniqueRequestID()
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.uniqueRequestID start." );
+
+ if(strHostID == null)
+ {
+ long hostid = 0;
+ try
+ {
+ InetAddress addr = InetAddress.getLocalHost();
+ // Get IP Address
+ byte[] ipAddr = addr.getAddress();
+
+ for(int i=0;i<ipAddr.length; i++)
+ {
+ int ss = (int)ipAddr[i];
+ if(ss<0)
+ ss = 256 + ss;
+ hostid = hostid * 256 + ss;
+ }
+ }
+ catch (UnknownHostException e)
+ {
+ Random random = new Random();
+ hostid = random.nextInt();
+ }
+ idcounter = (idcounter + 1) & 0xF;
+ // it's unique enough, we don't need such a huge number
+ strHostID = "" + hostid + ':' + (System.currentTimeMillis() & 0xFFFFFFF0) + idcounter;
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.uniqueRequestID done. strHostID=" + strHostID + "." );
+ return strHostID;
+ }
+
+}
+
+//##################################################################################
+/**
+ * Contains internal state of the MD5 class
+ */
+
+class MD5State
+ {
+ /**
+ * 128-byte state
+ */
+ int state[];
+
+ /**
+ * 64-bit character count (could be true Java long?)
+ */
+ int count[];
+
+ /**
+ * 64-byte buffer (512 bits) for storing to-be-hashed characters
+ */
+ byte buffer[];
+
+ public MD5State()
+ {
+ Debug.enterVerbose( "MD5State.constructor start." );
+
+ buffer = new byte[64];
+ count = new int[2];
+ state = new int[4];
+
+ state[0] = 0x67452301;
+ state[1] = 0xefcdab89;
+ state[2] = 0x98badcfe;
+ state[3] = 0x10325476;
+
+ count[0] = count[1] = 0;
+
+ Debug.leaveVerbose( "MD5State.constructor done." );
+ }
+
+ /**
+ Create this State as a copy of another state
+ **/
+ public MD5State (MD5State from)
+ {
+ this();
+
+ Debug.enterVerbose( "MD5State.cloner start." );
+
+ int i;
+
+ for (i = 0; i < buffer.length; i++)
+ this.buffer[i] = from.buffer[i];
+
+ for (i = 0; i < state.length; i++)
+ this.state[i] = from.state[i];
+
+ for (i = 0; i < count.length; i++)
+ this.count[i] = from.count[i];
+
+ Debug.leaveVerbose( "MD5State.cloner done." );
+ }
+
+ }; // MD5State
+
+/**
+ * Implementation of RSA's MD5 hash generator
+ *
+ * @version $Revision: 1.19 $
+ * @author Santeri Paavolainen <sjpaavol@cc.helsinki.fi>
+ */
+
+class MD5
+{
+ /**
+ * MD5 state
+ */
+ MD5State state;
+
+ /**
+ * If Final() has been called, finals is set to the current finals
+ * state. Any Update() causes this to be set to null.
+ */
+ MD5State finals;
+
+ /**
+ * Padding for Final()
+ */
+ static byte padding[] = {
+ (byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ /**
+ * Initialize MD5 internal state (object can be reused just by
+ * calling Init() after every Final()
+ */
+ public synchronized void Init () {
+ state = new MD5State();
+ finals = null;
+ }
+
+ /**
+ * Class constructor
+ */
+ public MD5 () {
+ this.Init();
+ }
+
+ /**
+ * Initialize class, and update hash with ob.toString()
+ *
+ * @param ob Object, ob.toString() is used to update hash
+ * after initialization
+ */
+ public MD5 (Object ob) {
+ this();
+ Update(ob.toString());
+ }
+
+ private int rotate_left (int x, int n) {
+ return (x << n) | (x >>> (32 - n));
+ }
+
+ /* I wonder how many loops and hoops you'll have to go through to
+ get unsigned add for longs in java */
+
+ private int uadd (int a, int b) {
+ long aa, bb;
+ aa = ((long) a) & 0xffffffffL;
+ bb = ((long) b) & 0xffffffffL;
+
+ aa += bb;
+
+ return (int) (aa & 0xffffffffL);
+ }
+
+ private int uadd (int a, int b, int c) {
+ return uadd(uadd(a, b), c);
+ }
+
+ private int uadd (int a, int b, int c, int d) {
+ return uadd(uadd(a, b, c), d);
+ }
+
+ private int FF (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, ((b & c) | (~b & d)), x, ac);
+ return uadd(rotate_left(a, s), b);
+ }
+
+ private int GG (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, ((b & d) | (c & ~d)), x, ac);
+ return uadd(rotate_left(a, s), b);
+ }
+
+ private int HH (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, (b ^ c ^ d), x, ac);
+ return uadd(rotate_left(a, s) , b);
+ }
+
+ private int II (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, (c ^ (b | ~d)), x, ac);
+ return uadd(rotate_left(a, s), b);
+ }
+
+ private int[] Decode (byte buffer[], int len, int shift) {
+ int out[];
+ int i, j;
+
+ out = new int[16];
+
+ for (i = j = 0; j < len; i++, j += 4) {
+ out[i] = ((int) (buffer[j + shift] & 0xff)) |
+ (((int) (buffer[j + 1 + shift] & 0xff)) << 8) |
+ (((int) (buffer[j + 2 + shift] & 0xff)) << 16) |
+ (((int) (buffer[j + 3 + shift] & 0xff)) << 24);
+
+/* System.out.println("out[" + i + "] = \t" +
+ ((int) buffer[j + 0 + shift] & 0xff) + "\t|\t" +
+ ((int) buffer[j + 1 + shift] & 0xff) + "\t|\t" +
+ ((int) buffer[j + 2 + shift] & 0xff) + "\t|\t" +
+ ((int) buffer[j + 3 + shift] & 0xff));*/
+ }
+
+ return out;
+ }
+
+ private void Transform (MD5State state, byte buffer[], int shift) {
+ int
+ a = state.state[0],
+ b = state.state[1],
+ c = state.state[2],
+ d = state.state[3],
+ x[];
+
+ x = Decode(buffer, 64, shift);
+
+ /* Round 1 */
+ a = FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
+ d = FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
+ c = FF (c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
+ b = FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
+ a = FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
+ d = FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
+ c = FF (c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
+ b = FF (b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
+ a = FF (a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
+ d = FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
+ c = FF (c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
+ b = FF (b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
+ a = FF (a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
+ d = FF (d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
+ c = FF (c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
+ b = FF (b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ a = GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
+ d = GG (d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
+ c = GG (c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
+ b = GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
+ a = GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
+ d = GG (d, a, b, c, x[10], 9, 0x2441453); /* 22 */
+ c = GG (c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
+ b = GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
+ a = GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
+ d = GG (d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
+ c = GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
+ b = GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
+ a = GG (a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
+ d = GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
+ c = GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
+ b = GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ a = HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
+ d = HH (d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
+ c = HH (c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
+ b = HH (b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
+ a = HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
+ d = HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
+ c = HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
+ b = HH (b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
+ a = HH (a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
+ d = HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
+ c = HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
+ b = HH (b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
+ a = HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
+ d = HH (d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
+ c = HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
+ b = HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ a = II (a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
+ d = II (d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
+ c = II (c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
+ b = II (b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
+ a = II (a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
+ d = II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
+ c = II (c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
+ b = II (b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
+ a = II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
+ d = II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
+ c = II (c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
+ b = II (b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
+ a = II (a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
+ d = II (d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
+ c = II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
+ b = II (b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
+
+ state.state[0] += a;
+ state.state[1] += b;
+ state.state[2] += c;
+ state.state[3] += d;
+ }
+
+ /**
+ * Updates hash with the bytebuffer given (using at maximum length bytes from
+ * that buffer)
+ *
+ * @param state Which state is updated
+ * @param buffer Array of bytes to be hashed
+ * @param offset Offset to buffer array
+ * @param length Use at maximum `length' bytes (absolute
+ * maximum is buffer.length)
+ */
+ public void Update (MD5State stat, byte buffer[], int offset, int length) {
+ int index, partlen, i, start;
+
+/* System.out.print("Offset = " + offset + "\tLength = " + length + "\t");
+ System.out.print("Buffer = ");
+ for (i = 0; i < buffer.length; i++)
+ System.out.print((int) (buffer[i] & 0xff) + " ");
+ System.out.print("\n");*/
+
+ finals = null;
+
+ /* Length can be told to be shorter, but not inter */
+ if ((length - offset)> buffer.length)
+ length = buffer.length - offset;
+
+ /* compute number of bytes mod 64 */
+ index = (int) (stat.count[0] >>> 3) & 0x3f;
+
+ if ((stat.count[0] += (length << 3)) <
+ (length << 3))
+ stat.count[1]++;
+
+ stat.count[1] += length >>> 29;
+
+ partlen = 64 - index;
+
+ if (length >= partlen) {
+ for (i = 0; i < partlen; i++)
+ stat.buffer[i + index] = buffer[i + offset];
+
+ Transform(stat, stat.buffer, 0);
+
+ for (i = partlen; (i + 63) < length; i+= 64)
+ Transform(stat, buffer, i);
+
+ index = 0;
+ } else
+ i = 0;
+
+ /* buffer remaining input */
+ if (i < length) {
+ start = i;
+ for (; i < length; i++)
+ stat.buffer[index + i - start] = buffer[i + offset];
+ }
+ }
+
+ /*
+ * Update()s for other datatypes than byte[] also. Update(byte[], int)
+ * is only the main driver.
+ */
+
+ /**
+ * Plain update, updates this object
+ */
+
+ public void Update (byte buffer[], int offset, int length) {
+ Update(this.state, buffer, offset, length);
+ }
+
+ public void Update (byte buffer[], int length) {
+ Update(this.state, buffer, 0, length);
+ }
+
+ /**
+ * Updates hash with given array of bytes
+ *
+ * @param buffer Array of bytes to use for updating the hash
+ */
+ public void Update (byte buffer[]) {
+ Update(buffer, 0, buffer.length);
+ }
+
+ /**
+ * Updates hash with a single byte
+ *
+ * @param b Single byte to update the hash
+ */
+ public void Update (byte b) {
+ byte buffer[] = new byte[1];
+ buffer[0] = b;
+
+ Update(buffer, 1);
+ }
+
+ /**
+ * Update buffer with given string.
+ *
+ * @param s String to be update to hash (is used as
+ * s.getBytes())
+ */
+ public void Update (String s) {
+ byte chars[];
+
+ /* deprecated chars = new byte[s.length()];
+ s.getBytes(0, s.length(), chars, 0);
+ */
+ chars = s.getBytes();
+
+ Update(chars, chars.length);
+ }
+
+ /**
+ * Update buffer with a single integer (only & 0xff part is used,
+ * as a byte)
+ *
+ * @param i Integer value, which is then converted to
+ * byte as i & 0xff
+ */
+
+ public void Update (int i) {
+ Update((byte) (i & 0xff));
+ }
+
+ private byte[] Encode (int input[], int len) {
+ int i, j;
+ byte out[];
+
+ out = new byte[len];
+
+ for (i = j = 0; j < len; i++, j += 4) {
+ out[j] = (byte) (input[i] & 0xff);
+ out[j + 1] = (byte) ((input[i] >>> 8) & 0xff);
+ out[j + 2] = (byte) ((input[i] >>> 16) & 0xff);
+ out[j + 3] = (byte) ((input[i] >>> 24) & 0xff);
+ }
+
+ return out;
+ }
+
+ /**
+ * Returns array of bytes (16 bytes) representing hash as of the
+ * current state of this object. Note: getting a hash does not
+ * invalidate the hash object, it only creates a copy of the real
+ * state which is finalized.
+ *
+ * @return Array of 16 bytes, the hash of all updated bytes
+ */
+ public synchronized byte[] Final () {
+ byte bits[];
+ int index, padlen;
+ MD5State fin;
+
+ if (finals == null) {
+ fin = new MD5State(state);
+
+ bits = Encode(fin.count, 8);
+
+ index = (int) ((fin.count[0] >>> 3) & 0x3f);
+ padlen = (index < 56) ? (56 - index) : (120 - index);
+
+ Update(fin, padding, 0, padlen);
+ /**/
+ Update(fin, bits, 0, 8);
+
+ /* Update() sets finalds to null */
+ finals = fin;
+ }
+
+ return Encode(finals.state, 16);
+ }
+
+ /**
+ * Turns array of bytes into string representing each byte as
+ * unsigned hex number.
+ *
+ * @param hash Array of bytes to convert to hex-string
+ * @return Generated hex string
+ */
+ public static String asHex (byte hash[]) {
+ StringBuffer buf = new StringBuffer(hash.length * 2);
+ int i;
+
+ for (i = 0; i < hash.length; i++) {
+ if (((int) hash[i] & 0xff) < 0x10)
+ buf.append("0");
+
+ buf.append(Long.toString((int) hash[i] & 0xff, 16));
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Returns 32-character hex representation of this objects hash
+ *
+ * @return String of this object's hash
+ */
+ public String asHex () {
+ return asHex(this.Final());
+ }
+
+} // MD5
+
diff --git a/java/rasj/odmg/RasODMGImplementation.java.getFreeServer_beginTA b/java/rasj/odmg/RasODMGImplementation.java.getFreeServer_beginTA
new file mode 100644
index 0000000..2fb2cb2
--- /dev/null
+++ b/java/rasj/odmg/RasODMGImplementation.java.getFreeServer_beginTA
@@ -0,0 +1,1361 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE: ODMG Implementation Bootstrap Object
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+package rasj.odmg;
+
+import rasj.*;
+import rasj.global.*;
+import rasj.clientcommhttp.*;
+import org.odmg.*;
+
+import java.io.*;
+import java.net.*;
+import java.lang.*;
+import java.util.*;
+
+
+/**
+ * This class implements the internal ODMG Bootstrap Object used by the rasj.odmg package.
+ * Because it contains a lot of functionality for internal purposes (e.g. methods for
+ * the RasManager), this class is not the official Implementation object the user works
+ * with, it is only used by the rasj.odmg package.
+ * <P>
+ * The public Implementation object is the class
+ * {@link rasj.RasImplementation rasj.RasImplementation}, which internally works with a
+ * RasODMGImplementation object.
+ *
+ * @see rasj.RasImplementation
+ */
+
+public class RasODMGImplementation implements RasImplementationInterface,RasCommDefs//implements Implementation
+ {
+
+ private String rasServer = "";
+ private String rasMgr = "";
+ private int rasMgrPort= RasGlobalDefs.RASMGRPORT_DEFAULT;
+ private String userIdentification = RasGlobalDefs.GUESTIDENT_DEFAULT;
+ private String databaseName = "";
+ private String capability = "dummy";
+ private int maxRetry = RasGlobalDefs.MAX_GETFREESERVER_ATTEMPTS;
+
+ /**
+ * current state of transaction
+ **/
+ private boolean isOpenTA = false;
+
+ /**
+ /**
+ * This variable holds the current RasTransaction object.
+ */
+ private RasTransaction transaction = null;
+
+ /**
+ * This variable holds the current Rasdatabase object.
+ */
+ private RasDatabase database = null;
+
+ /**
+ * This variable holds the current RasOQLQuery object.
+ */
+ private RasOQLQuery query = null;
+
+ /**
+ * The standard ODMG implementation sets the access mode when the database
+ * is opened, whereas the RasDaMan server expects this information when a
+ * transaction is started. Therefore it is saved in this variable.
+ *
+ * Available modes:
+ * OPEN_READ_ONLY = 1
+ * OPEN_READ_WRITE = 2
+ * OPEN_EXCLUSIVE = 3
+ */
+ private int accessMode = 0;
+
+ /**
+ * Since ODMG does not specify a "isDatabaseOpen" method but provides a
+ * DatabaseClosedException, this variable is set to 1 if an openDB command is
+ * executed (closeDB sets it back to 0).
+ */
+ private int dbIsOpen = 0;
+
+ /**
+ * This value is set to 1 if a transaction has been opened. Commiting or aborting
+ * a transaction sets it back to 0.
+ */
+ private int taIsOpen = 0;
+
+ private int clientID = 0;
+
+ /**
+ * This value is used to store possible error messages of exceptions occuring
+ * when opening or closing transactions.
+ * The ODMG specification does not allow these operations to throw
+ * any exceptions, but our implementation could produce exceptions when connecting
+ * to the RasDaMan httpserver. In order to not get lost, these exception messages
+ * are stored in this variable.
+ */
+ private String errorStatus = "";
+ // later: private String strUserAndPasswd = "anonymous:anonymouspasswd";
+
+ /**
+ * Standard constructor.
+ * @param server Complete URL of the RasDaMan httpserver (including port number)
+ */
+ public RasODMGImplementation(String server)
+ {
+ Debug.enterVerbose( "RasODMGImplementation.constructor: start, server=" + server + "." );
+ try
+ {
+ // server address is http://server:port, we need server and port
+ StringTokenizer t=new StringTokenizer (server,"/");
+ String xxx=t.nextToken();
+ rasMgr =t.nextToken("/:");
+ String portStr = t.nextToken(":");
+ rasMgrPort = Integer.parseInt(portStr);
+ }
+ catch(NoSuchElementException e)
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.constructor: done. server URL format error." );
+ throw new RasConnectionFailedException(RasGlobalDefs.URL_FORMAT_ERROR, server);
+ }
+
+ isOpenTA = false;
+
+ Debug.leaveVerbose( "RasODMGImplementation.constructor: done. ok." );
+ }
+
+ /**
+ * Gets the name of the actual server.
+ * @return the name of the RasDaMan server used
+ */
+ public String getRasServer()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getRasServer: server=" + rasServer + "." );
+ return rasServer;
+ }
+
+ /**
+ * Tells whether database is open.
+ * @return open status of database
+ */
+ public int dbIsOpen()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.dbIsOpen: dbIsOpen=" + dbIsOpen + "." );
+ return dbIsOpen;
+ }
+
+ /**
+ * Gets the client ID
+ * @return ID of this client
+ */
+ public int getClientID()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getClientID: clientID=" + clientID + "." );
+ return clientID;
+ }
+
+ /**
+ * Gets the database access mode
+ * @return accessMode code: OPEN_READ_ONLY = 1; OPEN_READ_WRITE = 2; OPEN_EXCLUSIVE = 3
+ */
+ public int getAccessMode()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getAccessMode: accessMode=" + accessMode + "." );
+ return accessMode;
+ }
+
+ /**
+ * Gets the current error status
+ * @return error status string
+ */
+ public String getErrorStatus()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getErrorStatus: errorStatus=" + errorStatus + "." );
+ return errorStatus;
+ }
+
+
+ /**
+ * Create a new transaction object and associate it with the current thread.
+ */
+ public Transaction newTransaction()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.newTransaction: start." );
+ transaction= new RasTransaction(this);
+ Debug.leaveVerbose( "RasODMGImplementation.newTransaction: done." );
+ return transaction;
+ }
+
+ /**
+ * Get current transaction for thread, or NULL if none.
+ */
+ public Transaction currentTransaction()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.currentTransaction." );
+ return transaction;
+ }
+
+ /**
+ * Create a new database object.
+ */
+ public Database newDatabase()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.newDatabase: start." );
+ database = new RasDatabase(this);
+ Debug.leaveVerbose( "RasODMGImplementation.newDatabase: done." );
+ return database;
+ }
+
+ /**
+ * Create a new query object.
+ */
+ public OQLQuery newOQLQuery()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.newOQLQuery: start." );
+ query = new RasOQLQuery(this);
+ Debug.leaveVerbose( "RasODMGImplementation.newOQLQuery: done." );
+ return query;
+ }
+
+ /**
+ * Create a new DList object.
+ */
+ public DList newDList()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.newDList." );
+ return new RasList();
+ }
+
+ /**
+ * Create a new DBag object.
+ */
+ public DBag newDBag()
+ {
+ return new RasBag();
+ }
+
+ /**
+ * Create a new DSet object.
+ */
+ public DSet newDSet()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.newDSet." );
+ return new RasSet();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DArray newDArray()
+ {
+ Debug.talkWarning( "RasODMGImplementation.newDArray: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DMap newDMap()
+ {
+ Debug.talkWarning( "RasODMGImplementation.newDMap: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Get a String representation of the object's identifier.
+ * @returns: OID string on success, null otherwise
+ */
+ public String getObjectId(Object obj)
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getObjectId: start." );
+
+ if( ! (obj instanceof RasObject) ) // currently all must be derived from RasObject
+ {
+ Debug.leaveWarning( "RasODMGImplementation.getObjectId: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ // if we come here: yes, we are derived from RasObject, let's proceed
+ RasOID roid = ((RasObject)obj).getOID();
+ String oid = roid.toString();
+ DBag resultBag = null;
+ if(!((RasObject)obj).getOID().isValid()) // OID of our object is not valid -> get one
+ {
+ Debug.talkWarning( "RasODMGImplementation.getObjectId: OID not Valid: " + roid + "." );
+ String params = "ClientID=" + clientID + "&Command=10";
+ RasHttpRequest request = new RasHttpRequest();
+ if(((RasTransaction)this.currentTransaction()).isOpenLocally()) // TA is open, we can proceed
+ // (decide w/o asking server -- PB 2003-jun-25)
+ {
+ // get new oid
+ try
+ {
+ request.execute(rasServer,params); // get it from server
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkCritical( "RasODMGImplementation.getObjectId: query execution failed: " + e.getMessage() );
+ }
+ }
+ else // TA is not open, so we do an open here
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: db not open, opening: " + databaseName + "." );
+ boolean openedDbHere = false; // did we open a db locally?
+ boolean openedTaHere = false; // did we open a db locally?
+ Database d = null;
+ Transaction t = null;
+ try
+ {
+ if(this.dbIsOpen == Database.NOT_OPEN) // we even open the db if not done already
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: db not open, opening: " + databaseName + "." );
+ d = this.newDatabase();
+ d.open( databaseName, Database.OPEN_READ_WRITE);
+ // fix: was: "RASBASE"; now: take name of last opened db. not good, but better maybe -- PB 2003-jun-13
+ // FIXME: r/w open not good, do we have info at this point? Maybe getOid needs r/w
+ openedDbHere = true;
+ }
+ t = this.newTransaction();
+ t.begin();
+ openedTaHere = true; // we know now we have an open TA
+ // get new oid
+ request.execute(rasServer,params); // get it from server
+ t.commit();
+ if(openedDbHere)
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: closing locally opened DB. " );
+ d.close();
+ openedDbHere = false; // no more locally opened DB to close
+ }
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getObjectId: failed: " + e.getMessage() );
+ try
+ {
+ if (openedTaHere)
+ t.abort();
+ if(openedDbHere)
+ d.close();
+ }
+ catch (ODMGException e3)
+ {
+ Debug.talkSparse( "RasODMGImplementation.getObjectId: error closing locally opened DB (ignored): " + e3.getMessage() );
+ }
+ }
+ } // if (TA open)
+
+ resultBag = (DBag)request.getResult(); // if all went fine we now have OID in result
+ if(resultBag != null)
+ {
+ Iterator iter = resultBag.iterator();
+ if(iter.hasNext())
+ roid = (RasOID)iter.next();
+ oid = roid.toString();
+ ((RasObject)obj).setOID(roid);
+ }
+ else
+ {
+ Debug.talkCritical( "RasODMGImplementation.getObjectId: empty query result, cannot fetch OID." );
+ oid = null;
+ }
+ } // valid OID
+
+ Debug.leaveVerbose( "RasODMGImplementation.getObjectId: done. oid=" + oid + "." );
+ return oid;
+ } // getObjectId()
+
+ /**
+ * Not implemented yet.
+ */
+ public Database getDatabase(Object obj)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getDatabase: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Open database
+ */
+ public void openDB(String name, int accessMode) throws ODMGException, ODMGRuntimeException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.openDB: start, db=" + name + ", accessMode=" + accessMode );
+
+ databaseName = name;
+ this.accessMode = accessMode;
+
+ try
+ {
+ getFreeServer(); // sets rasServer
+ executeOpenDB(databaseName,accessMode);
+ // executeCloseDB(); // does nothing, so clean away -- PB 2003-jun-25
+ dbIsOpen = 1;
+ }
+ catch (ODMGException e) // catch just for logging, then rethrow immediately
+ {
+ Debug.leaveCritical( "RasODMGImplementation.openDB: done. Exception: " + e.getMessage() );
+ throw new ODMGException( e.getMessage() );
+ }
+ catch (ODMGRuntimeException x) // catch just for logging, then rethrow immediately
+ {
+ Debug.leaveCritical( "RasODMGImplementation.openDB: done. ODMGRuntimeException: " + x.getMessage() );
+ throw new ODMGException( x.getMessage() );
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.openDB: done. OK." );
+ }
+
+ private void executeOpenDB(String name, int accessMode) throws ODMGException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.executeOpenDB: start, name=" + name + ", accessMode=" + accessMode );
+ String params = "Command=" + RasODMGGlobal.commOpenDB + "&Database=" + name + "&Capability=" + capability;
+ RasHttpRequest request = new RasHttpRequest();
+ request.execute(rasServer,params);
+ // Later, the client ID is determined here
+ clientID = 1; // not used anymore
+ Debug.leaveVerbose( "RasODMGImplementation.executeOpenDB: done." );
+ }
+
+ /**
+ * Closes an open database. At the moment, only one database can be open at
+ * a given time and thus no parameter "database" is necessary here.
+ */
+ public void closeDB() throws ODMGException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.closeDB start." );
+
+ // not necessary, others do close already
+ // PB: this is due to an old bug in O2 which needed a closeDB in order to free objects, hence we do this in commitTA/abortTA
+
+ dbIsOpen = 0;
+ Debug.leaveVerbose( "RasODMGImplementation.closeDB done." );
+ }
+
+ private void executeCloseDB() throws ODMGException
+ {
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commCloseDB;
+ RasHttpRequest request = new RasHttpRequest();
+ request.execute(rasServer,params);
+ }
+
+ /**
+ * Begin a transaction.
+ */
+ public void beginTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.beginTA start." );
+ try
+ {
+ getFreeServer();
+ executeOpenDB(databaseName,accessMode);
+ executeBeginTA();
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkWarning( "RasODMGImplementation.beginTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ Debug.leaveVerbose( "RasODMGImplementation.beginTA done." );
+ }
+
+ private void executeBeginTA()
+ {
+ String errorMsg = "Could not open transaction: ";
+ if(dbIsOpen == 0)
+ throw new DatabaseClosedException(errorMsg + "database not open");
+
+ String params = "ClientID=" + clientID + "&Command=";
+ // Is the database opened READ_ONLY or READ_WRITE ?
+ if(accessMode == Database.OPEN_READ_ONLY)
+ params = params + RasODMGGlobal.commBTreadOnly;
+ else
+ params = params + RasODMGGlobal.commBTreadWrite;
+ params = params + "&Capability=" + capability;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.executeBeginTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ }
+
+ /**
+ * Returns TRUE if a transaction is currently open.
+ * This method MUST be sincere in that it asks the server about its state! (some apps use it to override timeout)
+ */
+ public boolean isOpenTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.isOpenTA start." );
+ boolean result = false;
+
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commIsOpenTA;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);
+ result= (request.getResultType() == 99) ? true : false;
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.isOpenTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ result = false;
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.isOpenTA done. result=" + result );
+ return result;
+ }
+
+ /**
+ * Commit a transaction.
+ */
+ public void commitTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.commitTA start." );
+
+ try
+ {
+ executeCommitTA();
+ executeCloseDB(); // FIXME: why close here??? -- PB 2003-jun-13
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkWarning( "RasODMGImplementation.commitTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.commitTA done." );
+ }
+
+ private void executeCommitTA()
+ {
+ String errorMsg = "Could not commit transaction: ";
+ if(dbIsOpen == 0)
+ throw new DatabaseClosedException(errorMsg + "database not open");
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commCT;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);//RasODMGGlobal.getRasServer(),params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.executeCommitTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ }
+
+ /**
+ * Abort a transaction.
+ */
+ public void abortTA()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.abortTA start." );
+
+ try
+ {
+ executeAbortTA();
+ executeCloseDB();
+ }
+ catch(ODMGException e)
+ {
+ Debug.talkWarning( "RasODMGImplementation.abortTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.abortTA done." );
+ }
+
+ private void executeAbortTA()
+ {
+ String errorMsg = "Cannot abort transaction: ";
+ if(dbIsOpen == 0)
+ throw new DatabaseClosedException(errorMsg + "database not open");
+ String params = "ClientID=" + clientID + "&Command=" + RasODMGGlobal.commAT;
+ RasHttpRequest request = new RasHttpRequest();
+ try
+ {
+ request.execute(rasServer,params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ // this cannot occur (theoretically)
+ Debug.talkWarning( "RasODMGImplementation.executeAbortTA: " + e.getMessage() );
+ errorStatus = e.getMessage();
+ }
+ }
+
+ /**
+ * Set the maximum retry parameter
+ */
+ public void setMaxRetry(int newRetry)
+ {
+ Debug.talkVerbose( "RasODMGImplementation.setMaxRetry to " + newRetry + "." );
+ maxRetry = newRetry;
+ }
+
+ /**
+ * Get the maximum retry parameter
+ */
+ public int getMaxRetry()
+ {
+ Debug.talkVerbose( "RasODMGImplementation.getMaxRetry: maxRetry=" + maxRetry + "." );
+ return maxRetry;
+ }
+
+ /**
+ * Requests a free server and retry's
+ */
+ //private void getFreeServer( )
+ public void getFreeServer( )
+ throws RasQueryExecutionFailedException, RasConnectionFailedException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getFreeServer: start." );
+
+ String uniqueID = uniqueRequestID();
+
+ int millisec = RasGlobalDefs.GETFREESERVER_WAIT_INITIAL;
+ for (int retryCount = 1; retryCount <= maxRetry; retryCount++)
+ {
+ try
+ {
+ executeGetFreeServer(uniqueID);
+ // if no error, we have the server, so break
+ break;
+ }
+ catch(RasConnectionFailedException e)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getFreeServer: cannot obtain a free server:" + e.getMessage() );
+ // the following errors justify that we try again, maybe we get a free server a little later
+ int errno = e.getErrorNo();
+ if (errno==RasGlobalDefs.MANAGER_BUSY
+ /* || errno==RasGlobalDefs.NO_ACTIVE_SERVERS */ // if no such server is started, waiting won't help
+ || errno==RasGlobalDefs.WRITE_TRANS_IN_PROGRESS)
+ {
+ // retry, but with increasing wait period
+ millisec = millisec * RasGlobalDefs.GETFREESERVER_WAIT_INCREMENT;
+
+ Debug.talkCritical( "RasODMGImplementation.getFreeServer: no free server available, errno=" + errno + ", retry #" + retryCount + " of " + maxRetry + " after " + millisec + " msecs." );
+ try
+ {
+ Thread.sleep(millisec);
+ }
+ catch(InterruptedException intex)
+ { // wake up
+ }
+ }
+ else
+ {
+ Debug.talkCritical( "RasODMGImplementation.getFreeServer: giving up, cannot obtain free server. marking connection as closed." );
+ Debug.leaveVerbose( "RasODMGImplementation.getFreeServer: done." );
+
+ // reset ta & db
+ isOpenTA = false;
+ dbIsOpen = 0;
+ throw(e); // we give up, or we shouldn't retry with this kind of error
+ }
+ }
+ } // for
+
+ Debug.leaveVerbose( "RasODMGImplementation.getFreeServer: done." );
+ }
+
+ /**
+ * Requests a free server from rasmgr
+ */
+
+ private void executeGetFreeServer( String uniqueID ) throws RasQueryExecutionFailedException, RasConnectionFailedException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.executeGetFreeServer: enter, uniqueID=" + uniqueID );
+
+ try
+ {
+ Socket soclu = new Socket(rasMgr,rasMgrPort); // FIXME: where is this socket closed ??? PB
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: socket=" + soclu );
+ PrintStream ps = new PrintStream(soclu.getOutputStream());
+ String body = databaseName + " HTTP " + (accessMode == Database.OPEN_READ_ONLY ? "ro":"rw") + " " + uniqueID + " \0";
+ ps.print("POST getfreeserver HTTP/1.1\r\nAccept: text/plain\r\nContent-type: text/plain\r\n"
+ + "User-Agent: RasDaMan Java Client1.0\r\nAuthorization: ras " + userIdentification
+ + "\r\nContent length: " + body.length()+"\r\n\r\n" + body);
+ ps.flush();
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: sent body=" + body );
+
+ BufferedReader ds = new BufferedReader(new InputStreamReader(soclu.getInputStream()));
+ int resultCode = getResultCode(ds);
+ String bodyLine = getBodyLine(ds);
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: received result code=" + resultCode + ", bodyLine=" + bodyLine );
+
+ ps.close();
+ ds.close();
+ soclu.close(); // this one was missing all the time -- PB
+ Debug.talkVerbose( "RasODMGImplementation.executeGetFreeServer: socket closed: " + soclu );
+
+ if(resultCode==200)
+ {
+ StringTokenizer t=new StringTokenizer(bodyLine," ");
+ String host=t.nextToken();
+ String port=t.nextToken(" ");
+ capability=t.nextToken(" \t\r\n\0");
+ rasServer="http://" + host + ":" + port;
+ }
+ else
+ {
+ // if error =>bodyLine: errorCode someText
+ Debug.talkSparse( "RasODMGImplementation.executeGetFreeServer: bodyLine=" + bodyLine);
+ StringTokenizer t=new StringTokenizer(bodyLine," ");
+ String errorStr = t.nextToken();
+ int errorCode = Integer.parseInt(errorStr);
+ if( resultCode < 1000 )
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done. connection failed, code=" + errorCode );
+ throw new RasConnectionFailedException(errorCode,null);
+ }
+ else
+ {
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done. request format error, code=" + errorCode );
+ throw new RasConnectionFailedException(RasGlobalDefs.REQUEST_FORMAT_ERROR," code=" + errorCode);
+ }
+ }
+ }
+ catch( MalformedURLException e )
+ {
+ Debug.talkCritical( "RasODMGImplementation.executeGetFreeServer: malformed URL exception: " + e.getMessage() );
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done with exception: " + e.getMessage() );
+ throw new RasConnectionFailedException(RasGlobalDefs.MANAGER_CONN_FAILED,rasMgr);
+ }
+ catch( IOException e )
+ {
+ Debug.talkCritical( "RasODMGImplementation.executeGetFreeServer: IO exception: " + e.getMessage() );
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done with exception: " + e.getMessage() );
+ throw new RasClientInternalException( "RasODMGImplementation","executeGetFreeServer()", e.getMessage() );
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer: done." );
+ } // executeGetFreeServer()
+
+ public Object queryRequest(String parameters) throws RasQueryExecutionFailedException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.queryRequest start. parameters=" + parameters + "." );
+
+ BenchmarkTimer qTimer = new BenchmarkTimer("queryRequest");
+ qTimer.startTimer();
+
+ RasHttpRequest request= new RasHttpRequest();
+ request.execute(rasServer,parameters);
+
+ qTimer.stopTimer();
+ qTimer.print();
+
+ Debug.leaveVerbose( "RasODMGImplementation.executeGetFreeServer done." );
+ return request.getResult();
+ }
+
+
+ //private int getResultCode(BufferedReader ds) throws IOException
+ public int getResultCode(BufferedReader ds) throws IOException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getResultCode start." );
+
+ String s = ds.readLine();
+ StringTokenizer t = new StringTokenizer(s," ");
+ String http = t.nextToken();
+ String resultString = t.nextToken(" ");
+ int result = Integer.parseInt(resultString);
+
+ Debug.leaveVerbose( "RasODMGImplementation.getResultCode done. result=" + result + "." );
+ return result;
+ }
+
+ //private String getBodyLine(BufferedReader ds) throws IOException
+ public String getBodyLine(BufferedReader ds) throws IOException
+ {
+ Debug.enterVerbose( "RasODMGImplementation.getBodyLine start." );
+
+ String s;
+ do // was a "for(;;)" loop, cleaned it -- PB 2003-jun-13
+ {
+ s = ds.readLine();
+ if(s==null)
+ {
+ Debug.talkCritical( "RasODMGImplementation.getBodyLine: Unexpected EOF in rasmgr answer." );
+ throw new IOException("Unexpected EOF in rasmgr answer.");
+ }
+ }
+ while (s.length() != 0);
+
+ String result = ds.readLine();
+ Debug.leaveVerbose( "RasODMGImplementation.getBodyLine done. result=" + result + "." );
+ return result;
+ }
+
+ public void setUserIdentification(String userName, String plainPass)
+ {
+ Debug.enterVerbose( "RasODMGImplementation.setUserIdentification start." );
+
+ MD5 md5 = new MD5();
+ String hex;
+ md5.Init();
+ md5.Update(plainPass);
+ hex = md5.asHex();
+ userIdentification= userName + ":" + hex;
+
+ Debug.leaveVerbose( "RasODMGImplementation.setUserIdentification done." );
+ }
+
+ private String strHostID = null;
+ static private int idcounter = 0;
+
+ private String uniqueRequestID()
+ {
+ Debug.enterVerbose( "RasODMGImplementation.uniqueRequestID start." );
+
+ if(strHostID == null)
+ {
+ long hostid = 0;
+ try
+ {
+ InetAddress addr = InetAddress.getLocalHost();
+ // Get IP Address
+ byte[] ipAddr = addr.getAddress();
+
+ for(int i=0;i<ipAddr.length; i++)
+ {
+ int ss = (int)ipAddr[i];
+ if(ss<0)
+ ss = 256 + ss;
+ hostid = hostid * 256 + ss;
+ }
+ }
+ catch (UnknownHostException e)
+ {
+ Random random = new Random();
+ hostid = random.nextInt();
+ }
+ idcounter = (idcounter + 1) & 0xF;
+ // it's unique enough, we don't need such a huge number
+ strHostID = "" + hostid + ':' + (System.currentTimeMillis() & 0xFFFFFFF0) + idcounter;
+ }
+
+ Debug.leaveVerbose( "RasODMGImplementation.uniqueRequestID done. strHostID=" + strHostID + "." );
+ return strHostID;
+ }
+
+}
+
+//##################################################################################
+/**
+ * Contains internal state of the MD5 class
+ */
+
+class MD5State
+ {
+ /**
+ * 128-byte state
+ */
+ int state[];
+
+ /**
+ * 64-bit character count (could be true Java long?)
+ */
+ int count[];
+
+ /**
+ * 64-byte buffer (512 bits) for storing to-be-hashed characters
+ */
+ byte buffer[];
+
+ public MD5State()
+ {
+ Debug.enterVerbose( "MD5State.constructor start." );
+
+ buffer = new byte[64];
+ count = new int[2];
+ state = new int[4];
+
+ state[0] = 0x67452301;
+ state[1] = 0xefcdab89;
+ state[2] = 0x98badcfe;
+ state[3] = 0x10325476;
+
+ count[0] = count[1] = 0;
+
+ Debug.leaveVerbose( "MD5State.constructor done." );
+ }
+
+ /**
+ Create this State as a copy of another state
+ **/
+ public MD5State (MD5State from)
+ {
+ this();
+
+ Debug.enterVerbose( "MD5State.cloner start." );
+
+ int i;
+
+ for (i = 0; i < buffer.length; i++)
+ this.buffer[i] = from.buffer[i];
+
+ for (i = 0; i < state.length; i++)
+ this.state[i] = from.state[i];
+
+ for (i = 0; i < count.length; i++)
+ this.count[i] = from.count[i];
+
+ Debug.leaveVerbose( "MD5State.cloner done." );
+ }
+
+ }; // MD5State
+
+/**
+ * Implementation of RSA's MD5 hash generator
+ *
+ * @version $Revision: 1.24 $
+ * @author Santeri Paavolainen <sjpaavol@cc.helsinki.fi>
+ */
+
+class MD5
+{
+ /**
+ * MD5 state
+ */
+ MD5State state;
+
+ /**
+ * If Final() has been called, finals is set to the current finals
+ * state. Any Update() causes this to be set to null.
+ */
+ MD5State finals;
+
+ /**
+ * Padding for Final()
+ */
+ static byte padding[] = {
+ (byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ /**
+ * Initialize MD5 internal state (object can be reused just by
+ * calling Init() after every Final()
+ */
+ public synchronized void Init () {
+ state = new MD5State();
+ finals = null;
+ }
+
+ /**
+ * Class constructor
+ */
+ public MD5 () {
+ this.Init();
+ }
+
+ /**
+ * Initialize class, and update hash with ob.toString()
+ *
+ * @param ob Object, ob.toString() is used to update hash
+ * after initialization
+ */
+ public MD5 (Object ob) {
+ this();
+ Update(ob.toString());
+ }
+
+ private int rotate_left (int x, int n) {
+ return (x << n) | (x >>> (32 - n));
+ }
+
+ /* I wonder how many loops and hoops you'll have to go through to
+ get unsigned add for longs in java */
+
+ private int uadd (int a, int b) {
+ long aa, bb;
+ aa = ((long) a) & 0xffffffffL;
+ bb = ((long) b) & 0xffffffffL;
+
+ aa += bb;
+
+ return (int) (aa & 0xffffffffL);
+ }
+
+ private int uadd (int a, int b, int c) {
+ return uadd(uadd(a, b), c);
+ }
+
+ private int uadd (int a, int b, int c, int d) {
+ return uadd(uadd(a, b, c), d);
+ }
+
+ private int FF (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, ((b & c) | (~b & d)), x, ac);
+ return uadd(rotate_left(a, s), b);
+ }
+
+ private int GG (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, ((b & d) | (c & ~d)), x, ac);
+ return uadd(rotate_left(a, s), b);
+ }
+
+ private int HH (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, (b ^ c ^ d), x, ac);
+ return uadd(rotate_left(a, s) , b);
+ }
+
+ private int II (int a, int b, int c, int d, int x, int s, int ac) {
+ a = uadd(a, (c ^ (b | ~d)), x, ac);
+ return uadd(rotate_left(a, s), b);
+ }
+
+ private int[] Decode (byte buffer[], int len, int shift) {
+ int out[];
+ int i, j;
+
+ out = new int[16];
+
+ for (i = j = 0; j < len; i++, j += 4) {
+ out[i] = ((int) (buffer[j + shift] & 0xff)) |
+ (((int) (buffer[j + 1 + shift] & 0xff)) << 8) |
+ (((int) (buffer[j + 2 + shift] & 0xff)) << 16) |
+ (((int) (buffer[j + 3 + shift] & 0xff)) << 24);
+
+/* System.out.println("out[" + i + "] = \t" +
+ ((int) buffer[j + 0 + shift] & 0xff) + "\t|\t" +
+ ((int) buffer[j + 1 + shift] & 0xff) + "\t|\t" +
+ ((int) buffer[j + 2 + shift] & 0xff) + "\t|\t" +
+ ((int) buffer[j + 3 + shift] & 0xff));*/
+ }
+
+ return out;
+ }
+
+ private void Transform (MD5State state, byte buffer[], int shift) {
+ int
+ a = state.state[0],
+ b = state.state[1],
+ c = state.state[2],
+ d = state.state[3],
+ x[];
+
+ x = Decode(buffer, 64, shift);
+
+ /* Round 1 */
+ a = FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
+ d = FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
+ c = FF (c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
+ b = FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
+ a = FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
+ d = FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
+ c = FF (c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
+ b = FF (b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
+ a = FF (a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
+ d = FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
+ c = FF (c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
+ b = FF (b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
+ a = FF (a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
+ d = FF (d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
+ c = FF (c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
+ b = FF (b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ a = GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
+ d = GG (d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
+ c = GG (c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
+ b = GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
+ a = GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
+ d = GG (d, a, b, c, x[10], 9, 0x2441453); /* 22 */
+ c = GG (c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
+ b = GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
+ a = GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
+ d = GG (d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
+ c = GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
+ b = GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
+ a = GG (a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
+ d = GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
+ c = GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
+ b = GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ a = HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
+ d = HH (d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
+ c = HH (c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
+ b = HH (b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
+ a = HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
+ d = HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
+ c = HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
+ b = HH (b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
+ a = HH (a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
+ d = HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
+ c = HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
+ b = HH (b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
+ a = HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
+ d = HH (d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
+ c = HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
+ b = HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ a = II (a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
+ d = II (d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
+ c = II (c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
+ b = II (b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
+ a = II (a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
+ d = II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
+ c = II (c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
+ b = II (b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
+ a = II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
+ d = II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
+ c = II (c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
+ b = II (b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
+ a = II (a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
+ d = II (d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
+ c = II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
+ b = II (b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
+
+ state.state[0] += a;
+ state.state[1] += b;
+ state.state[2] += c;
+ state.state[3] += d;
+ }
+
+ /**
+ * Updates hash with the bytebuffer given (using at maximum length bytes from
+ * that buffer)
+ *
+ * @param state Which state is updated
+ * @param buffer Array of bytes to be hashed
+ * @param offset Offset to buffer array
+ * @param length Use at maximum `length' bytes (absolute
+ * maximum is buffer.length)
+ */
+ public void Update (MD5State stat, byte buffer[], int offset, int length) {
+ int index, partlen, i, start;
+
+/* System.out.print("Offset = " + offset + "\tLength = " + length + "\t");
+ System.out.print("Buffer = ");
+ for (i = 0; i < buffer.length; i++)
+ System.out.print((int) (buffer[i] & 0xff) + " ");
+ System.out.print("\n");*/
+
+ finals = null;
+
+ /* Length can be told to be shorter, but not inter */
+ if ((length - offset)> buffer.length)
+ length = buffer.length - offset;
+
+ /* compute number of bytes mod 64 */
+ index = (int) (stat.count[0] >>> 3) & 0x3f;
+
+ if ((stat.count[0] += (length << 3)) <
+ (length << 3))
+ stat.count[1]++;
+
+ stat.count[1] += length >>> 29;
+
+ partlen = 64 - index;
+
+ if (length >= partlen) {
+ for (i = 0; i < partlen; i++)
+ stat.buffer[i + index] = buffer[i + offset];
+
+ Transform(stat, stat.buffer, 0);
+
+ for (i = partlen; (i + 63) < length; i+= 64)
+ Transform(stat, buffer, i);
+
+ index = 0;
+ } else
+ i = 0;
+
+ /* buffer remaining input */
+ if (i < length) {
+ start = i;
+ for (; i < length; i++)
+ stat.buffer[index + i - start] = buffer[i + offset];
+ }
+ }
+
+ /*
+ * Update()s for other datatypes than byte[] also. Update(byte[], int)
+ * is only the main driver.
+ */
+
+ /**
+ * Plain update, updates this object
+ */
+
+ public void Update (byte buffer[], int offset, int length) {
+ Update(this.state, buffer, offset, length);
+ }
+
+ public void Update (byte buffer[], int length) {
+ Update(this.state, buffer, 0, length);
+ }
+
+ /**
+ * Updates hash with given array of bytes
+ *
+ * @param buffer Array of bytes to use for updating the hash
+ */
+ public void Update (byte buffer[]) {
+ Update(buffer, 0, buffer.length);
+ }
+
+ /**
+ * Updates hash with a single byte
+ *
+ * @param b Single byte to update the hash
+ */
+ public void Update (byte b) {
+ byte buffer[] = new byte[1];
+ buffer[0] = b;
+
+ Update(buffer, 1);
+ }
+
+ /**
+ * Update buffer with given string.
+ *
+ * @param s String to be update to hash (is used as
+ * s.getBytes())
+ */
+ public void Update (String s) {
+ byte chars[];
+
+ /* deprecated chars = new byte[s.length()];
+ s.getBytes(0, s.length(), chars, 0);
+ */
+ chars = s.getBytes();
+
+ Update(chars, chars.length);
+ }
+
+ /**
+ * Update buffer with a single integer (only & 0xff part is used,
+ * as a byte)
+ *
+ * @param i Integer value, which is then converted to
+ * byte as i & 0xff
+ */
+
+ public void Update (int i) {
+ Update((byte) (i & 0xff));
+ }
+
+ private byte[] Encode (int input[], int len) {
+ int i, j;
+ byte out[];
+
+ out = new byte[len];
+
+ for (i = j = 0; j < len; i++, j += 4) {
+ out[j] = (byte) (input[i] & 0xff);
+ out[j + 1] = (byte) ((input[i] >>> 8) & 0xff);
+ out[j + 2] = (byte) ((input[i] >>> 16) & 0xff);
+ out[j + 3] = (byte) ((input[i] >>> 24) & 0xff);
+ }
+
+ return out;
+ }
+
+ /**
+ * Returns array of bytes (16 bytes) representing hash as of the
+ * current state of this object. Note: getting a hash does not
+ * invalidate the hash object, it only creates a copy of the real
+ * state which is finalized.
+ *
+ * @return Array of 16 bytes, the hash of all updated bytes
+ */
+ public synchronized byte[] Final () {
+ byte bits[];
+ int index, padlen;
+ MD5State fin;
+
+ if (finals == null) {
+ fin = new MD5State(state);
+
+ bits = Encode(fin.count, 8);
+
+ index = (int) ((fin.count[0] >>> 3) & 0x3f);
+ padlen = (index < 56) ? (56 - index) : (120 - index);
+
+ Update(fin, padding, 0, padlen);
+ /**/
+ Update(fin, bits, 0, 8);
+
+ /* Update() sets finalds to null */
+ finals = fin;
+ }
+
+ return Encode(finals.state, 16);
+ }
+
+ /**
+ * Turns array of bytes into string representing each byte as
+ * unsigned hex number.
+ *
+ * @param hash Array of bytes to convert to hex-string
+ * @return Generated hex string
+ */
+ public static String asHex (byte hash[]) {
+ StringBuffer buf = new StringBuffer(hash.length * 2);
+ int i;
+
+ for (i = 0; i < hash.length; i++) {
+ if (((int) hash[i] & 0xff) < 0x10)
+ buf.append("0");
+
+ buf.append(Long.toString((int) hash[i] & 0xff, 16));
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Returns 32-character hex representation of this objects hash
+ *
+ * @return String of this object's hash
+ */
+ public String asHex () {
+ return asHex(this.Final());
+ }
+
+} // MD5
+
diff --git a/java/rasj/odmg/RasOID.class b/java/rasj/odmg/RasOID.class
new file mode 100644
index 0000000..6911374
--- /dev/null
+++ b/java/rasj/odmg/RasOID.class
Binary files differ
diff --git a/java/rasj/odmg/RasOID.java b/java/rasj/odmg/RasOID.java
new file mode 100644
index 0000000..9ebd948
--- /dev/null
+++ b/java/rasj/odmg/RasOID.java
@@ -0,0 +1,153 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+
+package rasj.odmg;
+
+import java.util.*;
+
+/**
+ * class represents an object identifier
+ */
+public class RasOID
+{
+ static final String rcsid = "@(#)Package rasj.odmg, class RasOID: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/odmg/RasOID.java,v 1.5 2003/12/10 21:04:30 rasdev Exp $";
+
+ /**
+ * system name
+ */
+ private String systemName;
+
+ /**
+ * database name
+ */
+ private String baseName;
+
+ /**
+ * local oid
+ */
+ private double localOID;
+
+ /**
+ * default constructor
+ */
+ public RasOID()
+ {
+ systemName = "";
+ baseName = "";
+ localOID = 0;
+ }
+
+
+ /**
+ * constructor
+ */
+ public RasOID(String system, String base, double oid)
+ {
+ systemName = system;
+ baseName = base;
+ localOID = oid;
+ }
+
+ /**
+ * String constructor
+ */
+ public RasOID(String oidString)
+ {
+ StringTokenizer str = new StringTokenizer(oidString, "|");
+ if(str.hasMoreTokens())
+ systemName = str.nextToken();
+ if(str.hasMoreTokens())
+ baseName = str.nextToken();
+ if(str.hasMoreTokens())
+ localOID = Double.parseDouble(str.nextToken());
+ }
+
+ /**
+ * returns system name as a string
+ */
+ public String getSystemName()
+ {
+ return systemName;
+ }
+
+ /**
+ * returns database name as a string
+ */
+ public String getBaseName()
+ {
+ return baseName;
+ }
+
+ /**
+ * returns local oid as a double
+ */
+ public double getLocalOID()
+ {
+ return localOID;
+ }
+
+ /**
+ * determines if oid is valid
+ */
+ public boolean isValid()
+ {
+ if (localOID != 0.0)
+ return true;
+ else
+ return false;
+ }
+
+
+ public void rasDeactivate()
+ {
+ if(!systemName.equals(""))
+ {
+ systemName = "";
+ }
+
+ if(!baseName.equals(""))
+ {
+ baseName = "";
+ }
+ }
+
+
+ /** gets the String representation of the oid */
+ public String toString()
+ {
+ return systemName+"|"+baseName+"|"+localOID;
+ }
+
+}
+
diff --git a/java/rasj/odmg/RasOQLQuery.class b/java/rasj/odmg/RasOQLQuery.class
new file mode 100644
index 0000000..08eefbe
--- /dev/null
+++ b/java/rasj/odmg/RasOQLQuery.class
Binary files differ
diff --git a/java/rasj/odmg/RasOQLQuery.java b/java/rasj/odmg/RasOQLQuery.java
new file mode 100644
index 0000000..939a92e
--- /dev/null
+++ b/java/rasj/odmg/RasOQLQuery.java
@@ -0,0 +1,425 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+package rasj.odmg;
+
+import org.odmg.*;
+import rasj.*;
+import rasj.clientcommhttp.*;
+import rasj.global.*;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * This class implements the ODMG OQLQuery interface.
+ *
+ * @version 1.0 (07-Apr-2000)
+ *
+ * @author Peter Zoller
+ */
+public class RasOQLQuery implements OQLQuery, RasCommDefs
+{
+ /**
+ * This variable holds a reference to the RasImplementation object which created
+ * this RasOQLQuery object
+ */
+
+ //private RasODMGImplementation rasImplementation=null;
+ private RasImplementationInterface rasImplementation=null;
+
+ /**
+ * Stores the query string.
+ */
+ private String queryString = "";
+
+ /**
+ * Stores the MDD parameter list
+ */
+ private LinkedList qParams = null;
+
+ /**
+ * Stores the number of MDD parameters
+ */
+ private int numberOfParams = 0;
+
+ /**
+ * Constructor
+ */
+ public RasOQLQuery(RasImplementationInterface imp)//RasODMGImplementation imp)
+ {
+ Debug.enterVerbose( "RasOQLQuery.constructor start." );
+ rasImplementation=imp;
+ Debug.leaveVerbose( "RasOQLQuery.constructor done." );
+ }
+
+ /**
+ * Defines the query to be executed.
+ *
+ * @param query The OQL query string.
+ */
+ public void create(String query) throws QueryInvalidException
+ {
+ Debug.talkVerbose( "RasOQLQuery.create query=" + query );
+ queryString = query;
+ }
+
+ /**
+ * Binds a parameter to the query.
+ */
+ public void bind(Object parameter)
+ throws QueryParameterCountInvalidException, QueryParameterTypeInvalidException
+ {
+ Debug.enterVerbose( "RasOQLQuery.bind start." );
+
+ // add the parameter to the set
+ if(qParams == null) qParams = new LinkedList();
+ qParams.add(parameter);
+ numberOfParams++;
+
+ Debug.enterVerbose( "RasOQLQuery.bind done." );
+ }
+
+ /**
+ * Execute the OQL query.
+ */
+ public Object execute() throws QueryException
+ {
+ Debug.enterVerbose( "RasOQLQuery.execute start." );
+
+ BenchmarkTimer rasjQueryTimer = new BenchmarkTimer("rasjQuery");
+ rasjQueryTimer.startTimer();
+
+ String mddData = null;
+ String params = null;
+ String dummy = null;
+ //RasHttpRequest request;
+ Object item;
+ StringBuffer buff;
+ int offset;
+ int buffIndex;
+ Object result = null;
+
+ try
+ {
+ String errorMsg = "Could not execute OQL-Query: ";
+ // test if database is open
+ if(rasImplementation.dbIsOpen() == 0)
+ {
+ Debug.leaveVerbose( "RasQOLQuery.execute done. database not open." );
+ throw new DatabaseClosedException(errorMsg + "database not open");
+ }
+
+ // test if we have an open transaction
+ params = "ClientID=" + rasImplementation.getClientID() + "&Command=" + RasODMGGlobal.commIsOpenTA;
+
+ /*
+ request = new RasHttpRequest();
+
+ request.execute(rasImplementation.getRasServer(),params);//RasODMGGlobal.getRasServer(),params);
+ if(request.getResultType() == 98)
+ throw new TransactionNotInProgressException(errorMsg + "no open transaction");
+ */
+ if(rasImplementation.isOpenTA()==false)
+ {
+ Debug.leaveVerbose( "RasQOLQuery.execute done. Error: no open transaction." );
+ throw new TransactionNotInProgressException(errorMsg + "no open transaction");
+ }
+
+ // test for correct number of query parameters
+ StringTokenizer strTok = new StringTokenizer(queryString);
+ String token = "";
+ int counter = 0;
+ while(strTok.hasMoreTokens())
+ {
+ token = strTok.nextToken();
+ if(token.charAt(0) == '$')
+ {
+ try
+ {
+ if(Integer.parseInt(token.substring(1, 2)) > counter)
+ counter++;
+ }
+ catch(NumberFormatException e)
+ {
+ // should not happen!
+ Debug.leaveVerbose( "RasOQLQuery.execute done. number format exception in query parsing." );
+ throw new QueryParameterCountInvalidException("There are was a NumberFormatException while parsing the query.");
+ }
+ }
+ }
+ if(counter != numberOfParams)
+ {
+ Debug.leaveVerbose( "RasOQLQuery.execute done. number of parameters does not match query." );
+ throw new QueryParameterCountInvalidException( counter + " variable(s) in the query string vs. " + numberOfParams + " parameter(s) bound to the query.");
+ }
+
+ // process the parameters
+ dummy = queryString.trim();
+ queryString = dummy;
+ if(numberOfParams > 0)
+ {
+ counter = 0;
+ ListIterator iter = qParams.listIterator(0);
+ while (iter.hasNext())
+ {
+ counter++;
+ item = iter.next();
+ if(item instanceof RasGMArray)
+ {
+ // we have a MDD parameter => substitute the $x occurance in
+ // the query string with #MDDx# and get the transfer encoding of
+ // the MDDs. The format is specified in the file
+ // clientcommhttp/RasHttprequest.java.
+ RasGMArray mdd = (RasGMArray)item;
+ if(mddData == null)
+ mddData = utils.getTransferEncoding(mdd);
+ else
+ mddData = mddData + utils.getTransferEncoding(mdd);
+ queryString = utils.substitute(queryString,"$"+counter,"#MDD"+counter+"#");
+ }
+ else
+ {
+ // no MDD parameter => substitute each occurence of the
+ // corresponding $ parameter in the query string with the
+ // value of this parameter
+ queryString = utils.substitute(queryString,"$"+counter,item.toString());
+ iter.remove();
+ numberOfParams--;
+ }
+ }
+ }
+
+ // what kind of query do we have?
+ // FIXME: this way you don't see it keyword is in comment, and you miss mixed case!! -- PB 2003-jun-15
+ if((queryString.indexOf("select") != -1) || (queryString.indexOf("SELECT") != -1))
+ {
+ //select query
+ params = "Command=" + RasODMGGlobal.commQueryExec + "&ClientID=" +
+ rasImplementation.getClientID() + "&QueryString=" + queryString;
+ }
+ else
+ {
+ // update query
+ params = "Command=" + RasODMGGlobal.commUpdateQueryExec + "&ClientID=" +
+ rasImplementation.getClientID() + "&QueryString=" + queryString +
+ "&Endianess=" + BIG_ENDIAN + "&NumberOfQueryParameters=" +
+ numberOfParams;
+ if(numberOfParams > 0)
+ params = params + "&BinDataSize=" + mddData.length() + "&BinData=" + mddData;
+ }
+
+ //request.execute(rasImplementation.getRasServer(),params);//RasODMGGlobal.getRasServer(),params);
+ //return request.getResult();
+ result = rasImplementation.queryRequest(params);
+ }
+ catch(RasQueryExecutionFailedException e)
+ {
+ Debug.leaveVerbose( "RasOQLQuery.execute done. query execution failed: " + e.getMessage() );
+ throw new QueryException(e.getMessage());
+ }
+ catch(IOException e2)
+ {
+ Debug.leaveVerbose( "RasOQLQuery.execute done. error while generating transfer encoding: " + e2.getMessage() );
+ throw new QueryException("Error while generating transfer encoding:\n" + e2.getMessage());
+ }
+
+ rasjQueryTimer.stopTimer();
+ rasjQueryTimer.print();
+
+ Debug.leaveVerbose( "RasOQLQuery.execute done. result=" + result );
+ return result;
+ } // execute()
+
+} // RasOQLQuery
+
+/*
+ * Utilities
+ */
+
+abstract class utils
+ {
+ static String substitute(final String sourceString, final String oldString, final String newString)
+ {
+ Debug.enterVerbose( "utils.substitute start." );
+
+ StringBuffer buff = new StringBuffer(sourceString);
+ int offset = 0;
+ int buffIndex = sourceString.indexOf(oldString,offset);
+ while(buffIndex != -1)
+ {
+ buff.replace(buffIndex,buffIndex+oldString.length(),newString);
+ offset = buffIndex+1;
+ buffIndex = buff.toString().indexOf(oldString,offset);
+ }
+
+ String result = buff.toString();
+ Debug.leaveVerbose( "utils.substitute done. result=" + result );
+ return result;
+ }
+
+ /** returns a byte array representing the GMArray. This byte array is used for uploading query
+ * parameters to the server.
+ * The exact format of the byte array is described in the documentation of class
+ * @see rasj.clientcommhttp.RasHttpRequest.
+ */
+ static String getTransferEncoding(RasGMArray mdd) throws IOException
+ {
+ Debug.enterVerbose( "utils.getTransferEncoding start." );
+
+ String tileDomain = null;
+ RasMInterval domain = mdd.spatialDomain();
+ long typeLength = mdd.getTypeLength();
+
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ DataOutputStream dStream = new DataOutputStream(outStream);
+
+ // get tilingDomain from the storageLayout object
+ if(mdd.getStorageLayout().getSpatialDomain() == null)
+ {
+ tileDomain = getTilingDomain(domain,typeLength,mdd.getStorageLayout());
+ }
+ else
+ tileDomain = mdd.getStorageLayout().getSpatialDomain().toString();
+
+
+ // write object type
+ //dStream.writeInt((int)getObjectType());
+ dStream.writeInt(1);
+ dStream.writeBytes(mdd.getObjectTypeName()+String.valueOf('\0'));
+ dStream.writeBytes(mdd.getTypeStructure()+String.valueOf('\0'));
+ dStream.writeInt((int)typeLength);
+ dStream.writeBytes(domain+String.valueOf('\0'));
+ dStream.writeBytes(tileDomain+String.valueOf('\0'));
+ dStream.writeBytes(mdd.getOID().toString()+String.valueOf('\0'));
+
+ // if we have an MArray of type ulong: test that each cell value does not
+ // exceed 2^32, because the server does only store 4 byte ushorts, and
+ // convert the java-8-byte-long-array to a java-byte-array containing
+ // only the 4 least bytes of each long value.
+ if(mdd instanceof RasMArrayLong)
+ {
+ int arraySize = (int)mdd.getArraySize();
+ byte[] longArray = mdd.getArray();
+ // we skip the first 4 bytes of each long => arraySize / 2
+ dStream.writeInt(arraySize / 2);
+ for(int i=0; i<arraySize; i+=RasGlobalDefs.SIZE_OF_LONG)
+ {
+ for(int j=0; j<4; j++)
+ {
+ // read the first 4 bytes of the former long value and check
+ // if they are 0. If not, the value is too large to fit into
+ // a 4 byte ulong => throw exception
+ if(longArray[i+j] != 0)
+ {
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(longArray));
+ dis.skipBytes(i);
+ long illegalValue = dis.readLong();
+ Debug.leaveVerbose( "utils.getTransferEncoding done. illegal long value." );
+ throw new RasIllegalULongValueException(illegalValue);
+ }
+ }
+ for(int j=4; j<RasGlobalDefs.SIZE_OF_LONG; j++)
+ {
+ // now write the next 4 bytes
+ dStream.writeByte(longArray[i+j]);
+ }
+ }
+ }
+ // if we have an MArray of type ushort: test that each cell value does not
+ // exceed 2^16, because the server does only store 2 byte ushorts, and
+ // convert the java-4-byte-integer-array to a java-byte-array containing
+ // only the 2 least bytes of each integer value.
+ else if(mdd instanceof RasMArrayInteger && mdd.getObjectTypeName().regionMatches(0, "UShort", 0, 5))
+ {
+ int arraySize = (int)mdd.getArraySize();
+ byte[] intArray = mdd.getArray();
+ // we skip the first 2 bytes of each integer => arraySize / 2
+ dStream.writeInt(arraySize / 2);
+ for(int i=0; i<arraySize; i+=RasGlobalDefs.SIZE_OF_INTEGER)
+ {
+ for(int j=0; j<2; j++)
+ {
+ // read the first 2 bytes of the former integer value and check
+ // if they are 0. If not, the value is too large to fit into
+ // a 2 byte ushort => throw exception
+ if(intArray[i+j] != 0)
+ {
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(intArray));
+ dis.skipBytes(i);
+ int illegalValue = dis.readInt();
+ Debug.leaveVerbose( "utils.getTransferEncoding done. illegal short value." );
+ throw new RasIllegalUShortValueException(illegalValue);
+ }
+ }
+ for(int j=2; j<RasGlobalDefs.SIZE_OF_INTEGER; j++)
+ {
+ // now write the next 2 bytes
+ dStream.writeByte(intArray[i+j]);
+ }
+ }
+ }
+ // all marrays other than ulong or ushort
+ else
+ {
+ dStream.writeInt((int)mdd.getArraySize());
+ dStream.write(mdd.getArray());
+ }
+ dStream.flush();
+
+ String result = outStream.toString("8859_1");
+ Debug.leaveVerbose( "utils.getTransferEncoding done. result=" + result );
+ return result;
+ } // getTransferEncoding()
+
+ // calculates the tiling domain based on the original MDD, the type length and the tileSize
+ // of the MDD's storageLayout.
+ static String getTilingDomain(final RasMInterval originalDomain, final long typeLength, final RasStorageLayout layout)
+ {
+ Debug.enterVerbose( "utils.getTilingDomain start." );
+
+ long tileSize = layout.getTileSize();
+ int dim = originalDomain.dimension();
+ double tmp = 1.0/dim;
+ int size=(int)(Math.pow((double)(tileSize / typeLength),tmp))-1;
+
+ String retVal = "0:"+String.valueOf(size);
+ for(int x=1; x<dim; x++)
+ retVal = retVal + ",0:" + size;
+ retVal = "[" + retVal + "]";
+
+ Debug.leaveVerbose( "utils.getTilingDomain done. result=" + retVal );
+ return retVal;
+ }
+
+ } // utils
diff --git a/java/rasj/odmg/RasObject.class b/java/rasj/odmg/RasObject.class
new file mode 100644
index 0000000..c067738
--- /dev/null
+++ b/java/rasj/odmg/RasObject.class
Binary files differ
diff --git a/java/rasj/odmg/RasObject.java b/java/rasj/odmg/RasObject.java
new file mode 100644
index 0000000..d24f966
--- /dev/null
+++ b/java/rasj/odmg/RasObject.java
@@ -0,0 +1,244 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+
+package rasj.odmg;
+
+import rasj.*;
+import rasj.global.*;
+import org.odmg.*;
+
+public class RasObject implements RasGlobalDefs
+{
+ static final String rcsid = "@(#)Package rasj.odmg, class RasObject: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/odmg/RasObject.java,v 1.9 2003/12/10 21:04:30 rasdev Exp $";
+
+ /**
+ * stores object name if it has one
+ */
+ protected String objectName;
+
+ /**
+ * stores object type name if it has one
+ */
+ private String typeName;
+
+ private int status;
+ private int lock;
+ private int type;
+ private String typeStructure = "";
+
+ /**
+ * object identifier
+ */
+ private RasOID oid;
+
+ /**
+ * default constructor
+ */
+ public RasObject()
+ {
+ objectName = "";
+ typeName = "";
+ status = 0;
+ lock = 0;
+ oid = new RasOID();
+ type = 0;
+ }
+
+ public RasObject(int objType)
+ {
+ objectName = "";
+ typeName = "";
+ status = 0;
+ lock = 0;
+ oid = new RasOID();
+ type = objType;
+ }
+
+ public RasObject(RasObject obj, int objType)
+ {
+ objectName = "";
+ typeName = "";
+ status = 0;
+ lock = 0;
+ oid = new RasOID();
+ type = objType;
+ }
+
+ /**
+ * get oid
+ */
+ public RasOID getOID()
+ {
+ return oid;
+ }
+
+ /**
+ * set oid
+ */
+ public void setOID(RasOID o)
+ {
+ oid = o;
+ }
+
+ /**
+ * set object name
+ */
+ public void setObjectName(String name) throws RasInvalidNameException
+ {
+ verifyName(name);
+
+ objectName = name;
+ }
+
+ /**
+ * set object type
+ */
+ public void setObjectType(int t)
+ {
+ type = t;
+ }
+
+ /**
+ * set object type
+ */
+ public void setObjectTypeName(String name) throws RasInvalidNameException
+ {
+ verifyName(name);
+
+ typeName = name;
+ }
+
+ /**
+ * set object type structure
+ */
+ public void setTypeStructure(String structure)
+ {
+ typeStructure = structure;
+ }
+
+ /**
+ * get type Structure
+ */
+ public String getTypeStructure()
+ {
+ return typeStructure;
+ }
+
+ /**
+ * get object name
+ */
+ public String getObjectName()
+ {
+ return objectName;
+ }
+
+ /**
+ * get object status
+ */
+ public int getStatus()
+ {
+ return status;
+ }
+
+
+ /**
+ * get object type
+ */
+ public int getObjectType()
+ {
+ return type;
+ }
+
+ /**
+ * get object typeName
+ */
+ public String getObjectTypeName()
+ {
+ return typeName;
+ }
+
+ /**
+ * set object status
+ */
+ public void setStatus(int newStatus)
+ {
+ status = newStatus;
+ }
+
+ /**
+ * get object lock
+ */
+ public int getLock()
+ {
+ return lock;
+ }
+
+ /**
+ * set object lock
+ */
+ public void setLock(int lockMode)
+ {
+ lock = lockMode;
+ }
+
+ public void rasDeactivate()
+ {
+ objectName = "";
+ status = 0;
+ lock = 0;
+ oid.rasDeactivate();
+ }
+
+ public RasType getTypeSchema()
+ {
+ return null;
+ }
+
+
+ private void verifyName(String name) throws RasInvalidNameException
+ {
+ for(int i = 0;i < name.length(); i++)
+ {
+ char c = name.charAt(i);
+
+ if(c == '_' || Character.isLetter(c)) continue;
+
+ if(Character.isDigit(c) && i > 0) continue;
+
+ throw new RasInvalidNameException(name);
+ }
+ }
+
+}
+
diff --git a/java/rasj/odmg/RasSet.class b/java/rasj/odmg/RasSet.class
new file mode 100644
index 0000000..2a6e974
--- /dev/null
+++ b/java/rasj/odmg/RasSet.class
Binary files differ
diff --git a/java/rasj/odmg/RasSet.java b/java/rasj/odmg/RasSet.java
new file mode 100644
index 0000000..a38f33d
--- /dev/null
+++ b/java/rasj/odmg/RasSet.java
@@ -0,0 +1,172 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+
+package rasj.odmg;
+
+import org.odmg.*;
+import java.util.*;
+
+/**
+ * This class implements the ODMG DSet interface.
+ * @version $Revision: 1.7 $
+ */
+public class RasSet extends RasCollection implements DSet
+
+{
+ static final String rcsid = "@(#)Package rasj.odmg, class RasSet: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/odmg/RasSet.java,v 1.7 2003/12/19 15:42:56 rasdev Exp $";
+
+ Set content;
+
+ /**
+ * constructor
+ */
+ public RasSet()
+ {
+ content = new HashSet();
+ }
+
+ /**
+ * Returns an iterator over the elements in this Set in proper sequence.
+ */
+ public Iterator iterator()
+ {
+ return content.iterator();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DSet difference(DSet otherSet)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DSet intersection(DSet otherSet)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public boolean properSubsetOf(DSet otherSet)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public boolean properSupersetOf(DSet otherSet)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public boolean subsetOf(DSet otherSet)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public boolean supersetOf(DSet otherSet)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public DSet union(DSet otherSet)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Appends the specified element to this Bag.
+ */
+ public boolean add(Object element)
+ {
+ return content.add(element);
+ }
+
+ /**
+ * Removes all of the elements from this set.
+ */
+ public void clear()
+ {
+ content.clear();
+ }
+
+ /**
+ * Returns true if this set contains the specified element.
+ */
+ public boolean contains(Object o)
+ {
+ return content.contains(o);
+ }
+
+ /**
+ * Returns true if this set contains no elements.
+ */
+ public boolean isEmpty()
+ {
+ return content.isEmpty();
+ }
+
+ /**
+ * Removes the given element from this set if it is present.
+ */
+ public boolean remove(Object o)
+ {
+ return content.remove(o);
+ }
+
+ /**
+ * Returns the number of elements in this Set.
+ */
+ public int size()
+ {
+ return content.size();
+ }
+
+}
+
diff --git a/java/rasj/odmg/RasTransaction.LOCAL_isOpenTA b/java/rasj/odmg/RasTransaction.LOCAL_isOpenTA
new file mode 100644
index 0000000..10ea687
--- /dev/null
+++ b/java/rasj/odmg/RasTransaction.LOCAL_isOpenTA
@@ -0,0 +1,173 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+package rasj.odmg;
+
+import org.odmg.*;
+import rasj.*;
+import rasj.global.*;
+import rasj.clientcommhttp.*;
+
+/**
+ * This class implements the ODMG Transaction interface.
+ *
+ * @version 1.0 (07-Apr-2000)
+ *
+ * @author Peter Zoller
+ */
+public class RasTransaction implements Transaction
+{
+ /**
+ * This variable holds a reference to the RasODMGImplementation object which created
+ * this RasDatabase object
+ */
+ //private RasODMGImplementation rasImplementation=null;
+ private RasImplementationInterface rasImplementation=null;
+
+ /**
+ * local state keeper whether TA is open;
+ * serves to optimize OQL queries: special method isOpenLocally() does not require server calls
+ */
+ private boolean isOpenTA = false;
+
+ public RasTransaction(RasImplementationInterface imp)
+ {
+ rasImplementation=imp;
+ isOpenTA = false; // local state keeper, maintained by TA methods
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void join()
+ {
+ Debug.talkCritical( "RasTransaction::join: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void leave()
+ {
+ Debug.talkCritical( "RasTransaction::leave: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Begin a transaction.
+ */
+ public void begin()
+ {
+ rasImplementation.beginTA();
+ isOpenTA = true; // TA is considered open if everything went fine.
+ }
+
+ /**
+ * Returns TRUE if a transaction is currently open.
+ */
+ public boolean isOpen()
+ {
+ boolean result = rasImplementation.isOpenTA();
+ Debug.talkVerbose( "RasTransaction::isOpen: result=" + result );
+ return result;
+ }
+
+ /**
+ * Returns TRUE if a transaction is supposed to be open as seen from client side.
+ * This is an optimization to save one server call within query execution,
+ * it is NOT an official interface method.
+ */
+ public boolean isOpenLocally()
+ {
+ boolean result = isOpenTA;
+ Debug.talkVerbose( "RasTransaction::isOpenLocally: result=" + result );
+ return result;
+ }
+
+ /**
+ * Commit a transaction.
+ */
+ public void commit()
+ {
+ isOpenTA = false; // if commit fails something went wrong, so consider TA closed anyway
+ rasImplementation.commitTA();
+ }
+
+ /**
+ * Abort a transaction.
+ */
+ public void abort()
+ {
+ isOpenTA = false; // if abort tails something went wrong, so consider TA closed anyway
+ rasImplementation.abortTA();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void checkpoint()
+ {
+ Debug.talkCritical( "RasTransaction::checkpoint: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void lock(Object obj, int mode) throws LockNotGrantedException
+ {
+ Debug.talkCritical( "RasTransaction::lock: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public boolean tryLock(Object obj, int mode)
+ {
+ Debug.talkCritical( "RasTransaction::tryLock: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Returns the errorStatus.
+ */
+
+ public String getErrorStatus()
+ {
+ String result = rasImplementation.getErrorStatus();
+ Debug.talkSparse( "RasTransaction::getErrorStatus: status=" + result );
+ return result;
+ }
+
+} // RasTransaction
diff --git a/java/rasj/odmg/RasTransaction.class b/java/rasj/odmg/RasTransaction.class
new file mode 100644
index 0000000..1bca570
--- /dev/null
+++ b/java/rasj/odmg/RasTransaction.class
Binary files differ
diff --git a/java/rasj/odmg/RasTransaction.java b/java/rasj/odmg/RasTransaction.java
new file mode 100644
index 0000000..10ea687
--- /dev/null
+++ b/java/rasj/odmg/RasTransaction.java
@@ -0,0 +1,173 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+package rasj.odmg;
+
+import org.odmg.*;
+import rasj.*;
+import rasj.global.*;
+import rasj.clientcommhttp.*;
+
+/**
+ * This class implements the ODMG Transaction interface.
+ *
+ * @version 1.0 (07-Apr-2000)
+ *
+ * @author Peter Zoller
+ */
+public class RasTransaction implements Transaction
+{
+ /**
+ * This variable holds a reference to the RasODMGImplementation object which created
+ * this RasDatabase object
+ */
+ //private RasODMGImplementation rasImplementation=null;
+ private RasImplementationInterface rasImplementation=null;
+
+ /**
+ * local state keeper whether TA is open;
+ * serves to optimize OQL queries: special method isOpenLocally() does not require server calls
+ */
+ private boolean isOpenTA = false;
+
+ public RasTransaction(RasImplementationInterface imp)
+ {
+ rasImplementation=imp;
+ isOpenTA = false; // local state keeper, maintained by TA methods
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void join()
+ {
+ Debug.talkCritical( "RasTransaction::join: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void leave()
+ {
+ Debug.talkCritical( "RasTransaction::leave: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Begin a transaction.
+ */
+ public void begin()
+ {
+ rasImplementation.beginTA();
+ isOpenTA = true; // TA is considered open if everything went fine.
+ }
+
+ /**
+ * Returns TRUE if a transaction is currently open.
+ */
+ public boolean isOpen()
+ {
+ boolean result = rasImplementation.isOpenTA();
+ Debug.talkVerbose( "RasTransaction::isOpen: result=" + result );
+ return result;
+ }
+
+ /**
+ * Returns TRUE if a transaction is supposed to be open as seen from client side.
+ * This is an optimization to save one server call within query execution,
+ * it is NOT an official interface method.
+ */
+ public boolean isOpenLocally()
+ {
+ boolean result = isOpenTA;
+ Debug.talkVerbose( "RasTransaction::isOpenLocally: result=" + result );
+ return result;
+ }
+
+ /**
+ * Commit a transaction.
+ */
+ public void commit()
+ {
+ isOpenTA = false; // if commit fails something went wrong, so consider TA closed anyway
+ rasImplementation.commitTA();
+ }
+
+ /**
+ * Abort a transaction.
+ */
+ public void abort()
+ {
+ isOpenTA = false; // if abort tails something went wrong, so consider TA closed anyway
+ rasImplementation.abortTA();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void checkpoint()
+ {
+ Debug.talkCritical( "RasTransaction::checkpoint: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void lock(Object obj, int mode) throws LockNotGrantedException
+ {
+ Debug.talkCritical( "RasTransaction::lock: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public boolean tryLock(Object obj, int mode)
+ {
+ Debug.talkCritical( "RasTransaction::tryLock: not yet implemented." );
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Returns the errorStatus.
+ */
+
+ public String getErrorStatus()
+ {
+ String result = rasImplementation.getErrorStatus();
+ Debug.talkSparse( "RasTransaction::getErrorStatus: status=" + result );
+ return result;
+ }
+
+} // RasTransaction
diff --git a/java/rasj/odmg/RasTransaction.java.ORIG b/java/rasj/odmg/RasTransaction.java.ORIG
new file mode 100644
index 0000000..29b7c90
--- /dev/null
+++ b/java/rasj/odmg/RasTransaction.java.ORIG
@@ -0,0 +1,146 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/** ***********************************************************
+ * <pre>
+ *
+ * PURPOSE:
+ *
+ *
+ *
+ * COMMENTS:
+ *
+ * </pre>
+ *********************************************************** */
+package rasj.odmg;
+
+import org.odmg.*;
+import rasj.*;
+import rasj.clientcommhttp.*;
+import rasj.global.*;
+
+/**
+ * This class implements the ODMG Transaction interface.
+ *
+ * @version 1.0 (07-Apr-2000)
+ *
+ * @author Peter Zoller
+ */
+public class RasTransaction implements Transaction
+{
+ /**
+ * This variable holds a reference to the RasODMGImplementation object which created
+ * this RasDatabase object
+ */
+ //private RasODMGImplementation rasImplementation=null;
+ private RasImplementationInterface rasImplementation=null;
+
+
+ public RasTransaction(RasImplementationInterface imp)
+ {
+ rasImplementation=imp;
+ }
+ /**
+ * Not implemented yet.
+ */
+ public void join()
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void leave()
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Begin a transaction.
+ */
+ public void begin()
+ {
+
+ rasImplementation.beginTA();
+ }
+
+ /**
+ * Returns TRUE if a transaction is currently open.
+ */
+ public boolean isOpen()
+ {
+ Debug.talkCritical( "RasTransaction::isOpen: calling rasImplementation.isOpenTA()" );
+ return rasImplementation.isOpenTA();
+ }
+
+ /**
+ * Commit a transaction.
+ */
+ public void commit()
+ {
+
+ rasImplementation.commitTA();
+ }
+
+ /**
+ * Abort a transaction.
+ */
+ public void abort()
+ {
+ rasImplementation.abortTA();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void checkpoint()
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public void lock(Object obj, int mode) throws LockNotGrantedException
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Not implemented yet.
+ */
+ public boolean tryLock(Object obj, int mode)
+ {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Returns the errorStatus.
+ */
+
+ public String getErrorStatus()
+ {
+ return rasImplementation.getErrorStatus();
+ }
+
+}
diff --git a/java/rasj/odmg/utils.class b/java/rasj/odmg/utils.class
new file mode 100644
index 0000000..3b868a0
--- /dev/null
+++ b/java/rasj/odmg/utils.class
Binary files differ