diff options
author | Constantin <jucovschi@gmail.com> | 2010-06-14 11:27:05 +0200 |
---|---|---|
committer | Constantin <jucovschi@gmail.com> | 2010-06-14 11:49:18 +0200 |
commit | 82821f8a31e5f98c27dced51f1bba0fc6637d598 (patch) | |
tree | da9cfb35536e1bcfc9076688420da0e0f0bb6efe /java/src/rasj | |
parent | 45325282eaf5e902962bd39d3c8b5aaf14a505d5 (diff) | |
download | rasdaman-upstream-82821f8a31e5f98c27dced51f1bba0fc6637d598.tar.gz rasdaman-upstream-82821f8a31e5f98c27dced51f1bba0fc6637d598.tar.xz rasdaman-upstream-82821f8a31e5f98c27dced51f1bba0fc6637d598.zip |
changed build system of java/ folder from makefile to ant (big compilation time improvement)
Diffstat (limited to 'java/src/rasj')
108 files changed, 26321 insertions, 0 deletions
diff --git a/java/src/rasj/Makefile b/java/src/rasj/Makefile new file mode 100644 index 0000000..b0e86e8 --- /dev/null +++ b/java/src/rasj/Makefile @@ -0,0 +1,102 @@ +# -*-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 +# +# COMMENTS: +# - FIXME: needs Makefile.rel for java.class rule, but Makefile.rel +# should be reserved for RDBMS modules +################################################################## +######################### Definitions ############################ + +# standard include with general options +include $(RMANBASE)/Makefile.inc + + +SRCS = RasBaseType.java RasClientInternalException.java RasCollectionType.java \ + RasConnectionFailedException.java RasDimensionMismatchException.java \ + RasException.java RasFastScale.java RasGMArray.java RasIllegalULongValueException.java \ + RasIllegalUShortValueException.java RasImplementation.java RasImplementationInterface.java \ + RasIndexOutOfBoundsException.java RasInvalidNameException.java RasMArrayByte.java \ + RasMArrayDouble.java RasMArrayFloat.java RasMArrayInteger.java RasMArrayLong.java \ + RasMArrayShort.java RasMArrayType.java RasMInterval.java RasMIntervalType.java \ + RasOIDType.java RasPoint.java RasPointType.java RasPrimitiveType.java \ + RasQueryExecutionFailedException.java RasResultIsNoCellException.java \ + RasResultIsNoIntervalException.java RasRuntimeException.java RasSInterval.java \ + RasSIntervalType.java RasStorageLayout.java RasStreamInputOverflowException.java \ + RasStructureType.java RasType.java RasTypeInvalidException.java \ + RasTypeNotSupportedException.java RasTypeUnknownException.java +OBJS = ${SRCS:%.java=%.class} +MISCCLEAN = *.class + +# directory where HTML documentation is created +DOCDIR_JAVA := $(DOCBASE)/rasj/ + +########################### Targets ############################## + +# compile everything +.PHONY : all +all: $(OBJS) + cd clientcommhttp; $(MAKE) + cd odmg; $(MAKE) + cd global; $(MAKE) + cd rnp; $(MAKE) + +# run test suite +.PHONY: systemtest +systemtest: + cd test; $(MAKE) systemtest + +# generate HTML doc +.PHONY: docu +docu: + mkdir -p $(DOCDIR_RASJ) + $(JAVADOC) -breakiterator -private -author -d $(DOCDIR_RASJ) -sourcepath $(RMANBASE)/java \ + rasj rasj.clientcommhttp rasj.odmg rasj.global rasdaview org.odmg examples + chmod -R g+w $(DOCDIR_RASJ) + cd test; $(MAKE) docu + +# delete classes +.PHONY : clean +clean: + -rm -f $(MISCCLEAN) + cd clientcommhttp; $(MAKE) clean + cd odmg; $(MAKE) clean + cd global; $(MAKE) clean + cd test; $(MAKE) clean + cd rnp; $(MAKE) clean + +# report environment used: +check: + echo CLASSPATH=$(CLASSPATH) + echo PATH=$(PATH) + echo JAVA_HOME=$(JAVA_HOME) + echo JSDK_HOME=$(JSDK_HOME) + java -version + +############################ Dependencies ####################### + +# FIXME: remove this dependency, establish .java.class rule in a general place +include $(RMANBASE)/Makefile.rel diff --git a/java/src/rasj/Makefile.dep b/java/src/rasj/Makefile.dep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/java/src/rasj/Makefile.dep diff --git a/java/src/rasj/RasBaseType.java b/java/src/rasj/RasBaseType.java new file mode 100644 index 0000000..53add89 --- /dev/null +++ b/java/src/rasj/RasBaseType.java @@ -0,0 +1,109 @@ +package rasj; + +/* +* 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: + * This class represents the Base types and is the superclass of + * the types RasStructureType and RasPrimitiveType in the + * representation of the RasDaMan type system. + * <P> + * <B>Note:</B> if a new base type is created using this class, it is only known on client-side but not + * stored within the database. If you want to introduce a new type for the RasDaMan system, you + * should use the "rasdl" utility. + * </P> + * @version $Revision: 1.6 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasBaseType extends RasType +{ + static final String rcsid = "@(#)Package rasj, class RasBaseType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasBaseType.java,v 1.6 2003/12/10 21:04:23 rasdev Exp $"; + + /** + * Stores the size of type in bytes + **/ + protected long typeSize; + + /** + * Default constructor. + **/ + public RasBaseType() + { + super(); + typeSize = 0; + } + + /** + * Constructor getting name of basetype. + * @param newTypeName name of the new base type + * @param newSize size of the new base type + **/ + public RasBaseType(String newTypeName, long newSize) + { + super(newTypeName); + typeSize = newSize; + } + + /** + * Retrieves the id of the type. + * @return the id of the type + **/ + public int getTypeID() + { + return 0; + } + + /** + * Checks if the current type is a base type (primitive type or structure type). + * @return true if it is a base type, false otherwise. + **/ + public boolean isBaseType() + { + return true; + } + + /** + * Retrieves the size of the type. + * @return the size of the base type. + **/ + public long getSize() + { + return typeSize; + } + + /** + * Returns a string representation of this object. + * @return a string description of this object. + **/ + public String toString() + { + return super.toString() + "typeSize: " + typeSize + "\n"; + } +} diff --git a/java/src/rasj/RasClientInternalException.java b/java/src/rasj/RasClientInternalException.java new file mode 100644 index 0000000..84726ff --- /dev/null +++ b/java/src/rasj/RasClientInternalException.java @@ -0,0 +1,93 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This runtime exception indicates an internal error on client-side , which cannot + * be solved by the user. In case of such an event, please send a bug message to + * info@active-knowledge.de containing the complete error message and a precise + * description of the actions that lead to this exception. + * @version $Revision: 1.4 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasClientInternalException extends RasRuntimeException +{ + static final String rcsid = "@(#)Package rasj, class RasException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasClientInternalException.java,v 1.4 2003/12/19 16:22:27 rasdev Exp $"; + + private int errNo = 0; + private String errText = null; + private String cName = null; + private String mName = null; + + /** + * standard constructor. + **/ + public RasClientInternalException(String className, String methodName, String msg) + { + errNo = RasGlobalDefs.INTERNAL_CLIENT_ERROR; + errText = ( (msg==null) ? "(none)" : msg ); + cName = ( (className==null) ? "(none)" : className ); + mName = ( (methodName==null) ? "(none)" : methodName ); + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + int index; + + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + index = msg.indexOf( RasGlobalDefs.KEYWORD_CLASS ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_CLASS.length(), cName); + msg = buf.toString(); + + buf = new StringBuffer(msg); + index = msg.indexOf( RasGlobalDefs.KEYWORD_METHOD ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_METHOD.length(), mName); + msg = buf.toString(); + + buf = new StringBuffer(msg); + index = msg.indexOf( RasGlobalDefs.KEYWORD_CODE ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_CODE.length(), errText); + msg = buf.toString(); + return msg; + } + +} diff --git a/java/src/rasj/RasCollectionType.java b/java/src/rasj/RasCollectionType.java new file mode 100644 index 0000000..6a9e3a3 --- /dev/null +++ b/java/src/rasj/RasCollectionType.java @@ -0,0 +1,96 @@ +package rasj; + +import rasj.*; +import rasj.global.*; +import java.util.*; + +/* +* 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: + * This class represents the Collection type in the ODMG conformant + * representation of the RasDaMan type system. + * @version $Revision: 1.6 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasCollectionType extends RasType +{ + static final String rcsid = "@(#)Package rasj, class RasCollectionType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasCollectionType.java,v 1.6 2003/12/10 21:04:23 rasdev Exp $"; + + private RasType elementType; + + /** + * Simple constructor. + **/ + public RasCollectionType() + { + super(); + elementType = null; + } + + /** + * Constructor getting the element type of the new collection type. + * @param type the element type of the new collection type + **/ + public RasCollectionType(RasType type) + { + super("RAS_COLLECTION"); + typeID = RasGlobalDefs.RAS_COLLECTION; + elementType = type; + } + + /** + * Retrieves the collection type's element type. + * @return the element type of this collection type + **/ + public RasType getElementType() + { + return elementType; + } + + /** + * Returns the type of this object (which is RAS_SET in this case). + * @return the type of this object (RAS_SET) + **/ + public String getKind() + { + return "RAS_SET"; + } + + /** + * Creates a string representation of this object. + * @return the string representation of this object + **/ + public String toString() + { + return super.toString() + "ElementType of Set: \n" + elementType + "\n "; + } +} diff --git a/java/src/rasj/RasConnectionFailedException.java b/java/src/rasj/RasConnectionFailedException.java new file mode 100644 index 0000000..54cfa07 --- /dev/null +++ b/java/src/rasj/RasConnectionFailedException.java @@ -0,0 +1,105 @@ +package rasj; + +import rasj.global.*; +import org.odmg.*; + +/* +* 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: + * This exception is raised when the connection to the RasDaMan server fails. This typically happens + * when the RasDaMan server is either not running or unable to connect to the base DBMS. Also + * communication failures between RasManager and RasServer may produce this kind of exception. + * @version $Revision: 1.8 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasConnectionFailedException extends ODMGRuntimeException +{ + static final String rcsid = "@(#)Package rasj.clientcommhttp, class RasConnectionFailedException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasConnectionFailedException.java,v 1.8 2003/12/19 16:22:27 rasdev Exp $"; + + /** + * The RasDaMan erro number + **/ + private int errorNo = 0; + + /** + * Optional parameter + **/ + private String param = null; + + /** + * Default constructor taking the rasdaman error number and an optional parameter. + * @param errNo the rasdaman error number + * @param parameter optional parameter that can be inserted into the error message + **/ + public RasConnectionFailedException(int errNo, String parameter) + { + super(); + errorNo = errNo; + param = ( (parameter==null) ? "(null)" : parameter ); + } + + /** + * Returns the RasDaMan error number + */ + public int getErrorNo() + { + return errorNo; + } + + /** + * Returns the error message. + **/ + public String getMessage() + { + String msg = super.getMessage(); + if(msg == null) + { + msg = RasErrorTexts.getErrorMessage(errorNo); + int index = 0; + + // replace parameters + switch(errorNo) + { + case RasGlobalDefs.MANAGER_CONN_FAILED: + StringBuffer buf = new StringBuffer(msg); + index = msg.indexOf( RasGlobalDefs.KEYWORD_URL ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_URL.length(), param); + msg = buf.toString(); + break; + } + } + return msg; + } + + +} diff --git a/java/src/rasj/RasDimensionMismatchException.java b/java/src/rasj/RasDimensionMismatchException.java new file mode 100644 index 0000000..9f1cf1b --- /dev/null +++ b/java/src/rasj/RasDimensionMismatchException.java @@ -0,0 +1,107 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This exception is thrown if the dimensions of two objects do not match. + * @version $Revision: 1.6 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasDimensionMismatchException extends RasException +{ + static final String rcsid = "@(#)Package rasj, class RasDimensionMismatchException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasDimensionMismatchException.java,v 1.6 2003/12/19 16:22:27 rasdev Exp $"; + + // first dimensionality + private long dim1; + // second dimensionality + private long dim2; + + /** + * Standard constructor getting two dimensionalities. + * @param pdim1 the dimension of the first object + * @param pdim2 the dimension of the second object + **/ + protected RasDimensionMismatchException( long pdim1, long pdim2) + { + super(RasGlobalDefs.DIMENSION_MISMATCH); + dim1 = pdim1; + dim2 = pdim2; + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + int index; + + if(super.getMessage() == null) + { + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + index = msg.indexOf( RasGlobalDefs.KEYWORD_DIM1 ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_DIM1.length(), String.valueOf(dim1)); + msg = buf.toString(); + index = msg.indexOf( RasGlobalDefs.KEYWORD_DIM1 ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_DIM1.length(), String.valueOf(dim2)); + msg = buf.toString(); + return msg; + } + else + return super.getMessage(); + } + + /** + * Returns the dimension of the first object. + * @return the dimension of the first object + **/ + public long getDim1() + { + return dim1; + } + + /** + * Returns the dimension of the second object. + * @return the dimension of the second object + **/ + public long getDim2() + { + return dim2; + } +} diff --git a/java/src/rasj/RasException.java b/java/src/rasj/RasException.java new file mode 100644 index 0000000..4e02e08 --- /dev/null +++ b/java/src/rasj/RasException.java @@ -0,0 +1,104 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This is the superclass of all exceptions in the rasj package, except for + * {@link rasj.RasQueryExecutionFailedException RasQueryExecutionFailedException}. + * @see rasj.RasRuntimeException + * @version $Revision: 1.6 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasException extends Exception +{ + static final String rcsid = "@(#)Package rasj, class RasException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasException.java,v 1.6 2003/12/19 16:22:27 rasdev Exp $"; + + protected int errNo = 0; + protected String errText = null; + + /** + * Standard constructor. + **/ + protected RasException() + { + } + + /** + * Constructor getting the error number. + * @param num the RasDaMan error number + **/ + protected RasException( int num ) + { + errNo = num; + } + + /** + * Constructor getting the error message. + * @param msg the error message + **/ + protected RasException( String msg ) + { + errText = ( (msg==null) ? "(null)" : msg ); + } + + /** + * Constructor getting error number and error message. + * @param num the RasDaMan error number + * @param msg the error message + **/ + protected RasException( int num, String msg ) + { + errNo = num; + errText = ( (msg==null) ? "(null)" : msg ); + } + + /** + * Method for retrieving the error number. + * @return the error number + **/ + public int getErrNo() + { + return errNo; + } + + /** + * Method retrieving the error message. + * @return the error message + **/ + public String getMessage() + { + return errText; + } + +} diff --git a/java/src/rasj/RasFastScale.java b/java/src/rasj/RasFastScale.java new file mode 100644 index 0000000..bbc21f4 --- /dev/null +++ b/java/src/rasj/RasFastScale.java @@ -0,0 +1,361 @@ +package rasj; + +import rasj.clientcommhttp.*; +import rasj.odmg.*; +import rasj.global.*; +import org.odmg.*; + +import java.io.*; +import java.net.*; +import java.util.*; +import java.sql.*; + +/* +* 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: + * Abstract base class for fast scaling + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +abstract class RasFastBaseScale implements RasGlobalDefs +{ + + OQLQuery query = null; + String collectionName = null; + RasMInterval fullDomain = null; + double lastScaleUsed; + + /** + * Default constructor. + * + * This constructor gets the name of the image collection and and an OQLQuery object as parameters. + * <P><B>Important:</B>This class does not open its own connection to the database nor start or + * commit any transactions. This has to be done by the application using FastScale.</P> + * @param collection the name of the collection containing the image(s) + * @param queryObject the OQLQuery object for connecting to the database + **/ + public RasFastBaseScale( final String collection, final OQLQuery queryObject ) + { + collectionName = collection; + query = queryObject; + fullDomain = readFullDomain(collectionName); + } + + /** + * Returns the full (unscaled) Domain of the image. + * @return the original domain of the image + **/ + public final RasMInterval getFullDomain() + { + return fullDomain; + } + + /** + * Returns the scaled domain of the image. + **/ + public RasMInterval scaleGetDomain( final RasMInterval areaOp, final RasPoint origin, double scale) + throws RasClientInternalException + { + try + { + int i; + int dim = areaOp.dimension(); + RasMInterval areaScale = new RasMInterval(dim); + + for( i=0 ; i<dim ; i++ ) + { + int low, high; + + // simple trafo of low coordinate + low = (int)(origin.item(i) + (areaOp.item(i).low() - origin.item(i)) * scale); + + // for the high coordinate use the low coordinate of the _next_ tile + // ( = areaOp.item(i).high() + 1 ) and subtract 1 ==> seamless tiling. + high = (int)(origin.item(i) + + (areaOp.item(i).high() + 1 - origin.item(i)) * scale - 1); + +/* FIXME At some point we need to have a clean design + // now make sure these values transformed back into the original domain are legal + // values. Due to floor rounding low <= true_low, i.e. underflow is possible. + if ((int)((low - origin.item(i)) / scale) < areaOp.item(i).low() - origin.item(i)) + { + low++; + } + + // Because of floor rounding, high is always legal. However, if the low + // coordinate of the next tile underflows, the high value of this one would + // no longer match seamlessly. Therefore we have to check whether the cell + // at high+1 transformed back into the original domain is a legal value too + // and use that as the real high boundary if so. + if ((int)((high+1 - origin.item(i)) / scale) <= + areaOp.item(i).high() - origin.item(i)) + { + high++; + } +*/ + + if (high < low) + return null; + + areaScale.stream(new RasSInterval(low, high)); + + } + return areaScale; + } + catch(RasIndexOutOfBoundsException e1) + { + throw new RasClientInternalException("RasFastBaseScale","scaleGetDomain",e1.getMessage()); + } + catch(RasStreamInputOverflowException e2) + { + throw new RasClientInternalException("RasFastBaseScale","scaleGetDomain",e2.getMessage()); + } + catch(RasResultIsNoIntervalException e3) + { + throw new RasClientInternalException("RasFastBaseScale","scaleGetDomain",e3.getMessage()); + } + } + + /** + * Reads the full domain of the given image. This method is called in the RasFastScale constructor. + * @param name name of the collection containing the image + * @return the full domain of the image + **/ + protected RasMInterval readFullDomain(String collection) throws RasClientInternalException + { + try { + query.create("SELECT sdom(img) FROM " + collection + " AS img"); + DBag resultBag = (DBag)query.execute(); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + if(iter.hasNext()) + return (RasMInterval)iter.next(); + else + throw new RasClientInternalException("RasFastScale","readFullDomain","query produced no result."); + } + else + throw new RasClientInternalException("RasFastScale","readFullDomain","query produced no result."); + + } + catch(Exception e1) { + throw new RasClientInternalException("RasFastScale","readFullDomain",e1.getMessage()); + } + } + + /** + * gets the minimal array + **/ + protected RasGMArray getMinimalArray(final String collection) throws RasClientInternalException + { + try { + RasMInterval iv; + iv = readFullDomain(collection); + RasMInterval getDomain = new RasMInterval(iv.dimension()); + int i; + for(i=0 ; i<iv.dimension() ; i++) + { + // we actually only get one point. + getDomain.stream(new RasSInterval(iv.item(i).low(), iv.item(i).low())); + } + query.create("SELECT img" + getDomain.toString() + " FROM " + collection + " AS img"); + DBag resultBag = (DBag)query.execute(); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + if(iter.hasNext()) + return (RasGMArray)iter.next(); + else + throw new RasClientInternalException("RasFastScale","getMinimalArray","query produced no result."); + } + else + throw new RasClientInternalException("RasFastScale","getMinimalArray","query produced no result."); + } + catch(Exception e1) { + throw new RasClientInternalException("RasFastScale","getMinimalArray",e1.getMessage()); + } + } + + /** + * gets the scaling domain + **/ + public RasMInterval getScaledDomain( final RasMInterval area, double scale) + throws RasClientInternalException + { + RasMInterval retval = null; + int nearest = -1, i = 0; + double nearScale = 0.0; + + // find the nearest scaling factor larger than the requested scale + for ( i = 0; i < (int)NUM_FAST_PRE_SCALE; i++ ) + { + if(FAST_PRE_SCALE_FACTORS[i] < scale) break; + nearest = i; + } + if ( nearest != -1 ) + { + retval=scaleGetDomain(area, fullDomain.getOrigin(), FAST_PRE_SCALE_FACTORS[nearest]); + if ( (scale != FAST_PRE_SCALE_FACTORS[nearest]) && (retval != null) ) + { + nearScale=scale/ FAST_PRE_SCALE_FACTORS[nearest]; + retval=scaleGetDomain(retval, fullDomain.getOrigin(), nearScale); + } + } + else + { + retval = scaleGetDomain(area, fullDomain.getOrigin(), scale); + } + + return retval; + } + + /** + * gets the last used scale + **/ + public double getLastScale() + { + return lastScaleUsed; + } + +} + +/** + * class for fast scaling + * @version $Revision: 1.17 $ + **/ +public class RasFastScale extends RasFastBaseScale implements RasGlobalDefs +{ + static final String rcsid = "@(#)Package rasj, class RasFastScale, RasFastBaseScale: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasFastScale.java,v 1.17 2003/12/10 21:04:23 rasdev Exp $"; + + /** + * Default constructor. + * + * This constructor gets the name of the image collection and and an OQLQuery object as parameters. + * <P><B>Important:</B>This class does not open its own connection to the database nor start or + * commit any transactions. This has to be done by the application using FastScale.</P> + * @param collection the name of the collection containing the image(s) + * @param queryObject the OQLQuery object for connecting to the database + **/ + public RasFastScale( final String collection, final OQLQuery queryObject ) + { + super(collection,queryObject); + + } + + /** + * Returns the scaled image. + * + * @param trimDomain the domain of the desired image sector + * @param scalingFactor the scaling factor ( values greater than 1 mean magnification, lesser than + * 1 lead to a reduction ) + * @param domType determines wether the scaling or the trimmimg have to be executed first. Currently + * only domType=1 is supported by the server. + * + */ + public Object getScaledImage (final RasMInterval trimDomain, double scalingFactor, int domType) + throws QueryException + { + // That one should be the simpler part. Just choose the appropriate + // scaling factor from the list and the corresponding collection, + // adapt the factor given here and execute the query. + + int i; + int nearest = -1; + String suffix = null; + RasGMArray res = null; + Object result = null; + + // find the nearest scaling factor larger than the requested scale + for ( i = 0; i < (int)NUM_FAST_PRE_SCALE; i++ ) + { + if(FAST_PRE_SCALE_FACTORS[i] < scalingFactor) break; + nearest = i; + } + + while(true) + { + try { + + double nearScale; + + // Try all collections, therefore decide on this here. + if (nearest == -1 || nearest == 0) + { + nearScale = 1.0; + suffix = ""; + } + else + { + nearScale = FAST_PRE_SCALE_FACTORS[nearest]; + suffix = FAST_PRE_SCALE_SUFFIXES[nearest]; + } + + // depending on the value of domType apply the trim domain to the scaled object + // (domType == 0) or to the unscaled object (domType != 0). + if (domType == 0) + query.create("SELECT scale(img," + scalingFactor / nearScale + ')' + trimDomain + + " FROM " + collectionName + suffix + " AS img"); + else + { + RasMInterval scaledTrimDomain = null; + + scaledTrimDomain = getScaledDomain(trimDomain, nearScale); + if ( scaledTrimDomain == null ) + { + nearest--; // we can't get an error here for the highest scale! + continue; // try the next higher scaling factor instead. + } + + query.create("SELECT scale(img" + scaledTrimDomain + ',' + scalingFactor / nearScale + + ") FROM " + collectionName + suffix + " AS img"); + //System.err.println("Query : " + query ); + + } + + DBag resultBag = (DBag)query.execute(); + if (resultBag != null) + { + result = (DBag)resultBag; + break; + } + else + throw new RasClientInternalException("RasFastScale","getScaledImage","query returned no result."); + } + catch(Exception e1) { + throw new RasClientInternalException("RasFastScale","getScaledImage",e1.getMessage()); + } + + } + return result; + } + +} diff --git a/java/src/rasj/RasGMArray.java b/java/src/rasj/RasGMArray.java new file mode 100644 index 0000000..da0843c --- /dev/null +++ b/java/src/rasj/RasGMArray.java @@ -0,0 +1,532 @@ +package rasj; + +import rasj.*; +import rasj.odmg.*; +import rasj.global.*; + +import java.io.*; + +/* +* 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: + * This class represents a generic MDD in the sense that it + * is independent of the cell base type. The only information + * available is the length in bytes of the base type. + * <P>More specific MDDs including base type information for more + * type safety are represented by a set of typed subclasses. + * @version $Revision: 1.26 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasGMArray extends RasObject implements RasGlobalDefs +{ + static final String rcsid = "@(#)Package rasj, class RasGMArray: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasGMArray.java,v 1.26 2003/12/10 21:04:23 rasdev Exp $"; + + /** spatial domain */ + protected RasMInterval domain; + + /** internal array representation in bytes*/ + protected byte[] data; + + /** internal array representation as Object for use in special marrays*/ + protected Object objectData; + + /** internal object for accessing one cell of the array */ + protected byte[] currentCell; + + /** size of internal array representation in bytes */ + protected long dataSize; + + /** length of the cell base type in bytes */ + protected long typeLength; + + /** store current data format */ + protected int currentFormat; //RasDataFormat -> RasGlobalDefs + + /** storage layout object */ + protected RasStorageLayout storageLayout; + + /** + * Default constructor. + **/ + public RasGMArray() + { + super(RAS_MARRAY); + data = null; + objectData = null; + currentCell = null; + dataSize = 0; + domain = null; + typeLength = 0; + currentFormat = RAS_ARRAY; + storageLayout = new RasStorageLayout(); + } + + /** + * Constructor for uninitialized MDD objects + * @param initDomain The initial Domain of the GMArray + * @param cellTypeLength The length of the cell type used + */ + public RasGMArray(final RasMInterval initDomain, long cellTypeLength) + { + super(RAS_MARRAY); + data = null; + objectData = null; + dataSize = 0; + domain = initDomain; + typeLength = cellTypeLength; + currentFormat = RAS_ARRAY; + storageLayout = new RasStorageLayout(); + + // If dimensionality is zero, just one scalar value is stored. + dataSize = ((domain.dimension() != 0) ? domain.cellCount() : 1) * typeLength; + data = new byte[(int)dataSize]; + currentCell = new byte[(int)cellTypeLength]; + } + + /** + * Constructor for uninitialized MDD objects with Storage Layout + * @param initDomain The initial Domain of the GMArray + * @param cellTypeLength The length of the cell type used + * @param RasStorageLayout The storage layout to be used + */ + public RasGMArray(final RasMInterval initDomain, long cellTypeLength, RasStorageLayout stl) + { + super(RAS_MARRAY); + data = null; + objectData = null; + dataSize = 0; + domain = initDomain; + typeLength = cellTypeLength; + currentFormat = RAS_ARRAY; + storageLayout = stl; + + // If dimensionality is zero, just one scalar value is stored. + dataSize = ((domain.dimension() != 0) ? domain.cellCount() : 1) * typeLength; + data = new byte[(int)dataSize]; + currentCell = new byte[(int)cellTypeLength]; + } + + + /** + * Copy constructor. + * @param obj a copy of this object will be created + **/ + public RasGMArray(final RasGMArray obj) + { + super(obj, RAS_MARRAY); + if(data!=null) + { + System.arraycopy(obj.getArray(), 0, data, 0, (int)obj.dataSize); + objectData = null; + } + dataSize = obj.getArraySize(); + domain = obj.spatialDomain(); + typeLength = obj.typeLength; + currentFormat = obj.currentFormat; + storageLayout = new RasStorageLayout(obj.storageLayout); + if(obj.typeLength != 0) + currentCell = new byte[(int)obj.typeLength]; + } + + /** + * This method copies the values of mArray to itself. + * @param mArray the values of this MArray will be copied + * @return itself (after having copied the values from mArray) + **/ + public RasGMArray setTo(final RasGMArray mArray) + { + if(this != mArray) + { + if(data != null) + { + data = null; + } + + if (mArray.data != null) + { + dataSize = mArray.dataSize; + data = mArray.data; + } + if (mArray.objectData != null) + { + dataSize = mArray.dataSize; + objectData = mArray.objectData; + } + + if(storageLayout != null) + { + storageLayout = null; + } + + + // this has to be changed to a clone() function in future + if(mArray.storageLayout != null) + storageLayout = new RasStorageLayout(mArray.storageLayout); + + domain = mArray.domain; + typeLength = mArray.typeLength; + currentFormat = mArray.currentFormat; + } + return this; + } + + /** + * Reads a cell of the MDD. The cell's value is returned + * as a byte array, the length of which depends on the size of the base type. + * If you want to get the cell value as a primitive type (like integer or byte), + * you either have to do a cast or use the type-specific MArrays + * that are derived from this class. + * @param point the coordinates of the requested cell + * @return a byte array representing the value of the requested cell. + **/ + public byte[] getCell(RasPoint point) throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + // first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + if(typeLength == 0) + return null; + + System.arraycopy(data, (int)(domain.cellOffset(point)*typeLength), currentCell, 0, (int)typeLength); + return currentCell; + + } + + /** + * Returns the storage layout object of this MDD. + * @return the storage layout object + **/ + public final RasStorageLayout getStorageLayout() + { + return storageLayout; + } + + /** + * Sets the storage layout object and checks compatibility with the domain. + * @param stl the new storage layout + */ + public void setStorageLayout(RasStorageLayout stl) throws RasDimensionMismatchException + { + if (!stl.isCompatible(domain)) + throw new RasDimensionMismatchException(domain.dimension(),stl.getSpatialDomain().dimension()); + else + storageLayout = stl; + } + + /** + * Returns a RasGMArray that is the intersection of the current domain + * with the specified interval. + * @param where the interval that is used for the intersection + * @return the result of the intersection of this GMArray with the parameter interval + */ + public RasGMArray intersectionWith(RasMInterval where) + { + RasGMArray tile = new RasGMArray(); + + try { + RasMInterval objDomain = spatialDomain(); + int numDims = objDomain.dimension(); + long tlength = getTypeLength(); + + byte[] objData = new byte[(int)(where.cellCount() * tlength)]; + tile.setSpatialDomain(where); + tile.setTypeLength(tlength); + tile.setArray(objData); + tile.setArraySize(where.cellCount() * tlength); + + long blockLength = + where.item(numDims-1).high() - where.item(numDims-1).low() + 1; + long total = where.cellCount()/blockLength; + + byte[] dest = objData; + byte[] source = getArray(); + int blength = (int)(blockLength * tlength); + + for (long cell=0; cell<total; cell++) + { + RasPoint p = where.cellPoint(cell*blockLength); + + System.arraycopy(source, (int)(objDomain.cellOffset(p) * tlength), dest, + (int)(where.cellOffset(p) * tlength), blength); + } + + return tile; + } + + catch(RasIndexOutOfBoundsException e1) { + // this canno toccur (theoretically) + throw new RasClientInternalException("RasGMArray","intersectionWith()",e1.getMessage()); + } + catch(RasResultIsNoCellException e2) { + // this canno toccur (theoretically) + throw new RasClientInternalException("RasGMArray","intersectionWith()",e2.getMessage()); + } + + } + + + // Read methods + /** + * Gets the spatial domain. + * @return the spatial domain of this GMArray + **/ + public final RasMInterval spatialDomain() + { + return domain; + } + + /** + * Gets the internal representation of this GMAarray (the byte array). + * @return the byte array representing this GMArray + **/ + public byte[] getArray() + { + return data; + } + + /** + * Gets the size of the internal representation of this GMArray (in bytes). + * @return the size of this GMArray + **/ + public final long getArraySize() + { + return dataSize; + } + + /** + * Gets the length of cell type (in bytes). + * @return the cell type length + **/ + public final long getTypeLength() + { + return typeLength; + } + + /** + * Gets the current data format (RAS_ARRAY). + * @return the current data format + **/ + public final int getCurrentFormat() + { + return currentFormat; + } + + + // Write methods + /** + * Sets the spatial domain. + * @param dom the new spatial domain of this GMArray + **/ + public void setSpatialDomain(final RasMInterval dom) + { + domain = dom; + } + + /** + * Sets the internal representation of the GMArray. + * @param newData the new byte array representing the contents of this GMArray + **/ + public void setArray(byte[] newData) + { + data = newData; + dataSize = newData.length; + objectData = null; + } + + /** + * Sets the size of the internal representation (in bytes). + * @param newValue the size of the internal representation (the byte array) + **/ + public void setArraySize(long newValue) + { + dataSize = newValue; + } + + /** + * Sets the length of the cell type (in bytes). + * @param newValue the cell type length + **/ + public void setTypeLength(long newValue) + { + typeLength = newValue; + /* Now create the byte array object used for returning cell values */ + currentCell = new byte[(int)newValue]; + } + + /** + * Sets the current data format. + * @param newFormat the new data format + **/ + public void setCurrentFormat(int newFormat) + { + currentFormat = newFormat; + } + + // Methods for database communication (internal use only) + + /* inserts an object into the database + public void insertObjIntoDB() + { + // Nothing is done in that case. RasMArray objects can just be inserted as elements + // of a collection which invokes RasGMArray.insertObjIntoDB(String collName) + // of the RasMArray objects. + + //RasDatabase.currentDatabase.communication.insertSingleMDDObj(this); + System.out.println(" do nothing "); + } + */ + + /* inserts myself into a specific collection in the database + public void insertObjIntoDB(String collName) throws RasException + { + // Insert myself in database only if I have a type name, otherwise + // an exception is thrown. + if(!typeName) + { + throw new RasErrorDatabaseClassUndefined(); + } + //RasDatabase.currentDatabase.communication.insertMDD(collName, this); + } + */ + + /** gets the String representation */ + public String toString() + { + String tileDomain = ""; + + RasType typeSchema = (RasType)(((RasGMArray)this).getTypeSchema()); + RasBaseType baseTypeSchema = (RasBaseType)(((RasGMArray)this).getBaseTypeSchema()); + + if(storageLayout.getSpatialDomain() == null) + tileDomain = getTilingDomain(domain,typeLength); + else + tileDomain = storageLayout.getSpatialDomain().toString(); + + String s = "\n" + getClass().getName(); + s = s + "\n" + + " Oid...................: " + getOID() + "\n" + + " Object Name...........: " + getObjectName() + "\n" + + " Object Type...........: " + getObjectType() + "\n" + + " Object Type Name......: " + getObjectTypeName() + "\n" + + " Type Structure........: " + ((getTypeStructure() != null) ? getTypeStructure() : "<nn>") + "\n" + + " Type Schema...........: " + ((typeSchema != null) ? typeSchema.toString() : "<nn>") + "\n" + + " Domain................: " + domain + "\n" + + " TilingDomain..........: " + tileDomain + "\n" + + " TileSize..............: " + storageLayout.getTileSize() + " bytes\n" + + " Base Type Schema......: " + ((baseTypeSchema != null) ? baseTypeSchema.toString() : "<nn>") + "\n" + + " Base Type Length......: " + typeLength + "\n" + + " Data format...........: " + currentFormat + "\n" + + " Data size (bytes).....: " + dataSize + "\n"; + + return s; + } + + /** gets the String for testing */ + public String toTestString() + { + String tileDomain = ""; + + RasType typeSchema = (RasType)(((RasGMArray)this).getTypeSchema()); + RasBaseType baseTypeSchema = (RasBaseType)(((RasGMArray)this).getBaseTypeSchema()); + + if(storageLayout.getSpatialDomain() == null) + tileDomain = getTilingDomain(domain,typeLength); + else + tileDomain = storageLayout.getSpatialDomain().toString(); + + StringBuffer buffer = new StringBuffer(getArray().length * 4); // for most elements 3 characters and a space + buffer.append("\n" + getClass().getName()); + buffer.append("\n" + //+ " Oid...................: " + getOID() + "\n" + + " Object Name...........: " + getObjectName() + "\n" + + " Object Type...........: " + getObjectType() + "\n" + + " Object Type Name......: " + getObjectTypeName() + "\n" + + " Type Structure........: " + ((getTypeStructure() != null) ? getTypeStructure() : "<nn>") + "\n" + + " Type Schema...........: " + ((typeSchema != null) ? typeSchema.toString() : "<nn>") + "\n" + + " Domain................: " + domain + "\n" + + " TilingDomain..........: " + tileDomain + "\n" + + " TileSize..............: " + storageLayout.getTileSize() + " bytes\n" + + " Base Type Schema......: " + ((baseTypeSchema != null) ? baseTypeSchema.toString() : "<nn>") + "\n" + + " Base Type Length......: " + typeLength + "\n" + + " Data format...........: " + currentFormat + "\n" + + " Data size (bytes).....: " + dataSize + "\n" + ); + + //print bytes, just for testing!!! + for(int j=0; j < getArray().length; j++) + { + buffer.append(" " + getArray()[j]); + } + + return buffer.toString(); + } + + /** + * Returns the base type schema of this GMArray. + * @return the base type schema + **/ + public RasBaseType getBaseTypeSchema() + { + RasType type = getTypeSchema(); + RasBaseType baseType = null; + + if (type != null) + { + if (type.getTypeID() == RasGlobalDefs.RAS_MARRAY) + { + RasMArrayType mArrayType = (RasMArrayType)type; + baseType = (mArrayType.getBaseType()); + } + } + + return baseType; + } + + + //######### for internal use + + // calculates the tiling domain based on the original MDD, the type length and the tileSize + // of the MDD's storageLayout. + private String getTilingDomain(final RasMInterval originalDomain, final long typeLength) + { + long tileSize = storageLayout.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; + return "["+retVal+"]"; + } + +} + + diff --git a/java/src/rasj/RasIllegalULongValueException.java b/java/src/rasj/RasIllegalULongValueException.java new file mode 100644 index 0000000..34f7fbb --- /dev/null +++ b/java/src/rasj/RasIllegalULongValueException.java @@ -0,0 +1,88 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This exception is thrown if a {@link rasj.RasMArrayLong RasMArrayLong} is trying to be sent to the + * server where one or more cell values exceed 2^32 or are negative. Such cell values are illegal + * because the ODMG standard restricts unsigned long values in C++ (i.e. in the RasDaMan server) + * to 4 bytes, whereas java long values have 8 bytes. + * <p> + * Although in this case the server would store only the least 4 bytes of the cell value without throwing an + * exception, the java client interface does not allow sending such illegal long values in order + * to enforce application integrity. + * @see rasj.RasMArrayLong + * @version $Revision: 1.3 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasIllegalULongValueException extends RasRuntimeException +{ + static final String rcsid = "@(#)Package rasj, class RasIllegalULongValueException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasIllegalULongValueException.java,v 1.3 2003/12/19 16:22:27 rasdev Exp $"; + + // the base type + long illegalValue = 0; + + /** + * Standard constructor getting the illegal long value + * @param illegalLongValue the cell value that caused the error + **/ + public RasIllegalULongValueException(long illegalLongValue) + { + super(RasGlobalDefs.ILLEGAL_ULONG_VALUE); + illegalValue = illegalLongValue; + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + int i; + + if(super.getMessage() == null) + { + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + i = msg.indexOf( RasGlobalDefs.KEYWORD_VAL ); + if(i != -1) + buf.replace(i, i+RasGlobalDefs.KEYWORD_VAL.length(), String.valueOf(illegalValue)); + msg = buf.toString(); + return msg; + } + else + return super.getMessage(); + } + +} diff --git a/java/src/rasj/RasIllegalUShortValueException.java b/java/src/rasj/RasIllegalUShortValueException.java new file mode 100644 index 0000000..6c8ae17 --- /dev/null +++ b/java/src/rasj/RasIllegalUShortValueException.java @@ -0,0 +1,87 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This exception is thrown if a {@link rasj.RasMArrayShort RasMArrayShort} is trying to be sent to the + * server for ODMG type UShort where one or more cell values exceed 2^16 or are negative. Such cell values are illegal + * because the ODMG standard restricts unsigned short values (i.e. in the RasDaMan server) + * to 2 bytes, whereas java integer values have 4 bytes. + * Although in this case the server would store only the least 2 bytes of the cell value without throwing an + * exception, the java client interface does not allow sending such illegal short values in order + * to enforce application integrity. + * @see rasj.RasMArrayShort + * @version $Revision: 1.4 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasIllegalUShortValueException extends RasRuntimeException +{ + static final String rcsid = "@(#)Package rasj, class RasIllegalUShortValueException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasIllegalUShortValueException.java,v 1.4 2003/12/19 16:22:27 rasdev Exp $"; + + // the base type + int illegalValue = 0; + + /** + * Standard constructor getting the illegal short value + * @param illegalShortValue the cell value that caused the error + **/ + public RasIllegalUShortValueException(int illegalUShortValue) + { + super(RasGlobalDefs.ILLEGAL_USHORT_VALUE); + illegalValue = illegalUShortValue; + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + int i; + + if(super.getMessage() == null) + { + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + i = msg.indexOf( RasGlobalDefs.KEYWORD_VAL ); + if(i != -1) + buf.replace(i, i+RasGlobalDefs.KEYWORD_VAL.length(), String.valueOf(illegalValue)); + msg = buf.toString(); + return msg; + } + else + return super.getMessage(); + } + +} diff --git a/java/src/rasj/RasImplementation.java b/java/src/rasj/RasImplementation.java new file mode 100644 index 0000000..d30a7f3 --- /dev/null +++ b/java/src/rasj/RasImplementation.java @@ -0,0 +1,349 @@ +package rasj; + +import rasj.odmg.*; +import rasj.global.*; // RASJ_VERSION +import rasj.rnp.*; +import org.odmg.*; +import rasj.clientcommhttp.*; + +import java.io.*; +import java.net.*; +import java.lang.*; +import java.util.*; + +/* +* 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 + * This class implements an ODMG Bootstrap Object. This is the only vendor-dependent + * object a user needs for performing database operations. + * @version $Revision: 1.16 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasImplementation implements Implementation + { + /** + * This is the "real" Implementation object that is used. Because it contains a lot of + * internal methods that have to be used by the rasj.odmg package, it has been put + * into that package in order to avoid making this internal methods publicly visible and + * available. + **/ + private RasImplementationInterface imp = null; + + private static boolean isRNP = true; // use RNP by default + + /** + * C/s protocol indicators. + */ + public static final String PROTOCOL_RNP = "RNP" ; // RNP protocol indicator + public static final String PROTOCOL_RPC = "RPC" ; // RPC protocol indicator + public static final String PROTOCOL_HTTP = "HTTP" ; // HTTP protocol indicator + public static final String PROTOCOL_COMP = "COMPAT" ; // "compatiblity", means: using RNP (legacy) + + /** + * Standard constructor. + * @param server - Complete URL of the RasDaMan httpserver (including port number) + */ + public RasImplementation(String server) + { + Debug.talkCritical( RasGlobalDefs.RASJ_VERSION ); + Debug.talkCritical( " Using server " + server ); + + String envVar = System.getProperty("RMANPROTOCOL"); // uses "-D" option + + boolean useRNP = isRNP; + + if(envVar != null) + { + Debug.talkWarning( "environment variable RMANPROTOCOL enforces protocol " + envVar ); + if ( envVar.equalsIgnoreCase( PROTOCOL_RNP ) ) + useRNP = true; + else if ( envVar.equalsIgnoreCase( PROTOCOL_RPC ) ) + { + Debug.talkCritical( "Error: protocol " + PROTOCOL_RPC + " not supported by rasj: using " + PROTOCOL_RNP + " instead." ); + useRNP = true; + } + else if ( envVar.equalsIgnoreCase( PROTOCOL_HTTP ) ) + useRNP = false; + else if ( envVar.equalsIgnoreCase( PROTOCOL_COMP ) ) + { + Debug.talkCritical( "Compatibility mode specified, using " + PROTOCOL_RNP + "." ); + useRNP = true; + } + else + { + Debug.talkCritical( "Error: unknown protocol: " + envVar + "; using protocol " + PROTOCOL_RNP + "." ); + useRNP = true; + } + } + + if(useRNP) + { + Debug.talkVerbose( "RasImplementation.constructor: using protocol " + PROTOCOL_RNP + "." ); + imp = new RasRNPImplementation(server); + } + else + { + Debug.talkVerbose( "RasImplementation.constructor: using protocol " + PROTOCOL_HTTP + "." ); + imp = new RasODMGImplementation(server); + } + } // RasImplementation() + + /** + * Extended constructor, allowing to set protocol (does not query env var). + * If the protocol is illegal, RNP is assumed as default. + * @param server - Complete URL of the RasDaMan httpserver (including port number) + * @param protocol - c/s communication protocol selector, one of: "RNP", "HTTP" + */ + public RasImplementation(String server, String protocol) + { + Debug.talkCritical( RasGlobalDefs.RASJ_VERSION ); + Debug.talkCritical( " Using server " + server ); + + if( protocol.equalsIgnoreCase( PROTOCOL_RNP ) ) + { + Debug.talkVerbose( "Using protocol " + PROTOCOL_RNP + "." ); + imp = new RasRNPImplementation(server); + } + else if( protocol.equalsIgnoreCase( PROTOCOL_HTTP ) ) + { + Debug.talkVerbose( "Using protocol " + PROTOCOL_HTTP + "." ); + imp = new RasODMGImplementation(server); + } + else + { + Debug.talkCritical( "Error: unknown protocol: " + protocol + "; using " + PROTOCOL_RNP + " instead." ); + imp = new RasRNPImplementation(server); + } + + } // RasImplementation() + + public static void setRNP() + { + isRNP = true; + } + + public static void setHTTP() + { + isRNP = false; + } + + public boolean isDefaultRNP() + { + Debug.talkVerbose( "RasImplementation.isDefaultRNP: RNP=" + isRNP + "." ); + return isRNP; + } + + /** + * returns 1 if an openDB command is executed (closeDB sets it back to 0). + */ + public int dbIsOpen() + { + return imp.dbIsOpen(); + } + + /* + * Create a new transaction object and associate it with the current thread. + */ + public Transaction newTransaction() + { + return imp.newTransaction(); + } + + /** + * Get current transaction for thread, or NULL if none. + */ + public Transaction currentTransaction() + { + return imp.currentTransaction(); + } + + /** + * Create a new database object. + */ + public Database newDatabase() + { + return imp.newDatabase(); + } + + /** + * Create a new query object. + */ + public OQLQuery newOQLQuery() + { + return imp.newOQLQuery(); + } + + /** + * Create a new DList object. + */ + public DList newDList() + { + return imp.newDList(); + } + + /** + * Create a new DBag object. + */ + public DBag newDBag() + { + return imp.newDBag(); + } + + /** + * Create a new DSet object. + */ + public DSet newDSet() + { + return imp.newDSet(); + } + + /** + * Not implemented yet. + */ + public DArray newDArray() + { + throw new NotImplementedException(); + } + + /** + * Not implemented yet. + */ + public DMap newDMap() + { + throw new NotImplementedException(); + } + + /** + * Get a String representation of the object's identifier. + */ + public String getObjectId(Object obj) + { + return imp.getObjectId(obj); + } + + /** + * Not implemented yet. + */ + public Database getDatabase(Object obj) + { + throw new NotImplementedException(); + } + + /** + * Open database + */ + public void openDB(String name, int accessMode) throws ODMGException + { + imp.openDB(name,accessMode); + } + + /** + * 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 + { + imp.closeDB(); + } + + /** + * Begin a transaction. + */ + public void beginTA()throws ODMGException + { + imp.beginTA(); + } + + /** + * Returns TRUE if a transaction is currently open. + */ + public boolean isOpenTA()throws ODMGException + { + Debug.talkCritical( "RasImplementation::isOpenTA: calling imp.isOpenTA()" ); + return imp.isOpenTA(); + } + + /** + * Commit a transaction. + */ + public void commitTA()throws ODMGException + { + imp.commitTA(); + } + + /** + * Abort a transaction. + */ + public void abortTA()throws ODMGException + { + imp.abortTA(); + } + + /** + * Set the maximum retry parameter + */ + public void setMaxRetry(int newRetry) + { + imp.setMaxRetry(newRetry); + } + + /** + * Get the maximum retry parameter + */ + public int getMaxRetry() + { + return imp.getMaxRetry(); + } + + /** + * Set user identification : name/plain password + * (default is rasguest/rasguest) + */ + public void setUserIdentification(String userName, String plainPass) + { + imp.setUserIdentification(userName,plainPass); + } + + /** + * Set trace output threshold + * (0 = minimal, 4 = verbose; 1 = default) + */ + public void setTraceThreshold( int level ) + { + Debug.talkCritical( "setting trace level to " + level ); + rasj.global.Debug.setDebugThreshold( level ); + } + +} + + diff --git a/java/src/rasj/RasImplementationInterface.java b/java/src/rasj/RasImplementationInterface.java new file mode 100644 index 0000000..f59d506 --- /dev/null +++ b/java/src/rasj/RasImplementationInterface.java @@ -0,0 +1,95 @@ +package rasj; + +import org.odmg.*; +import java.io.*; + +/* +* 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: + * This interface contains the methods implemented by RasOdmgImplementation and RasRnpImplementation + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + public interface RasImplementationInterface extends Implementation + { + String getRasServer(); + + int dbIsOpen(); + + int getClientID(); + + int getAccessMode(); + + String getErrorStatus(); + + Transaction newTransaction(); + + Transaction currentTransaction(); + + Database newDatabase(); + + OQLQuery newOQLQuery(); + + DList newDList(); + + DBag newDBag(); + + DSet newDSet(); + + DArray newDArray(); + + DMap newDMap(); + + String getObjectId(Object obj); + + Database getDatabase(Object obj); + + void openDB(String name, int accessMode)throws ODMGException; + + void closeDB() throws ODMGException; + + void beginTA(); + + boolean isOpenTA(); + + void commitTA(); + + void abortTA(); + + void setMaxRetry(int newRetry); + + int getMaxRetry(); + + void setUserIdentification(String userName, String plainPass); + + Object queryRequest(String parameters) throws RasQueryExecutionFailedException; + } + diff --git a/java/src/rasj/RasIndexOutOfBoundsException.java b/java/src/rasj/RasIndexOutOfBoundsException.java new file mode 100644 index 0000000..315c6d7 --- /dev/null +++ b/java/src/rasj/RasIndexOutOfBoundsException.java @@ -0,0 +1,127 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This exception is thrown when a cell index for an MDD exceeds + * the objects's bounds. + * @version $Revision: 1.6 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasIndexOutOfBoundsException extends RasException +{ + static final String rcsid = "@(#)Package rasj, class RasIndexOutOfBoundsException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasIndexOutOfBoundsException.java,v 1.6 2003/12/19 16:22:27 rasdev Exp $"; + + // lower bound + private long low; + // upper bound + private long high; + // index which caused the error + private long index; + + /** + * stamdard constructor getting lower bound, upper bound and the index. + * @param dlow lower bound of the object + * @param dhigh upper bound of the object + * @param dindex the index that caused this exception + **/ + protected RasIndexOutOfBoundsException(long dlow, long dhigh, long dindex ) + { + super(RasGlobalDefs.INDEX_OUT_OF_BOUNDS); + low = dlow; + high = dhigh; + index = dindex; + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + int i; + + if(super.getMessage() == null) + { + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + i = msg.indexOf( RasGlobalDefs.KEYWORD_LOW ); + if(i != -1) + buf.replace(i, i+RasGlobalDefs.KEYWORD_LOW.length(), String.valueOf(low)); + msg = buf.toString(); + i = msg.indexOf( RasGlobalDefs.KEYWORD_HIGH ); + if(i != -1) + buf.replace(i, i+RasGlobalDefs.KEYWORD_HIGH.length(), String.valueOf(high)); + msg = buf.toString(); + i = msg.indexOf( RasGlobalDefs.KEYWORD_INDEX ); + if(i != -1) + buf.replace(i, i+RasGlobalDefs.KEYWORD_INDEX.length(), String.valueOf(index)); + msg = buf.toString(); + return msg; + } + else + return super.getMessage(); + } + + /** + * Returns the lower bound of the accessed object. + * @return the lower bound of the object + **/ + public long getLow() + { + return low; + } + + /** + * Returns the higher bound of the accessed object. + * @return the higher bound of the object + **/ + public long getHigh() + { + return high; + } + + /** + * Returns the index responsible for throwing this exception. + * @return the index that caused the exception + **/ + public long getIndex() + { + return index; + } + +} + diff --git a/java/src/rasj/RasInvalidNameException.java b/java/src/rasj/RasInvalidNameException.java new file mode 100644 index 0000000..72f3c88 --- /dev/null +++ b/java/src/rasj/RasInvalidNameException.java @@ -0,0 +1,77 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This exception is thrown if a object name contains unaccepted characters + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasInvalidNameException extends RasRuntimeException +{ + static final String rcsid = "@(#)Package rasj, class RasInvalidNameException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasInvalidNameException.java,v 1.3 2003/12/19 16:22:27 rasdev Exp $"; + + String wrongName = null; + + public RasInvalidNameException(String name) + { + super(RasGlobalDefs.INVALID_OBJECT_NAME_ERROR); + + wrongName = ( (name==null) ? "(null)" : name ); + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + int i; + + if(super.getMessage() == null) + { + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + i = msg.indexOf( RasGlobalDefs.KEYWORD_INVNAME ); + if(i != -1) + buf.replace(i, i+RasGlobalDefs.KEYWORD_INVNAME.length(), wrongName); + msg = buf.toString(); + return msg; + } + else + return super.getMessage(); + } + +} + diff --git a/java/src/rasj/RasMArrayByte.java b/java/src/rasj/RasMArrayByte.java new file mode 100644 index 0000000..71556a2 --- /dev/null +++ b/java/src/rasj/RasMArrayByte.java @@ -0,0 +1,110 @@ +package rasj; + +import rasj.*; +import rasj.odmg.*; +import rasj.global.*; + +/* +* 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: + * This class represents a MArray with base type Byte. + * @version $Revision: 1.7 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasMArrayByte extends RasGMArray +{ + + /** default constructor */ + public RasMArrayByte() + { + super(); + typeLength = SIZE_OF_BYTE; + } + + /** + * constructor for uninitialized MDD objects + * * @param initDomain The initial Domain of the MArray + */ + public RasMArrayByte(final RasMInterval initDomain) + { + super(initDomain, SIZE_OF_BYTE); + } + + /** + * Constructor for uninitialized MDD objects with Storage Layout + * @param initDomain The initial Domain of the MArray + * @param RasStorageLayout The storage layout to be used + */ + public RasMArrayByte(final RasMInterval initDomain, RasStorageLayout stl) + { + super(initDomain, SIZE_OF_BYTE, stl); + } + + /** + * copy constructor + * @param obj a copy of this object will be created + */ + public RasMArrayByte(final RasMArrayByte obj) + { + super(obj); + } + + /** + * subscript operator for read access of a cell. The cell value is returned + * as a byte[1] array. + */ + public byte[] getCell(RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + //first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + byte[] retValue = new byte[1]; + retValue[0] = data[(int)domain.cellOffset(point)]; + return retValue; + } + + /** subscript operator for read access of a cell. The cell value is returned as + * a Byte. + */ + public byte getByte(final RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + // first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + return data[(int)domain.cellOffset(point)]; + } + + +} + diff --git a/java/src/rasj/RasMArrayDouble.java b/java/src/rasj/RasMArrayDouble.java new file mode 100644 index 0000000..955ef6a --- /dev/null +++ b/java/src/rasj/RasMArrayDouble.java @@ -0,0 +1,195 @@ +package rasj; + +import rasj.*; +import rasj.odmg.*; +import rasj.global.*; + +import java.io.*; + +/* +* 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: + * This class represents a MArray with base type double. + * @version $Revision: 1.5 $ + * method intersectionWith(RasMInterval) uses byte array and is not optimized for special data arrays + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasMArrayDouble extends RasGMArray +{ + + /** default constructor */ + public RasMArrayDouble() + { + super(); + typeLength = SIZE_OF_DOUBLE; + } + + /** + * constructor for uninitialized MDD objects + * @param initDomain The initial Domain of the MArray + */ + public RasMArrayDouble(final RasMInterval initDomain) + { + super(initDomain, SIZE_OF_DOUBLE); + objectData = new double[(int)(dataSize/SIZE_OF_DOUBLE)]; + data = null; + } + + /** + * Constructor for uninitialized MDD objects with Storage Layout + * @param initDomain The initial Domain of the MArray + * @param RasStorageLayout The storage layout to be used + */ + public RasMArrayDouble(final RasMInterval initDomain, RasStorageLayout stl) + { + super(initDomain, SIZE_OF_DOUBLE, stl); + objectData = new double[(int)(dataSize/SIZE_OF_DOUBLE)]; + data = null; + } + + /** + * copy constructor + * @param obj a copy of this object will be created + */ + public RasMArrayDouble(final RasMArrayDouble obj) + { + super(obj); + if(obj.objectData!=null) + { + objectData = new double[(int)(obj.dataSize/SIZE_OF_DOUBLE)]; + System.arraycopy(obj.getDoubleArray(), 0, objectData, 0, (int)(obj.dataSize/SIZE_OF_DOUBLE)); + data = null; + } + } + + /** + * subscript operator for read access of a cell. The cell value is returned + * as a byte[4] array. This kind of access to a cell is significantly slower + * than getDouble(), because each cell value has to be converted from double to a + * byte[SIZE_OF_DOUBLE] array. + * The user has to take care that each Cell value is stored, before getting the next Cell. + */ + public byte[] getCell(RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + double cellValue; + long tmp; + + //first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + cellValue = ((double[])objectData)[(int)domain.cellOffset(point)]; + for(int i=0; i<SIZE_OF_DOUBLE; i++) + { + tmp = Double.doubleToRawLongBits(cellValue); + tmp >>>= (((SIZE_OF_DOUBLE -1)-i)*8); + currentCell[i] = (byte)tmp; + } + + return currentCell; + } + + /** subscript operator for read access of a cell. The cell value is returned as + * an double. This access method is faster then getCell(), because no conversion + * from double to Byte[SIZE_OF_DOUBLE] has to be done. + */ + public double getDouble(final RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + // first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + return ((double[])objectData)[(int)domain.cellOffset(point)]; + } + + /** + * get the internal representation of the array + */ + public double[] getDoubleArray() + { + if(objectData==null) + { + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + objectData = new double[data.length/SIZE_OF_DOUBLE]; + try + { + for(int j=0; j<data.length/SIZE_OF_DOUBLE; j++) + { + ((double[])objectData)[j] = dis.readDouble(); + } + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayDouble", "getDoubleArray()", + "IOException while converting data to objectData array " + e.getMessage()); + } + } + return (double[])objectData; + } + + /** get the internal representation of the array in bytes, + * please use getDoubleArray() + */ + public byte[] getArray() + { + if(data==null) + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + try + { + for(int j=0; j<((double[])objectData).length; j++) + dos.writeDouble(((double[])objectData)[j]); + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayDouble", "getArray()", + "IOException while converting objectData to data array " + e.getMessage()); + } + data = bos.toByteArray(); + } + return data; + } + + /** set the internal representation of the array */ + public void setArray(double[] newData) + { + objectData = newData; + data = null; + dataSize = newData.length * SIZE_OF_DOUBLE; + } + +} + diff --git a/java/src/rasj/RasMArrayFloat.java b/java/src/rasj/RasMArrayFloat.java new file mode 100644 index 0000000..d303823 --- /dev/null +++ b/java/src/rasj/RasMArrayFloat.java @@ -0,0 +1,195 @@ +package rasj; + +import rasj.*; +import rasj.odmg.*; +import rasj.global.*; +import java.io.*; + +/* +* 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: + * This class represents a MArray with base type float. + * @version $Revision: 1.5 $ + * method intersectionWith(RasMInterval) uses byte array and is not optimized for special data arrays + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasMArrayFloat extends RasGMArray +{ + + /** default constructor */ + public RasMArrayFloat() + { + super(); + typeLength = SIZE_OF_FLOAT; + } + + /** + * constructor for uninitialized MDD objects + * @param initDomain The initial Domain of the MArray + * */ + public RasMArrayFloat(final RasMInterval initDomain) + { + super(initDomain, SIZE_OF_FLOAT); + objectData = new float[(int)(dataSize/SIZE_OF_FLOAT)]; + data = null; + } + + /** + * Constructor for uninitialized MDD objects with Storage Layout + * @param initDomain The initial Domain of the MArray + * @param RasStorageLayout The storage layout to be used + */ + public RasMArrayFloat(final RasMInterval initDomain, RasStorageLayout stl) + { + super(initDomain, SIZE_OF_FLOAT, stl); + objectData = new float[(int)(dataSize/SIZE_OF_FLOAT)]; + data = null; + } + + /** + * copy constructor + * @param obj a copy of this object will be created + * */ + public RasMArrayFloat(final RasMArrayFloat obj) + { + super(obj); + if(obj.objectData!=null) + { + objectData = new float[(int)(obj.dataSize/SIZE_OF_FLOAT)]; + System.arraycopy(obj.getFloatArray(), 0, objectData, 0, (int)(obj.dataSize/SIZE_OF_FLOAT)); + data = null; + } + } + + /** + * subscript operator for read access of a cell. The cell value is returned + * as a byte[SIZE_OF_FLOAT] array. This kind of access to a cell is significantly slower + * than getFloat(), because each cell value has to be converted from float to a + * byte[SIZE_OF_FLOAT] array. + * The user has to take care that each Cell value is stored, before getting the next Cell. + */ + public byte[] getCell(RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + float cellValue; + int tmp; + + //first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + cellValue = ((float[])objectData)[(int)domain.cellOffset(point)]; + for(int i=0; i<SIZE_OF_FLOAT; i++) + { + tmp = Float.floatToRawIntBits(cellValue); + tmp >>>= (((SIZE_OF_FLOAT -1)-i)*8); + currentCell[i] = (byte)tmp; + } + + return currentCell; + + } + + /** subscript operator for read access of a cell. The cell value is returned as + * an float. This access method is faster then getCell(), because no conversion + * from float to Byte[SIZE_OF_FLOAT] has to be done. + */ + public float getFloat( final RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + // first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + return ((float[])objectData)[(int)domain.cellOffset(point)]; + } + + /** + * get the internal representation of the array + */ + public float[] getFloatArray() + { + if(objectData==null) + { + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + objectData = new float[data.length/SIZE_OF_FLOAT]; + try + { + for(int j=0; j<data.length/SIZE_OF_FLOAT; j++) + { + ((float[])objectData)[j] = dis.readFloat(); + } + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayFloat", "getFloatArray()", + "IOException while converting data to objectData array " + e.getMessage()); + } + } + return (float[])objectData; + } + + /** get the internal representation of the array in bytes, + * please use getFloatArray() + */ + public byte[] getArray() + { + if(data==null) + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + try + { + for(int j=0; j<((float[])objectData).length; j++) + dos.writeFloat(((float[])objectData)[j]); + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayFloat", "getArray()", + "IOException while converting objectData to data array " + e.getMessage()); + } + data = bos.toByteArray(); + } + return data; + } + + /** set the internal representation of the array */ + public void setArray(float[] newData) + { + objectData = newData; + data = null; + dataSize = newData.length * SIZE_OF_FLOAT; + } + +} + diff --git a/java/src/rasj/RasMArrayInteger.java b/java/src/rasj/RasMArrayInteger.java new file mode 100644 index 0000000..bd07401 --- /dev/null +++ b/java/src/rasj/RasMArrayInteger.java @@ -0,0 +1,196 @@ +package rasj; + +import rasj.*; +import rasj.odmg.*; +import rasj.global.*; +import java.io.*; + +/* +* 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: + * This class represents a MArray with base type Integer. + * @version $Revision: 1.11 $ + * for ODMG type UShort(2 bytes, due to ODMG standard) you can use RasMArrayInteger, + * but only values up to 2^16 (performance loss because of convertion 4 bytes-> 2 bytes!); + * method intersectionWith(RasMInterval) uses byte array and is not optimized for special data arrays + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasMArrayInteger extends RasGMArray +{ + + /** default constructor */ + public RasMArrayInteger() + { + super(); + typeLength = SIZE_OF_INTEGER; + } + + /** + * constructor for uninitialized MDD objects + * @param initDomain The initial Domain of the MArray + * */ + public RasMArrayInteger(final RasMInterval initDomain) + { + super(initDomain, SIZE_OF_INTEGER); + objectData = new int[(int)(dataSize/SIZE_OF_INTEGER)]; + data = null; + } + + /** + * Constructor for uninitialized MDD objects with Storage Layout + * @param initDomain The initial Domain of the MArray + * @param RasStorageLayout The storage layout to be used + */ + public RasMArrayInteger(final RasMInterval initDomain, RasStorageLayout stl) + { + super(initDomain, SIZE_OF_INTEGER, stl); + objectData = new int[(int)(dataSize/SIZE_OF_INTEGER)]; + data = null; + } + + + /** + * copy constructor + * @param obj a copy of this object will be created + */ + public RasMArrayInteger(final RasMArrayInteger obj) + { + super(obj); + if(obj.objectData!=null) + { + objectData = new int[(int)(obj.dataSize/SIZE_OF_INTEGER)]; + System.arraycopy(obj.getIntArray(), 0, objectData, 0, (int)(obj.dataSize/SIZE_OF_INTEGER)); + data = null; + } + } + + /** + * subscript operator for read access of a cell. The cell value is returned + * as a byte[SIZE_OF_INTEGER] array. This kind of access to a cell is significantly slower + * than getInt(), because each cell value has to be converted from int to a + * byte[SIZE_OF_INTEGER] array. + * The user has to take care that each Cell value is stored, before getting the next Cell. + */ + public byte[] getCell(RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + int cellValue; + int tmp; + + //first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + cellValue = ((int[])objectData)[(int)domain.cellOffset(point)]; + for(int i=0; i<SIZE_OF_INTEGER; i++) + { + tmp = cellValue; + tmp >>>= (((SIZE_OF_INTEGER -1)-i)*8); + currentCell[i] = (byte)tmp; + } + + return currentCell; + + } + + /** subscript operator for read access of a cell. The cell value is returned as + * an Integer. This access method is faster then getCell(), because no conversion + * from int to Byte[SIZE_OF_INTEGER] has to be done. + */ + public int getInt( final RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + // first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + return ((int[])objectData)[(int)domain.cellOffset(point)]; + } + + /** + * get the internal representation of the array + */ + public int[] getIntArray() + { + if(objectData==null) + { + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + objectData = new int[data.length/SIZE_OF_INTEGER]; + try + { + for(int j=0; j<data.length/SIZE_OF_INTEGER; j++) + { + ((int[])objectData)[j] = dis.readInt(); + } + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayInteger", "getIntArray()", + "IOException while converting data to objectData array " + e.getMessage()); + } + } + return (int[])objectData; + } + + /** get the internal representation of the array in bytes, + * please use getIntArray() + */ + public byte[] getArray() + { + if(data==null) + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + try + { + for(int j=0; j<((int[])objectData).length; j++) + dos.writeInt(((int[])objectData)[j]); + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayInteger", "getArray()", + "IOException while converting objectData to data array " + e.getMessage()); + } + data = bos.toByteArray(); + } + return data; + } + + /** set the internal representation of the array */ + public void setArray(int[] newData) + { + objectData = newData; + data = null; + dataSize = newData.length * SIZE_OF_INTEGER; + } +} + diff --git a/java/src/rasj/RasMArrayLong.java b/java/src/rasj/RasMArrayLong.java new file mode 100644 index 0000000..936f460 --- /dev/null +++ b/java/src/rasj/RasMArrayLong.java @@ -0,0 +1,198 @@ +package rasj; + +import rasj.*; +import rasj.odmg.*; +import rasj.global.*; +import java.io.*; + +/* +* 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: + * This class represents a MArray with base type long. + * @version $Revision: 1.7 $ + * for ODMG type Long(4 bytes, due to ODMG standard) please use RasMArrayInteger, + * for ODMG type ULong(4 bytes, due to ODMG standard) you can use RasMArrayLong, + * but only values up to 2^32 (performance loss because of convertion 8 bytes-> 4 bytes!); + * method intersectionWith(RasMInterval) uses byte array and is not optimized for special data arrays + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasMArrayLong extends RasGMArray +{ + + /** default constructor */ + public RasMArrayLong() + { + super(); + typeLength = SIZE_OF_LONG; + } + + /** + * constructor for uninitialized MDD objects + * @param initDomain The initial Domain of the MArray + */ + public RasMArrayLong(final RasMInterval initDomain) + { + super(initDomain, SIZE_OF_LONG); + objectData = new long[(int)(dataSize/SIZE_OF_LONG)]; + data = null; + } + + /** + * Constructor for uninitialized MDD objects with Storage Layout + * @param initDomain The initial Domain of the MArray + * @param RasStorageLayout The storage layout to be used + */ + public RasMArrayLong(final RasMInterval initDomain, RasStorageLayout stl) + { + super(initDomain, SIZE_OF_LONG, stl); + objectData = new long[(int)(dataSize/SIZE_OF_LONG)]; + data = null; + } + + + /** + * copy constructor + * @param obj a copy of this object will be created + */ + public RasMArrayLong(final RasMArrayLong obj) + { + super(obj); + if(obj.objectData!=null) + { + objectData = new long[(int)(obj.dataSize/SIZE_OF_LONG)]; + System.arraycopy(obj.getLongArray(), 0, objectData, 0, (int)(obj.dataSize/SIZE_OF_LONG)); + data = null; + } + } + + /** + * subscript operator for read access of a cell. The cell value is returned + * as a byte[SIZE_OF_LONG] array. This kind of access to a cell is significantly slower + * than getLong(), because each cell value has to be converted from long to a + * byte[SIZE_OF_LONG] array. + * The user has to take care that each Cell value is stored, before getting the next Cell. + */ + public byte[] getCell(RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + long cellValue; + long tmp; + + //first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + cellValue = ((long[])objectData)[(int)domain.cellOffset(point)]; + for(int i=0; i<SIZE_OF_LONG; i++) + { + tmp = cellValue; + tmp >>>= (((SIZE_OF_LONG -1)-i)*SIZE_OF_LONG); + currentCell[i] = (byte)tmp; + } + + return currentCell; + + } + + /** subscript operator for read access of a cell. The cell value is returned as + * an long. This access method is faster then getCell(), because no conversion + * from long to Byte[SIZE_OF_LONG] has to be done. + */ + public long getLong( final RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + // first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + return ((long[])objectData)[(int)domain.cellOffset(point)]; + } + + /** + * get the internal representation of the array + */ + public long[] getLongArray() + { + if(objectData==null) + { + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + objectData = new long[data.length/SIZE_OF_LONG]; + try + { + for(int j=0; j<data.length/SIZE_OF_LONG; j++) + { + ((long[])objectData)[j] = dis.readLong(); + } + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayLong", "getLongArray()", + "IOException while converting data to objectData array " + e.getMessage()); + } + } + return (long[])objectData; + } + + /** get the internal representation of the array in bytes, + * please use getLongArray() + */ + public byte[] getArray() + { + if(data==null) + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + try + { + for(int j=0; j<((long[])objectData).length; j++) + dos.writeLong(((long[])objectData)[j]); + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayLong", "getArray()", + "IOException while converting objectData to data array " + e.getMessage()); + } + data = bos.toByteArray(); + } + return data; + } + + /** set the internal representation of the array */ + public void setArray(long[] newData) + { + objectData = newData; + data = null; + dataSize = newData.length * SIZE_OF_LONG; + } +} + diff --git a/java/src/rasj/RasMArrayShort.java b/java/src/rasj/RasMArrayShort.java new file mode 100644 index 0000000..98c4657 --- /dev/null +++ b/java/src/rasj/RasMArrayShort.java @@ -0,0 +1,195 @@ +package rasj; + +import rasj.*; +import rasj.odmg.*; +import rasj.global.*; +import java.io.*; + +/* +* 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: + * This class represents a MArray with base type short. + * @version $Revision: 1.6 $ + * method intersectionWith(RasMInterval) uses byte array and is not optimized for special data arrays + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasMArrayShort extends RasGMArray +{ + + /** default constructor */ + public RasMArrayShort() + { + super(); + typeLength = SIZE_OF_SHORT; + } + + /** + * constructor for uninitialized MDD objects + * @param initDomain The initial Domain of the MArray + */ + public RasMArrayShort(final RasMInterval initDomain) + { + super(initDomain, SIZE_OF_SHORT); + objectData = new short[(int)(dataSize/SIZE_OF_SHORT)]; + data = null; + } + + /** + * Constructor for uninitialized MDD objects with Storage Layout + * @param initDomain The initial Domain of the MArray + * @param RasStorageLayout The storage layout to be used + */ + public RasMArrayShort(final RasMInterval initDomain, RasStorageLayout stl) + { + super(initDomain, SIZE_OF_SHORT, stl); + objectData = new short[(int)(dataSize/SIZE_OF_SHORT)]; + data = null; + } + + /** + * copy constructor + * @param obj a copy of this object will be created + */ + public RasMArrayShort(final RasMArrayShort obj) + { + super(obj); + if(obj.objectData!=null) + { + objectData = new short[(int)(obj.dataSize/SIZE_OF_SHORT)]; + System.arraycopy(obj.getShortArray(), 0, objectData, 0, (int)(obj.dataSize/SIZE_OF_SHORT)); + data = null; + } + } + + /** + * subscript operator for read access of a cell. The cell value is returned + * as a byte[SIZE_OF_SHORT] array. This kind of access to a cell is significantly slower + * than getShort(), because each cell value has to be converted from short to a + * byte[SIZE_OF_SHORT] array. + * The user has to take care that each Cell value is stored, before getting the next Cell. + */ + public byte[] getCell(RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + short cellValue; + short tmp; + + //first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + cellValue = ((short[])objectData)[(int)domain.cellOffset(point)]; + for(int i=0; i<SIZE_OF_SHORT; i++) + { + tmp = cellValue; + tmp >>>= (((SIZE_OF_SHORT -1)-i)*8); + currentCell[i] = (byte)tmp; + } + + return currentCell; + + } + + /** subscript operator for read access of a cell. The cell value is returned as + * an short. This access method is faster then getCell(), because no conversion + * from short to byte[SIZE_OF_SHORT] has to be done. + */ + public int getShort(final RasPoint point) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + // first test dimensionality + if(point.dimension() != domain.dimension()) + throw new RasDimensionMismatchException(point.dimension(), domain.dimension()); + + return ((short[])objectData)[(int)domain.cellOffset(point)]; + } + + /** + * get the internal representation of the array + */ + public short[] getShortArray() + { + if(objectData==null) + { + ByteArrayInputStream bis = new ByteArrayInputStream(data); + DataInputStream dis = new DataInputStream(bis); + objectData = new short[data.length/SIZE_OF_SHORT]; + try + { + for(int j=0; j<data.length/SIZE_OF_SHORT; j++) + { + ((short[])objectData)[j] = dis.readShort(); + } + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayShort", "getShortArray()", + "IOException while converting data to objectData array " + e.getMessage()); + } + } + return (short[])objectData; + } + + /** get the internal representation of the array in bytes, + * please use getShortArray() + */ + public byte[] getArray() + { + if(data==null) + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + try + { + for(int j=0; j<((short[])objectData).length; j++) + dos.writeShort(((short[])objectData)[j]); + } + catch(IOException e) + { + throw new RasClientInternalException("RasMArrayShort", "getArray()", + "IOException while converting objectData to data array " + e.getMessage()); + } + data = bos.toByteArray(); + } + return data; + } + + /** set the internal representation of the array */ + public void setArray(short[] newData) + { + objectData = newData; + data = null; + dataSize = newData.length * SIZE_OF_SHORT; + } + +} + diff --git a/java/src/rasj/RasMArrayType.java b/java/src/rasj/RasMArrayType.java new file mode 100644 index 0000000..baef491 --- /dev/null +++ b/java/src/rasj/RasMArrayType.java @@ -0,0 +1,91 @@ +package rasj; + +import rasj.*; +import rasj.global.*; + +import java.util.*; + +/* +* 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: + * This class represents the MArray type in the ODMG conformant + * representation of the RasDaMan type system. + * @version $Revision: 1.8 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasMArrayType extends RasType +{ + static final String rcsid = "@(#)Package rasj, class RasMArrayType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasMArrayType.java,v 1.8 2003/12/19 16:22:27 rasdev Exp $"; + + private RasBaseType baseType; + + /** + * Default constructor. + **/ + public RasMArrayType() + { + super(); + baseType = null; + } + + /** + * Constructor getting the type of th new MArray. + * @param newBaseType the type of the new MArray + **/ + public RasMArrayType(RasBaseType newBaseType) + { + super("RAS_MARRAY"); + typeID = RasGlobalDefs.RAS_MARRAY; + baseType = newBaseType; + } + + /** + * Retrieves the base type of this MArray. + * @return the base type of this MArray + **/ + public RasBaseType getBaseType() + { + return baseType; + } + + /** + * Returns a string representing this object. + * @return the string representation of this object + **/ + public String toString() + { + return super.toString() + "BaseType of MArray: \n" + baseType + "\n "; + } + + + +} diff --git a/java/src/rasj/RasMInterval.java b/java/src/rasj/RasMInterval.java new file mode 100644 index 0000000..dec1e3c --- /dev/null +++ b/java/src/rasj/RasMInterval.java @@ -0,0 +1,1332 @@ +package rasj; + +import java.lang.*; +import java.util.*; + +/* +* 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: + * The spatial domain of an MDD is represented by an object + * of class RasMInterval. It specifies lower and upper bound + * of the point set for each dimension of an MDD. Internally, + * the class is realized through an array of intervals of type + * RasSInterval. + * + * For the operations union, difference, and intersection the + * dimensionalties of the operands must be equal, otherwise an + * exception is raised. The semantics of the operations are + * defined as follows for each dimension: + * + * | ... fixed bound + * -* ... open bound + * + * + * class orientation union difference intersection + * ----------------------------------------------------------- + * 1 |-a-| |-b-| error a error + * + * 2 |-a-| [a1,b2] [a1,b1] [b1,a2] + * 2 |-b-| + * + * 3 |--a--| a error b + * 3 |-b-| + * + * 4 |-b-| [b1,a2] [b2,a2] [a1,b2] + * 4 |-a-| + * + * 5 |--b--| b error a + * 5 |-a-| + * + * 6 |-b-| |-a-| error a error + * + * 7 |-a-|-b-| [a1,b2] a [a2,a2] + * + * 8 |-b-|-a-| [b1,a2] a [b2,b2] + * + * 9 |--a--| a [a1,b1] b + * 9 |-b-| + * + * 10 |--a--| a [b2,a2] b + * 10 |-b-| + * + * 11 |-a-| a error a + * 11 |-b-| + * + * 12 |--b--| b error a + * 12 |-a-| + * + * 13 |--b--| b error a + * 13 |-a-| + * + * ----------------------------------------------------- + * + * 14 |--a--* a error b + * 14 |-b-| + * + * 15 |--a--* a [b2,a2] b + * 15 |-b-| + * + * 16 |-b-| |-a-* error a error + * + * 17 |-b-|-a-* [b1,a2] a [b2,b2] + * + * 18 |--a--* [b1,a2] [b2,a2] [a1,b2] + * 18 |-b-| + * + * ----------------------------------------------------- + * + * 19 *--a--| a error b + * 19 |-b-| + * + * 20 *--a--| a [a1,b1] b + * 20 |-b-| + * + * 21 *-a-| |-b-| error a error + * + * 22 *-a-|-b-| [a1,b2] a [a2,a2] + * + * 23 *--a--| [a1,b2] [a1,b1] [b1,a2] + * 23 |-b-| + * + * ----------------------------------------------------- + * + * 24 |--b--* b error a + * 24 |-a-| + * + * 25 |--b--* b error a + * 25 |-a-| + * + * 26 |-a-| |-b-* error a error + * + * 27 |-a-|-b-* [a1,b2] a [a2,a2] + * + * 28 |--b--* [a1,b2] [a1,b1] [b1,a2] + * 28 |-a-| + * + * ----------------------------------------------------- + * + * 29 *--b--| b error a + * 29 |-a-| + * + * 30 *--b--| b error a + * 30 |-a-| + * + * 31 *-b-| |-a-| error a error + * + * 32 *-b-|-a-| [b1,a2] a [b2,b2] + * + * 33 *--b--| [b1,a2] [b2,a2] [a1,b2] + * 33 |-a-| + * + * ----------------------------------------------------- + * + * 34 *-a-| |-b-* error a error + * + * 35 *-a-|-b-* [a1,b2] a [a2,a2] + * + * 36 *-a-| [a1,b2] [a1,b1] [b1,a2] + * 36 |-b-* + * + * ----------------------------------------------------- + * + * 37 *-b-| |-a-* error a error + * + * 38 *-b-|-a-* [b1,a2] a [b2,b2] + * + * 39 *-b-| [b1,a2] [a1,b1] [a1,b2] + * 39 |-a-* + * + * ----------------------------------------------------- + * + * 40 *-a-| b error a + * 40 *-b-| + * + * 41 *-a-| a error a + * 41 *-b-| + * + * 42 *-b-| a [b2,a2] b + * 42 *-a-| + * + * ----------------------------------------------------- + * + * 43 |-a-* a [a1,b1] b + * 43 |-b-* + * + * 44 |-a-* a error a + * 44 |-b-* + * + * 45 |-b-* b error a + * 45 |-a-* + * + * ----------------------------------------------------- + * 46 *-a-* |-b-| a error b + * + * 47 *-b-* |-a-| b error b + * + * 48 *-a-* a [b2,a2] b + * 48 *-b-| + * + * 49 *-a-* a [a1,b1] b + * 49 |-b-* + * + * 50 *-b-* b error a + * 50 *-a-| + * + * 51 *-b-* b error a + * 51 |-a-* + * + * 52 *-a-* a error a + * 52 *-b-* + * + * Attention: The difference operation has to be reconsidered in future + * concerning a discrete interpretation of the intervals. + * + * The closure operation defines an interval which is the smallest + * interval containing the two operands. + * The method intersectsWith() returns false in the error cases of the + * intersection operation and true otherwise. + * + * * @version $Revision: 1.15 $ + * + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasMInterval +{ + static final String rcsid = "@(#)Package rasj, class RasMInterval: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasMInterval.java,v 1.15 2003/12/10 21:04:23 rasdev Exp $"; + + /** array for storing the intervals */ + protected RasSInterval[] intervals; + + /** dimensionality of the domain */ + protected int dimensionality; + + /** number of components initialized already */ + protected int streamInitCnt; + + /** + * Constructor getting dimensionality for stream initializing. + * @param dim the dimensionality of this MInterval + **/ + public RasMInterval(int dim) + { + dimensionality = dim; + streamInitCnt = 0; + intervals = new RasSInterval[dimensionality]; + + for(int i=0; i<dim; i++) + intervals[i] = new RasSInterval(); + } + + /** + * Constructor taking a string representation (for example "[1:255, 1:200]"). + * @param mIntStr a string specifying the MInterval + **/ + public RasMInterval(String mIntStr) throws RasResultIsNoIntervalException + { + dimensionality = 1; + streamInitCnt = 0; + + if(mIntStr.trim().charAt(0) != '[') + { + // error + dimensionality = 0; + return; + } + + /** for parsing the string */ + + StringTokenizer strTok = new StringTokenizer(mIntStr.trim(), "[:,]"); + String strCurTok = null; + + /** calculate dimensionality */ + dimensionality = strTok.countTokens()/2; + + intervals = new RasSInterval[ dimensionality ]; + + + for(int i=0; i<dimensionality; i++) + { + RasSInterval sint = new RasSInterval(); + + strCurTok = strTok.nextToken(); + + if(strCurTok.equals("*")) + { + sint.setLow('*'); + } + else + { + sint.setLow(Long.parseLong(strCurTok.trim())); + } + + + strCurTok = strTok.nextToken(); + + if(strCurTok.equals("*")) + { + sint.setHigh('*'); + } + else + { + sint.setHigh(Long.parseLong(strCurTok.trim())); + } + + intervals[i] = sint; + } + } + + /** + * Method for stream initialization with intervals. + * @param newInterval the interval that has to be streamed + **/ + public void stream(final RasSInterval newInterval) throws RasStreamInputOverflowException + { + if(streamInitCnt >= dimensionality) + throw new RasStreamInputOverflowException(); + + intervals[streamInitCnt++] = newInterval; + + } + + /** + * Method for stream initialization with point intervals. + * @param p the point interval that has to be streamed + **/ + public void stream(long p) throws RasStreamInputOverflowException, RasResultIsNoIntervalException + { + if(streamInitCnt >= dimensionality) + throw new RasStreamInputOverflowException(); + + intervals[streamInitCnt++] = new RasSInterval(p, p); + + } + + /** + * Default constructor. + **/ + public RasMInterval() + { + dimensionality = 0; + streamInitCnt = 0; + + intervals = null; + } + + /** + * Copy constructor. + * @param mInterval the MInterval that is to be copied + **/ + public RasMInterval(final RasMInterval mInterval) + throws RasStreamInputOverflowException, RasIndexOutOfBoundsException + { + dimensionality = mInterval.dimension(); + streamInitCnt = mInterval.streamInitCnt; + intervals = new RasSInterval[ dimensionality ]; + + for(int i=0; i<dimensionality; i++) + intervals[i] = new RasSInterval(mInterval.item(i)); + } + + /** + * Determines if the self mInterval intersects with the delivered one. + * @param mInterval the MInterval to be intersected + **/ + public boolean intersectsWith(final RasMInterval mInterval) + throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + boolean result = true; + + if(dimensionality != mInterval.dimension()) + throw new RasDimensionMismatchException( dimensionality, mInterval.dimension()); + + /** none of the interval pairs are allowed to be disjoint */ + for(int i=0; i<dimensionality; i++) + { + if(0 == intervals[i].intersectsWith(mInterval.item(i)) || -1 == intervals[i].intersectsWith(mInterval.item(i))) + { + result = false; + break; + } + } + return result; + } + + /** + * Read access the i-th interval. + * @param i the dimension to be read + **/ + public RasSInterval item(int i) throws RasIndexOutOfBoundsException + { + if(i < 0 || i >= dimensionality) + throw new RasIndexOutOfBoundsException(0, dimensionality-1, i); + + return intervals[i]; + } + + /** + * Write access to the i-th interval. + * @param i the dimension that is to be accessed + * @param value the interval that is to be assigned to the specified dimension + **/ + public void setItem(int i, RasSInterval value) throws RasIndexOutOfBoundsException + { + if(i < 0 || i >= dimensionality) + throw new RasIndexOutOfBoundsException(0, dimensionality-1, i); + intervals[i] = value; + } + + /* + * set MInterval + public final RasMInterval setTo(final RasMInterval mInterval) + throws RasStreamInputOverflowException, RasIndexOutOfBoundsException + { + if(this != mInterval) + { + if((intervals != null) && dimensionality != mInterval.dimension()) + { + intervals = null; + } + + dimensionality = mInterval.dimension(); + streamInitCnt = mInterval.streamInitCnt; + + if(intervals == null) + intervals = new RasSInterval[ dimensionality ]; + + for(int i=0; i<dimensionality; i++) + intervals[i] = new RasSInterval(mInterval.item(i)); + } + + return this; + } + */ + + /** + * Method for testing equality of two MIntervals. Two domains are equal + * if they have the same number of dimensions and each dimension has the + * same lower and upper bounds. + * @param mint the MInterval that is compared to this MInterval + * @return true if the two MIntervals are equal + **/ + public boolean equals(final RasMInterval mint) + { + boolean returnValue = false; + + try { + if(dimensionality == mint.dimensionality) + { + returnValue = true; + + for(int i=0; i<dimensionality && returnValue ; i++) + returnValue &= (intervals[i] == mint.item(i)); + } + + return returnValue; + } + + catch(RasIndexOutOfBoundsException e) { + return false; + } + } + + /** + * Method for testing inequality. This is the negation of the equals method. + * @param mint the MInterval that is compared to this MInterval + * @return true if the two MIntervals are not equal + **/ + public boolean notEquals(final RasMInterval mint) + { + return !equals(mint); + } + + /** + * Method for testing if this interval covers the given point. + * @param pnt the point to be tested + * @return + * <TABLE BORDER=0 CELLPADDING=3> + * <TR><TD ALIGN=RIGHT><B>-1</B></TD><TD> if the point has not the same dimensionality</TD></TR> + * <TR><TD ALIGN=RIGHT><B>1</B></TD><TD> if the point is covered by this MInterval</TD></TR> + * <TR><TD ALIGN=RIGHT><B>0</B></TD><TD> if the point is not covered</TD></TR> + * </TABLE> + **/ + public final int covers(RasPoint pnt) + { + if (dimensionality != pnt.dimension()) + return -1; + try { + for (int i = 0; i < pnt.dimension(); i++) + { + if ((intervals[i].isLowFixed() && pnt.item(i) < intervals[i].low()) || + (intervals[i].isHighFixed() && pnt.item(i) > intervals[i].high())) + return 0; + } + return 1; + } + catch(RasIndexOutOfBoundsException e) { + // This cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","covers(RasPoint pnt)",e.getMessage()); + } + } + + /** + * Method for testing if this interval covers the given interval. + * @param inter2 the MInterval to be tested + * @return + * <TABLE BORDER=0i CELLPADDING=3> + * <TR><TD ALIGN=RIGHT><B>-1</B></TD><TD> if the point has not the same dimensionality</TD></TR> + * <TR><TD ALIGN=RIGHT><B>1</B></TD><TD> if the point is covered by this MInterval</TD></TR> + * <TR><TD ALIGN=RIGHT><B>0</B></TD><TD> if the point is not covered</TD></TR> + **/ + public int covers(RasMInterval inter2) + { + if(dimensionality != inter2.dimension()) + return -1; + + try { + for (int i = 0; i < dimensionality ; i++) + { + if ( + ( intervals[i].isLowFixed() && + (!(inter2.item(i).isLowFixed()) || + intervals[i].low() > inter2.item(i).low() // both lows fixed here + ) + ) || // end of lows check + ( intervals[i].isHighFixed() && + (!(inter2.item(i).isHighFixed()) || + intervals[i].high() < inter2.item(i).high() // both highs fixed here + ) + ) + ) + return 0; + } + return 1; + } + catch( RasIndexOutOfBoundsException e) { + // this can not occur (theoretically) + throw new RasClientInternalException("RasMInterval","covers(RasMInterval inter2)",e.getMessage()); + } + } + + /** + * Gets the dimensionality of this MInterval. + * @return the dimensionality of this MInterval + **/ + public int dimension() + { + return dimensionality; + } + + /** + * Gets the point with the lowest coordinates in every dimension. + * @return the origin of this MInterval (the point with the lowest coordinates) + **/ + public RasPoint getOrigin() + { + try { + int i; + RasPoint pt = new RasPoint(dimensionality); + + for(i=0; i<dimensionality; i++) + pt.stream(intervals[i].low()); + + return pt; + } + catch(RasStreamInputOverflowException e) { + // This cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","getOrigin()",e.getMessage()); + } + } + + /** + * Gets the point with the highest coordinates in every dimension. + * @return the point with the highest coordinates in this MInterval + **/ + public RasPoint getHigh() + { + try { + int i; + RasPoint pt = new RasPoint(dimensionality); + + for(i=0; i<dimensionality; i++) + pt.stream(intervals[i].high()); + + return pt; + } + catch(RasStreamInputOverflowException e) { + // This cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","getHigh()",e.getMessage()); + } + } + + /** + * Gets the size of this MInterval as a point, that means the point specifies the extent + * of this MInterval ( i.e. high() - low() ) in each dimension. + * @return the size of this MInterval + **/ + public RasPoint getExtent() + { + try { + int i; + RasPoint pt = new RasPoint(dimensionality); + + for(i=0; i<dimensionality; i++) + pt.stream(intervals[i].high() - intervals[i].low() + 1); + + return pt; + } + catch(RasStreamInputOverflowException e) { + // This cannot occur (theoretically) + System.err.println("Error in method RasMInterval.getExtent()"); + return null; + } + } + + /** + * This method checks if this MInterval is mergeable with another MInterval. + * Two RasMIntervals are "mergeable" if they have the same low() and high() + * values in all dimensions except in one where they differ by one point, + * this is, a.low()==b.high()+1 or b.low()==a.high()+1. For instance, the + * following two blocks are mergeable: + * + * <pre> + * +-------------+---------------------------------------+ + * | A | B | + * +-------------|---------------------------------------| + * + * and the following two are not: + * + * +-------------+-------------------------+ + * | | B | + * | A +-------------------------+ + * +-------------+ + * + * </pre> + * @param b the MInterval to be checked + * @return true if the two intervalls are mergeable + **/ + public boolean isMergeable(final RasMInterval b) + { + final RasMInterval a = this; // An alias to this object + + // The blocks must have the same dimensionality to be mergeable + if (a.dimensionality != b.dimensionality) + return false; + + // Count the number of adjacent frontiers + int onesDifferences = 0; + + // Is Mergeable variable + boolean isMerg = true; + + // For all dimensions + try { + for (int i=0; i<dimensionality; i++) + { + if (a.item(i).low() != b.item(i).low()) // Diferente origins + { + if ((a.item(i).low() == b.item(i).high()+1) || // If borders are adjacent + (b.item(i).low() == a.item(i).high()+1)) + { + ++onesDifferences; // Update counter + } + else + { + isMerg = false; // Else non-mergeable blocks + break; + } + } + else // Same origins + { + if (a.item(i).high() != b.item(i).high()) // Check ending + { + isMerg = false; // Not the same, can't be + break; // mergeable + } + } + } + + if (isMerg && (onesDifferences!=1)) // Only one adjacent borded + isMerg = false; // allowed + + return isMerg; // Return result + } + + catch(RasIndexOutOfBoundsException e) { + // This cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","isMergeable()",e.getMessage()); + } + + } + + /** + * This methods translates the current MInterval by a point. + * It adds the coordinates of the given point to the lower bounds of the + * current MInterval. This operation is only legal if all lower bounds are + * fixed and the point has the same dimension as the MInterval!<P> + * Note that this method modifies the current MInterval. If you want to + * get a new MInterval, use the {@link #createTranslation(RasPoint) createTranslation} method + * instead.<P> + * @param t the point to be added + * @return the current MInterval + **/ + public RasMInterval translate(RasPoint t) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + int i; + + if(dimensionality != t.dimension()) + throw new RasDimensionMismatchException(dimensionality, t.dimension()); + + try { + + for(i=0; i<dimensionality; i++) + { + intervals[i].setInterval(intervals[i].low() + t.item(i), + intervals[i].high() + t.item(i)); + } + } + catch(RasIndexOutOfBoundsException e) { + // this cannor occur (theoretically) + throw new RasClientInternalException("RasMInterval","translate()",e.getMessage()); + } + + return this; + } + + + /** + * This method returns a new MInterval resulting from a translation of the current + * MInterval by the given point. + * It creates a copy of the current MInterval and adds the coordinates of the given + * point to its lower bounds.<P> + * This operation is only legal if all lower bounds are + * fixed and the point has the same dimension as the MInterval!<P> + * @param t the point to be added + * @return the new MInterval + **/ + public RasMInterval createTranslation(RasPoint t) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(dimensionality != t.dimension()) + throw new RasDimensionMismatchException(dimensionality, t.dimension()); + + RasMInterval result = new RasMInterval(dimensionality); + + try { + for(int i=0; i<dimensionality; i++) + result.intervals[i].setInterval(intervals[i].low() + t.item(i), + intervals[i].high() + t.item(i)); + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","createTranslation()",e.getMessage()); + } + + return result; + } + + /** + * Calculates the union of two MIntervals. This is only possible for two MIntervals + * having the same dimensionality. + * <P>Note that this operation modifies the current object. If you want to get a new MInterval, + * use {@link #createUnion(RasMInterval) createUnion} instead.</P> + * @param mint1 the first MInterval + * @param mint2 the second MInterval + * @return the current MInterval (representing the union of mint1 and mint2) + **/ + public RasMInterval unionOf(final RasMInterval mint1, final RasMInterval mint2) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(mint1.dimension() != mint2.dimension()) + throw new RasDimensionMismatchException( mint1.dimension(), mint2.dimension()); + + // cleanup + initializing of this + + dimensionality = mint1.dimension(); + streamInitCnt = dimensionality; + intervals = new RasSInterval[ dimensionality ]; + + try { + + for(int i=0; i<dimensionality; i++) + { + intervals[i] = new RasSInterval(); + intervals[i].unionOf(mint1.item(i), mint2.item(i)); + } + return this; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","unionOf()",e.getMessage()); + } + + } + + /** + * Calculates the union of the current MIntervall with another one. + * <P>Note that this operation modifies the current object. If you want to get a new MInterval, + * use {@link #createUnion(RasMInterval) createUnion} instead.</P> + * @param mint the MInterval to be used for the union + * @return the current MInterval (after the union with mint) + **/ + public RasMInterval unionWith(final RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(dimensionality != mint.dimension()) + throw new RasDimensionMismatchException( dimensionality, mint.dimension()); + + try { + + for(int i=0; i<dimensionality; i++) + intervals[i].unionWith(mint.item(i)); + return this; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","unionWith()",e.getMessage()); + } + + } + + /** + * @deprecated This methdod provides just another name for the + * unionWith method and might not be supported in future versions. Please + * use {@link #unionWith(RasMInterval) unionWith} instead. + * @param mint the MInterval to be added + * @return the current MInterval after adding mint + **/ + public RasMInterval addToSelf(final RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + return unionWith(mint); + } + + + /** + * Returns a new MInterval calculated from a union of the current MInterval + * and the given one. + * @param mint the MInterval to be unioned with this MInterval + * @return the union of this MInterval and mint + **/ + public RasMInterval createUnion(final RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(dimensionality != mint.dimension()) + throw new RasDimensionMismatchException( dimensionality, mint.dimension()); + + RasMInterval result = new RasMInterval(dimensionality); + try { + for(int i=0; i<dimensionality; i++) + result.stream(intervals[i].createUnion(mint.item(i))); + return result; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","createUnion()",e.getMessage()); + } + catch(RasStreamInputOverflowException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","createUnion()",e.getMessage()); + } + + } + + + /** + * @deprecated This methdod provides just another name for the + * createUnion method and might not be supported in future versions. Please + * use {@link #createUnion(RasMInterval) createUnion} instead. + * @param mint the MInterval to be added + * @return the current MInterval after adding mint + **/ + public RasMInterval add(final RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + return createUnion(mint); + } + + + /** + * Calculates the difference of two MIntervals. + * <P>Note that this operation modifies the current object. If you want to get a new MInterval, + * use {@link #createDifference(RasMInterval) createDifference} instead.</P> + * @param mint1 the first MInterval + * @param mint2 the second MInterval + * @return the current MInterval (representing the difference of mint1 and mint2) + **/ + public RasMInterval differenceOf(final RasMInterval mint1, final RasMInterval mint2) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(mint1.dimension() != mint2.dimension()) + throw new RasDimensionMismatchException( mint1.dimension(), mint2.dimension()); + + // cleanup + initializing of this + + dimensionality = mint1.dimension(); + streamInitCnt = dimensionality; + intervals = new RasSInterval[ dimensionality ]; + + try { + + for(int i=0; i<dimensionality; i++) + { + intervals[i] = new RasSInterval(); + intervals[i].differenceOf(mint1.item(i), mint2.item(i)); + } + return this; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","differenceOf()",e.getMessage()); + } + } + + /** + * Calculates the difference of the current MInterval and the given one. + * <P>Note that this operation modifies the current object. If you want to get a new MInterval, + * use {@link #createDifference(RasMInterval) createDifference} instead.</P> + * @param mint the MInterval used for building the difference + * @return the current MInterval (representing the difference of this MInterval and mint) + **/ + public RasMInterval differenceWith(final RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(dimensionality != mint.dimension()) + throw new RasDimensionMismatchException(dimensionality, mint.dimension()); + + try { + for(int i=0; i<dimensionality; i++) + { + intervals[i].differenceWith(mint.item(i)); + } + return this; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","differenceWith()",e.getMessage()); + } + } + + /** + * @deprecated This methdod provides just another name for the + * differenceWith method and might not be supported in future versions. Please + * use {@link #differenceWith(RasMInterval) differenceWith} instead. + * @param mint1 the MInterval used for building the difference + * @return the difference of this MInterval and mint2 + **/ + public RasMInterval diffFromSelf(RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + return differenceWith(mint); + } + + /** + * Returns a new MInterval calculated from a difference of the current MInterval + * and the given one. + * @param mint the MInterval used for calculating the difference with the current MInterval + * @return the difference of this MInterval and mint + **/ + public RasMInterval createDifference(RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(dimensionality != mint.dimension()) + throw new RasDimensionMismatchException(dimensionality, mint.dimension()); + + RasMInterval result = new RasMInterval(dimensionality); + + try { + for(int i=0; i<dimensionality; i++) + result.stream(intervals[i].createDifference(mint.item(i))); + return result; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","createDifference()",e.getMessage()); + } + catch(RasStreamInputOverflowException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","createDifference()",e.getMessage()); + } + + } + + /** + * @deprecated This methdod provides just another name for the + * createDifference method and might not be supported in future versions. Please + * use {@link #createDifference(RasMInterval) createDifference} instead. + * @param mint the MInterval used for calculating the difference with the current MInterval + * @return the difference of this MInterval and mint + **/ + public RasMInterval diff(RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + return createDifference(mint); + } + + + // Methods/Operators for the intersection operation: + /** + * This method calculates the intersection of two MIntervals. This is only possible if the + * two MIntervals have the same dimensionality. + * <P>Note that this operation modifies the current object. If you want to get a new MInterval, + * use {@link #createIntersection(RasMInterval) createIntersection} instead.</P> + * @param mint1 the first MInterval + * @param mint2 the second MInterval + * @return the current MInterval (representing the intersection of mint1 and mint2) + **/ + public RasMInterval intersectionOf(RasMInterval mint1, RasMInterval mint2) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(mint1.dimension() != mint2.dimension()) + throw new RasDimensionMismatchException( mint1.dimension(), mint2.dimension()); + + // cleanup + initializing of this + + dimensionality = mint1.dimension(); + streamInitCnt = dimensionality; + intervals = new RasSInterval[ dimensionality ]; + + try { + for(int i=0; i<dimensionality; i++) + { + intervals[i] = new RasSInterval(); + intervals[i].intersectionOf(mint1.item(i), mint2.item(i)); + } + return this; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","intersectionOf()",e.getMessage()); + } + + } + + /** + * Calculates the intersection of the current MInterval and the given one. + * <P>Note that this operation modifies the current object. If you want to get a new MInterval, + * use {@link #createIntersection(RasMInterval) createIntersection} instead.</P> + * @param mint the MInterval used for building the intersection + * @return the current MInterval (representing the intersection of this MInterval and mint) + **/ + public RasMInterval intersectionWith(RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(dimensionality != mint.dimension()) + throw new RasDimensionMismatchException(dimensionality, mint.dimension()); + + try { + for(int i=0; i<dimensionality; i++) + intervals[i].intersectionWith(mint.item(i)); + return this; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","intersectionWith()",e.getMessage()); + } + } + + /** + * @deprecated This methdod provides just another name for the + * intersectionWith method and might not be supported in future versions. Please + * use {@link #intersectionWith(RasMInterval) intersectionWith} instead. + * @param mint the MInterval used for building the intersection + * @return the intersection of this MInterval and mint + **/ + public RasMInterval multWithSelf(RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + return intersectionWith(mint); + } + + + /** + * Returns a new MInterval calculated from the intersection of the current MInterval + * and the given one. + * @param mint the MInterval used for calculating the intersection with the current MInterval + * @return the intersection of this MInterval and mint + **/ + public RasMInterval createIntersection (RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(dimensionality != mint.dimension()) + throw new RasDimensionMismatchException( dimensionality, mint.dimension()); + + RasMInterval result = new RasMInterval(dimensionality); + try { + for(int i=0; i<dimensionality; i++) + result.stream(intervals[i].createIntersection(mint.item(i))); + return result; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","createIntersection()",e.getMessage()); + } + catch(RasStreamInputOverflowException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","createIntersection()",e.getMessage()); + } + } + + /** + * @deprecated This methdod provides just another name for the + * createIntersection method and might not be supported in future versions. Please + * use {@link #createIntersection(RasMInterval) createIntersection} instead. + * @param mint the MInterval used for calculating the intersection with the current MInterval + * @return the intersection of this MInterval and mint + **/ + public RasMInterval mult(final RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + return createIntersection(mint); + } + + + // Methods/Operators for the closure operation: + /** + * Calculates the closure of two MIntervals. + * <P>Note that this operation modifies the current object. If you want to get a new MInterval, + * use {@link #createClosure(RasMInterval) createClosure} instead.</P> + * @param mint1 the first MInterval + * @param mint2 the second MInterval + * @return the current MInterval (representing the closure of mint1 and mint2) + **/ + public RasMInterval closureOf(RasMInterval mint1, RasMInterval mint2) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + + if(mint1.dimension() != mint2.dimension()) + throw new RasDimensionMismatchException( mint1.dimension(), mint2.dimension()); + + // cleanup + initializing of this + + dimensionality = mint1.dimension(); + streamInitCnt = dimensionality; + intervals = new RasSInterval[ dimensionality ]; + + try + { + for(int i=0; i<dimensionality; i++) + { + intervals[i] = new RasSInterval(); + intervals[i].closureOf(mint1.item(i), mint2.item(i)); + } + return this; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","closureOf()",e.getMessage()); + } + } + + /** + * Calculates the closure of the current MInterval and the given one. + * <P>Note that this operation modifies the current object. If you want to get a new MInterval, + * use {@link #createClosure(RasMInterval) createClosure} instead.</P> + * @param mint the MInterval used for building the closure + * @return the current MInterval (representing the closure of this MInterval and mint) + **/ + public RasMInterval closureWith(final RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(dimensionality != mint.dimension()) + throw new RasDimensionMismatchException( dimensionality, mint.dimension()); + + try + { + for(int i=0; i<dimensionality; i++) + intervals[i].closureWith(mint.item(i)); + return this; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","closureWith()",e.getMessage()); + } + } + + /** + * Returns a new MInterval calculated from the closure of the current MInterval + * and the given one. + * @param mint the MInterval used for calculating the closure with the current MInterval + * @return the closure of this MInterval and mint + **/ + public RasMInterval createClosure(RasMInterval mint) + throws RasDimensionMismatchException, RasResultIsNoIntervalException + { + if(dimensionality != mint.dimension()) + throw new RasDimensionMismatchException( dimensionality, mint.dimension()); + + RasMInterval result = new RasMInterval(dimensionality); + + try + { + for(int i=0; i<dimensionality; i++) + result.stream(intervals[i].createClosure(mint.item(i))); + return result; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","createClosure()",e.getMessage()); + } + catch(RasStreamInputOverflowException e) { + // this cannot occur (theoretically) + throw new RasClientInternalException("RasMInterval","createClosure()",e.getMessage()); + } + + } + + // Methods for internal use only: + + /** + * Calculates the number of cells. + **/ + long cellCount() + { + long cellCount=1; + + for(int i=0; i<dimensionality; i++) + cellCount *= intervals[i].high() - intervals[i].low() + 1; + + return cellCount; + } + + /** + * Calculates the offset in cells for one dimensional (linear) access to + * the given point (dimension ordering is high first). + **/ + long cellOffset( final RasPoint point) + throws RasIndexOutOfBoundsException + { + int i = 0; + long offset = 0; + + // calculate offset + for(i = 0; i < dimensionality - 1; i++) + { + if(point.item(i) < intervals[i].low() || point.item(i) > intervals[i].high()) + throw new RasIndexOutOfBoundsException(intervals[i].low(), intervals[i].high(), point.item(i) ); + + offset = (offset + point.item(i) - intervals[i].low()) * (intervals[i+1].high() - intervals[i+1].low() + 1); + } + + // now i = dimensionality - 1 + if(point.item(i) < intervals[i].low() || point.item(i) > intervals[i].high()) + throw new RasIndexOutOfBoundsException(intervals[i].low(), intervals[i].high(), point.item(i) ); + + offset += point.item(i) - intervals[i].low(); + + return offset; + } + + /** + * This method calculates the spatial domain + * coordinates as a point from the offset + * specified. Lower dimensions are higher + * valued which means that the highest dimension + * is stored in a sequence. + **/ + RasPoint cellPoint(long offset) throws RasResultIsNoCellException + { + int i; + long factor=1; + RasPoint pt = new RasPoint(dimensionality); + + try { + + if(offset >= cellCount()) + throw new RasResultIsNoCellException(); + + for(i=0; i<dimensionality; i++) + factor *= intervals[i].high() - intervals[i].low() + 1; + + for(i=0; i<dimensionality; i++) + { + factor /= intervals[i].high() - intervals[i].low() + 1; + pt.stream(intervals[i].low() + (offset - (offset%factor))/factor); + offset %= factor; + } + + return pt; + } + catch( RasStreamInputOverflowException e ) { + // this cannot occur (theoretically) + System.err.println("Error in method RasMInterval.cellPoint()."); + return null; + } + } + + // delete the specified dimension + void deleteDimension(int dim) throws RasException + { + if(dim < 0 || dim >= dimensionality) + throw new RasIndexOutOfBoundsException(0, dimensionality-1, dim); + + dimensionality -= 1; + streamInitCnt = dimensionality; + RasSInterval[] newIntervals = new RasSInterval[ dimensionality ]; + + for(int i=0, j=0; i<dimensionality; i++, j++) + { + if(i==dim) j++; + newIntervals[i] = intervals[j]; + } + + intervals = newIntervals; + } + + // calculate the size of the storage space occupied + long getStorageSize() + { + long sz = 26; //18 + 2 * 4 + + if (dimensionality > 0) + sz += dimensionality * 18; + + return sz; + } + + /** gives back the string representation */ + public String toString() + { + String retString = ""; + if(dimensionality > 0) + { + for(int i=0; i<dimensionality-1; i++) + { + retString = retString + intervals[i].toString() + ","; + } + retString = retString + intervals[dimensionality-1].toString(); + } + + return "[" + retString + "]"; + } +} diff --git a/java/src/rasj/RasMIntervalType.java b/java/src/rasj/RasMIntervalType.java new file mode 100644 index 0000000..ec31e17 --- /dev/null +++ b/java/src/rasj/RasMIntervalType.java @@ -0,0 +1,49 @@ +package rasj; + +import rasj.*; +import java.util.*; + +/* +* 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: + * This class represents the MInterval type in the ODMG conformant + * representation of the RasDaMan type system. + * @version $Revision: 1.4 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasMIntervalType extends RasType +{ + static final String rcsid = "@(#)Package rasj, class RasMIntervalType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasMIntervalType.java,v 1.4 2003/12/10 21:04:23 rasdev Exp $"; + + +} diff --git a/java/src/rasj/RasOIDType.java b/java/src/rasj/RasOIDType.java new file mode 100644 index 0000000..feb4d92 --- /dev/null +++ b/java/src/rasj/RasOIDType.java @@ -0,0 +1,49 @@ +package rasj; + +import rasj.*; +import java.util.*; + +/* +* 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: + * This class represents the OID type in the ODMG conformant + * representation of the RasDaMan type system. + * @version $Revision: 1.4 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasOIDType extends RasType +{ + static final String rcsid = "@(#)Package rasj, class RasOIDType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasOIDType.java,v 1.4 2003/12/10 21:04:23 rasdev Exp $"; + + +} diff --git a/java/src/rasj/RasPoint.java b/java/src/rasj/RasPoint.java new file mode 100644 index 0000000..b0f3793 --- /dev/null +++ b/java/src/rasj/RasPoint.java @@ -0,0 +1,426 @@ +package rasj; + +import java.lang.*; +import java.util.*; + +/* +* 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: + * This class represents an n-dimensional point vector. + * @version $Revision: 1.9 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasPoint +{ + static final String rcsid = "@(#)Package rasj, class RasPoint: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasPoint.java,v 1.9 2003/12/10 21:04:23 rasdev Exp $"; + + // array holding the point coordinates + private long[] points; + // dimensionality of the point + private int dimensionality; + // number of components initialized already + private int streamInitCnt; + + /** + * Constructor getting the dimensionality for stream initialization. + * @param dim the dimensionality of this point + **/ + public RasPoint(int dim) + { + dimensionality = dim; + streamInitCnt = 0; + + points = new long[dimensionality]; + + for(int i=0; i< dimensionality; i++) + points[i] = 0; + } + + /** + * Method for stream initialization of this point. + * @param newElement a new dimension that is added to this point + **/ + public RasPoint stream(long newElement) throws RasStreamInputOverflowException + { + if(streamInitCnt >= dimensionality) + throw new RasStreamInputOverflowException(); + + points[streamInitCnt++] = newElement; + return this; + } + + /** + * constructor taking a string representation for this point (for example "[1, 2, 3]"). + * @param stringRep the string representation for this point + **/ + public RasPoint(String stringRep) + { + dimensionality = 1; + streamInitCnt = 0; + + if(stringRep.trim().charAt(0) != '[') + { + // error + dimensionality = 0; + return; + } + + // for parsing the string + StringTokenizer strTok = new StringTokenizer(stringRep.trim(), "[,]"); + String strCurTok = null; + + // calculate dimensionality + dimensionality = strTok.countTokens(); + + points = new long[dimensionality]; + + for(int i=0; i<dimensionality; i++) + { + strCurTok = strTok.nextToken(); + points[i] = Long.parseLong(strCurTok.trim()); + } + } + + /** + * Easy-to-use constructor for two dimensional points. + * @param p1 the value of the first dimension + * @param p2 the value of the second dimension + **/ + public RasPoint(long p1, long p2) + { + dimensionality = 2; + streamInitCnt = 2; + + points = new long[dimensionality]; + points[0] = p1; + points[1] = p2; + } + + /** + * Easy-to-use constructor for three dimensional points. + * @param p1 the value of the first dimension + * @param p2 the value of the second dimension + * @param p3 the value of the third dimension + **/ + public RasPoint(long p1, long p2, long p3) + { + dimensionality =3; + streamInitCnt = 3; + + points = new long[dimensionality]; + points[0] = p1; + points[1] = p2; + points[2] = p3; + } + + /** + * Easy-to-use constructor for four dimensional points. + * @param p1 the value of the first dimension + * @param p2 the value of the second dimension + * @param p3 the value of the third dimension + * @param p4 the value of the fourth dimension + **/ + public RasPoint(long p1, long p2, long p3, long p4) + { + dimensionality = 4; + streamInitCnt = 4; + + points = new long[dimensionality]; + points[0] = p1; + points[1] = p2; + points[2] = p3; + points[3] = p4; + } + + /** + * Easy-to-use constructor for five dimensional points. + * @param p1 the value of the first dimension + * @param p2 the value of the second dimension + * @param p3 the value of the third dimension + * @param p4 the value of the fourth dimension + * @param p5 the value of the fifth dimension + **/ + public RasPoint(long p1, long p2, long p3, long p4, long p5) + { + dimensionality = 5; + streamInitCnt = 5; + + points = new long[dimensionality]; + points[0] = p1; + points[1] = p2; + points[2] = p3; + points[3] = p4; + points[4] = p5; + } + + /** + * Default constructor. + **/ + public RasPoint() + { + dimensionality = 0; + streamInitCnt = 0; + + points = null; + } + + /** + * Copy constructor that initializes this point with the values of the given one. + * @param pt the point used to copy the values from + **/ + public RasPoint(final RasPoint pt) + { + dimensionality = pt.dimension(); + streamInitCnt = dimensionality; + points = new long[ dimensionality ]; + + try { + for(int i=0; i<dimensionality; i++) + points[i] = pt.item(i); + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + System.out.println("Error in RasPoint copy constructor."); + } + } + + /** + * Read access to the i-th coordinate. + * @param i the dimension that is to be read + * @return the value of the i-th coordinate + **/ + public long item(int i) throws RasIndexOutOfBoundsException + { + if(i < 0 || i >= dimensionality) + throw new RasIndexOutOfBoundsException(0, dimensionality-1, i); + + return points[i]; + } + + /** + * write access to the i-th coordinate + * @param i the coordinate that is to be accessed + * @param value the value that is to be assigned to the specified coordinate + **/ + public void setItem(int i, long value) throws RasIndexOutOfBoundsException + { + if(i < 0 || i >= dimensionality) + throw new RasIndexOutOfBoundsException(0, dimensionality-1, i); + points[i] = value; + } + + /** + * This method copies the values of the given point to the current point. All + * previously defined values of the current point will be deleted. + * @param pt the point to be copied + * @return the current point with its new values + **/ + public final RasPoint setTo(final RasPoint pt) throws RasIndexOutOfBoundsException + { + if(this != pt) + { + if((points != null) && dimensionality != pt.dimension()) + { + points = null; + } + + dimensionality = pt.dimension(); + streamInitCnt = dimensionality; + + if(points == null) + points = new long[ dimensionality ]; + + for(int i=0; i<dimensionality; i++) + points[i] = pt.item(i); + + } + + return this; + } + + /** + * Compares this point to another point. + * @param p the point to be compared + * @return + * <TABLE BORDER=0 CELLPADDING=3> + * <TR><TD ALIGN=RIGHT VALIGN=TOP><B>-2</B></TD><TD> if the points have not the same dimensionality</TD></TR> + * <TR><TD ALIGN=RIGHT VALIGN=TOP><B>-1</B></TD><TD> if the current point is "lesser" than point p. + * <BR>In this context, "lesser" refers to the comparison of the coordinates in decreasing order + * of magnitude For example, the point (2,2,9) is "lesser" than the point (2,3,1).</TD></TR> + * <TR><TD ALIGN=RIGHT VALIGN=TOP><B>0</B></TD><TD> if the two points have an equal value</TD></TR> + * <TR><TD ALIGN=RIGHT VALIGN=TOP><B>1</B></TD><TD> if the current point is "greater" than point p + * ("greater" is the opposite of "lesser").</TD></TR> + * </TABLE> + **/ + public final int comparedWith(final RasPoint p) + { + if(dimensionality != p.dimensionality) + return -2; + + try { + for (int i = 0; i < dimensionality; i++) + { + if (points[i] > p.item(i)) + return 1; + if (points[i] < p.item(i)) + return -1 ; + } + return 0; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + System.out.println("Error in method RasPoint.comparedWith()."); + return -2; + } + } + + /** + * Method for testing equality of two points.<BR>Two points are equal + * if they have the same dimensionality and identic values in each dimension. + * @param pt the point that is compared to the current point + * @return true if the two points are equal + **/ + public boolean equals(final RasPoint pt) throws RasDimensionMismatchException + { + boolean returnValue = false; + + if(dimensionality != pt.dimensionality) + { + throw new RasDimensionMismatchException(dimensionality, pt.dimensionality); + } + try { + returnValue = true; + for(int i=0; i<dimensionality && returnValue ; i++) + returnValue &= (points[i] == pt.item(i)); + return returnValue; + } + catch(RasIndexOutOfBoundsException e) { + // this cannot occur (theoretically) + return false; + } + } + + /** + * Method for testing inequality. This is the negation of the equals method. + * @param pt the point that is compared to the current point + * @return true if the two points are not equal + **/ + public boolean notEquals(final RasPoint pt) throws RasDimensionMismatchException + { + return !equals(pt); + } + + /** + * Method for vector addition. The current point will be modified to contain + * the result of the addition. + * @param pt the point ot be added to the current point + * @return the current point after the addition + **/ + public RasPoint add(final RasPoint pt) throws RasDimensionMismatchException + { + if(dimensionality != pt.dimension()) + throw new RasDimensionMismatchException(dimensionality, pt.dimension()); + + try { + RasPoint result = new RasPoint(dimensionality); + for(int i=0; i<dimensionality; i++) + { + result.stream(points[i] + pt.item(i)); + } + return result; + } + catch(RasException e) { + // this cannot occur (theoretically) + System.err.println("Error in method RasPoint.add()."); + return null; + } + } + + + /** + * Method for vector multiplication. The current point will be modified to contain + * the result of the multiplication. + * @param pt the point ot be multiplied to the current point + * @return the current point after the multiplication + **/ + public RasPoint mult(final RasPoint pt) throws RasDimensionMismatchException + { + if(dimensionality != pt.dimension()) + throw new RasDimensionMismatchException(dimensionality, pt.dimension()); + + try { + RasPoint result= new RasPoint(dimensionality); + for(int i=0; i<dimensionality; i++) + { + result.stream(points[i] * pt.item(i)); + } + return result; + } + catch(RasException e) { + // this cannot occur (theoretically) + System.err.println("Error in method RasPoint.mult()."); + return null; + } + } + + + /** + * Gets the dimensionality of this point. + * @return the dimensionality of this point + **/ + public int dimension() + { + return dimensionality; + } + + + /** + * Gives back the string representation of this point. + * @return the string representation of this point + **/ + public String toString() + { + String retString = ""; + if(dimensionality > 0) + { + for(int i=0; i<dimensionality-1; i++) + { + retString = retString + Long.toString(points[i]) + ","; + } + retString = retString + Long.toString(points[dimensionality-1]); + } + + return "[" + retString + "]"; + } + +} diff --git a/java/src/rasj/RasPointType.java b/java/src/rasj/RasPointType.java new file mode 100644 index 0000000..3f0f4b1 --- /dev/null +++ b/java/src/rasj/RasPointType.java @@ -0,0 +1,49 @@ +package rasj; + +import rasj.*; +import java.util.*; + +/* +* 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: + * This class represents the Point type in the ODMG conformant + * representation of the RasDaMan type system. + * @version $Revision: 1.4 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasPointType extends RasType +{ + static final String rcsid = "@(#)Package rasj, class RasPointType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasPointType.java,v 1.4 2003/12/10 21:04:23 rasdev Exp $"; + + +} diff --git a/java/src/rasj/RasPrimitiveType.java b/java/src/rasj/RasPrimitiveType.java new file mode 100644 index 0000000..5d7543d --- /dev/null +++ b/java/src/rasj/RasPrimitiveType.java @@ -0,0 +1,169 @@ +package rasj; + +import rasj.*; +import rasj.global.*; + +import java.util.*; + +/* +* 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: + * This class represents the primitive types in the ODMG conformant + * representation of the RasDaMan type system. + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasPrimitiveType extends RasBaseType implements RasGlobalDefs +{ + static final String rcsid = "@(#)Package rasj, class RasPrimitiveType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasPrimitiveType.java,v 1.8 2003/12/10 21:04:23 rasdev Exp $"; + + private String rasTypeName = null; + + public RasPrimitiveType() + { + super(); + } + + public RasPrimitiveType(String name, int type) + { + super(name, 0); + typeID = type; + + switch(typeID) + { + case RAS_LONG: typeSize = SIZE_OF_RAS_LONG; rasTypeName = "RAS_LONG"; break; + case RAS_ULONG: typeSize = SIZE_OF_RAS_ULONG; rasTypeName = "RAS_ULONG"; break; + case RAS_SHORT: typeSize = SIZE_OF_RAS_SHORT; rasTypeName = "RAS_SHORT"; break; + case RAS_USHORT: typeSize = SIZE_OF_RAS_USHORT; rasTypeName = "RAS_USHORT"; break; + case RAS_BOOLEAN: typeSize = SIZE_OF_RAS_BOOLEAN; rasTypeName = "RAS_BOOLEAN"; break; + case RAS_BYTE: typeSize = SIZE_OF_RAS_BYTE; rasTypeName = "RAS_BYTE"; break; + case RAS_DOUBLE: typeSize = SIZE_OF_RAS_DOUBLE; rasTypeName = "RAS_DOUBLE"; break; + case RAS_FLOAT: typeSize = SIZE_OF_RAS_FLOAT; rasTypeName = "RAS_FLOAT"; break; + case RAS_CHAR: typeSize = SIZE_OF_RAS_CHAR; rasTypeName = "RAS_CHAR"; break; + } + } + + + public int getTypeID() + { + return typeID; + } + + public String toString() + { + return super.toString(); + } + + public Boolean getBoolean(Object cell) throws RasTypeInvalidException + { + if(typeID != RAS_BOOLEAN) + { + throw new RasTypeInvalidException("RAS_BOOLEAN",rasTypeName); + } + + return (Boolean)cell; + } + + + public Character getCharacter(Object cell) throws RasTypeInvalidException + { + if(typeID != RAS_CHAR) + { + throw new RasTypeInvalidException("RAS_CHAR",rasTypeName); + } + + return (Character)cell; + } + + + public Byte getByte(Object cell) throws RasTypeInvalidException + { + if(typeID != RAS_BYTE) + { + throw new RasTypeInvalidException("RAS_BYTE",rasTypeName); + } + + return (Byte)cell; + } + + + public Short getShort(Object cell) throws RasTypeInvalidException + { + if(typeID != RAS_SHORT) + { + throw new RasTypeInvalidException("RAS_SHORT",rasTypeName); + } + + return (Short)cell; + } + + + public Integer getInteger(Object cell) throws RasTypeInvalidException + { + if((typeID != RAS_LONG) || (typeID != RAS_USHORT)) + { + throw new RasTypeInvalidException("RAS_LONG",rasTypeName); + } + + return (Integer)cell; + } + + public Long getLong(Object cell) throws RasTypeInvalidException + { + if(typeID != RAS_ULONG) + { + throw new RasTypeInvalidException("RAS_ULONG",rasTypeName); + } + + return (Long)cell; + } + + public Float getFloat(Object cell) throws RasTypeInvalidException + { + if(typeID != RAS_FLOAT) + { + throw new RasTypeInvalidException("RAS_FLOAT",rasTypeName); + } + + return (Float)cell; + } + + public Double getDouble(Object cell) throws RasTypeInvalidException + { + if(typeID != RAS_DOUBLE) + { + throw new RasTypeInvalidException("RAS_DOUBLE",rasTypeName); + } + + return (Double)cell; + } + +} diff --git a/java/src/rasj/RasQueryExecutionFailedException.java b/java/src/rasj/RasQueryExecutionFailedException.java new file mode 100644 index 0000000..697fe6c --- /dev/null +++ b/java/src/rasj/RasQueryExecutionFailedException.java @@ -0,0 +1,172 @@ +package rasj; + +import java.util.*; +import rasj.global.*; +import org.odmg.*; + +/* +* 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: + * This exception extends the ODMGQueryInvalidException by offering direct access to the + * RasDaMan error number and the line, column and token in the querystring that produced the error. + * @version $Revision: 1.10 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasQueryExecutionFailedException extends QueryInvalidException +{ + static final String rcsid = "@(#)Package rasj, class RasQueryExecutionFailedException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasQueryExecutionFailedException.java,v 1.10 2003/12/19 16:22:27 rasdev Exp $"; + + /** + * the official RasDaMan error number + */ + private int errNo; + + /** + * line number of the error + */ + private int line; + + /** + * column of the error + */ + private int column; + + /** + * token that caused the error + */ + private String token; + + public RasQueryExecutionFailedException(String string) + { + if (string==null) + { + line = 0; + column = 0; + token = "(null)"; + } + else + { + StringTokenizer tokenizer= new StringTokenizer( string, RasGlobalDefs.KEYWORD_TAB ); + String Ttoken=tokenizer.nextToken(); + Ttoken=tokenizer.nextToken(); + errNo=Integer.parseInt(Ttoken); + if(tokenizer.hasMoreTokens()) + { + line=Integer.parseInt(tokenizer.nextToken()); + column=Integer.parseInt(tokenizer.nextToken()); + token=tokenizer.nextToken(); + } + else + { + line=0; + column=0; + token=""; + } + } + } + + /** + * Default Constructor setting the error specification + *@param errorNo official RasDaMan error number + *@param lineNo line in the query string that contained the error + *@param colNo column in the query string that contains the error + *@param tok token that caused the error + */ + public RasQueryExecutionFailedException( int errorNo, int lineNo, int colNo, String tok ) + { + super(); + errNo = errorNo; + line = lineNo; + column = colNo; + token = ( (tok==null) ? "(null)" : tok ); + } + + public String getMessage() + { + int index; + + if(super.getMessage() == null) + + { + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + index = msg.indexOf( RasGlobalDefs.KEYWORD_TOKEN ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_TOKEN.length(), token); + + msg = buf.toString(); + index = msg.indexOf( RasGlobalDefs.KEYWORD_ERRNO ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_ERRNO.length(), String.valueOf(errNo)); + + msg = buf.toString(); + index = msg.indexOf( RasGlobalDefs.KEYWORD_LINENO ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_LINENO.length(), String.valueOf(line)); + + msg = buf.toString(); + index = msg.indexOf( RasGlobalDefs.KEYWORD_COLNO ); + if(index != -1) + buf.replace(index, index+RasGlobalDefs.KEYWORD_COLNO.length(), String.valueOf(column)); + + return buf.toString(); + } + else + return super.getMessage(); + } + + /** + * returns the line number of the error + */ + public int getLine() + { + return line; + } + + /** + * return the column number of the error + */ + public int getColumn() + { + return column; + } + + /** + * returns the token that caused the error + */ + public String getToken() + { + return token; + } + + } diff --git a/java/src/rasj/RasResultIsNoCellException.java b/java/src/rasj/RasResultIsNoCellException.java new file mode 100644 index 0000000..f299137 --- /dev/null +++ b/java/src/rasj/RasResultIsNoCellException.java @@ -0,0 +1,69 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This exception is thrown if the result of an operation is no cell. This might happen + * if the cast operator for casting to the base type of class r_Marray is invoked + * on an object which is not 'zero-dimensional'. + * @version $Revision: 1.5 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasResultIsNoCellException extends RasException +{ + static final String rcsid = "@(#)Package rasj, class RasResultIsNoCellException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasResultIsNoCellException.java,v 1.5 2003/12/10 21:04:23 rasdev Exp $"; + + /** + * Standard constructor. + **/ + protected RasResultIsNoCellException() + { + super(RasGlobalDefs.RESULT_IS_NO_CELL); + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + if(super.getMessage() == null) + return RasErrorTexts.getErrorMessage(errNo); + else + return super.getMessage(); + } + +} + diff --git a/java/src/rasj/RasResultIsNoIntervalException.java b/java/src/rasj/RasResultIsNoIntervalException.java new file mode 100644 index 0000000..7dd6749 --- /dev/null +++ b/java/src/rasj/RasResultIsNoIntervalException.java @@ -0,0 +1,67 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This exception is thrown if the result of an operation is no interval. + * @version $Revision: 1.6 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasResultIsNoIntervalException extends RasException +{ + static final String rcsid = "@(#)Package rasj, class RasResultIsNoIntervalException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasResultIsNoIntervalException.java,v 1.6 2003/12/10 21:04:23 rasdev Exp $"; + + /** + * Standard constructor. + **/ + protected RasResultIsNoIntervalException() + { + super(RasGlobalDefs.RESULT_IS_NO_INTERVAL); + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + if(super.getMessage() == null) + return RasErrorTexts.getErrorMessage(errNo); + else + return super.getMessage(); + } + +} + diff --git a/java/src/rasj/RasRuntimeException.java b/java/src/rasj/RasRuntimeException.java new file mode 100644 index 0000000..afef833 --- /dev/null +++ b/java/src/rasj/RasRuntimeException.java @@ -0,0 +1,104 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This abstract class is the superclass of all runtime exceptions in the rasj package + * except for {@link rasj.RasConnectionFailedException RasConnectionFailedException}. + * @see rasj.RasException + * @version $Revision: 1.4 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public abstract class RasRuntimeException extends RuntimeException +{ + static final String rcsid = "@(#)Package rasj, class RasRuntimeException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasRuntimeException.java,v 1.4 2003/12/19 16:22:27 rasdev Exp $"; + + protected int errNo = 0; + protected String errText = null; + + /** + * Standard constructor. + **/ + protected RasRuntimeException() + { + } + + /** + * Constructor getting the error number. + * @param num the RasDaMan error number + **/ + protected RasRuntimeException( int num ) + { + errNo = num; + } + + /** + * Constructor getting the error message. + * @param msg the error message + **/ + protected RasRuntimeException( String msg ) + { + errText = ( (msg==null) ? "(null)" : msg ); + } + + /** + * Constructor getting error number and error message. + * @param num the RasDaMan error number + * @param msg the error message + **/ + protected RasRuntimeException( int num, String msg ) + { + errNo = num; + errText = ( (msg==null) ? "(null)" : msg ); + } + + /** + * Method for retrieving the error number. + * @return the error number + **/ + public int getErrNo() + { + return errNo; + } + + /** + * Method retrieving the error message. + * @return the error message + **/ + public String getMessage() + { + return errText; + } + +} diff --git a/java/src/rasj/RasSInterval.java b/java/src/rasj/RasSInterval.java new file mode 100644 index 0000000..9e6d4fe --- /dev/null +++ b/java/src/rasj/RasSInterval.java @@ -0,0 +1,1343 @@ +package rasj; + +import java.lang.*; +import java.util.*; + +/* +* 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: + * The class represents an interval with lower and upper bound. + * Operations on the interval are defined according to the + * ODMG-93 standard. + * The operations union, difference, and intersection are + * defined according to the following table: + * + * | ... fixed bound + * -* ... open bound + * + * class orientation union difference intersection + * ----------------------------------------------------------- + * 1 |-a-| |-b-| error a error + * + * 2 |-a-| [a1,b2] [a1,b1] [b1,a2] + * 2 |-b-| + * + * 3 |--a--| a error b + * 3 |-b-| + * + * 4 |-b-| [b1,a2] [b2,a2] [a1,b2] + * 4 |-a-| + * + * 5 |--b--| b error a + * 5 |-a-| + * + * 6 |-b-| |-a-| error a error + * + * 7 |-a-|-b-| [a1,b2] a [a2,a2] + * + * 8 |-b-|-a-| [b1,a2] a [b2,b2] + * + * 9 |--a--| a [a1,b1] b + * 9 |-b-| + * + * 10 |--a--| a [b2,a2] b + * 10 |-b-| + * + * 11 |-a-| a error a + * 11 |-b-| + * + * 12 |--b--| b error a + * 12 |-a-| + * + * 13 |--b--| b error a + * 13 |-a-| + * + * ----------------------------------------------------- + * + * 14 |--a--* a error b + * 14 |-b-| + * + * 15 |--a--* a [b2,a2] b + * 15 |-b-| + * + * 16 |-b-| |-a-* error a error + * + * 17 |-b-|-a-* [b1,a2] a [b2,b2] + * + * 18 |--a--* [b1,a2] [b2,a2] [a1,b2] + * 18 |-b-| + * + * ----------------------------------------------------- + * + * 19 *--a--| a error b + * 19 |-b-| + * + * 20 *--a--| a [a1,b1] b + * 20 |-b-| + * + * 21 *-a-| |-b-| error a error + * + * 22 *-a-|-b-| [a1,b2] a [a2,a2] + * + * 23 *--a--| [a1,b2] [a1,b1] [b1,a2] + * 23 |-b-| + * + * ----------------------------------------------------- + * + * 24 |--b--* b error a + * 24 |-a-| + * + * 25 |--b--* b error a + * 25 |-a-| + * + * 26 |-a-| |-b-* error a error + * + * 27 |-a-|-b-* [a1,b2] a [a2,a2] + * + * 28 |--b--* [a1,b2] [a1,b1] [b1,a2] + * 28 |-a-| + * + * ----------------------------------------------------- + * + * 29 *--b--| b error a + * 29 |-a-| + * + * 30 *--b--| b error a + * 30 |-a-| + * + * 31 *-b-| |-a-| error a error + * + * 32 *-b-|-a-| [b1,a2] a [b2,b2] + * + * 33 *--b--| [b1,a2] [b2,a2] [a1,b2] + * 33 |-a-| + * + * ----------------------------------------------------- + * + * 34 *-a-| |-b-* error a error + * + * 35 *-a-|-b-* [a1,b2] a [a2,a2] + * + * 36 *-a-| [a1,b2] [a1,b1] [b1,a2] + * 36 |-b-* + * + * ----------------------------------------------------- + * + * 37 *-b-| |-a-* error a error + * + * 38 *-b-|-a-* [b1,a2] a [b2,b2] + * + * 39 *-b-| [b1,a2] [a1,b1] [a1,b2] + * 39 |-a-* + * + * ----------------------------------------------------- + * + * 40 *-a-| b error a + * 40 *-b-| + * + * 41 *-a-| a error a + * 41 *-b-| + * + * 42 *-b-| a [b2,a2] b + * 42 *-a-| + * + * ----------------------------------------------------- + * + * 43 |-a-* a [a1,b1] b + * 43 |-b-* + * + * 44 |-a-* a error a + * 44 |-b-* + * + * 45 |-b-* b error a + * 45 |-a-* + * + * ----------------------------------------------------- + * 46 *-a-* |-b-| a error b + * + * 47 *-b-* |-a-| b error a + * + * 48 *-a-* a [b2,a2] b + * 48 *-b-| + * + * 49 *-a-* a [a1,b1] b + * 49 |-b-* + * + * 50 *-b-* b error a + * 50 *-a-| + * + * 51 *-b-* b error a + * 51 |-a-* + * + * 52 *-a-* a error a + * 52 *-b-* + * + * Attention: The difference operation has to be reconsidered in future + * concerning a discrete interpretation of the intervals. + * + * The closure operation defines an interval which is the smallest + * interval containing the two operands. + * The method intersectsWith() returns 0 in the error cases of the + * intersection operation and 1 otherwise. + * + * @version $Revision: 1.7 $ + * + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + + +public class RasSInterval +{ + static final String rcsid = "@(#)Package rasj, class RasSInterval: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasSInterval.java,v 1.7 2003/12/10 21:04:23 rasdev Exp $"; + + /**Attributes storing the bounds:*/ + long lowerBound; + long upperBound; + + /**Attributes specifying wheter the lower/upper bound is fixed or not:*/ + boolean lowFixed; + boolean highFixed; + + /** + * The default constructor creates an interval with open bounds. + **/ + public RasSInterval() + { + lowerBound = 0; + upperBound = 0; + lowFixed = false; + highFixed = false; + } + + /** + * Copy constructor. + * @param sint SInterval to be copied + **/ + public RasSInterval(RasSInterval sint) + { + lowerBound = sint.lowerBound; + upperBound = sint.upperBound; + lowFixed = sint.lowFixed; + highFixed = sint.highFixed; + } + + /** + * Constructor taking a string representation of the SInterval (for example "*:200"). + * @param stringRep the string representation of the SInterval + **/ + public RasSInterval(String stringRep) throws RasResultIsNoIntervalException + { + lowerBound = 0; + upperBound = 0; + lowFixed = false; + highFixed = false; + + + /**for parsing the string*/ + StringTokenizer strTok = new StringTokenizer(stringRep.trim(), ":"); + String strCurTok = strTok.nextToken(); + + if(strCurTok.equals("*")) + { + setLow('*'); + } + else + { + setLow(Long.parseLong(strCurTok.trim())); + } + + + strCurTok = strTok.nextToken(); + + if(strCurTok.equals("*")) + { + setHigh('*'); + } + else + { + setHigh(Long.parseLong(strCurTok.trim())); + } + } + + + /** + * Constructor for an SInterval with fixed bounds. + * @param low the lower bound + * @param high the upper bound + **/ + public RasSInterval(long low, long high) throws RasResultIsNoIntervalException + { + lowerBound = low; + upperBound = high; + lowFixed = true; + highFixed = true; + + if(low > high) + throw new RasResultIsNoIntervalException(); + } + + + /** + * Constructor for an SInterval with an open lower bound. + * @param c arbitrary character, usually '*'. The value of this parameter is + * meaningless, it's only needed in order to provide a constructor similar to + * the one for fixed bounds. + * @param high the upper bound + **/ + public RasSInterval(char c, long high) + { + lowerBound = 0; + upperBound = high; + lowFixed = false; + highFixed = true; + } + + /** + * Constructor for an SInterval with an open upper bound. + * @param c arbitrary character, usually '*'. The value of this parameter is + * meaningless, it's only needed in order to provide a constructor similar to + * the one for fixed bounds. + * @param low the lower bound + **/ + public RasSInterval(long low, char c) + { + lowerBound = low; + upperBound = 0; + lowFixed = true; + highFixed = false; + } + + /** + * Constructor for an SInterval with an open bounds. For both parameters, + * arbitrary characters (usually '*') can be specified. The values of these parameters are + * meaningless, they are only needed in order to provide a constructor similar to + * the one for fixed bounds. + * @param c1 arbitrary character + * @param c2 arbitrary character + **/ + public RasSInterval(char c1, char c2) + { + lowerBound = 0; + upperBound = 0; + lowFixed = false; + highFixed = false; + } + + /** + * Method for testing equality of two SIntervals. Two SIntervals are equal + * if they have the same lower and upper bounds. + * @param interval the SInterval that is compared to this SInterval + * @return true if the two SIntervals are equal + **/ + public boolean equals(final RasSInterval interval) + { + boolean returnValue = true; + + if(lowFixed) + returnValue &= interval.lowFixed && lowerBound == interval.lowerBound; + else + returnValue &= !interval.lowFixed; + + if(highFixed) + returnValue &= interval.highFixed && upperBound == interval.upperBound; + else + returnValue &= !interval.highFixed; + + return returnValue; + } + + /** + * Method for testing inequality of two SIntervals. Two SIntervals are inequal + * if they have different lower or upper bounds. + * @param interval the SInterval that is compared to this SInterval + * @return true if the two SIntervals are not equal + **/ + public boolean notEquals(final RasSInterval interval) + { + return !equals(interval); + } + + + // Read/Write methods: + /** + * Gets the lower bound of the interval. + * @return the lower bound + **/ + public long low() + { + return lowerBound; + } + + /** + * Gets the upper bound of the interval. + * @return the upper bound + **/ + public long high() + { + return upperBound; + } + + /** + * Checks if the lower bound is fix. + * @return true if the lower bound is fix, false otherwise + **/ + public boolean isLowFixed() + { + return lowFixed; + } + + /** + * Checks if the upper bound is fix. + * @return true if the lower bound is fix, false otherwise + **/ + public boolean isHighFixed() + { + return highFixed; + } + + /** + * Sets the lower bound to a fixed value. + * @param low the new lower bound + **/ + public void setLow(long low) throws RasResultIsNoIntervalException + { + if(highFixed && low > upperBound) + throw new RasResultIsNoIntervalException(); + + lowerBound = low; + lowFixed = true; + } + + /** + * Sets the upper bound to a fixed value. + * @param high the new upper bound + **/ + public void setHigh(long high) throws RasResultIsNoIntervalException + { + if(lowFixed && high < lowerBound) + throw new RasResultIsNoIntervalException(); + + upperBound = high; + highFixed = true; + } + + /** + * Sets the lower bound open. + * @param c arbitrary character (usually '*') + **/ + public void setLow(char c) + { + lowerBound = 0; + lowFixed = false; + } + + /** + * Sets the upper bound open. + * @param c arbitrary character (usually '*') + **/ + public void setHigh(char c) + { + upperBound = 0; + highFixed = false; + } + + /** + * Sets both bounds to a fixed value. + * @param low the new lower bound + * @param high the new upper bound + **/ + public void setInterval(long low, long high) throws RasResultIsNoIntervalException + { + if(low > high) + throw new RasResultIsNoIntervalException(); + + lowerBound = low; + upperBound = high; + lowFixed = true; + highFixed = true; + } + + /** + * Sets the lower bound open and the upper bound to a fixed value. + * @param c arbitrary character (usually '*') + * @param high the new upper bound + **/ + public void setInterval(char c, long high) + { + lowerBound = 0; + upperBound = high; + lowFixed = false; + highFixed = true; + } + + /** + * Sets the upper bound open and the lower bound to a fixed value. + * @param c arbitrary character (usually '*') + * @param low the new lower bound + **/ + public void setInterval(long low, char c) + { + lowerBound = low; + upperBound = 0; + lowFixed = true; + highFixed = false; + } + + /** + * Sets both bounds open. + * @param c1 arbitrary character (usually '*') + * @param c2 arbitrary character (usually '*') + **/ + public void setInterval(char c1, char c2) + { + lowerBound = 0; + upperBound = 0; + lowFixed = false; + highFixed = false; + } + + /** + * Determines if the current interval intersects with the given one. + * @param interval the interval to be compared + * @return + * <TABLE BORDER=0 CELLPADDING=3> + * <TR><TD ALIGN=RIGHT><B>-1</B></TD><TD> if the intervals do not intersect</TD></TR> + * <TR><TD ALIGN=RIGHT VALIGN=TOP><B><classNo></B></TD><TD> if the intervals do intersect, where <classNo> is one of the classes specified in the description for class {@link RasSInterval RasSInterval}.</TD></TR> + * </TABLE> + **/ + public int intersectsWith(RasSInterval interval) + { + int classnr = classify(this, interval); + + if(classnr != 1 && classnr != 6 && classnr != 16 && classnr != 21 && + classnr != 26 && classnr != 31 && classnr != 34 && classnr != 37) + { + return classnr; + } + else + { + return -1; + } + } + + //Methods/Operators for the union operation: + /** + * Calculates the union of two SIntervals. + * <P>Note that this operation modifies the current object. If you want to get a new SInterval, + * use {@link #createUnion(RasSInterval) createUnion} instead.</P> + * @param interval1 the first SInterval + * @param interval2 the second SInterval + * @return the current SInterval (representing the union of interval1 and interval2) + **/ + public RasSInterval unionOf(RasSInterval interval1, RasSInterval interval2) + throws RasResultIsNoIntervalException + { + copySInterval(calcUnion(interval1, interval2),this); + return this; + } + + /** + * Calculates the union of the current SIntervall with another one. + * <P>Note that this operation modifies the current object. If you want to get a new SInterval, + * use {@link #createUnion(RasSInterval) createUnion} instead.</P> + * @param interval the SInterval to be used for the union + * @return the current SInterval (after the union with interval) + **/ + public RasSInterval unionWith(RasSInterval interval) + throws RasResultIsNoIntervalException + { + copySInterval(calcUnion(this, interval),this); + return this; + } + + /** + * @deprecated This methdod provides just another name for the + * unionWith method and might not be supported in future versions. Please + * use {@link #unionWith(RasSInterval) unionWith} instead. + * @param interval the SInterval to be unioned with this SInterval + * @return the union of this SInterval and interval + **/ + public RasSInterval addToSelf(RasSInterval interval) throws RasResultIsNoIntervalException + { + RasSInterval retInterval = new RasSInterval(); + retInterval = calcUnion(interval, this); + return retInterval; + } + + /** + * Returns a new SInterval calculated from a union of the current SInterval + * and the given one. + * @param mint the SInterval to be unioned with this SInterval + * @return the union of this SInterval and interval + **/ + public RasSInterval createUnion(RasSInterval interval) throws RasResultIsNoIntervalException + { + RasSInterval result = calcUnion(interval, this); + return result; + } + + /** + * @deprecated This methdod provides just another name for the + * createUnion method and might not be supported in future versions. Please + * use {@link #createUnion(RasSInterval) createUnion} instead. + * @param interval the SInterval to be unioned with this SInterval + * @return the union of this SInterval and interval + **/ + public RasSInterval add(RasSInterval interval) throws RasResultIsNoIntervalException + { + RasSInterval result; + result = calcUnion(interval, this); + return result; + } + + + // Methods/Operators for the difference operation: + + /** + * Calculates the difference of two SIntervals. + * <P>Note that this operation modifies the current object. If you want to get a new SInterval, + * use {@link #createDifference(RasSInterval) createDifference} instead.</P> + * @param interval1 the first SInterval + * @param interval2 the second SInterval + * @return the current SInterval (representing the difference of interval1 and interval2) + **/ + public RasSInterval differenceOf(RasSInterval interval1, RasSInterval interval2) + throws RasResultIsNoIntervalException + { + copySInterval(calcDifference(interval1, interval2),this); + return this; + } + + + /** + * Calculates the difference of the current SInterval and the given one. + * <P>Note that this operation modifies the current object. If you want to get a new SInterval, + * use {@link #createDifference(RasSInterval) createDifference} instead.</P> + * @param interval the SInterval used for building the difference + * @return the current SInterval (representing the difference of this SInterval and interval) + **/ + public RasSInterval differenceWith(RasSInterval interval) + throws RasResultIsNoIntervalException + { + copySInterval(calcDifference(interval, this), this); + return this; + } + + /** + * @deprecated This methdod provides just another name for the + * differenceWith method and might not be supported in future versions. Please + * use {@link #differenceWith(RasSInterval) differenceWith} instead. + * @param interval the SInterval used for building the difference + * @return the current SInterval (representing the difference of this SInterval and interval) + **/ + public RasSInterval diffFromSelf(RasSInterval interval) + throws RasResultIsNoIntervalException + { + return differenceWith(interval); + } + + /** + * Returns a new SInterval calculated from a difference of the current SInterval + * and the given one. + * @param interval the SInterval used for calculating the difference with the current SInterval + * @return the difference of this SInterval and interval + **/ + public RasSInterval createDifference(RasSInterval interval) + throws RasResultIsNoIntervalException + { + RasSInterval result = calcDifference(interval, this); + return result; + } + + /** + * @deprecated This methdod provides just another name for the + * createDifference method and might not be supported in future versions. Please + * use {@link #createDifference(RasSInterval) createDifference} instead. + * @param interval the SInterval used for calculating the difference with the current SInterval + * @return the difference of this SInterval and interval + **/ + public RasSInterval diff(RasSInterval interval) + throws RasResultIsNoIntervalException + { + RasSInterval result = calcDifference(interval, this); + return result; + } + + + // Methods/Operators for the intersection operation: + /** + * This method calculates the intersection of two SIntervals. + * <P>Note that this operation modifies the current object. If you want to get a new SInterval, + * use {@link #createIntersection(RasSInterval) createIntersection} instead.</P> + * @param interval1 the first SInterval + * @param interval2 the second SInterval + * @return the current SInterval (representing the intersection of interval1 and interval2) + **/ + public RasSInterval intersectionOf(final RasSInterval interval1, final RasSInterval interval2) + throws RasResultIsNoIntervalException + { + copySInterval(calcIntersection(interval1, interval2),this); + return this; + } + + /** + * Calculates the intersection of the current SInterval and the given one. + * <P>Note that this operation modifies the current object. If you want to get a new SInterval, + * use {@link #createIntersection(RasSInterval) createIntersection} instead.</P> + * @param interval the SInterval used for building the intersection + * @return the current SInterval (representing the intersection of this SInterval and interval) + **/ + public RasSInterval intersectionWith(final RasSInterval interval) + throws RasResultIsNoIntervalException + { + copySInterval(calcIntersection(interval, this),this); + return this; + } + + /** + * @deprecated This methdod provides just another name for the + * intersectionWith method and might not be supported in future versions. Please + * use {@link #intersectionWith(RasSInterval) intersectionWith} instead. + * @param interval the SInterval used for building the intersection + * @return the intersection of this SInterval and interval + **/ + public RasSInterval multWithSelf(final RasSInterval interval) + throws RasResultIsNoIntervalException + { + return intersectionWith(interval); + } + + /** + * Returns a new SInterval calculated from the intersection of the current SInterval + * and the given one. + * @param interval the SInterval used for calculating the intersection with the current SInterval + * @return the intersection of this SInterval and interval + **/ + public RasSInterval createIntersection(final RasSInterval interval) + throws RasResultIsNoIntervalException + { + RasSInterval result = calcIntersection(interval, this); + return result; + } + + /** + * @deprecated This methdod provides just another name for the + * createIntersection method and might not be supported in future versions. Please + * use {@link #createIntersection(RasSInterval) createIntersection} instead. + * @param interval the SInterval used for calculating the intersection with the current SInterval + * @return the intersection of this SInterval and interval + **/ + public RasSInterval mult(final RasSInterval interval) + throws RasResultIsNoIntervalException + { + return createIntersection(interval); + } + + + // Methods/Operators for the closure operation: + /** + * Calculates the closure of two SIntervals. + * <P>Note that this operation modifies the current object. If you want to get a new SInterval, + * use {@link #createClosure(RasSInterval) createClosure} instead.</P> + * @param interval1 the first SInterval + * @param interval2 the second SInterval + * @return the current SInterval (representing the closure of interval1 and interval2) + **/ + public RasSInterval closureOf(final RasSInterval interval1, final RasSInterval interval2) + throws RasResultIsNoIntervalException + { + copySInterval(calcClosure(interval1, interval2),this); + return this; + } + + /** + * Calculates the closure of the current SInterval and the given one. + * <P>Note that this operation modifies the current object. If you want to get a new SInterval, + * use {@link #createClosure(RasSInterval) createClosure} instead.</P> + * @param interval the SInterval used for building the closure + * @return the current SInterval (representing the closure of this SInterval and interval) + **/ + public RasSInterval closureWith(final RasSInterval interval) + throws RasResultIsNoIntervalException + { + RasSInterval retInterval = new RasSInterval(); + retInterval = calcClosure(interval, this); + return retInterval; + } + + /** + * Returns a new SInterval calculated from the closure of the current SInterval + * and the given one. + * @param interval the SInterval used for calculating the closure with the current SInterval + * @return the closure of this SInterval and interval + **/ + public RasSInterval createClosure(final RasSInterval interval) + throws RasResultIsNoIntervalException + { + RasSInterval result; + result = calcClosure(interval, this); + return result; + } + + + // Methods for internal use only: + // calculate the size of the storage space occupied + private long getStorageSize() + { + return (18); // 2 * (8 + 1) + } + + // copy the values of source to target + private void copySInterval(RasSInterval source, RasSInterval target) + { + target.lowerBound = source.lowerBound; + target.upperBound = source.upperBound; + target.highFixed = source.highFixed; + target.lowFixed = source.lowFixed; + } + + // Calculation methods for the operations: + private RasSInterval calcUnion(final RasSInterval a, final RasSInterval b) + throws RasResultIsNoIntervalException + { + RasSInterval result = new RasSInterval(); + + switch(classify(a, b)) + { + case 2: + case 7: + case 9: + case 12: + case 22: + case 23: + case 27: + case 28: + case 35: + case 36: + // result = [a1:b2] + + if(a.isLowFixed()) + result.setLow(a.low()); + else + result.setLow('*'); + + if(b.isHighFixed()) + result.setHigh(b.high()); + else + result.setHigh('*'); + + break; + + case 4: + case 8: + case 10: + case 13: + case 17: + case 18: + case 32: + case 33: + case 38: + case 39: + // result = [b1:a2] + + if(b.isLowFixed()) + result.setLow(b.low()); + else + result.setLow('*'); + + if(a.isHighFixed()) + result.setHigh(a.high()); + else + result.setHigh('*'); + + break; + + case 3: + case 11: + case 14: + case 15: + case 19: + case 20: + case 41: + case 42: + case 43: + case 44: + case 46: + case 48: + case 49: + case 52: + result = a; + break; + + case 5: + case 24: + case 25: + case 29: + case 30: + case 40: + case 45: + case 47: + case 50: + case 51: + result = b; + break; + + default: // case in { 1, 6, 16, 21, 26, 31, 34, 37 } + throw new RasResultIsNoIntervalException(); + } + + return result; + } + + + // + private RasSInterval calcDifference(final RasSInterval a, final RasSInterval b) + throws RasResultIsNoIntervalException + { + RasSInterval result = new RasSInterval(); + + switch(classify(a, b)) + { + case 2: + case 9: + case 20: + case 23: + case 28: + case 36: + case 39: + case 43: + case 49: + // result = [a1:b1] + + if(a.isLowFixed()) + result.setLow(a.low()); + else + result.setLow('*'); + + if(b.isLowFixed()) + result.setHigh(b.low()); + else + result.setHigh('*'); + + break; + + case 1: + case 6: + case 7: + case 8: + case 16: + case 17: + case 21: + case 22: + case 26: + case 27: + case 31: + case 32: + case 34: + case 35: + case 37: + case 38: + result = a; + break; + + case 4: + case 10: + case 15: + case 18: + case 33: + case 42: + case 48: + // result = [b2:a2] + + if(b.isHighFixed()) + result.setLow(b.high()); + else + result.setLow('*'); + + if(a.isHighFixed()) + result.setHigh(a.high()); + else + result.setHigh('*'); + + break; + + default: // case in { 3, 5, 11, 12, 13, 14, 19, 24, 25, 29, 30, 40, 41, 44, 45, 46, 47, 50, 51, 52 } + throw new RasResultIsNoIntervalException(); + } + + return result; + } + + + // + private RasSInterval calcIntersection(final RasSInterval a, final RasSInterval b) + throws RasResultIsNoIntervalException + { + RasSInterval result = new RasSInterval(); + + switch(classify(a, b)) + { + case 4: + case 18: + case 33: + case 39: + // result = [a1:b2] + + if(a.isLowFixed()) + result.setLow(a.low()); + else + result.setLow('*'); + + if(b.isHighFixed()) + result.setHigh(b.high()); + else + result.setHigh('*'); + + break; + + case 2: + case 23: + case 28: + case 36: + // result = [b1:a2] + + if(b.isLowFixed()) + result.setLow(b.low()); + else + result.setLow('*'); + + if(a.isHighFixed()) + result.setHigh(a.high()); + else + result.setHigh('*'); + + break; + + case 5: + case 11: + case 12: + case 13: + case 24: + case 25: + case 29: + case 30: + case 40: + case 41: + case 44: + case 45: + case 47: + case 50: + case 51: + case 52: + result = a; + break; + + case 3: + case 9: + case 10: + case 14: + case 15: + case 19: + case 20: + case 42: + case 43: + case 46: + case 48: + case 49: + result = b; + break; + + case 7: + case 22: + case 27: + case 35: + // result = [a2:a2] + + if(a.isHighFixed()) + result.setInterval(a.high(), a.high()); + else + result.setInterval('*', '*'); + + break; + + case 8: + case 17: + case 32: + case 38: + // result = [b2:b2] + + if(b.isHighFixed()) + result.setInterval(b.high(), b.high()); + else + result.setInterval('*', '*'); + + break; + + default: // case in { 1, 6, 16, 21, 26, 31, 34, 37 } + throw new RasResultIsNoIntervalException(); + } + + return result; + } + + + + private RasSInterval calcClosure(final RasSInterval a, final RasSInterval b) + throws RasResultIsNoIntervalException + { + RasSInterval closure = new RasSInterval(); + + if(!a.isLowFixed() || !b.isLowFixed()) + closure.setLow('*'); + else + closure.setLow(Math.min(a.low(), b.low())); + + if(!a.isHighFixed() || !b.isHighFixed()) + closure.setHigh('*'); + else + closure.setHigh(Math.max(a.high(), b.high())); + + return closure; + } + + + // compute the class of the two operands + + + /************************************************************* + * Method name...: classify + * + * Arguments.....: Two intervals for the classification. + * Return value..: The classification class number (1..52). + * Description...: The method classifies the two intervals into + * one of 13 classes according to their spatial + * relationship. Based on the classification, the + * result of the operations union, difference, + * and intersection can be calculated as shown + * in the table + ************************************************************/ + + + private int classify(final RasSInterval a, final RasSInterval b) + { + int classification = 0; + + if(a.isLowFixed() && a.isHighFixed() && b.isLowFixed() && b.isHighFixed()) + { + // classification 1..13 + + if(a.low() < b.low()) + { + if(a.high() < b.high()) + { + if(a.high() < b.low()) + classification = 1; + else + if(a.high() == b.low()) + classification = 7; + else + classification = 2; + } + else if(a.high() == b.high()) + classification = 9; + else + classification = 3; + } + else if(a.low() == b.low()) + { + if(a.high() < b.high()) + classification = 12; + else if(a.high() == b.high()) + classification = 11; + else + classification = 10; + } + else + if(a.high() < b.high()) + classification = 5; + else if(a.high() == b.high()) + classification = 13; + else + { + if(a.low() < b.high()) + classification = 4; + else if(a.low() == b.high()) + classification = 8; + else + classification = 6; + } + } + else if(a.isLowFixed() && !a.isHighFixed() && b.isLowFixed() && b.isHighFixed()) + { + // classification 14..18 + + if(a.low() < b.low()) + classification = 14; + else if(a.low() == b.low()) + classification = 15; + else + { + if(b.high() < a.low()) + classification = 16; + else if(b.high() == a.low()) + classification = 17; + else + classification = 18; + } + } + else if(!a.isLowFixed() && a.isHighFixed() && b.isLowFixed() && b.isHighFixed()) + { + // classification 19..23 + + if(a.high() > b.high()) + classification = 19; + else if(a.high() == b.high()) + classification = 20; + else + { + if(a.high() < b.low()) + classification = 21; + else if(a.high() == b.low()) + classification = 22; + else + classification = 23; + } + } + else if(a.isLowFixed() && a.isHighFixed() && b.isLowFixed() && !b.isHighFixed()) + { + // classification 24..28 + + if(b.low() < a.low()) + classification = 24; + else if(b.low() == a.low()) + classification = 25; + else + { + if(a.high() < b.low()) + classification = 26; + else if(a.high() == b.low()) + classification = 27; + else + classification = 28; + } + } + else if(a.isLowFixed() && a.isHighFixed() && !b.isLowFixed() && b.isHighFixed()) + { + // classification 29..33 + + if(b.high() > a.high()) + classification = 29; + else if(b.high() == a.high()) + classification = 30; + else + { + if(b.high() < a.low()) + classification = 31; + else if(b.high() == a.low()) + classification = 32; + else + classification = 33; + } + } + else if(!a.isLowFixed() && a.isHighFixed() && b.isLowFixed() && !b.isHighFixed()) + { + // classification 34..36 + + if(a.high() < b.low()) + classification = 34; + else if(a.high() == b.low()) + classification = 35; + else + classification = 36; + } + else if(a.isLowFixed() && !a.isHighFixed() && !b.isLowFixed() && b.isHighFixed()) + { + // classification 37..39 + + if(b.high() < a.low()) + classification = 37; + else if(b.high() == a.low()) + classification = 38; + else + classification = 39; + } + else if(!a.isLowFixed() && a.isHighFixed() && !b.isLowFixed() && b.isHighFixed()) + { + // classification 40..42 + + if(a.high() < b.high()) + classification = 40; + else if(a.high() == b.high()) + classification = 41; + else + classification = 42; + } + else if(a.isLowFixed() && !a.isHighFixed() && b.isLowFixed() && !b.isHighFixed()) + { + // classification 43..45 + + if(a.low() < b.low()) + classification = 43; + else if(a.low() == b.low()) + classification = 44; + else + classification = 45; + } + else if(!a.isLowFixed() && !a.isHighFixed() && b.isLowFixed() && b.isHighFixed()) + classification = 46; + else if( a.isLowFixed() && a.isHighFixed() && !b.isLowFixed() && !b.isHighFixed()) + classification = 47; + else if(!a.isLowFixed() && !a.isHighFixed() && !b.isLowFixed() && b.isHighFixed()) + classification = 48; + else if(!a.isLowFixed() && !a.isHighFixed() && b.isLowFixed() && !b.isHighFixed()) + classification = 49; + else if(!a.isLowFixed() && a.isHighFixed() && !b.isLowFixed() && !b.isHighFixed()) + classification = 50; + else if( a.isLowFixed() && !a.isHighFixed() && !b.isLowFixed() && !b.isHighFixed()) + classification = 51; + else // !a.isLowFixed() && !a.isHighFixed() && !b.isLowFixed() && !b.isHighFixed() + classification = 52; + + return classification; + } + + + /** gives back the string representation */ + public String toString() + { + return (lowFixed ? Long.toString(lowerBound) : "*") + + ":" + + (highFixed ? Long.toString(upperBound) : "*"); + } + +} + diff --git a/java/src/rasj/RasSIntervalType.java b/java/src/rasj/RasSIntervalType.java new file mode 100644 index 0000000..519e28c --- /dev/null +++ b/java/src/rasj/RasSIntervalType.java @@ -0,0 +1,49 @@ +package rasj; + +import rasj.*; +import java.util.*; + +/* +* 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: + * This class represents the SInterval type in the ODMG conformant + * representation of the RasDaMan type system. + * @version $Revision: 1.4 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasSIntervalType extends RasType +{ + static final String rcsid = "@(#)Package rasj, class RasSIntervalType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasSIntervalType.java,v 1.4 2003/12/10 21:04:23 rasdev Exp $"; + + +} diff --git a/java/src/rasj/RasStorageLayout.java b/java/src/rasj/RasStorageLayout.java new file mode 100644 index 0000000..ab1feae --- /dev/null +++ b/java/src/rasj/RasStorageLayout.java @@ -0,0 +1,154 @@ +package rasj; + +/* +* 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: + * This class is used to express the storage options for MDD objects. + * In the current version, either the tile-size (for example 256000 bytes) or the + * tiling-domain (for example "[0:127,0:511]") can be specified. If + * neither is done, the default tile-size will be 128 kBytes. + * + * @version $Revision: 1.10 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasStorageLayout + +{ + static final String rcsid = "@(#)Package rasj.odmg, class RasStorageLayout: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasStorageLayout.java,v 1.10 2003/12/10 21:04:23 rasdev Exp $"; + + /** + * Default tile size in kBytes. This value is currently set + * to 128000 and is used if the user has not specified + * a tile size explicitly. + **/ + static final int DEFAULT_TILE_SIZE = 128000; + + /** + * the spatial domain of the current storageLayout + **/ + private RasMInterval spatialDomain; + + /** + * the current tile size in bytes + **/ + private int tileSize; + + /** + * Default constructor. + **/ + public RasStorageLayout() + { + spatialDomain = null; + tileSize = DEFAULT_TILE_SIZE; + } + + /** + * Copy constructor taking another storage layout object as a parameter. + * @param stl the sorage layout object to be copied + **/ + public RasStorageLayout(RasStorageLayout stl) + { + spatialDomain = stl.getSpatialDomain(); + tileSize = stl.getTileSize(); + } + + /** + * Returns the current tiling-domain of this storage layout object. + * @return the tiling-domain of this storage layout object + **/ + public final RasMInterval getSpatialDomain() + { + return spatialDomain; + } + + /** + * Sets the tile-size (in bytes) and resets the tiling-domain to null. + * @param size the tile-size (in bytes) + **/ + public void setTileSize(int size) + { + tileSize = size; + spatialDomain = null; + } + + /** + * Returns the current tile-size (in bytes). + * @return the tile-size + **/ + public final int getTileSize() + { + return tileSize; + } + + /** + * Sets the tiling-domain for this storage layout object and resets the tile-size + * to null. + * @param domain the tiling-domain + **/ + public void setTileDomain(String domain) + throws RasResultIsNoIntervalException, RasStreamInputOverflowException, RasIndexOutOfBoundsException + { + spatialDomain = new RasMInterval(domain); + tileSize = 0; + } + + /** + * This method tests if the current storageLayout object is compatible to a given domain. + * @param domain the domain to be compared + * @return true if the tiling-domain of this storage layout object is either null or + * has the same number of dimensions as the given domain, otherwise false + **/ + public boolean isCompatible(RasMInterval domain) + { + if(spatialDomain == null) + return true; + else + return (domain.dimension() == spatialDomain.dimension()); + + } + + /** + * Returns a string representation of this class. + **/ + public String toString() + { + if(spatialDomain != null) + return "\nTileDomain: " + spatialDomain + "\n"; + else + return "\nTileSize: " + tileSize + "\n"; + + } + + +} + diff --git a/java/src/rasj/RasStreamInputOverflowException.java b/java/src/rasj/RasStreamInputOverflowException.java new file mode 100644 index 0000000..60b7ca1 --- /dev/null +++ b/java/src/rasj/RasStreamInputOverflowException.java @@ -0,0 +1,69 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This exception is thrown if an initialization overflow has occured. + * It typically arises when a stream input operator is invoked more + * often than the object has dimensions. + * @version $Revision: 1.5 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasStreamInputOverflowException extends RasException +{ + static final String rcsid = "@(#)Package rasj, class RasStreamInputOverflowException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasStreamInputOverflowException.java,v 1.5 2003/12/10 21:04:23 rasdev Exp $"; + + /** + * Standard constructor. + */ + protected RasStreamInputOverflowException() + { + super(RasGlobalDefs.STREAM_INPUT_OVERFLOW); + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + if(super.getMessage() == null) + return RasErrorTexts.getErrorMessage(errNo); + else + return super.getMessage(); + } + +} + diff --git a/java/src/rasj/RasStructureType.java b/java/src/rasj/RasStructureType.java new file mode 100644 index 0000000..e996c4a --- /dev/null +++ b/java/src/rasj/RasStructureType.java @@ -0,0 +1,100 @@ +package rasj; + +import rasj.*; +import rasj.global.*; + +import java.util.*; + +/* +* 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: + * This class represents all user defined structured types in the ODMG conformant + * representation of the RasDaMan type system. + * @version $Revision: 1.8 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasStructureType extends RasBaseType +{ + static final String rcsid = "@(#)Package rasj, class RasStructureType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasStructureType.java,v 1.8 2003/12/10 21:04:23 rasdev Exp $"; + + private RasBaseType[] baseTypes; + private String[] attributes; + + public RasStructureType() + { + super(); + baseTypes = null; + attributes = null; + } + + public RasStructureType(String name, RasBaseType[] btyp, String[] attr) + { + super(name, 0); + baseTypes = btyp; + attributes = attr; + + for(int i=0; i < baseTypes.length/2; i++) + { + typeSize = typeSize + baseTypes[i].getSize(); + //System.out.println(typeSize); + } + typeID = RasGlobalDefs.RAS_STRUCTURE; + } + + public int getTypeID() + { + return RasGlobalDefs.RAS_STRUCTURE; + } + + + public boolean isStructType() + { + return true; + } + + public String toString() + { + //System.out.println("struct type: "); + String s = super.toString() + "struct " + super.typeName + "\n{\n"; + for(int i=0; i < (attributes.length/2)-1; i++) + { + s = s + " " + baseTypes[i] + " " + attributes[i] + ", \n"; + + if(i == (attributes.length/2)-2) + { + s = s + baseTypes[i+1] + " " + attributes[i+1] + "\n}\n"; + } + + } + return s; + } +} diff --git a/java/src/rasj/RasType.java b/java/src/rasj/RasType.java new file mode 100644 index 0000000..1e3afda --- /dev/null +++ b/java/src/rasj/RasType.java @@ -0,0 +1,365 @@ +package rasj; + +import rasj.*; +import rasj.global.*; +import java.util.*; + + +/* +* 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: + * This class the superclass for all types in the ODMG conformant + * representation of the RasDaMan type system. + * @version $Revision: 1.10 $ + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasType +{ + static final String rcsid = "@(#)Package rasj, class RasType: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasType.java,v 1.10 2003/12/10 21:04:23 rasdev Exp $"; + + protected String typeName; + protected int typeID; + + /** + * Default constructor. + **/ + public RasType() + { + typeName = ""; + typeID = 0; + } + + /** + * Constructor getting the name of the new type. + * @param newTypeName the name of the new type + **/ + public RasType(String newTypeName) + { + typeName = newTypeName; + typeID = 0; + } + + /** + * Retrieves the id of this type. + * @return the type id + **/ + public int getTypeID() + { + return typeID; + } + + /** + * Retrieves the name of this type. + * @return the type name + **/ + public String getName() + { + return typeName; + } + + /** + * Checks if this type is a primitive or structured type. + * @return true if this is a structured type, otherwise false + **/ + public boolean isStructType() + { + return false; + } + + /** + * Checks if this type is a base type (primitive type or structure type). + * @return true for a primitive or structured type, otherwise false + **/ + public boolean isBaseType() + { + return false; + } + + + /** + * Builds the type schema from a string representation. + * @param typeString the string representation of the type + **/ + public static RasType getAnyType(String typeString) + { + StringTokenizer strTok = new StringTokenizer(typeString, "{}[]<>,: "); + String currentStr = ""; + RasType returnValue = null; + if(strTok.hasMoreTokens()) + { + currentStr = strTok.nextToken(); + if(currentStr.equals("set")) + { + //System.out.println("getSet"); + returnValue = getSet(strTok.nextToken("")); + } + else if(currentStr.equals("marray")) + { + //System.out.println("getMArray"); + returnValue = getMArrayType(strTok.nextToken("")); + } + else + { + //System.out.println("getType"); + returnValue = getType(typeString); + } + } + return returnValue; + } + + // converts array of cells from NT byte order to Unix byte order. + //public void convertToLittleEndian(String cells, int noCells) + //{ + //} + + // converts array of cells from Unix byte order to NT byte order. + //public void convertToBigEndian(String cells, int noCells) + //{ + //} + + private static RasType getSet(String setStr) + { + StringTokenizer setTok = new StringTokenizer(setStr, "{}[]<>,: "); + String currentStr = ""; + RasType returnValue = null; + RasType elementType = null; + if(setTok.hasMoreTokens()) + { + currentStr = setTok.nextToken(); + //Fehler falls kein <! + if(currentStr.equals("marray")) + elementType = getMArrayType(setTok.nextToken("")); + else elementType = getType(setStr); + } + + returnValue = new RasCollectionType(elementType); + + return returnValue; + } + + private static RasType getType(String typeStr) + { + StringTokenizer typeTok = new StringTokenizer(typeStr, "{}[]<>,: "); + String currentStr = ""; + RasType returnValue = null; + if(typeTok.hasMoreTokens()) + { + currentStr = typeTok.nextToken(); + if(currentStr.equals("struct")) + { + //System.out.println("getStructureType"); + returnValue = getStructureType(typeTok.nextToken("")); + } + else if(currentStr.equals("interval")) + { + returnValue = getSIntervalType(typeTok.nextToken("")); + returnValue.typeID = RasGlobalDefs.RAS_SINTERVAL; + } + else if(currentStr.equals("minterval")) + { + returnValue = getMIntervalType(typeTok.nextToken("")); + returnValue.typeID = RasGlobalDefs.RAS_MINTERVAL; + } + else if(currentStr.equals("point")) + { + returnValue = getPointType(typeTok.nextToken("")); + returnValue.typeID = RasGlobalDefs.RAS_POINT; + } + else if(currentStr.equals("oid")) + { + returnValue = getOIDType(typeTok.nextToken("")); + returnValue.typeID = RasGlobalDefs.RAS_OID; + } + else + { + //System.out.println("getPrimitiveType"); + returnValue = getPrimitiveType(typeStr); + } + } + return returnValue; + } + + private static RasMArrayType getMArrayType(String mArrayStr) + { + //StringTokenizer mArrayTok = new StringTokenizer(mArrayStr, "{}[]<>,: "); + //System.out.println("enter getMArrayType" + mArrayStr); + RasMArrayType returnValue = null; + RasBaseType baseType = null; + //Fehler falls kein <! + // get base type (structure or primitive type) + baseType = getBaseType(mArrayStr); + //System.out.println("base type: " + baseType); + returnValue = new RasMArrayType(baseType); + + return returnValue; + } + + + private static RasBaseType getBaseType(String baseStr) + { + StringTokenizer baseTok = new StringTokenizer(baseStr, "{}[]<>,: "); + String currentStr = ""; + //System.out.println(baseStr); + RasBaseType returnValue = null; + if(baseTok.hasMoreTokens()) + { + currentStr = baseTok.nextToken(); + if(currentStr.equals("struct")) + { + returnValue = getStructureType(baseTok.nextToken("")); + } + else + { + returnValue = getPrimitiveType(baseStr); + //System.out.println("getPrimitiveType"); + } + } + + return returnValue; + } + + + private static RasPrimitiveType getPrimitiveType(String primStr) throws RasTypeUnknownException + { + StringTokenizer primTok = new StringTokenizer(primStr, "{}[]<>,: "); + String currentStr = ""; + RasPrimitiveType returnValue = null; + if(primTok.hasMoreTokens()) + { + currentStr = primTok.nextToken(); + if(currentStr.equals("char")) + returnValue = new RasPrimitiveType("RAS_CHAR", RasGlobalDefs.RAS_CHAR); + else if(currentStr.equals("octet")) + returnValue = new RasPrimitiveType("RAS_BYTE", RasGlobalDefs.RAS_BYTE); + else if(currentStr.equals("short")) + returnValue = new RasPrimitiveType("RAS_SHORT", RasGlobalDefs.RAS_SHORT); + else if(currentStr.equals("ushort")) + returnValue = new RasPrimitiveType("RAS_USHORT", RasGlobalDefs.RAS_USHORT); + else if(currentStr.equals("long")) + returnValue = new RasPrimitiveType("RAS_LONG", RasGlobalDefs.RAS_LONG); + else if(currentStr.equals("ulong")) + returnValue = new RasPrimitiveType("RAS_ULONG", RasGlobalDefs.RAS_ULONG); + else if(currentStr.equals("bool")) + returnValue = new RasPrimitiveType("RAS_BOOLEAN", RasGlobalDefs.RAS_BOOLEAN); + else if(currentStr.equals("float")) + returnValue = new RasPrimitiveType("RAS_FLOAT", RasGlobalDefs.RAS_FLOAT); + else if(currentStr.equals("double")) + returnValue = new RasPrimitiveType("RAS_DOUBLE", RasGlobalDefs.RAS_DOUBLE); + else + throw new RasTypeUnknownException(currentStr); + } + + return returnValue; + } + + + private static RasStructureType getStructureType(String structStr) throws RasTypeUnknownException + { + StringTokenizer structTok = new StringTokenizer(structStr, "[]<>,: "); + RasStructureType returnValue = null; + String structName = ""; + RasBaseType[] baseType = new RasBaseType[structTok.countTokens()/2]; + String[] attributeName = new String[structTok.countTokens()/2]; + //System.out.println("enter getStructureType"); + // get struct name + if(structTok.hasMoreTokens()) + { + structName = structTok.nextToken(); + if(structName.equals("{")) + structName=""; + else + structTok.nextToken(); + //System.out.println("StructName:" + structName); + } + else + { + // no struct name + throw new RasTypeUnknownException(""); + } + + //Fehler falls kein { so lange bis } dazwischen ,!!! + for(int i=0; i < attributeName.length; i++) + { + // get type + String more = structTok.nextToken(); + if(more.equals("}")) + break; + else + { + baseType[i] = getBaseType(more); + //System.out.println("BaseType:"+ i + baseType[i]); + // get attribut name + if(structTok.hasMoreTokens()) + { + attributeName[i] = structTok.nextToken(); + //System.out.println("Attribut:"+ i + attributeName[i]); + } + else + // no attribut name + throw new RasTypeUnknownException(""); + } + } + + returnValue = new RasStructureType(structName, baseType, attributeName); + return returnValue; + } + + private static RasSIntervalType getSIntervalType(String sintStr) + { + return new RasSIntervalType(); + } + + private static RasMIntervalType getMIntervalType(String mintStr) + { + return new RasMIntervalType(); + } + + private static RasPointType getPointType(String pointStr) + { + return new RasPointType(); + } + + private static RasOIDType getOIDType(String oidStr) + { + return new RasOIDType(); + } + + /** + * @return the string represntation of this type + **/ + public String toString() + { + return "typeName: " + typeName + "\n typeID: " + typeID +"\n "; + } + +} diff --git a/java/src/rasj/RasTypeInvalidException.java b/java/src/rasj/RasTypeInvalidException.java new file mode 100644 index 0000000..540e15a --- /dev/null +++ b/java/src/rasj/RasTypeInvalidException.java @@ -0,0 +1,93 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This exception is thrown if a {@link rasj.RasPrimitiveType primitive type} is accessed by a method + * having the wrong type. + * @see rasj.RasPrimitiveType + * @version $Revision: 1.7 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasTypeInvalidException extends RasException +{ + static final String rcsid = "@(#)Package rasj, class RasTypeInvalidException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasTypeInvalidException.java,v 1.7 2003/12/19 16:22:27 rasdev Exp $"; + + // the base type + String bType = null; + + // the type of the access method + String aType = null; + + /** + * Standard constructor getting the type of the base type and the type of the + * access method that caused the error. + * @param baseType the type of the base type + * @param accessType the type of the access method that caused the error + **/ + protected RasTypeInvalidException(String baseType, String accessType) + { + super(RasGlobalDefs.TYPE_INVALID); + bType = ( (baseType==null) ? "(null)" : baseType ); + aType = ( (accessType==null) ? "(null)" : accessType ); + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + int i; + + if(super.getMessage() == null) + { + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + i = msg.indexOf( RasGlobalDefs.KEYWORD_ATYPE ); + if(i != -1) + buf.replace(i, i+RasGlobalDefs.KEYWORD_ATYPE.length(), String.valueOf(bType)); + msg = buf.toString(); + i = msg.indexOf( RasGlobalDefs.KEYWORD_BTYPE ); + if(i != -1) + buf.replace(i, i+RasGlobalDefs.KEYWORD_BTYPE.length(), String.valueOf(aType)); + msg = buf.toString(); + return msg; + } + else + return super.getMessage(); + } + +} diff --git a/java/src/rasj/RasTypeNotSupportedException.java b/java/src/rasj/RasTypeNotSupportedException.java new file mode 100644 index 0000000..911e837 --- /dev/null +++ b/java/src/rasj/RasTypeNotSupportedException.java @@ -0,0 +1,82 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This runtime exception is raised when the + * {@link rasj.RasType BaseType} of a query result is not supported + * by the current version of the rasj package. + * @version $Revision: 1.3 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +public class RasTypeNotSupportedException extends RasRuntimeException +{ + static final String rcsid = "@(#)Package rasj, class RasDimensionMismatchException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasTypeNotSupportedException.java,v 1.3 2003/12/19 16:22:27 rasdev Exp $"; + + // the unknown type + private String rType = null; + + /** + * Standard constructor getting the type that caused the error. + * @param type the unknown type that caused this exception + **/ + public RasTypeNotSupportedException(String type) + { + super(RasGlobalDefs.TYPE_NOT_SUPPORTED); + rType = ( (type==null) ? "(null)" : type ); + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + int i; + + if(super.getMessage() == null) + { + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + i = msg.indexOf( RasGlobalDefs.KEYWORD_TYPE ); + if(i != -1) + buf.replace(i, i+RasGlobalDefs.KEYWORD_TYPE.length(), String.valueOf(rType)); + msg = buf.toString(); + return msg; + } + else + return super.getMessage(); + } + +} diff --git a/java/src/rasj/RasTypeUnknownException.java b/java/src/rasj/RasTypeUnknownException.java new file mode 100644 index 0000000..5f27808 --- /dev/null +++ b/java/src/rasj/RasTypeUnknownException.java @@ -0,0 +1,83 @@ +package rasj; + +import rasj.global.*; + +/* +* 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: + * This runtime exception is raised when the + * {@link rasj.RasType RasType} of a query result is unknown + * on client-side. + * @version $Revision: 1.6 $ + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + + +public class RasTypeUnknownException extends RasRuntimeException +{ + static final String rcsid = "@(#)Package rasj, class RasDimensionMismatchException: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasTypeUnknownException.java,v 1.6 2003/12/19 16:22:27 rasdev Exp $"; + + // the unknown type + private String rType = null; + + /** + * Standard constructor getting the type that caused the error. + * @param type the unknown type that caused this exception + **/ + protected RasTypeUnknownException(String type) + { + super(RasGlobalDefs.TYPE_UNKNOWN); + rType = ( (type==null) ? "(null)" : type ); + } + + /** + * Returns the error message. + * @return the error message. + **/ + public String getMessage() + { + int i; + + if(super.getMessage() == null) + { + String msg = RasErrorTexts.getErrorMessage(errNo); + + StringBuffer buf = new StringBuffer(msg); + i = msg.indexOf( RasGlobalDefs.KEYWORD_TYPE ); + if(i != -1) + buf.replace( i, i+RasGlobalDefs.KEYWORD_TYPE.length(), String.valueOf(rType) ); + msg = buf.toString(); + return msg; + } + else + return super.getMessage(); + } + +} diff --git a/java/src/rasj/Rasj.el b/java/src/rasj/Rasj.el new file mode 100644 index 0000000..3dd7e16 --- /dev/null +++ b/java/src/rasj/Rasj.el @@ -0,0 +1,91 @@ + + + +(jde-set-project-name "Rasj") +(jde-set-variables + '(jde-use-font-lock t) + '(jde-db-set-initial-breakpoint t) + '(jde-run-option-garbage-collection (quote (t t))) + '(jde-db-option-stack-size (quote ((128 . "kilobytes") (400 . "kilobytes")))) + '(jde-compiler "javac") + '(jde-compile-option-extdirs nil) + '(jde-db-read-vm-args nil) + '(jde-compile-option-bootclasspath nil) + '(jde-run-working-directory "./") + '(jde-compile-option-debug (quote ("selected" (t nil nil)))) + '(jde-db-option-verbose (quote (nil nil nil))) + '(jde-run-option-heap-size (quote ((1 . "megabytes") (16 . "megabytes")))) + '(jde-run-read-app-args nil) + '(jde-db-option-java-profile (quote (nil . "./java.prof"))) + '(jde-entering-java-buffer-hooks (quote (jde-reload-project-file))) + '(jde-run-option-java-profile (quote (nil . "./java.prof"))) + '(jde-gen-window-listener-template (quote ("'& (P \"Window name: \")" "\".addWindowListener(new WindowAdapter() {\" 'n>" "\"public void windowActivated(WindowEvent e) {}\" 'n>" "\"public void windowClosed(WindowEvent e) {}\" 'n>" "\"public void windowClosing(WindowEvent e) {System.exit(0);}\" 'n>" "\"public void windowDeactivated(WindowEvent e) {}\" 'n>" "\"public void windowDeiconified(WindowEvent e) {}\" 'n>" "\"public void windowIconified(WindowEvent e) {}\" 'n>" "\"public void windowOpened(WindowEvent e) {}});\" 'n>"))) + '(jde-db-option-vm-args nil) + '(jde-make-program "gmake") + '(jde-compile-option-target (quote ("1.1"))) + '(jde-run-application-class "") + '(jde-global-classpath nil) + '(jde-run-option-verbose (quote (nil nil nil))) + '(jde-db-option-heap-size (quote ((1 . "megabytes") (16 . "megabytes")))) + '(jde-db-mode-hook nil) + '(jde-key-bindings (quote (("" . jde-compile) ("" . jde-run) ("" . jde-db) ("" . jde-build) ("" . jde-run-menu-run-applet) ("" . jde-browse-jdk-doc) ("" . jde-save-project) ("" . jde-gen-println)))) + '(jde-db-option-garbage-collection (quote (t t))) + '(jde-run-option-properties nil) + '(jde-compile-option-nowarn nil) + '(jde-compile-option-depend nil) + '(jde-compile-option-vm-args nil) + '(jde-db-read-app-args nil) + '(jde-read-compile-args nil) + '(jde-db-option-properties nil) + '(jde-run-applet-doc "index.html") + '(jde-compile-option-directory "") + '(jde-run-java-vm "java") + '(jde-project-file-name "Rasj.el") + '(jde-db-option-verify (quote (nil t))) + '(jde-gen-property-change-support (quote ("'&" "\"protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);\" 'n>" "\"/**\" 'n>\"* Adds a PropertyChangeListener to the listener list.\" 'n>" "\"* The listener is registered for all properties.\" 'n>" "\"*\" 'n> \"* @param listener The PropertyChangeListener to be added\" 'n> \"*/\" 'n>" "\"public void addPropertyChangeListener(PropertyChangeListener listener) {\" 'n>" "\"pcs.addPropertyChangeListener(listener);\" 'n> \"}\" 'n> 'n>" "\"/**\" 'n>\"* Removes a PropertyChangeListener from the listener list.\" 'n>" "\"* This removes a PropertyChangeListener that was registered for all properties.\" 'n>" "\"*\" 'n> \"* @param listener The PropertyChangeListener to be removed\" 'n> \"*/\" 'n>" "\"public void removePropertyChangeListener(PropertyChangeListener listener) {\" 'n>" "\"pcs.removePropertyChangeListener(listener);\" 'n> \"}\" 'n> 'n>" "\"/**\" 'n>\"* Adds a PropertyChangeListener for a specific property.\" 'n>" "\"* The listener will be invoked only when a call on firePropertyChange\" 'n>" "\"* names that specific property.\" 'n>" "\"*\" 'n> \"* @param propertyName The name of the property to listen on\" 'n>" "\"* @param listener The PropertyChangeListener to be added\" 'n> \"*/\" 'n>" "\"public void addPropertyChangeListener(String propertyName,\" 'n>" "\"PropertyChangeListener listener) {\" 'n>" "\"pcs.addPropertyChangeListener(propertyName, listener);\" 'n> \"}\" 'n> 'n>" "\"/**\" 'n>\"* Removes a PropertyChangeListener for a specific property.\" 'n>" "\"*\" 'n> \"* @param propertyName The name of the property that was listened on\" 'n>" "\"* @param listener The PropertyChangeListener to be removed\" 'n> \"*/\" 'n>" "\"public void removePropertyChangeListener(String propertyName,\" 'n>" "\"PropertyChangeListener listener) {\" 'n>" "\"pcs.removePropertyChangeListener(propertyName, listener);\" 'n> \"}\" 'n> 'n>" "\"/**\" 'n>\"* Reports a bound property update to any registered listeners. \" 'n>" "\"* No event is fired if old and new are equal and non-null.\" 'n>" "\"*\" 'n> \"* @param propertyName The programmatic name of the property that was changed\" 'n>" "\"* @param oldValue The old value of the property\" 'n>" "\"* @param newValue The new value of the property.\" 'n> \"*/\" 'n>" "\"public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {\" 'n>" "\"pcs.firePropertyChange(propertyName, oldValue, newValue);\" 'n> \"}\" 'n> 'n>" "\"/**\" 'n>\"* Reports a bound property update to any registered listeners. \" 'n>" "\"* No event is fired if old and new are equal and non-null.\" 'n>" "\"* This is merely a convenience wrapper around the more general\" 'n>" "\"* firePropertyChange method that takes Object values.\" 'n>" "\"* No event is fired if old and new are equal and non-null.\" 'n>" "\"*\" 'n> \"* @param propertyName The programmatic name of the property that was changed\" 'n>" "\"* @param oldValue The old value of the property\" 'n>" "\"* @param newValue The new value of the property.\" 'n> \"*/\" 'n>" "\"public void firePropertyChange(String propertyName, int oldValue, int newValue) {\" 'n>" "\"pcs.firePropertyChange(propertyName, oldValue, newValue);\" 'n> \"}\" 'n> 'n>" "\"/**\" 'n>\"* Reports a bound property update to any registered listeners. \" 'n>" "\"* No event is fired if old and new are equal and non-null.\" 'n>" "\"* This is merely a convenience wrapper around the more general\" 'n>" "\"* firePropertyChange method that takes Object values.\" 'n>" "\"* No event is fired if old and new are equal and non-null.\" 'n>" "\"*\" 'n> \"* @param propertyName The programmatic name of the property that was changed\" 'n>" "\"* @param oldValue The old value of the property\" 'n>" "\"* @param newValue The new value of the property.\" 'n> \"*/\" 'n>" "\"public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {\" 'n>" "\"pcs.firePropertyChange(propertyName, oldValue, newValue);\" 'n> \"}\" 'n> 'n>" "\"/**\" 'n>\"* Fires an existing PropertyChangeEvent to any registered listeners.\" 'n>" "\"* No event is fired if the given event's old and new values are equal and non-null. \" 'n>" "\"*\" 'n> \"* @param evt The PropertyChangeEvent object.\" 'n>\"*/\" 'n>" "\"public void firePropertyChange(PropertyChangeEvent evt) {\" 'n>" "\"pcs.firePropertyChange(evt);\" 'n> \"}\" 'n> 'n>" "\"/**\" 'n>\"* Checks if there are any listeners for a specific property.\" 'n>" "\"*\" 'n> \"* @param evt The PropertyChangeEvent object.\" 'n>" "\"* @return <code>true</code>if there are one or more listeners for the given property\" 'n>" "\"*/\" 'n>" "\"public boolean hasListeners(String propertyName) {\" 'n>" "\"return pcs.hasListeners(propertyName);\" 'n> \"}\" 'n> 'n>"))) + '(jde-gen-mouse-motion-listener-template (quote ("'& (P \"Component name: \")" "\".addMouseMotionListener(new MouseMotionAdapter() {\" 'n>" "\"public void mouseDragged(MouseEvent e) {}\" 'n>" "\"public void mouseMoved(MouseEvent e) {}});\" 'n>"))) + '(jde-run-option-vm-args nil) + '(jde-gen-console-buffer-template (quote ("(funcall jde-gen-boilerplate-function) 'n" "\"/**\" 'n" "\" * \"" "(file-name-nondirectory buffer-file-name) 'n" "\" *\" 'n" "\" *\" 'n" "\" * Created: \" (current-time-string) 'n" "\" *\" 'n" "\" * @author \" (user-full-name) 'n" "\" * @version\" 'n" "\" */\" 'n>" "'n>" "\"public class \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\" {\" 'n> 'n>" "\"public \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\"() {\" 'n>" "'n>" "\"}\" 'n>" "'n>" "\"public static void main(String[] args) {\" 'n>" "'p 'n>" "\"}\" 'n> 'n>" "\"} // \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "'n>"))) + '(jde-jdk-doc-url "http://www.javasoft.com/products/jdk/1.2/docs/index.html") + '(jde-run-option-stack-size (quote ((128 . "kilobytes") (400 . "kilobytes")))) + '(jde-db-option-heap-profile (quote (nil "./java.hprof" 5 20 "Allocation objects"))) + '(jde-db-option-classpath nil) + '(jde-run-option-verify (quote (nil t))) + '(jde-db-option-application-args nil) + '(jde-gen-get-set-var-template (quote ("'n>" "(P \"Variable type: \" type) \" \"" "(P \"Variable name: \" name) \";\" 'n> 'n>" "\"/**\" 'n>" "\"* Get the value of \" (s name) \".\" 'n>" "\"* @return Value of \" (s name) \".\" 'n>" "\"*/\" 'n>" "\"public \" (s type) \" get\" (jde-gen-init-cap (jde-gen-lookup-named 'name))" "\"() {return \" (s name) \";}\" 'n> 'n>" "\"/**\" 'n>" "\"* Set the value of \" (s name) \".\" 'n>" "\"* @param v Value to assign to \" (s name) \".\" 'n>" "\"*/\" 'n>" "\"public void set\" (jde-gen-init-cap (jde-gen-lookup-named 'name))" "\"(\" (s type) \" v) {this.\" (s name) \" = v;}\" 'n>"))) + '(jde-gen-println (quote ("'&" "\"System.out.println(\" (P \"Print out: \") \");\" 'n>"))) + '(jde-run-mode-hook nil) + '(jde-compile-option-sourcepath nil) + '(jde-compile-option-depend-switch (quote ("-Xdepend"))) + '(jde-gen-buffer-boilerplate nil) + '(jde-build-use-make nil) + '(jde-db-startup-commands nil) + '(jde-compile-option-verbose-path nil) + '(jde-compile-option-command-line-args "") + '(jde-mode-abbreviations (quote (("ab" . "abstract") ("bo" . "boolean") ("br" . "break") ("by" . "byte") ("byv" . "byvalue") ("cas" . "cast") ("ca" . "catch") ("ch" . "char") ("cl" . "class") ("co" . "const") ("con" . "continue") ("de" . "default") ("dou" . "double") ("el" . "else") ("ex" . "extends") ("fa" . "false") ("fi" . "final") ("fin" . "finally") ("fl" . "float") ("fo" . "for") ("fu" . "future") ("ge" . "generic") ("go" . "goto") ("impl" . "implements") ("impo" . "import") ("ins" . "instanceof") ("in" . "int") ("inte" . "interface") ("lo" . "long") ("na" . "native") ("ne" . "new") ("nu" . "null") ("pa" . "package") ("pri" . "private") ("pro" . "protected") ("pu" . "public") ("re" . "return") ("sh" . "short") ("st" . "static") ("su" . "super") ("sw" . "switch") ("sy" . "synchronized") ("th" . "this") ("thr" . "throw") ("throw" . "throws") ("tra" . "transient") ("tr" . "true") ("vo" . "void") ("vol" . "volatile") ("wh" . "while")))) + '(jde-gen-code-templates (quote (("Get Set Pair" . jde-gen-get-set) ("toString method" . jde-gen-to-string-method) ("Action Listener" . jde-gen-action-listener) ("Window Listener" . jde-gen-window-listener) ("Mouse Listener" . jde-gen-mouse-listener) ("Mouse Motion Listener" . jde-gen-mouse-motion-listener) ("Inner Class" . jde-gen-inner-class) ("println" . jde-gen-println) ("property change support" . jde-gen-property-change-support)))) + '(jde-compile-option-classpath nil) + '(jde-gen-boilerplate-function (quote jde-gen-create-buffer-boilerplate)) + '(jde-gen-class-buffer-template (quote ("(funcall jde-gen-boilerplate-function) 'n" "\"/**\" 'n" "\" * \"" "(file-name-nondirectory buffer-file-name) 'n" "\" *\" 'n" "\" *\" 'n" "\" * Created: \" (current-time-string) 'n" "\" *\" 'n" "\" * @author \" (user-full-name) 'n" "\" * @version\" 'n" "\" */\" 'n>" "'n>" "\"public class \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\" \" (jde-gen-get-super-class) \" {\" 'n> 'n>" "\"public \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\"() {\" 'n>" "'p 'n>" "\"}\" 'n>" "'n>" "\"} // \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "'n>"))) + '(jde-gen-action-listener-template (quote ("'& (P \"Component name: \")" "\".addActionListener(new ActionListener() {\" 'n>" "\"public void actionPerformed(ActionEvent e) {\" 'n>" "\"}});\" 'n>"))) + '(jde-enable-abbrev-mode nil) + '(jde-quote-classpath t) + '(jde-run-option-application-args nil) + '(jde-run-java-vm-w "javaw") + '(jde-run-read-vm-args nil) + '(jde-run-applet-viewer "appletviewer") + '(jde-gen-inner-class-template (quote ("'& \"class \" (P \"Class name: \" class)" "(P \"Superclass: \" super t)" "(let ((parent (jde-gen-lookup-named 'super)))" "(if (not (string= parent \"\"))" "(concat \" extends \" parent))) \" {\" 'n>" "\"public \" (s class) \"() {\" 'n> \"}\" 'n> \"}\" 'n>"))) + '(jde-compile-option-deprecation nil) + '(jde-db-marker-regexp "^Breakpoint hit: .*(\\([^$]*\\).*:\\([0-9]*\\))") + '(jde-db-debugger (quote ("jdb" . "Executable"))) + '(jde-db-source-directories (quote ("./"))) + '(jde-gen-jfc-app-buffer-template (quote ("(funcall jde-gen-boilerplate-function) 'n" "\"import java.awt.*;\" 'n" "\"import java.awt.event.*;\" 'n" "\"import com.sun.java.swing.*;\" 'n 'n" "\"/**\" 'n" "\" * \"" "(file-name-nondirectory buffer-file-name) 'n" "\" *\" 'n" "\" *\" 'n" "\" * Created: \" (current-time-string) 'n" "\" *\" 'n" "\" * @author \" (user-full-name) 'n" "\" * @version\" 'n" "\" */\" 'n>" "'n>" "\"public class \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\" extends JFrame {\" 'n> 'n>" "\"public \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\"() {\" 'n>" "\"super(\\\"\" (P \"Enter app title: \") \"\\\");\" 'n>" "\"setSize(600, 400);\" 'n>" "\"addWindowListener(new WindowAdapter() {\" 'n>" "\"public void windowClosing(WindowEvent e) {System.exit(0);}\" 'n>" "\"public void windowOpened(WindowEvent e) {}});\" 'n>" "\"}\" 'n>" "'n>" "\"public static void main(String[] args) {\" 'n>" "'n>" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\" f = new \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\"();\" 'n>" "\"f.show();\" 'n>" "'p 'n>" "\"}\" 'n> 'n>" "\"} // \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "'n>"))) + '(jde-make-args "") + '(jde-gen-mouse-listener-template (quote ("'& (P \"Component name: \")" "\".addMouseListener(new MouseAdapter() {\" 'n>" "\"public void mouseClicked(MouseEvent e) {}\" 'n>" "\"public void mouseEntered(MouseEvent e) {}\" 'n>" "\"public void mouseExited(MouseEvent e) {}\" 'n>" "\"public void mousePressed(MouseEvent e) {}\" 'n>" "\"public void mouseReleased(MouseEvent e) {}});\" 'n>"))) + '(jde-run-option-classpath nil) + '(jde-gen-buffer-templates (quote (("Class" . jde-gen-class) ("Console" . jde-gen-console) ("Swing App" . jde-gen-jfc-app)))) + '(jde-compile-option-verbose nil) + '(jde-compile-option-optimize nil) + '(jde-compile-option-encoding nil) + '(jde-run-option-heap-profile (quote (nil "./java.hprof" 5 20 "Allocation objects"))) + '(jde-gen-to-string-method-template (quote ("'&" "\"public String toString() {\" 'n>" "\"return super.toString();\" 'n>" "\"}\" 'n>")))) diff --git a/java/src/rasj/clientcommhttp/Makefile b/java/src/rasj/clientcommhttp/Makefile new file mode 100644 index 0000000..7c9dc43 --- /dev/null +++ b/java/src/rasj/clientcommhttp/Makefile @@ -0,0 +1,62 @@ +# -*-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/clientcommhttp +# +# COMMENTS: +# +################################################################## +######################### Definitions ############################ + +# standard include with general options +include $(RMANBASE)/Makefile.inc + +# directory where HTML documentation is created +DOCDIR := $(DOCBASE)/rasdaman/java/rasj/clientcommhttp + +SRCS = RasCommDefs.java RasHttpRequest.java RasUtils.java +OBJS = ${SRCS:%.java=%.class} +MISCCLEAN = *.class + +########################### Targets ############################## + +# compile everything +.PHONY : all +all: $(OBJS) + +# HTML docu +docj: + -rm -rf $(DOCDIR)/rasj/clientcommhttp + $(JAVADOC) -author -d $(DOCDIR) rasj/clientcommhttp + +# delete all object files +clean: + -rm -f $(MISCCLEAN) + +############################ Dependencies ####################### +# general rules +# FIXME: should not be used here (only for relational adapter modules in rel*/), but is needed for Java targets +include $(RMANBASE)/Makefile.rel + diff --git a/java/src/rasj/clientcommhttp/Makefile.dep b/java/src/rasj/clientcommhttp/Makefile.dep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/java/src/rasj/clientcommhttp/Makefile.dep diff --git a/java/src/rasj/clientcommhttp/RasCommDefs.java b/java/src/rasj/clientcommhttp/RasCommDefs.java new file mode 100644 index 0000000..f08fae3 --- /dev/null +++ b/java/src/rasj/clientcommhttp/RasCommDefs.java @@ -0,0 +1,54 @@ +/* +* 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.clientcommhttp; + +public interface RasCommDefs +{ + static final String rcsid = "@(#)Package rasj.clientcommhttp, class RasCommDefs: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/clientcommhttp/RasCommDefs.java,v 1.5 2003/12/10 21:04:26 rasdev Exp $"; + + final public byte RASCLIENT = 1; + final public byte BROWSER = 2; + + final public byte RESPONSE_ERROR = 0; + final public byte RESPONSE_MDDS = 1; + final public byte RESPONSE_SKALARS = 2; + final public byte RESPONSE_INT = 3; + final public byte RESPONSE_OID = 4; + final static byte RESPONSE_OK_NEGATIVE = 98; + final public byte RESPONSE_OK = 99; + + final public byte BIG_ENDIAN = 0; + final public byte LITTLE_ENDIAN = 1; +} diff --git a/java/src/rasj/clientcommhttp/RasHttpRequest.java b/java/src/rasj/clientcommhttp/RasHttpRequest.java new file mode 100644 index 0000000..8bbc7c1 --- /dev/null +++ b/java/src/rasj/clientcommhttp/RasHttpRequest.java @@ -0,0 +1,804 @@ +/* +* 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: + * - return type complex not yet supported. + * </pre> + *********************************************************** */ + +package rasj.clientcommhttp; + +import rasj.*; +import org.odmg.*; +import rasj.odmg.*; +import rasj.global.*; + +import java.io.*; +import java.net.*; +import java.lang.*; +import java.util.*; + +/** + * This class handles a HTTP-request to the RasDaMan server. + * The specified RasDaMan server is contacted, the specified command is sent to + * the server, and the result of the query is retrieved and stored in a byte array. + * The specification of the communication protocol is given below. + * <P> + * + * @version $Revision: 1.35 $ + * + * </UL><P> + * <B>Request structure</B><P><UL> + * The rasj HTTP request to the rasdaman server uses the HTTP POST-Format with the following + * parameters: + * <P> + * <TABLE BORDER=1 WIDTH=100%> + * <TR><TH>Parameter:</TH><TH>Description:</TH><TH>Required for</TH></TR> + * <TR><TD>Command</TD> + * <TD>Integer value specifying the desired action (e.g. OpenDB, BT, CT, CloseDB ...)</TD> + * <TD>all requests</TD></TR> + * <TR><TD>Database</TD> + * <TD>String value specifying the database</TD> + * <TD>OpenDB, CloseDB</TD></TR> + * <TR><TD>ClientType</TD> + * <TD>Integer value defining the type of the client (at the moment always RasClient)</TD> + * <TD>all requests</TD></TR> + * <TR><TD>ClientID</TD> + * <TD>Integer value specifying the ClientID (currently set to 1 for every client)</TD> + * <TD>all requests</TD></TR> + * <TR><TD>QueryString</TD> + * <TD>String value containing the RasQL query</TD> + * <TD>executeQuery</TD></TR> + * <TR><TD>Endianess</TD> + * <TD>Integer value containing the Client Endianess</TD> + * <TD>only insert queries</TD></TR> + * <TR><TD>NumberOfQueryParameters</TD> + * <TD>Integer value specifying the number of query parameters</TD> + * <TD>only insert queries</TD></TR> + * <TR><TD>QueryParameters</TD> + * <TD>Byte Array containing the query parameters (MDDs) using the following format:<BR> + * <TABLE BORDER=1> + * <TR><TH>Integer</TH><TH>String</TH><TH>String</TH><TH>Integer</TH><TH>String</TH><TH>String</TH> + * <TH>String</TH><TH>Long</TH><TH>Byte[]</TH> + * </TR> + * <TR><TD>objectType</TD><TD>objectTypeName</TD><TD>typeStructure</TD><TD>typeLength</TD> + * <TD>domain</TD><TD>storageLayout</TD><TD>OID</TD><TD>dataSize</TD><TD>binary data</TD></TR> + * </TABLE> + *</TD> + * <TD>only insert queries</TD></TR> + * </TABLE> + * </P> + * </UL><P> + * + * <B>Result formats / internal representation:</B><P><UL> + * The result of a HTTP request has one of the following forms:<P> + * MDD Collections:<BR> + * <TABLE BORDER=1><TR><TH ROWSPAN=2>Byte</TH><TH ROWSPAN=2>Byte</TH> + * <TH ROWSPAN=2>String</TH><TH ROWSPAN=2>Long(4Bytes)</TH> + * <TH COLSPAN=5>resultElement 1</TH><TH ROWSPAN=3> ... </TH></TR> + * <TR><TD>String</TD><TD>String</TD><TD>String</TD><TD>Long(4Bytes)</TD><TD>Byte[]</TD></TR> + * <TR><TD>Result type<P>1=MDDCollection</TD> + * <TD>Endianess</TD> + * <TD>Collection type</TD> + * <TD>Number of results</TD> + * <TD>BaseType description</TD> + * <TD>Spatial domain</TD> + * <TD>OID</TD> + * <TD>Size of the Binary Data Block</TD> + * <TD>Binary Data Block</TD></TR> + * </TABLE><P> + * + * Skalar Collections:<BR> + * <TABLE BORDER=1><TR><TH ROWSPAN=2>Byte</TH><TH ROWSPAN=2>Byte</TH> + * <TH ROWSPAN=2>String</TH><TH ROWSPAN=2>Long(4Bytes)</TH> + * <TH COLSPAN=4>resultElement 1</TH><TH ROWSPAN=3> ... </TH></TR> + * <TR><TD>String</TD><TD>Long(4Bytes)</TD><TD>Byte[]</TD></TR> + * <TR><TD>Result type<P>2=SkalarCollection</TD> + * <TD>Endianess</TD> + * <TD>Collection type</TD> + * <TD>Number of results</TD> + * <TD>ElementType description</TD> + * <TD>Size of the Binary Data Block</TD> + * <TD>Binary Data Block</TD></TR> + * </TABLE><P> + * + * Errors:<BR> + * <TABLE BORDER=1><TR><TH>Byte</TH><TH>Byte</TH> + * <TH>Long(4Bytes)</TH><TH>Long(4Bytes)</TH><TH>Long(4Bytes)</TH> + * <TH>String</TH></TR> + * <TR><TD>Result type<P>0=Error</TD> + * <TD>Endianess</TD> + * <TD>Error number</TD> + * <TD>Line number</TD> + * <TD>Column number</TD> + * <TD>Token</TD> + * </TABLE><P> + * + * Single Integer Value:<BR> + * <TABLE BORDER=1><TR><TH>Byte</TH><TH>Integer</TH></TR> + * <TR><TD>Result type<P>3=Integer</TD><TD>Value</TD></TR> + * </TABLE><P> + * + * OID:<BR> + * <TABLE BORDER=1><TR><TH>Byte</TH><TH>String</TH><TH>String</TH><TH>Double</TH></TR> + * <TR><TD>Result type<P>4=OID</TD><TD>system</TD><TD>basename</TD><TD>localOID</TD></TR> + * </TABLE><P> + * + * Acknowledgement:<BR> + * <TABLE BORDER=1><TR><TH>Byte</TH></TR> + * <TR><TD>Result type<P>99=OK</TD></TR> + * </TABLE><P> + * + * </UL> + * + */ + +public class RasHttpRequest implements RasCommDefs, RasGlobalDefs +{ + + static final String rcsid = "@(#)Package rasj.clientcommhttp, class RasRequest: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/clientcommhttp/RasHttpRequest.java,v 1.35 2003/12/19 15:36:43 rasdev Exp $"; + +/** + * The type of this client */ + private String client = "RASCLIENT"; + +/** + * The result type ( MDD Collection, Skalar Collection, Error, Integer ). This field is set + * automatically when a query has been executed, so there's no setResultType method. + */ + private byte resultType = 0; + +/** + * The result of the query +**/ + private Object result = null; + +/** + * This method sends a query to the RasDaMan Server and retrieves the results. + * + * @param con server connection + * @param parameters the parameters for the request as name/value pairs (for example "clientID=4354351&queryString=select img from test") + */ + public void execute( String serverURL, String parameters ) + throws RasQueryExecutionFailedException, RasConnectionFailedException + { + Debug.enterVerbose( "RasHttpRequest.execute: start. serverURL=" + serverURL + ", parameters=" + parameters ); + + BenchmarkTimer httpTimer = new BenchmarkTimer("httpRequest"); + BenchmarkTimer rcvTimer = new BenchmarkTimer("receive"); + + try + { + URL url = new URL( serverURL ); + + Debug.talkVerbose( "RasHttpRequest.execute: sending to " + url + " POST request=" + parameters ); + + httpTimer.startTimer(); + + BenchmarkTimer sendTimer = new BenchmarkTimer("send"); + sendTimer.startTimer(); + + // Send the query + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestProperty("Content-type","application/octet-stream"); + con.setRequestProperty("User-Agent","RasDaMan Java Client"); + con.setRequestProperty("Version","1.0"); + con.setRequestMethod("POST"); + con.setDoInput(true); + con.setDoOutput(true); + con.setUseCaches(false); + + OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(),"8859_1"); + out.write(parameters,0,parameters.length()); + out.flush(); + out.close(); + + sendTimer.stopTimer(); + sendTimer.print(); + + rcvTimer.startTimer(); + + // Read response + BenchmarkTimer getInputTimer = new BenchmarkTimer("getInputStream"); + getInputTimer.startTimer(); + DataInputStream in = new DataInputStream(con.getInputStream()); + // int BuffSize = con.getContentLength(); // not used -- PB 2003-jun-14 + // Debug.talkVerbose("RasHttpRequest.execute: buffSize=" + BuffSize); + getInputTimer.stopTimer(); + getInputTimer.print(); + + + /* variables for later use */ + byte[] b1 = new byte[1]; + byte[] b4 = new byte[4]; + byte endianess = 0; + String collType = null; + int numberOfResults = 0; + int dataSize = 0; + byte[] binData = null; + int readBytes = 0; + int readBytesTmp = 0; + DBag resultBag; + RasGMArray res = null; + + in.read(b1); + + resultType = b1[0]; + Debug.talkVerbose("RasHttpRequest.execute: resultType=" + resultType ); + switch( resultType ) + { + case RESPONSE_OK: + case RESPONSE_OK_NEGATIVE: + //Nothing todo + break; + + // +++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_MDDS: + Debug.talkVerbose("RasHttpRequest.execute: result type is MDD." ); + // read Endianess + while(in.read(b1) == 0) + ; + endianess = b1[0]; + + // read Collection Type + collType = RasUtils.readString(in); + Debug.talkVerbose("RasHttpRequest.execute: colltype=" + collType); + + // read NumberOfResults + while(in.available() < 4) + ; + in.read(b4); + numberOfResults = RasUtils.ubytesToInt(b4,endianess); + Debug.talkVerbose("RasHttpRequest.execute: number of results: " + numberOfResults); + + // Initialize return-set and parameters + resultBag = new RasBag(); + String mddBaseType = null; + String domain = null; + String oid = ""; + RasOID roid = null; + + // do this for each result + for(int x = 0; x < numberOfResults; x++) + { + Debug.talkVerbose("RasHttpRequest.execute: handling result #" + (x+1) ); + //read mddBaseType + mddBaseType = RasUtils.readString(in); + + // read spatialDomain + domain = RasUtils.readString(in); + + // read OID + oid = RasUtils.readString(in); + //System.err.println("OID is " + oid); + roid = new RasOID(oid); + + // read size of binData + while(in.available() < 4) + ; + in.read(b4); + + dataSize = RasUtils.ubytesToInt(b4,endianess); + + Debug.talkVerbose("RasHttpRequest.execute: mddBaseType is " + mddBaseType + ", spatialDomain=" + domain + ", size of BinData=" + dataSize ); + + // read binData + binData = new byte[dataSize]; + readBytes = 0; + readBytesTmp = 0; + + while( (readBytesTmp != -1) && (readBytes < dataSize) ) + { + readBytesTmp = in.read(binData,readBytes,dataSize-readBytes); + readBytes += readBytesTmp; + } + + Debug.talkVerbose("RasHttpRequest.execute: read " + readBytes + " bytes."); + + RasType rType = RasType.getAnyType(mddBaseType); + //System.out.println(rType); + RasBaseType rb = null; + + if(rType.getClass().getName().equals("rasj.RasMArrayType")) + { + RasMArrayType tmp = (RasMArrayType)rType; + rb = tmp.getBaseType(); + } + else + { + Debug.talkCritical("RasHttpRequest.execute: exception: element of MDD Collection is no MArray" ); + throw new RasClientInternalException("RasHttpRequest","execute()","element of MDD Collection is no MArray"); + } + + if(rb.isBaseType()) + { + if(rb.isStructType()) + { + // It is a structType + //System.err.println("It is a structType"); + RasStructureType sType = (RasStructureType)rb; + //System.out.println(sType); + res = new RasGMArray(new RasMInterval(domain), 0); + res.setTypeLength(rb.getSize()); + res.setArraySize(dataSize); + res.setArray(binData); + //insert into result set + resultBag.add(res); + break; + + } else + { + // It is a primitiveType + RasPrimitiveType pType = (RasPrimitiveType)rb; + + //System.err.println("It's a primitive type: " + pType); + switch(pType.getTypeID()) + { + case RAS_BOOLEAN: + case RAS_BYTE: + case RAS_CHAR: + //System.err.println("It's a byte array!"); + res = new RasMArrayByte(new RasMInterval(domain)); + break; + case RAS_SHORT: + //System.err.println("It's a short array!"); + res = new RasMArrayShort(new RasMInterval(domain)); + break; + + case RAS_USHORT: + //System.err.println("It's a ushort array!"); + byte[] tmData = new byte[dataSize*2]; + for(int i=0;i<dataSize*2;) + { + tmData[i] = 0; + tmData[i+1] = 0; + tmData[i+2] = binData[i/2]; + tmData[i+3] = binData[i/2+1]; + i = i+SIZE_OF_INTEGER; + } + binData = tmData; + res = new RasMArrayInteger(new RasMInterval(domain)); + break; + + case RAS_INT: + case RAS_LONG: + //System.err.println("It's a integer array!"); + res = new RasMArrayInteger(new RasMInterval(domain)); + break; + case RAS_ULONG: + //System.err.println("It's a ulong array!"); + byte[] tmpData = new byte[dataSize*2]; + for(int i=0;i<dataSize*2;) + { + tmpData[i] = 0; + tmpData[i+1] = 0; + tmpData[i+2] = 0; + tmpData[i+3] = 0; + tmpData[i+4] = binData[i/2]; + tmpData[i+5] = binData[i/2+1]; + tmpData[i+6] = binData[i/2+2]; + tmpData[i+7] = binData[i/2+3]; + i = i+SIZE_OF_LONG; + } + binData = tmpData; + res = new RasMArrayLong(new RasMInterval(domain)); + break; + case RAS_FLOAT: + //System.err.println("It's a float array!"); + res = new RasMArrayFloat(new RasMInterval(domain)); + break; + case RAS_DOUBLE: + //System.err.println("It's a double array!"); + res = new RasMArrayDouble(new RasMInterval(domain)); + break; + default: + //System.err.println("It's a GMArray!"); + res = new RasGMArray(new RasMInterval(domain), pType.getSize()); + //throw new RasTypeNotSupportedException(pType.getName()); + } + // set array data + res.setArray(binData); + // set oid + res.setOID(roid); + //insert into result set + resultBag.add(res); + } + + } + else throw new RasClientInternalException("RasHttpRequest","execute()","Type of MDD is no Base Type"); + } + + result = resultBag; + + // close stream + in.close(); + + break; + + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_SKALARS: + //System.err.println("Skalar = 2"); + // read Endianess + while(in.read(b1) == 0); + endianess = b1[0]; + + // read Collection Type + collType = RasUtils.readString(in); + RasType rt = new RasType(); + try + { + rt = rt.getAnyType(collType); + //System.err.println("Colltype is " + rt); + } + catch(Exception e) + { + throw new RasTypeNotSupportedException(rt + " as RasCollectionType"); + } + if(rt.getTypeID()!=RasGlobalDefs.RAS_COLLECTION) + throw new RasTypeNotSupportedException(rt + " as RasCollectionType"); + + // read NumberOfResults + while(in.available() < 4); + in.read(b4); + numberOfResults = RasUtils.ubytesToInt(b4,endianess); + //System.err.println("Number of results: " + numberOfResults); + + // Initailize return-list + resultBag = new RasBag(); + + // do this for each result + for(int x = 0; x < numberOfResults; x++) + { + // read elementType + String elementType = RasUtils.readString(in); + RasType et = new RasType(); + et = ((RasCollectionType)rt).getElementType(); + //System.err.println("ElementType is " + et); + + // read size of binData + while(in.available() < 4); + in.read(b4); + dataSize = RasUtils.ubytesToInt(b4,endianess); + //System.err.print("Size of BinData: "); + //System.err.println(dataSize); + + // read binData + binData = new byte[dataSize]; + readBytes = 0; + readBytesTmp = 0; + while( (readBytesTmp != -1) && (readBytes < dataSize) ) + { + readBytesTmp = in.read(binData,readBytes,dataSize-readBytes); + readBytes += readBytesTmp; + /* + System.err.println("Read " + readBytesTmp +" Bytes (" + + readBytes + " Bytes overall)"); + */ + } + + ByteArrayInputStream bis = new ByteArrayInputStream(binData); + DataInputStream dis = new DataInputStream(bis); + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + switch(et.getTypeID()) + { + case RasGlobalDefs.RAS_MINTERVAL: + resultBag.add(new RasMInterval(new String(binData))); + break; + case RasGlobalDefs.RAS_SINTERVAL: + resultBag.add(new RasSInterval(new String(binData))); + break; + case RasGlobalDefs.RAS_POINT: + resultBag.add(new RasPoint(new String(binData))); + break; + case RasGlobalDefs.RAS_OID: + resultBag.add(new RasOID(new String(binData))); + break; + case RAS_BOOLEAN: + case RAS_BYTE: + case RAS_CHAR: + byte b = binData[0]; + resultBag.add(new Byte(b)); + break; + case RAS_DOUBLE: + double d = dis.readDouble(); + resultBag.add(new Double(d)); + break; + case RAS_FLOAT: + float f = dis.readFloat(); + resultBag.add(new Float(f)); + break; + case RAS_ULONG: + byte[] bu = new byte[8]; + bu[0] = 0; + bu[1] = 0; + bu[2] = 0; + bu[3] = 0; + bu[4] = dis.readByte(); + bu[5] = dis.readByte(); + bu[6] = dis.readByte(); + bu[7] = dis.readByte(); + ByteArrayInputStream bis2 = new ByteArrayInputStream(bu); + DataInputStream dis2 = new DataInputStream(bis2); + long ul = dis2.readLong(); + resultBag.add(new Long(ul)); + break; + case RAS_LONG: + case RAS_INT: + int i = dis.readInt(); + resultBag.add(new Integer(i)); + break; + case RAS_USHORT: + int j = dis.readUnsignedShort(); + resultBag.add(new Integer(j)); + break; + case RAS_SHORT: + short s = dis.readShort(); + resultBag.add(new Short(s)); + break; + default: + throw new RasTypeNotSupportedException(et + " as ElementType "); + } + } + result = resultBag; + + // close stream + in.close(); + break; + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_ERROR: + Debug.talkCritical("RasHttpRequest.execute: execution failed. Error = 0"); + + // read Endianess + while(in.read(b1) == 0) + ; + endianess = b1[0]; + + // read Error Number + while(in.available() < 4) + ; + in.read(b4); + int errNo = RasUtils.ubytesToInt(b4,endianess); + + // read Line Number + while(in.available() < 4) + ; + in.read(b4); + int lineNo = RasUtils.ubytesToInt(b4,endianess); + + // read Column Number + while(in.available() < 4) + ; + in.read(b4); + int colNo = RasUtils.ubytesToInt(b4,endianess); + + // read token + String token = RasUtils.readString(in); + + Debug.talkCritical("RasHttpRequest.execute: Errno=" + errNo + ", lineNo=" + lineNo + ", colNo=" + colNo + ", Token=" + token); + + throw new RasQueryExecutionFailedException(errNo,lineNo,colNo,token); + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_INT: + // read Integer Value + //System.err.println("Now reading integer value..."); + while(in.available() < 4); + in.read(b4); + result = new Integer(RasUtils.ubytesToInt(b4,endianess)); + //System.err.println("Int Value is : " + result.getInt()); + break; + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_OID: + // read Values + String sys = RasUtils.readString(in); + String base = RasUtils.readString(in); + double d = in.readDouble(); + //System.out.println(sys+base+"localOID als double = " + d); + resultBag = new RasBag(); + resultBag.add(new RasOID(sys, base, d)); + result = resultBag; + // close stream + in.close(); + break; + default: + Debug.talkCritical( "RasHttpRequest.execute: illegal response type: " + resultType ); + break; + + } + + con.disconnect(); // close connection to server -- PB 2003-jun-15 + } + catch( MalformedURLException e ) + { + Debug.leaveCritical( "RasHttpRequest.execute: leave. malformed URL: " + e.getMessage() ); + throw new RasConnectionFailedException(MANAGER_CONN_FAILED, serverURL ); + } + catch( IOException e ) + { + Debug.leaveCritical( "RasHttpRequest.execute: leave. IO exception: " + e.getMessage() ); + throw new RasClientInternalException("RasHttpRequest","execute()",e.getMessage()); + } + catch( RasResultIsNoIntervalException e ) + { + Debug.leaveCritical( "RasHttpRequest.execute: leave. result no interval: " + e.getMessage() ); + throw new RasClientInternalException("RasHttpRequest","execute()",e.getMessage()); + } + + rcvTimer.stopTimer(); + rcvTimer.print(); + + httpTimer.stopTimer(); + httpTimer.print(); + + Debug.leaveVerbose( "RasHttpRequest.execute: leave. resultType=" + resultType ); + } // execute() + + +/** + * returns the result type (MDDColl, SkalarColl, Error, Integer) + */ + public byte getResultType() + { + return resultType; + } + +/** + * returns the result of the query + */ + public Object getResult() + { + return result; + } + +/** + * returns the result of the query as an Integer + */ + public int getIntegerResult() + { + if (result != null) + { + Integer myInt = (Integer)result; + return myInt.intValue(); + } + else + return 0; + } + +/** + * returns the result of the query as a DCollection + */ + public DCollection getDCollection() + { + return (DCollection)result; + } + +/** + * returns the result of the query as a DBag + */ + public DBag getDBag() + { + return (DBag)result; + } + +/** + * This method specifies the type of the client. The clientType determines + * how the results are coded + * and returned by the server. Default type and the only type supported right now + * is "RASCLIENT". The results are sent back using the "application/octet-stream" + * mime type and are coded as a byte stream as described in the class documentation. + * <P> + * Future versions will support other types like, for example, "BROWSER", where the + * results will be coded as standard HTTP-responses of certain mime types (for example + * "image/gif"). + * + * @param clientType currently only "RASCLIENT" supported + */ + public void setClientType ( String clientType ) + { + client = clientType; + } + +/** + * main program for testing purposes + */ + +/* BEGIN experimental *********************** + public static void main( String[] args ) + { + String server = "localhost"; + String port = "7001"; + String base = "RASBASE"; + String user = "rasguest"; + String passwd = "rasguest"; + String query = "select r from RAS_COLLECTIONNAMES as r"; + int count = 1; + + System.out.println( "Query test started." ); + + for (int i=args.length-1; i>=0; i--) + { + if (args[i].equals("--server")) + server = args[i+1]; + if (args[i].equals("--port")) + port = args[i+1]; + if (args[i].equals("--database")) + base = args[i+1]; + if (args[i].equals("--user")) + user = args[i+1]; + if (args[i].equals("--passwd")) + passwd = args[i+1]; + if (args[i].equals("--query")) + query = args[i+1]; + if (args[i].equals("--count")) + count = Integer.parseInt(args[i+1]); + } + + try + { + RasImplementation myApp = new RasImplementation("http://"+server+":"+port); + myApp.setUserIdentification(user, passwd); + + System.out.println( "opening database..." ); + Database myDb = myApp.newDatabase(); + myDb.open( base, Database.OPEN_READ_ONLY ); + + System.out.println( "starting transaction..." ); + Transaction myTa = myApp.newTransaction(); + myTa.begin(); + + String parameters = "Command=8&ClientID=1&QueryString=" + query; + String serverUrl = "http://" + server + ":" + 7102; // port; + + for (int i = 0; i < count; i++) + { + System.out.println( "sending query #" + i + "..." ); + execute( serverUrl, parameters ); + } + + System.out.println( "closing transaction..." ); + myTa.abort(); + + System.out.println( "closing database..." ); + myDb.close(); + System.out.println( "all done." ); + + } + catch(Exception e) + { + System.err.println( e.getMessage() ); + } + + System.out.println( "Query test done." ); + + } // main() +END experimental ***********************/ +} + + + diff --git a/java/src/rasj/clientcommhttp/RasUtils.java b/java/src/rasj/clientcommhttp/RasUtils.java new file mode 100644 index 0000000..1ffa049 --- /dev/null +++ b/java/src/rasj/clientcommhttp/RasUtils.java @@ -0,0 +1,110 @@ +/* +* 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.clientcommhttp; + +import java.io.*; +import java.net.*; +import java.lang.*; + +/** + * + * This class provides some useful methods for reading binary data from a stream + * or converting objects to a byte array for transmission. + * + */ +public final class RasUtils implements RasCommDefs +{ + static final String rcsid = "@(#)Package rasj.clientcommhttp, class RasUtils: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/clientcommhttp/RasUtils.java,v 1.5 2003/12/10 21:04:26 rasdev Exp $"; + + public RasUtils() + { + } + + /** + * This method is used for turning up to 4 unsigned bytes into signed integers. + * + * @param uBytes one to four Bytes which are interpreted as an unsigned Integer + * @param endianess determines the order of the bytes: 0 = bigendian, 1 = little endian + */ + public static int ubytesToInt( byte[] uBytes, byte endianess ) + { + int tmpi; + byte tmpb; + int retval = 0; + + for( int i = 0; i < uBytes.length; i++ ) + { + if( endianess == BIG_ENDIAN ) + tmpb = uBytes[uBytes.length-i-1]; + else + tmpb = uBytes[i]; + + tmpi = 0; + /* Byte < 0 */ + if( (int)tmpb < 0 ) + tmpi = 256 + tmpb; + else + tmpi = tmpb; + + tmpi <<= (i*8); + retval += tmpi; + } + return retval; + } + + /** + * Reads characters from a stream until a '\0' character is reached. + * + * @param in BufferedInputStream to be read from ( must have been initialized before! ) + */ + public static String readString( InputStream in ) + throws IOException + { + byte b = (byte) '\0'; + byte[] b1 = new byte[1]; + String retval = ""; + + while(in.read(b1) == 0); + while(b1[0] != b) + { + retval =retval + (char)b1[0]; + while(in.read(b1) == 0); + } + return retval; + } + + + +} diff --git a/java/src/rasj/global/BenchmarkTimer.java b/java/src/rasj/global/BenchmarkTimer.java new file mode 100644 index 0000000..18c2638 --- /dev/null +++ b/java/src/rasj/global/BenchmarkTimer.java @@ -0,0 +1,109 @@ +/* +* 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: + * - keep consistent with rasj.global.BenchmarkTimer! + * </pre> + *********************************************************** */ + +package rasj.global; + +import java.util.*; +import java.lang.Float; + +public class BenchmarkTimer + { + + private static final String srcFileVersion = "CVS version information: $Source: /home/rasdev/CVS-repository/rasdaman/java/rasj/global/BenchmarkTimer.java,v $ $Revision: 1.1 $"; + + private static final String OUTPUTPREFIX = "-- Timer "; + + String text; + long startTime; + long endTime; + long totalTime; + + public BenchmarkTimer(String t) + { + text = t==null ? "(no text)" : t; + reset(); + } + + public void reset() + { + startTime = 0; + endTime = 0; + totalTime = 0; + // Debug.talkVerbose( OUTPUTPREFIX + text + " reset."); + } + + public void startTimer() + { + Debug.talkSparse( OUTPUTPREFIX + text + " started."); // level must be less than verbose to get crisp output + startTime = System.currentTimeMillis(); + } + + public void stopTimer() + { + endTime = System.currentTimeMillis(); + totalTime += endTime; + // Debug.talkVerbose( OUTPUTPREFIX + text + " stopped."); + } + + public long getTotalTime() + { + return totalTime; + } + + public void print() + { + Debug.talkSparse( OUTPUTPREFIX + text + ": " + (totalTime-startTime) + " ms elapsed."); + // level must be less than verbose to get crisp output + } + +// ---------------------------------------------------------------------------------- + + /** + test routine for timer + */ + public static void main(String a[]) + { + Debug.enterVerbose( "Benchmark test start" ); + + BenchmarkTimer timer = new BenchmarkTimer("Test"); + + timer.startTimer(); + for(int i=0;i<20000000;i++); + timer.stopTimer(); + + timer.print(); + + Debug.leaveVerbose( "Benchmark test stop" ); + } + } + diff --git a/java/src/rasj/global/Debug.java b/java/src/rasj/global/Debug.java new file mode 100644 index 0000000..408c36b --- /dev/null +++ b/java/src/rasj/global/Debug.java @@ -0,0 +1,229 @@ +/* +* 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: generate debug output into servlet log + * Methods of this static class perform debugging output into + * the servlet log (usually /opt/jakarta/logs/servlet.log). + * For entering a method to be traced, logging indent level is + * increased; the logging methods for leaving a method decrease + * indent, and the trace methods inbetween leave indentation unchanged. + * [Needless to say that both statically and dynamically the number + * of enters and leaves should match.] + * Four trace levels are provided, intended for reporting increasingly + * verbose (i.e., for decreasingly dangerous events): + * critical (always logged), + * warning (default level), + * sparse, + * verbose. + * For each combination of enter/inside/leave of a method and trace + * levels corresponding report functions are provided. + * Finally, the debug level can be changed any time with + * setDebugLevel(). + * Initialisation requires passing the servlet object to gain an + * output stream to write to. + * + * + * COMMENTS: + * - keep consistent with rasogc.Debug !!! + * - documentation to be done + * </pre> + ************************************************************/ + +package rasj.global; + +import java.lang.System; + +/** + * Methods of this static class perform debugging output into + * the servlet log (usually /opt/jakarta/logs/servlet.log). + * For entering a method to be traced, logging indent level is + * increased; the logging methods for leaving a method decrease + * indent, and the trace methods inbetween leave indentation unchanged. + * [Needless to say that both statically and dynamically the number + * of enters and leaves should match.] + * <P> + * Four trace levels are provided, intended for reporting increasingly + * verbose (i.e., for decreasingly dangerous events): + * <UL> + * <LI>critical (always logged), + * <LI>warning (default level), + * <LI>sparse, + * <LI>verbose. + * </UL> + * For each combination of enter/inside/leave of a method and trace + * levels corresponding report functions are provided. + * Finally, the debug level can be changed any time with + * setDebugLevel(). + * <P> + * Initialisation requires passing the servlet object to gain an + * output stream to write to. + * <P> + * + * @version $Revision: 1.2 $ + * + */ + +public class Debug + { + static final String rcsid = "@(#)Package rasj.global, class Debug: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/global/Debug.java,v 1.2 2006/01/19 18:24:16 rasdev Exp $"; + + // + // debug threshold levels (constant defs): + // + + /** log only critical events **/ + public static final int CRITICAL_LEVEL = 0; // print always + + /** log also warnings which do not really impede processing **/ + public static final int WARNING_LEVEL = 1; + + /** log also occasional output interesting for debugging **/ + public static final int SPARSE_LEVEL = 2; + + /** log all information available to aid debugging **/ + public static final int VERBOSE_LEVEL = 3; + + + /** + * debug threshold default + **/ + public static final int DEFAULT_LEVEL = WARNING_LEVEL; + + /** + * debug threshold - only levels below it are displayed: + **/ + private static int debugThreshold = DEFAULT_LEVEL; + + /** + unit of indentation to display calling hierarchy + **/ + private static final String INDENT = ". "; + + /** + * indentation counter + **/ + private static int indentLevel = 0; + + /** + * set debug threshold to control further output + **/ + public static void setDebugThreshold(int level) + { + if (level >= 0) + { + debugThreshold = level; + System.err.println( "Debug::setDebugThreshold: setting debug level to " + level ); + } + else + System.err.println( "Debug::setDebugThreshold: ignoring illegal debug level value: " + level ); + } + + /** + the following set of methods logs for entering/within/leaving a method. + Entering increases printing indent level, talk leaves it unchanged, and leaving decreases indentation. + these choices are crossed with the debug levels to achieve handy, short calls. + **/ + + /** method enter msg, output only with critical level **/ + public static void enterCritical( String what ) { enter( CRITICAL_LEVEL, what ); } + /** method enter msg, output only with warning level **/ + public static void enterWarning( String what ) { enter( WARNING_LEVEL, what ); } + /** method enter msg, output only with sparse level **/ + public static void enterSparse( String what ) { enter( SPARSE_LEVEL, what ); } + /** method enter msg, output only with verbose log level **/ + public static void enterVerbose( String what ) { enter( VERBOSE_LEVEL, what ); } + + /** method leave msg, output only with critical level **/ + public static void leaveCritical( String what ) { leave( CRITICAL_LEVEL, what ); } + /** method leave msg, output only with warning level **/ + public static void leaveWarning( String what ) { leave( WARNING_LEVEL, what ); } + /** method leave msg, output only with sparse level **/ + public static void leaveSparse( String what ) { leave( SPARSE_LEVEL, what ); } + /** method leave msg, output only with verbose log level **/ + public static void leaveVerbose( String what ) { leave( VERBOSE_LEVEL, what ); } + + /** method inside msg, output only with critical level **/ + public static void talkCritical( String what ) { talk( CRITICAL_LEVEL, what ); } + /** method inside msg, output only with warning level **/ + public static void talkWarning( String what ) { talk( WARNING_LEVEL, what ); } + /** method inside msg, output only with sparse level **/ + public static void talkSparse( String what ) { talk( SPARSE_LEVEL, what ); } + /** method inside msg, output only with verbose log level **/ + public static void talkVerbose( String what ) { talk( VERBOSE_LEVEL, what ); } + + /** + * writes messages to the "standard" error log stream, increments indentation + **/ + private static void enter(int level, String what) + { + StringBuffer s = new StringBuffer(100); // to hold indent prefix + + if(level <= debugThreshold) + { + indentLevel++; // indent one more to the right + s.append( "rasj[" + Integer.toString(level) + "] " ); // document log level + for (int i=0; i<indentLevel; i++) + s.append( INDENT ); + s.append( what ); + System.err.println( s ); + } + } + + + /** + * writes messages to the "standard" error log stream, decrements indentation + **/ + static void leave(int level, String what) + { + StringBuffer s = new StringBuffer(100); // to hold indent prefix + + if(level <= debugThreshold) + { + s.append( "rasj[" + Integer.toString(level) + "] " ); // document log level + for (int i=0; i<indentLevel; i++) + s.append( INDENT ); + s.append( what ); + System.err.println( s ); + indentLevel--; // indent one less, go left + } + } + + /** + * writes messages to the "standard" error log stream; indentation unchanged + **/ + static void talk(int level, String what) + { + StringBuffer s = new StringBuffer(100); // to hold indent prefix + + if(level <= debugThreshold) + { + s.append( "rasj[" + Integer.toString( level) + "] " ); // document log level + for (int i=0; i<indentLevel; i++) + s.append( INDENT ); + s.append( what ); + System.err.println( s ); + } + } + } diff --git a/java/src/rasj/global/Makefile b/java/src/rasj/global/Makefile new file mode 100644 index 0000000..a658fdd --- /dev/null +++ b/java/src/rasj/global/Makefile @@ -0,0 +1,86 @@ +# -*-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.global +# +# COMMENTS: +# - FIXME: errtxts has been i18nalized, reflect it in the RasError code! +# +################################################################## +######################### Definitions ############################ + +# standard include with general options +include $(RMANBASE)/Makefile.inc + +# error text file +ERRTXT_FILE = $(RMANBASE)/bin/errtxts_en + +SRCS = RasErrorTexts.java RasGlobalDefs.java Debug.java BenchmarkTimer.java +OBJS = ${SRCS:%.java=%.class} Version.class +MISCCLEAN = *.class Version.java + +# directory where HTML documentation is created +DOCDIR := $(DOCBASE)/java/rasj/global + +########################### Targets ############################## + +# compile everything +.PHONY : all +all: Version.java errortexts + $(MAKE) $(OBJS) + +.PHONY : errortexts +# create array of error messages in class RasErrorTexts +errortexts: + if (test -f $(ERRTXT_FILE)) \ + then \ + grep "\^E\^" $(ERRTXT_FILE) \ + | sed -e '/^#/ d' \ + | sed -e 's+\^E\^+:+g' \ + | sed -e 's+^+"+g' \ + | sed -e 's+$$+\",+g' > tmpfile; \ + cat RasErrorTexts.template1 tmpfile RasErrorTexts.template2 > RasErrorTexts.java; \ + else \ + echo "Error: errtxts file $(ERRTXT_FILE) not found."; \ + exit 1; \ + fi + -rm tmpfile + +# always generate to have an up-to date version & generation time info: +.PHONY: Version.java +Version.java: + @ sed s/%%DATE%%/`date +%Y-%b-%d`/ <Version.java.template \ + | sed s/%%VERSION%%/$(RMANVERSIONNAME)/ \ + | sed "s/%%GENERATION_DATE%%/`date`/" >Version.java + +# delete all files +.PHONY: clean +clean: + -rm -f $(SRCS) $(MISCCLEAN) + +############################ Dependencies ####################### +# general rules +include $(RMANBASE)/Makefile.rel + diff --git a/java/src/rasj/global/Makefile.dep b/java/src/rasj/global/Makefile.dep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/java/src/rasj/global/Makefile.dep diff --git a/java/src/rasj/global/RasErrorTexts.java b/java/src/rasj/global/RasErrorTexts.java new file mode 100644 index 0000000..c208a4c --- /dev/null +++ b/java/src/rasj/global/RasErrorTexts.java @@ -0,0 +1,313 @@ +/* +* 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: + * first part of three constituting RasErrorTexts.java: + * - part 1: Java src + * - part 2: generated from errtxts file + * - part 3: Java src + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +package rasj.global; + +import java.io.*; + +// This file is created automatically - do not edit unless allowed explicitly (look for +// a message "changes can only be made after here")! + +public abstract class RasErrorTexts +{ + + public static String[] errorMessages = { + +// end of RasErrorTexts.template1 +"66:Exception: Memory allocation failed.", +"100:Exception: Internal error: DL parse error.", +"200:Exception: The result is no point.", +"201:Exception: The result is no interval.", +"202:Exception: Index violation ( index range [$low,$high], index $index ).", +"203:Exception: Dimension mismatch between $dim1 and $dim2.", +"204:Exception: Stream initialization overflow.", +"205:Exception: Result is no cell.", +"206:Serialisable exception r_Ebase_dbms: error in base DBMS.", +"207:Internal client exception in class $class, method $method: $code.", +"208:Exception: Access type $aType does not fit base type $bType.", +"209:Exception: RasType $type is unknown.", +"210:Exception: Base type $type is not supported yet.", +"211:Exception: Database is not open.", +"212:Exception: RPC layer connection to RasDaMan failed.", +"213:Exception: Wrong URL format (should be http://address:port)", +"214:Exception: Illegal java long value $val for server base type ULong.", +"215:Exception: Illegal java integer value $val for server base type UShort.", +"216:Exception: System collection is not writable.", +"217:Exception: System collection has no OID.", +"218:Exception: Conversion format is not supported.", +"219:Exception: The specified tile size is smaller than the length of the base type of the mdd object.", +"220:Exception: The tiling strategy in the storage layout is not compatible with the marray.", +"221:Exception: The domain passed as an argument was not initialised correctly (dimension is 0).", +"222:Exception: The type name or type structure does not represent a marray type.", +"223:Exception: The rc index requires a marray type that has a specified domain (with fixed borders in all dimensions).", +"224:Exception: The tile configuration is incompatible to the marray domain.", +"229:Exception: The parameterized query has invalid parameter format.", +"230:Exception: The r_Object was already assigned a type.", +"231:Exception: The Marray has no base type.", +"232:Exception: The interval has at least one open bound.", +"233:Exception: The intervals don't have the same dimension.", +"234:Exception: The string passed to the tiling object was not correct.", +"235:Exception: Connection to server already closed.", +"236:Exception: Error in compression engine", +"237:Exception: Client communication failure", +"238:Exception: Base type not supported by conversion/compression module.", +"239:Exception: Standard overlay using types larger than 16 bytes is not supported.", +"240:Exception: Insert into a RC index is not allowed.", +"241:Exception: No tiling defined at that region. Update not possible.", +"300:Parsing error $errorNo in line $lineNo, column $columnNo: Unexpected name $token.", +"301:Parsing error $errorNo in line $lineNo, column $columnNo, token $token: All cell values of an MDD must be of the same type. ", +"302:Parsing error $errorNo in line $lineNo, column $columnNo, token $token: Number of cells specified does not match the number of cells of the given spatial domain.", +"303:Parsing error $errorNo in line $lineNo, column $columnNo, token $token: OId is not valid.", +"308:Parsing error: Unexpected end of query.", +"309:Parsing error: Unknown error.", +"310:Lexical analysing error $errorNo in line $lineNo, column $columnNo: Unexpected characters $token.", +"311:Parsing error $errorNo in line $lineNo, column $columnNo, token $token: Complex constructor must have both arguments of the same type (i.e. float or double). ", +"312:Parsing error $errorNo in line $lineNo, column $columnNo, token $token: Variable already defined. ", +"313:Parsing error $errorNo in line $lineNo, column $columnNo, token $token: Only constant interval bounds allowed. ", +"330:Preprocessing error $errorNo in line $lineNo, column $columnNo: Unexpected name $token: ", +"331:Preprocessing error $errorNo in line $lineNo, column $columnNo, token $token: attempt to redefine function.", +"332:Preprocessing error $errorNo in line $lineNo, column $columnNo, token $token: number of actual arguments for the called function differs from the number of formal arguments.", +"333:Preprocessing error $errorNo in line $lineNo, column $columnNo, token $token: the called function name is ambiguous, try the full qualified name.", +"349:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand out of range.", +"350:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: General. ", +"351:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Spatial domains of the binary induce operands are incompatible.", +"352:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand types are incompatible.", +"353:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of quantifier must be multidimensional.", +"354:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of quantifier must be of type r_Marray<d_Boolean>.", +"355:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Collection name is unknown.", +"356:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Specified domain does not intersect with spatial domain of MDD.", +"357:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Variable is unknown.", +"358:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Projection operand is not of type r_Marray<T>.", +"359:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Result of the where clause must be of type boolean.", +"360:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Type of operand is not supported.", +"361:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Multiple query targets are not supported.", +"362:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Specified domain dimensionality does not equal defined dimensionality of MDD.", +"363:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Cell base types of binary induce operation are incompatible.", +"364:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Cell base type and scalar type of binary induce operation are incompatible.", +"365:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Scalar types of binary operation are incompatible.", +"366:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Cell base type of unary induce operation is not supported.", +"367:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Scalar type of unary operation is not supported.", +"368:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Cell base type for induced dot operation must be complex.", +"369:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Scalar type for dot operation must be complex.", +"370:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Struct selector is not valid.", +"371:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Retrieval query must start with a SELECT statement.", +"372:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Update query must start with an INSERT, UPDATE, DELETE, DROP or CREATE statement.", +"373:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Unsatisfied MDD constant parameter.", +"380:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Data type can not be converted to selected data exchange format.", +"381:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Error in convertor of the selected data exchange format.", +"382:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Unknown conversion format.", +"383:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Parameter of oid function must be a persistent object of type MDD.", +"384:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: OId is not valid.", +"385:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operation is not supported on strings.", +"386:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Base name of oid is not matching the currently opened one.", +"387:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: System name of oid is not matching the currently used one.", +"388:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Interval bound must be either an integer expression or an asterisk.", +"389:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: No interval (in case of fixed bounds, the upper one can not be smaller than the lower one).", +"390:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Minterval dimension specifications must be either of type interval or integer.", +"391:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Spatial operation must be either of type minterval, point, or integer.", +"393:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of operation lo/hi must be of type interval.", +"394:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operation lo/hi can not be used for an open bound.", +"395:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of function sdom() must be of type MDD.", +"396:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Selection operation is not supported on this data type.", +"397:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of minterval selection must be of type integer.", +"398:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Index for minterval selection is out of range.", +"399:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of point selection must be of type integer.", +"400:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Domain of MDD constructor has to be defined.", +"401:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Can not evaluate domain expression to an minterval.", +"402:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Projected cell is not defined.", +"403:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Binary operation is not supported on these data types.", +"404:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Type of cell expression is not supported.", +"405:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: First operand of shift function must be of type MDD.", +"406:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Second operand of shift function must be of type Point.", +"407:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Dimensionality of MDD and point expression are not matching.", +"408:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Second operand of shift function must be a constant expression.", +"409:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Spatial domain shift of open bounds is not supported.", +"410:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of point expression must be of type integer.", +"411:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Index for point selection is out of range.", +"412:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Value expression must be either of type atomic or complex.", +"413:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Condition expression must be of type boolean.", +"415:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of count_cells must be of type r_Marray<d_Boolean>.", +"416:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: First operand of scale function must be of type MDD.", +"417:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Second operand of scale function must be either of type Point, Integer or Float.", +"418:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Second operand of bit function must be of integral type.", +"419:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Could not scale the domain.", +"420:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Extend operation with open bounds is not supported.", +"421:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Target interval of extend operation does not cover MDD to be extended.", +"422:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Second operand of extend function must be an minterval.", +"499:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Language feature is not supported.", +"510:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: The argument is outside the function domain.", +"511:Execution error $errorNo in line $lineNo, column $columnNo, near token $token: The function result exceeds the allowed range.", +"700:Admin error: General error creating RasDaMan database.", +"701:Admin error: Error creating table in tablespace RAS_DB_SCHEMA.", +"702:Admin error: Error inserting into table RAS_COUNTERS.", +"703:Admin error: Error creating table in tablespace RAS_DB_BLOB.", +"704:Admin error: Error creating index in tablespace RAS_DB_INDEX.", +"705:Admin error: Error inserting into table RAS_BASETYPENAMES.", +"706:Admin error: Error creating table in default tablespace.", +"707:Admin error: Error on COMMIT creating RasDaMan database.", +"708:Admin error: Database to be created already exists.", +"800:RasManager Error: Could not connect to RasServer $url.", +"801:RasManager Error: System overloaded, please try again later.", +"802:RasManager Error: Access denied, incorrect user/password.", +"803:RasManager Error: Access denied, no permission for operation.", +"804:RasManager Error: Access denied, capability refused.", +"805:RasManager Error: No suitable servers started, call administrator.", +"806:RasManager Error: Write transaction in progress, please retry again later.", +"807:RasManager Error: Requested database unknown.", +"808:RasManager Error: Request format error.", +"820:RNP Error: First parameter has to be the clientID (clientcomm internal).", +"821:RNP Error: Client ID invalid, probably a timeout occurred.", +"822:RNP Error: Unknown command in client request.", +"830:base DBMS Error: Cannot connect to base DBMS server (invalid connect string in rasmgr config file?).", +"900:Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Type in typedef definition not supported.", +"901:Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Set template type has to be a type reference.", +"902:Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Type reference not found.", +"903:Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: MDD base type has to be a type reference or an atomic type.", +"904:Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: MDD type must have a domain specification.", +"905:Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Struct type name exists already.", +"906:Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: MDD type name exists already.", +"907:Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Set type name exists already.", +"950:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update target must be an iterator variable.", +"951:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update source must be an expression resulting in an r_Marray<>.", +"952:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update base type does not match MDD base type.", +"953:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update domain is not within MDD definition domain.", +"954:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update target expression must be an assignable value (l-value).", +"955:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Collection name exists already.", +"956:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Unknown collection type.", +"957:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Unknown collection name.", +"958:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Allocation of new oid failed.", +"959:Update error $errorNo in line $lineNo, column $columnNo, near token $token: MDD and collection types are incompatible.", +"960:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Insert expression must be of type MDD.", +"961:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update domain must be of type Minterval.", +"962:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Number of update intervals must match source dimensionaltiy.", +"963:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update domain dimensionality must match target MDD dimensionaltiy.", +"964:Update error $errorNo in line $lineNo, column $columnNo, near token $token: Type is not persistent.", +"965:Update error $errorNo: MDD type $token unknown.", +"966:Update error $errorNo: MDD type is missing.", +"1000:General error: RasDaMan tables inconsistent.", +"1001:General error: RasDaMan server incompatible with database.", +"1002:General error: Blob with zero length encountered.", +"1003:General error: Tile container for TC index not found.", +"1004:General error: Index of MDD Object is not defined.", +"1005:General error: Storage structure of MDD Object is not defined.", +"1006:General error: Unknown index type requested.", +"1007:General error: Illegal index type requested.", +"1008:General error: No valid collection type passed to MDD collection.", +"1009:General error: MDD object not valid or not persistent.", +"1010:General error: No valid MDD type passed to MDD object.", +"1011:General error: An illegal state has been reached. This is caused by a compiler bug or a library bug.", +"1012:General error: Invalid collection type passed to MDD collection.", +"1013:General error: The name of the type is too long.", +"1014:General error: Invalid name of the object, should contain only [a-zA-Z0-9_]", +"2000:Internal error: There seems to be another database open.", +"2001:Internal error: Invalid OId type encountered.", +"2002:Internal error: Entry in user defined type not found.", +"2003:Internal error: Entry in user defined type out of bounds.", +"2004:Internal error: Transient index used instead of persistent index.", +"2005:Internal error: Index returned tiles multiple times.", +"2006:Internal error: Tile was not inserted into index.", +"2007:Internal error: Transient index access out of bounds.", +"2008:Internal error: MDD object exists multiple times in cache.", +"2009:Internal error: Some tile(s) were not inserted into the MDD object.", +"2010:Internal error: A conversion module returned an incorrect base type.", +"2011:Internal error: The collection type has no element type.", +"2012:Internal error: The marray type has no base type.", +"2013:Internal error: The property has no base type.", +"2014:Internal error: The scalar was passed a NULL value.", +"2015:Internal error: The index node that had to be split was not found in its parent.", +"2016:Internal error: The index found more cells than allowed.", +"2017:Internal error: The storage layout is incompatible with the index entries.", +"2018:Internal error: Object does not support swapping.", +"2019:Internal error: Error encountered during swapping.", +"2020:Internal error: Binary export for object is not supported.", +"2021:Internal error: Binary import for object is not supported.", +"2022:Internal error: Operands and result types don't match.", +"3000:Format conversion error: DEM area does not contain any non-null value, empty result generated.", +"10000:Unexpected internal server error.", +/** *********************************************************** + * <pre> + * + * SOURCE: RasErrorTexts.template2 + * + * PACKAGE: rasj.global + * CLASS: RasErrorTexts + * + * PURPOSE: + * third part of three constituting RasErrorTexts.java: + * - part 1: Java src + * - part 2: generated from errtxts file + * - part 3: Java src + * + * + * </pre> + *********************************************************** */ + +// end of error code array, start of RasErrorTexts.template2 + + "" // this last, empty string is needed because the last one, generated from errtxts, has a "," at the end + }; + + public static String getErrorMessage( int errNo ) + { + StringBuffer buf; + String prefix = String.valueOf(errNo)+":"; + int index = 0; + String retVal = null; + + while(index < errorMessages.length-1) // last string is empty, see above + { + if(errorMessages[index].startsWith(prefix)) + { + buf = new StringBuffer(errorMessages[index]); + index = errorMessages[index].indexOf(":"); + buf.delete(0,index+1); + retVal = buf.toString(); + index = errorMessages.length+1; + } + else + index++; + + } + if(retVal == null) + retVal = "No error message available for error number " + errNo + "."; + + return retVal; + } + +} + + diff --git a/java/src/rasj/global/RasErrorTexts.template1 b/java/src/rasj/global/RasErrorTexts.template1 new file mode 100644 index 0000000..ce36ab7 --- /dev/null +++ b/java/src/rasj/global/RasErrorTexts.template1 @@ -0,0 +1,50 @@ +/* +* 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: + * first part of three constituting RasErrorTexts.java: + * - part 1: Java src + * - part 2: generated from errtxts file + * - part 3: Java src + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +package rasj.global; + +import java.io.*; + +// This file is created automatically - do not edit unless allowed explicitly (look for +// a message "changes can only be made after here")! + +public abstract class RasErrorTexts +{ + + public static String[] errorMessages = { + +// end of RasErrorTexts.template1 diff --git a/java/src/rasj/global/RasErrorTexts.template2 b/java/src/rasj/global/RasErrorTexts.template2 new file mode 100644 index 0000000..03c4ac5 --- /dev/null +++ b/java/src/rasj/global/RasErrorTexts.template2 @@ -0,0 +1,72 @@ +/* +* 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: + * third part of three constituting RasErrorTexts.java: + * - part 1: Java src + * - part 2: generated from errtxts file + * - part 3: Java src + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +// end of error code array, start of RasErrorTexts.template2 + + "" // this last, empty string is needed because the last one, generated from errtxts, has a "," at the end + }; + + public static String getErrorMessage( int errNo ) + { + StringBuffer buf; + String prefix = String.valueOf(errNo)+":"; + int index = 0; + String retVal = null; + + while(index < errorMessages.length-1) // last string is empty, see above + { + if(errorMessages[index].startsWith(prefix)) + { + buf = new StringBuffer(errorMessages[index]); + index = errorMessages[index].indexOf(":"); + buf.delete(0,index+1); + retVal = buf.toString(); + index = errorMessages.length+1; + } + else + index++; + + } + if(retVal == null) + retVal = "No error message available for error number " + errNo + "."; + + return retVal; + } + +} + + diff --git a/java/src/rasj/global/RasGlobalDefs.java b/java/src/rasj/global/RasGlobalDefs.java new file mode 100644 index 0000000..51ea769 --- /dev/null +++ b/java/src/rasj/global/RasGlobalDefs.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.global; + +public interface RasGlobalDefs +{ + static final String rcsid = "@(#)Package rasj, class RasGlobalDefs: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/global/RasGlobalDefs.java,v 1.23 2006/01/17 23:49:11 rasdev Exp $"; + + // rasj version string (similar to executables startup message) -- can't we get rasdaman version info automatically? + // static final String RASJ_VERSION = "rasj: rasdaman Java API. rasdaman v5.1revC -- generated Mit Jun 25 10:46:59 CEST 2003."; + static final String RASJ_VERSION = "rasj: rasdaman Java API. rasdaman " + Version.VERSION + " -- generated " + Version.DATE + "."; + + // fastscale predefines; FIXME: should be used dynamically! -- PB 2003-jun-25 + static final int NUM_FAST_PRE_SCALE = 8; + static final double[] FAST_PRE_SCALE_FACTORS = {1.0/2, 1.0/4, 1.0/8, 1.0/16, 1.0/32, 1.0/64, 1.0/128, 1.0/256}; + static final String[] FAST_PRE_SCALE_SUFFIXES = {"_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8"}; + + //RasDataFormat + static final int RAS_ARRAY = 0; // no compression, row-major memory representation + static final int RAS_TIFF = RAS_ARRAY + 1; // TIFF format + static final int RAS_JPEG = RAS_TIFF + 1; // JPEG format + static final int RAS_HDF = RAS_JPEG + 1; // HDF format + static final int RAS_PNG = RAS_HDF + 1; // PNG format + static final int RAS_ZLIB = RAS_PNG + 1; // ZLIB format + static final int RAS_AUTO_COMPRESSION = RAS_ZLIB + 1; // automatic compression + + //RasTypeID + static final int RAS_UNKNOWN = 0; + static final int RAS_MARRAY = RAS_UNKNOWN + 1; + static final int RAS_COLLECTION = RAS_MARRAY + 1; + static final int RAS_SINTERVAL = RAS_COLLECTION + 1; + static final int RAS_MINTERVAL = RAS_SINTERVAL + 1; + static final int RAS_POINT = RAS_MINTERVAL + 1; + static final int RAS_OID = RAS_POINT + 1; + static final int RAS_STRUCTURE = RAS_OID + 1; + static final int RAS_RGB = RAS_STRUCTURE + 1; + static final int RAS_INT = RAS_RGB + 1; + static final int RAS_SHORT = RAS_INT + 1; + static final int RAS_USHORT = RAS_SHORT + 1; + static final int RAS_LONG = RAS_USHORT + 1; + static final int RAS_ULONG = RAS_LONG + 1; + static final int RAS_FLOAT = RAS_ULONG + 1; + static final int RAS_DOUBLE = RAS_FLOAT + 1; + static final int RAS_BOOLEAN = RAS_DOUBLE + 1; + static final int RAS_BYTE = RAS_BOOLEAN + 1; + static final int RAS_CHAR = RAS_BYTE + 1; + static final int RAS_STRING = RAS_CHAR + 1; + static final int RAS_COMPLEX1 = RAS_STRING +1; + + + //object status + public static final int NO_STATUS = 0; + public static final int DELETED = NO_STATUS + 1; + public static final int CREATED = DELETED + 1; + public static final int MODIFIED = CREATED + 1; + public static final int READ = MODIFIED + 1; + public static final int TRANSIENT = READ + 1; + + // java BaseType sizes + public final int SIZE_OF_INTEGER = 4; + public final int SIZE_OF_LONG = 8; + public final int SIZE_OF_FLOAT = 4; + public final int SIZE_OF_BYTE = 1; + public final int SIZE_OF_SHORT = 2; + public final int SIZE_OF_CHAR = 2; + public final int SIZE_OF_BOOLEAN = 1; + public final int SIZE_OF_DOUBLE = 8; + + // RasPrimitiveType sizes + public final int SIZE_OF_RAS_LONG = 4; + public final int SIZE_OF_RAS_ULONG = 4; + public final int SIZE_OF_RAS_FLOAT = 4; + public final int SIZE_OF_RAS_BYTE = 1; + public final int SIZE_OF_RAS_SHORT = 2; + public final int SIZE_OF_RAS_USHORT = 2; + public final int SIZE_OF_RAS_CHAR = 1; + public final int SIZE_OF_RAS_BOOLEAN = 1; + public final int SIZE_OF_RAS_DOUBLE = 8; + + // error codes - these match the errtxts file + final static int INTERNAL_DL_PARSE_EXCEPTION = 100; + + final static int RESULT_IS_NO_INTERVAL = 201; + final static int INDEX_OUT_OF_BOUNDS = 202; + final static int DIMENSION_MISMATCH = 203; + final static int STREAM_INPUT_OVERFLOW = 204; + final static int RESULT_IS_NO_CELL = 205; + final static int BASE_DBS_ERROR = 206; + final static int INTERNAL_CLIENT_ERROR = 207; + final static int TYPE_INVALID = 208; + final static int TYPE_UNKNOWN = 209; + final static int TYPE_NOT_SUPPORTED = 210; + final static int DB_NOT_OPEN = 211; + final static int DB_CONN_FAILED = 212; + final static int URL_FORMAT_ERROR = 213; + final static int ILLEGAL_ULONG_VALUE = 214; + final static int ILLEGAL_USHORT_VALUE = 215; + + final static int MANAGER_CONN_FAILED = 800; + final static int MANAGER_BUSY = 801; + final static int ACC_DEN_INC_LOGIN = 802; + final static int ACC_DEN_NO_PERMISSION = 803; + final static int ACC_DEN_CAPABILITY_WRONG = 804; + final static int NO_ACTIVE_SERVERS = 805; + final static int WRITE_TRANS_IN_PROGRESS = 806; + final static int DATABASE_NOT_DEFINED = 807; + final static int REQUEST_FORMAT_ERROR = 808; + + final static int INVALID_OBJECT_NAME_ERROR = 1014; + + // time constants for retries in RasODMGImplementation.getFreeServer(): + // if we sum up we achieve a total of (.2 + .4 +...+ 3.2) = 6.3 secs maximum wait time. that looks ok. + final static int MAX_GETFREESERVER_ATTEMPTS = 5; // # of tries in total until giving up on current request + final static int GETFREESERVER_WAIT_INITIAL = 100; // first waiting period + final static int GETFREESERVER_WAIT_INCREMENT = 2; // multiplication factor for subsequent wait cycles + + // server connection constants + final static int RASMGRPORT_DEFAULT = 7001; // default port used to caontact rasmgr + final static String GUESTIDENT_DEFAULT = "rasguest:8e70a429be359b6dace8b5b2500dedb0"; + // default read-only user + + public final static String KEYWORD_TAB = "\t"; + public final static String KEYWORD_CLASS = "$class"; + public final static String KEYWORD_METHOD = "$method"; + public final static String KEYWORD_CODE = "$code"; + public final static String KEYWORD_URL = "$url"; + public final static String KEYWORD_DIM1 = "$dim1"; + public final static String KEYWORD_DIM2 = "$dim2"; + public final static String KEYWORD_VAL = "$val"; + public final static String KEYWORD_LOW = "$low"; + public final static String KEYWORD_HIGH = "$high"; + public final static String KEYWORD_INDEX = "$index"; + public final static String KEYWORD_INVNAME = "$InvName"; + public final static String KEYWORD_TOKEN = "$token"; + public final static String KEYWORD_ERRNO = "$errorNo"; + public final static String KEYWORD_LINENO = "$lineNo"; + public final static String KEYWORD_COLNO = "$columnNo"; + public final static String KEYWORD_ATYPE = "$aType"; + public final static String KEYWORD_BTYPE = "$bType"; + public final static String KEYWORD_TYPE = "$type"; +} diff --git a/java/src/rasj/global/Version.java b/java/src/rasj/global/Version.java new file mode 100644 index 0000000..6adb1a0 --- /dev/null +++ b/java/src/rasj/global/Version.java @@ -0,0 +1,46 @@ +/* +* 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: + * provide version information. + * + * + * COMMENTS: + * ./. + * + * </pre> + ********************************************************** **/ + +package rasj.global; + +public class Version +{ + // version information + public static final String VERSION = "6.1test"; + + // date of .jar generation + public static final String DATE = "Tue Jan 6 17:52:20 CET 2009"; +} + diff --git a/java/src/rasj/global/Version.java.template b/java/src/rasj/global/Version.java.template new file mode 100644 index 0000000..9865b1c --- /dev/null +++ b/java/src/rasj/global/Version.java.template @@ -0,0 +1,46 @@ +/* +* 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: + * provide version information. + * + * + * COMMENTS: + * ./. + * + * </pre> + ********************************************************** **/ + +package rasj.global; + +public class Version +{ + // version information + public static final String VERSION = "%%VERSION%%"; + + // date of .jar generation + public static final String DATE = "%%GENERATION_DATE%%"; +} + diff --git a/java/src/rasj/odmg/Makefile b/java/src/rasj/odmg/Makefile new file mode 100644 index 0000000..6c768a7 --- /dev/null +++ b/java/src/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/src/rasj/odmg/Makefile.dep b/java/src/rasj/odmg/Makefile.dep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/java/src/rasj/odmg/Makefile.dep diff --git a/java/src/rasj/odmg/RasBag.java b/java/src/rasj/odmg/RasBag.java new file mode 100644 index 0000000..5ed1843 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasCollection.java b/java/src/rasj/odmg/RasCollection.java new file mode 100644 index 0000000..f782c94 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasDatabase.java b/java/src/rasj/odmg/RasDatabase.java new file mode 100644 index 0000000..d494b37 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasList.java b/java/src/rasj/odmg/RasList.java new file mode 100644 index 0000000..210daf0 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasODMGGlobal.java b/java/src/rasj/odmg/RasODMGGlobal.java new file mode 100644 index 0000000..431cefc --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasODMGImplementation.java b/java/src/rasj/odmg/RasODMGImplementation.java new file mode 100644 index 0000000..cc6a569 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasODMGImplementation.java.BEFORE_Connection b/java/src/rasj/odmg/RasODMGImplementation.java.BEFORE_Connection new file mode 100644 index 0000000..4d7f76d --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasODMGImplementation.java.getFreeServer_beginTA b/java/src/rasj/odmg/RasODMGImplementation.java.getFreeServer_beginTA new file mode 100644 index 0000000..2fb2cb2 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasOID.java b/java/src/rasj/odmg/RasOID.java new file mode 100644 index 0000000..9ebd948 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasOQLQuery.java b/java/src/rasj/odmg/RasOQLQuery.java new file mode 100644 index 0000000..939a92e --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasObject.java b/java/src/rasj/odmg/RasObject.java new file mode 100644 index 0000000..d24f966 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasSet.java b/java/src/rasj/odmg/RasSet.java new file mode 100644 index 0000000..a38f33d --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasTransaction.LOCAL_isOpenTA b/java/src/rasj/odmg/RasTransaction.LOCAL_isOpenTA new file mode 100644 index 0000000..10ea687 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasTransaction.java b/java/src/rasj/odmg/RasTransaction.java new file mode 100644 index 0000000..10ea687 --- /dev/null +++ b/java/src/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/src/rasj/odmg/RasTransaction.java.ORIG b/java/src/rasj/odmg/RasTransaction.java.ORIG new file mode 100644 index 0000000..29b7c90 --- /dev/null +++ b/java/src/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/src/rasj/rasj-protocol.html b/java/src/rasj/rasj-protocol.html new file mode 100644 index 0000000..eea7bf9 --- /dev/null +++ b/java/src/rasj/rasj-protocol.html @@ -0,0 +1,109 @@ +<H1>rasdaman c/s protocol</H1> +(taken from rasdaman/java/rasj/clientcomm/RasHttpRequest.java) +<P> + +<B>Request structure</B><P> + +<UL> +The rasj HTTP request to the rasdaman server uses the HTTP POST-Format with the following +parameters: +<P> +<TABLE BORDER=1 WIDTH=100%> +<TR><TH>Parameter:</TH><TH>Description:</TH><TH>Required for</TH></TR> +<TR><TD>Command</TD> +<TD>Integer value specifying the desired action (e.g. OpenDB, BT, CT, CloseDB ...)</TD> +<TD>all requests</TD></TR> +<TR><TD>Database</TD> +<TD>String value specifying the database</TD> +<TD>OpenDB, CloseDB</TD></TR> +<TR><TD>ClientType</TD> +<TD>Integer value defining the type of the client (at the moment always RasClient)</TD> +<TD>all requests</TD></TR> +<TR><TD>ClientID</TD> +<TD>Integer value specifying the ClientID (currently set to 1 for every client)</TD> +<TD>all requests</TD></TR> +<TR><TD>QueryString</TD> +<TD>String value containing the RasQL query</TD> +<TD>executeQuery</TD></TR> +<TR><TD>Endianess</TD> +<TD>Integer value containing the Client Endianess</TD> +<TD>only insert queries</TD></TR> +<TR><TD>NumberOfQueryParameters</TD> +<TD>Integer value specifying the number of query parameters</TD> +<TD>only insert queries</TD></TR> +<TR><TD>QueryParameters</TD> +<TD>Byte Array containing the query parameters (MDDs) using the following format:<BR> +<TABLE BORDER=1> +<TR><TH>Integer</TH><TH>String</TH><TH>String</TH><TH>Integer</TH><TH>String</TH><TH>String</TH> +<TH>String</TH><TH>Long</TH><TH>Byte[]</TH> +</TR> +<TR><TD>objectType</TD><TD>objectTypeName</TD><TD>typeStructure</TD><TD>typeLength</TD> +<TD>domain</TD><TD>storageLayout</TD><TD>OID</TD><TD>dataSize</TD><TD>binary data</TD></TR> +</TABLE> +/TD> +<TD>only insert queries</TD></TR> +</TABLE> +</P> +</UL><P> + +<B>Result formats / internal representation:</B><P><UL> +The result of a HTTP request has one of the following forms:<P> +MDD Collections:<BR> +<TABLE BORDER=1><TR><TH ROWSPAN=2>Byte</TH><TH ROWSPAN=2>Byte</TH> +<TH ROWSPAN=2>String</TH><TH ROWSPAN=2>Long(4Bytes)</TH> +<TH COLSPAN=5>resultElement 1</TH><TH ROWSPAN=3> ... </TH></TR> +<TR><TD>String</TD><TD>String</TD><TD>String</TD><TD>Long(4Bytes)</TD><TD>Byte[]</TD></TR> +<TR><TD>Result type<P>1=MDDCollection</TD> +<TD>Endianess</TD> +<TD>Collection type</TD> +<TD>Number of results</TD> +<TD>BaseType description</TD> +<TD>Spatial domain</TD> +<TD>OID</TD> +<TD>Size of the Binary Data Block</TD> +<TD>Binary Data Block</TD></TR> +</TABLE><P> + +Skalar Collections:<BR> +<TABLE BORDER=1><TR><TH ROWSPAN=2>Byte</TH><TH ROWSPAN=2>Byte</TH> +<TH ROWSPAN=2>String</TH><TH ROWSPAN=2>Long(4Bytes)</TH> +<TH COLSPAN=4>resultElement 1</TH><TH ROWSPAN=3> ... </TH></TR> +<TR><TD>String</TD><TD>Long(4Bytes)</TD><TD>Byte[]</TD></TR> +<TR><TD>Result type<P>2=SkalarCollection</TD> +<TD>Endianess</TD> +<TD>Collection type</TD> +<TD>Number of results</TD> +<TD>ElementType description</TD> +<TD>Size of the Binary Data Block</TD> +<TD>Binary Data Block</TD></TR> +</TABLE><P> + +Errors:<BR> +<TABLE BORDER=1><TR><TH>Byte</TH><TH>Byte</TH> +<TH>Long(4Bytes)</TH><TH>Long(4Bytes)</TH><TH>Long(4Bytes)</TH> +<TH>String</TH></TR> +<TR><TD>Result type<P>0=Error</TD> +<TD>Endianess</TD> +<TD>Error number</TD> +<TD>Line number</TD> +<TD>Column number</TD> +<TD>Token</TD> +</TABLE><P> + +Single Integer Value:<BR> +<TABLE BORDER=1><TR><TH>Byte</TH><TH>Integer</TH></TR> +<TR><TD>Result type<P>3=Integer</TD><TD>Value</TD></TR> +</TABLE><P> + +OID:<BR> +<TABLE BORDER=1><TR><TH>Byte</TH><TH>String</TH><TH>String</TH><TH>Double</TH></TR> +<TR><TD>Result type<P>4=OID</TD><TD>system</TD><TD>basename</TD><TD>localOID</TD></TR> +</TABLE><P> + +Acknowledgement:<BR> +<TABLE BORDER=1><TR><TH>Byte</TH></TR> +<TR><TD>Result type<P>99=OK</TD></TR> +</TABLE><P> + +</UL> + diff --git a/java/src/rasj/rnp/Makefile b/java/src/rasj/rnp/Makefile new file mode 100644 index 0000000..8597847 --- /dev/null +++ b/java/src/rasj/rnp/Makefile @@ -0,0 +1,61 @@ +# -*-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 = RasRNPImplementation.java Rnp.java RnpBaseClientComm.java \ + RnpDecoder.java RnpEncoder.java RnpException.java RnpFragment.java\ + RnpFragmentHeader.java RnpMessage.java RnpMessageHeader.java \ + RnpParameter.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/src/rasj/rnp/Makefile.dep b/java/src/rasj/rnp/Makefile.dep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/java/src/rasj/rnp/Makefile.dep diff --git a/java/src/rasj/rnp/RasRNPImplementation.java b/java/src/rasj/rnp/RasRNPImplementation.java new file mode 100644 index 0000000..23baac2 --- /dev/null +++ b/java/src/rasj/rnp/RasRNPImplementation.java @@ -0,0 +1,1761 @@ +/* +* 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.rnp; + +import rasj.odmg.*; +import rasj.*; +import rasj.global.*; +import rasj.clientcommhttp.*; +import org.odmg.*; +import rasj.odmg.RasOQLQuery; + +import java.io.*; +import java.net.*; +import java.lang.*; +import java.util.*; + +public class RasRNPImplementation extends RnpBaseClientComm implements RasImplementationInterface, RasCommDefs,RasGlobalDefs + { + public static final int pmt_none = 0; + public static final int pmt_clientid = 1; + public static final int pmt_rErrorString = 2; + public static final int pmt_dbname = 3; + public static final int pmt_accesmode = 4; + public static final int pmt_queryString = 5; + public static final int pmt_httpqanswer = 6; + public static final int pmt_oidstring = 7; + public static final int pmt_capability = 8; + public static final int pmt_transstatus = 9; + public static final int pmt_objecttype =10; + + public static final int cmd_none = 0; + public static final int cmd_connect = 1; + public static final int cmd_disconnect = 2; + public static final int cmd_opendb = 3; + public static final int cmd_closedb = 4; + public static final int cmd_beginta = 5; + public static final int cmd_committa = 6; + public static final int cmd_abortta = 7; + public static final int cmd_istaopen = 8; + public static final int cmd_queryhttp = 9; + public static final int cmd_getnewoid =10; + + public static final int rasServerId = 3072002; + + 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 = 5; // was 120; -- PB 2003-nov-20 + + private RasTransaction transaction = null; + private RasDatabase database = null; + private RasOQLQuery query = null; + + private int accessMode = 0; + private boolean readWrite = false; + private int dbIsOpen = 0; + private int taIsOpen = 0; + private int clientID = 0; + + private String errorStatus = ""; + + public static boolean useTurbo = true; // whenever possible pack multiple requests into one call + + + + public RasRNPImplementation(String server) + { + super(rasServerId); + + Debug.enterVerbose( "RasRNPImplementation.RasRNPImplementation start. server=" + server ); + try + { + StringTokenizer t=new StringTokenizer (server,"/"); + String xxx=t.nextToken(); + rasMgr =t.nextToken("/:"); + String portStr = t.nextToken(":"); + rasMgrPort = Integer.parseInt(portStr); + } + catch(NoSuchElementException e) + { + Debug.talkCritical( "RasRNPImplementation.RasRNPImplementation: " + e.getMessage() ); + Debug.leaveVerbose( "RasRNPImplementation.RasRNPImplementation done: " + e.getMessage() ); + throw new RasConnectionFailedException(RasGlobalDefs.URL_FORMAT_ERROR, server); + } + Debug.leaveVerbose( "RasRNPImplementation.RasRNPImplementation done." ); + } // RasRNPImplementation() + + public String getErrorStatus() + { + Debug.talkSparse( "RasRNPImplementation.getErrorStatus: " + errorStatus ); + return errorStatus; + } + + public String getRasServer() + { + Debug.talkSparse( "RasRNPImplementation.getRasServer: " + rasServer ); + return rasServer; + } + + public int dbIsOpen() + { + Debug.talkSparse( "RasRNPImplementation.dbIsOpen: " + dbIsOpen ); + return dbIsOpen; + } + + public int getClientID() + { + Debug.talkSparse( "RasRNPImplementation.getClientID: " + clientID ); + return clientID; + } + + public int getAccessMode() + { + Debug.talkSparse( "RasRNPImplementation.getAccessMode: " + accessMode ); + return accessMode; + } + + public Transaction newTransaction() + { + transaction = new RasTransaction(this); + Debug.talkSparse( "RasRNPImplementation.newTransaction." ); + return transaction; + } + + public Transaction currentTransaction() + { + Debug.talkSparse( "RasRNPImplementation.currentTransaction." ); + return transaction; + } + + public Database newDatabase() + { + database=new RasDatabase(this); + Debug.talkSparse( "RasRNPImplementation.newDatabase." ); + return database; + } + + public OQLQuery newOQLQuery() + { + query=new RasOQLQuery(this); + Debug.talkSparse( "RasRNPImplementation.newOQLQuery." ); + return query; + } + + public DList newDList() + { + Debug.talkSparse( "RasRNPImplementation.newDList." ); + return new RasList(); + } + + public DBag newDBag() + { + Debug.talkSparse( "RasRNPImplementation.newDBag." ); + return new RasBag(); + } + + public DSet newDSet() + { + Debug.talkSparse( "RasRNPImplementation.newDSet." ); + return new RasSet(); + } + + public DArray newDArray() + { + Debug.talkCritical( "RasRNPImplementation.newDArray: not yet implemented." ); + throw new NotImplementedException(); + } + + public DMap newDMap() + { + Debug.talkCritical( "RasRNPImplementation.newDMap: not yet implemented." ); + throw new NotImplementedException(); + } + + public Database getDatabase(Object obj) + { + Debug.talkCritical( "RasRNPImplementation.getDatabase: not yet implemented." ); + throw new NotImplementedException(); + } + + public String getObjectId(Object obj) + { + Debug.enterVerbose( "RasRNPImplementation.getObjectId start." ); + String oid = null; + if (obj instanceof RasObject) + { + RasOID roid = ((RasObject)obj).getOID(); + oid = roid.toString(); + if (!((RasObject)obj).getOID().isValid()) + { + roid = executeGetNewObjectId(); + oid = roid.toString(); + ((RasObject)obj).setOID(roid); + } + else + { + Debug.leaveCritical( "RasRNPImplementation.getObjectId done. not yet implemented." ); + throw new NotImplementedException(); + } + } + Debug.leaveVerbose( "RasRNPImplementation.getObjectId done. oid=" + oid ); + return oid; + } + + public void setMaxRetry(int newRetry) + { + Debug.talkVerbose( "RasRNPImplementation.setMaxRetry: setting to " + newRetry ); + maxRetry = newRetry; + } + + public int getMaxRetry() + { + Debug.talkVerbose( "RasRNPImplementation.getMaxRetry: is " + maxRetry ); + return maxRetry; + } + + public void openDB(String name, int accessMode) throws ODMGException + { + Debug.enterVerbose( "RasRNPImplementation.openDB start. db=" + name + ", accessMode=" + accessMode ); + databaseName = name; + this.accessMode = accessMode; + readWrite = (accessMode != Database.OPEN_READ_ONLY) ? true:false; + getFreeServer(false); // fake server + + // "turbo" doesn't work because connect delivers the client id needed for later calls + // if(useTurbo==false) + // { + executeConnect(); + executeOpenDB(databaseName); + executeCloseDB(); + executeDisconnect(); + // } + // else executeTurboOpen(name); + + dbIsOpen = 1; + Debug.leaveVerbose( "RasRNPImplementation.openDB done." ); + } + + public void closeDB() throws ODMGException + { + Debug.talkVerbose( "RasRNPImplementation.closeDB." ); + dbIsOpen = 0; + } + + public void beginTA() + { + Debug.enterVerbose( "RasRNPImplementation.beginTA start." ); + if(useTurbo==false) + { + try + { + getFreeServer(true); + executeConnect(); + executeOpenDB(databaseName); + executeBeginTA(); + } + catch(ODMGException e) + { + errorStatus = e.getMessage(); + Debug.talkCritical( "RasRNPImplementation.beginTA: " + errorStatus ); + } + } + else + { + try + { + getFreeServer(true); + executeTurboBegin(databaseName); + } + catch(ODMGException e) + { + errorStatus = e.getMessage(); + Debug.talkCritical( "RasRNPImplementation.beginTA: " + errorStatus ); + } + } + Debug.leaveVerbose( "RasRNPImplementation.beginTA done." ); + } + + public boolean isOpenTA() + { + Debug.enterVerbose( "RasRNPImplementation.isOpenTA start." ); + boolean result = false; + try + { + if(executeIsOpenTA()!=0) + result = true; + } + catch(ODMGException e) + { + errorStatus = e.getMessage(); + Debug.talkCritical( "RasRNPImplementation.isOpenTA: " + errorStatus ); + } + Debug.leaveVerbose( "RasRNPImplementation.isOpenTA done. result=" + result ); + return result; + } + + public void commitTA() + { + Debug.enterVerbose( "RasRNPImplementation.commitTA start." ); + if(useTurbo==false) + { + try + { + executeCommitTA(); + executeCloseDB(); + executeDisconnect(); + } + catch(ODMGException e) + { + errorStatus = e.getMessage(); + Debug.talkCritical( "RasRNPImplementation.commitTA: " + errorStatus ); + } + } + else + { + try + { + executeTurboCommit(); + } + catch(ODMGException e) + { + errorStatus = e.getMessage(); + Debug.talkCritical( "RasRNPImplementation.commitTA: " + errorStatus ); + } + } + Debug.leaveVerbose( "RasRNPImplementation.commitTA done." ); + } + + public void abortTA() + { + Debug.enterVerbose( "RasRNPImplementation.abortTA done." ); + if (useTurbo==false) + { + try + { + executeAbortTA(); + executeCloseDB(); + executeDisconnect(); + } + catch(ODMGException e) + { + errorStatus = e.getMessage(); + Debug.talkCritical( "RasRNPImplementation.abortTA: " + errorStatus ); + } + } + else + { + try + { + executeTurboAbort(); + } + catch(ODMGException e) + { + errorStatus = e.getMessage(); + Debug.talkCritical( "RasRNPImplementation.abortTA: " + errorStatus ); + } + } + Debug.leaveVerbose( "RasRNPImplementation.abortTA done." ); + } + + public Object queryRequest(String parameters) throws RasQueryExecutionFailedException + { + Debug.talkVerbose( "RasRNPImplementation.queryRequest." ); + return executeQueryRequest(parameters); + } + + private void executeTurboOpen(String name) throws ODMGException + { + Debug.enterVerbose( "RasRNPImplementation.executeTurboOpen start. name=" + name ); + clientID = 0; + startMessage(); + + //connect + startFragment(cmd_connect); + encoder.addParameterInt32(pmt_clientid,clientID); + encoder.addParameterString(pmt_capability,capability); + endFragment(); + + //opendb + startFragment(cmd_opendb); + encoder.addParameterInt32(pmt_clientid,clientID); + encoder.addParameterString(pmt_dbname,name); + endFragment(); + + //close db + startFragment(cmd_closedb); + encoder.addParameterInt32(pmt_clientid,clientID); + endFragment(); + + //disconnect + startFragment(cmd_disconnect); + encoder.addParameterInt32(pmt_clientid,clientID); + endFragment(); + + endMessage(); + + //send message and receive answer + turboSendRequestGetAnswer(); + + // connect answer + RnpFragment fragment=decoder.getFirstFragment(); + checkForError(); + decoder.getFirstParameter(); + clientID=decoder.getDataAsInteger(); + + //opendb answer + fragment=decoder.getNextFragment(fragment); + checkForError(); + + //closedb answer + fragment=decoder.getNextFragment(fragment); + checkForError(); + + //disconnect answer + decoder.getNextFragment(fragment); + checkForError(); + clientID = 0; + Debug.leaveVerbose( "RasRNPImplementation.executeTurboOpen done." ); + } + + private void executeTurboBegin(String name) throws ODMGException + { + Debug.enterVerbose( "RasRNPImplementation.executeTurboBegin start. name=" + name ); + clientID = 0; + startMessage(); + + //connect + startFragment(cmd_connect); + encoder.addParameterInt32(pmt_clientid,clientID); + encoder.addParameterString(pmt_capability,capability); + endFragment(); + + //opendb + startFragment(cmd_opendb); + encoder.addParameterInt32(pmt_clientid,clientID); + encoder.addParameterString(pmt_dbname,name); + endFragment(); + + // begin ta + startFragment(cmd_beginta); + encoder.addParameterInt32(pmt_clientid,clientID); + encoder.addParameterInt32(pmt_accesmode, readWrite ? 1:0); + endFragment(); + + endMessage(); + + //send message and receive answer + turboSendRequestGetAnswer(); + + // connect answer + RnpFragment fragment=decoder.getFirstFragment(); + checkForError(); + decoder.getFirstParameter(); + clientID=decoder.getDataAsInteger(); + + //opendb answer + fragment=decoder.getNextFragment(fragment); + checkForError(); + + // begin ta answer + decoder.getNextFragment(fragment); + checkForError(); + Debug.leaveVerbose( "RasRNPImplementation.executeTurboBegin done." ); + } + + private void executeTurboCommit() throws ODMGException + { + Debug.enterVerbose( "RasRNPImplementation.executeTurboCommit start." ); + startMessage(); + + //commit + startFragment(cmd_committa); + encoder.addParameterInt32(pmt_clientid,clientID); + endFragment(); + + //close + startFragment(cmd_closedb); + encoder.addParameterInt32(pmt_clientid,clientID); + endFragment(); + + //disconnect + startFragment(cmd_disconnect); + encoder.addParameterInt32(pmt_clientid,clientID); + endFragment(); + + endMessage(); + + //send message and receive answer + turboSendRequestGetAnswer(); + + //commit answer + RnpFragment fragment=decoder.getFirstFragment(); + checkForError(); + + //close answer + fragment=decoder.getNextFragment(fragment); + checkForError(); + + //disconnect answer + decoder.getNextFragment(fragment); + checkForError(); + clientID = 0; + Debug.leaveVerbose( "RasRNPImplementation.executeTurboCommit done." ); + } + + private void executeTurboAbort() throws ODMGException + { + Debug.enterVerbose( "RasRNPImplementation.executeTurboAbort start." ); + startMessage(); + + //abort + startFragment(cmd_abortta); + encoder.addParameterInt32(pmt_clientid,clientID); + endFragment(); + + //close + startFragment(cmd_closedb); + encoder.addParameterInt32(pmt_clientid,clientID); + endFragment(); + + //disconnect + startFragment(cmd_disconnect); + encoder.addParameterInt32(pmt_clientid,clientID); + endFragment(); + + endMessage(); + + //send message and receive answer + turboSendRequestGetAnswer(); + + //abort answer + RnpFragment fragment=decoder.getFirstFragment(); + checkForError(); + + //close answer + fragment=decoder.getNextFragment(fragment); + checkForError(); + + //disconnect answer + decoder.getNextFragment(fragment); + checkForError(); + clientID = 0; + Debug.leaveVerbose( "RasRNPImplementation.executeTurboAbort done." ); + } + + private RasOID executeGetNewObjectId() + { + Debug.enterVerbose( "RasRNPImplementation.executeGetNewObjectId start." ); + startRequest(cmd_getnewoid); + encoder.addParameterInt32(pmt_clientid,clientID); + encoder.addParameterInt32(pmt_objecttype,1); + sendRequestGetAnswer(); + decoder.getFirstParameter(); + RasOID result = new RasOID(decoder.getDataAsString()); + Debug.leaveVerbose( "RasRNPImplementation.executeGetNewObjectId done." ); + return result; + } + + private int executeIsOpenTA()throws ODMGException + { + startRequest(cmd_istaopen); + encoder.addParameterInt32(pmt_clientid,clientID); + sendRequestGetAnswer(); + decoder.getFirstParameter(); + int result = decoder.getDataAsInteger(); + Debug.leaveVerbose( "RasRNPImplementation.executeIsOpenTA done. result=" + result ); + return result; + } + +//######## These functions are kept only for testing purpose, we will emove them soon #### + private void executeConnect() throws ODMGException + { + startRequest(cmd_connect); + encoder.addParameterInt32(pmt_clientid,clientID); + encoder.addParameterString(pmt_capability,capability); + sendRequestGetAnswer(); + checkForError(); + decoder.getFirstParameter(); + clientID=decoder.getDataAsInteger(); + } + + private void executeDisconnect() throws ODMGException + { + startRequest(cmd_disconnect); + encoder.addParameterInt32(pmt_clientid,clientID); + sendRequestGetAnswer(); + checkForError(); + } + + private void executeOpenDB(String name) throws ODMGException + { + startRequest(cmd_opendb); + encoder.addParameterInt32(pmt_clientid,clientID); + encoder.addParameterString(pmt_dbname,name); + sendRequestGetAnswer(); + checkForError(); + } + + private void executeCloseDB() throws ODMGException + { + startRequest(cmd_closedb); + encoder.addParameterInt32(pmt_clientid,clientID); + sendRequestGetAnswer(); + checkForError(); + } + + private void executeBeginTA() throws ODMGException + { + startRequest(cmd_beginta); + encoder.addParameterInt32(pmt_clientid,clientID); + encoder.addParameterInt32(pmt_accesmode, readWrite ? 1:0); + sendRequestGetAnswer(); + checkForError(); + } + + private void executeCommitTA()throws ODMGException + { + startRequest(cmd_committa); + encoder.addParameterInt32(pmt_clientid,clientID); + sendRequestGetAnswer(); + checkForError(); + } + + private void executeAbortTA()throws ODMGException + { + startRequest(cmd_abortta); + encoder.addParameterInt32(pmt_clientid,clientID); + sendRequestGetAnswer(); + checkForError(); + } + +//################################################################################ + + public void getFreeServer(boolean realServer)throws RasQueryExecutionFailedException, RasConnectionFailedException + { + Debug.enterVerbose( "RasRNPImplementation.getFreeServer start. realServer=" + realServer ); + String uniqueID = uniqueRequestID(); + + for (int retryCount = 0; ;retryCount++) + { + try + { + executeGetFreeServer(realServer,uniqueID); + break; + } + catch(RasConnectionFailedException e) + { + int errno = e.getErrorNo(); + // FIXME: adapt algorithm to that of http, see RasODMGImplementation.java + if ( ( errno==RasGlobalDefs.MANAGER_BUSY + // || errno==RasGlobalDefs.NO_ACTIVE_SERVERS // if server doesn't run waiting won't help -- PB 2003-nov-20 + || errno==RasGlobalDefs.WRITE_TRANS_IN_PROGRESS) + && retryCount < maxRetry) + { + int millisec = 50 * retryCount + 50; + if(millisec > 1000) + millisec = 1000; + Debug.talkVerbose( "RasRNPImplementation.getFreeServer: retry #" + retryCount + ", sleeping " + millisec + "msecs" ); + try + { + Thread.sleep(millisec); + } + catch(InterruptedException intex) + { + // wake up + } + } + else + { + Debug.talkCritical( "RasRNPImplementation.getFreeServer: " + e.getMessage() ); + Debug.leaveVerbose( "RasRNPImplementation.getFreeServer done: " + e.getMessage() ); + throw(e); + } + } // catch + } // for + + Debug.leaveVerbose( "RasRNPImplementation.getFreeServer done." ); + } // getFreeServer + + private void executeGetFreeServer(boolean realServer, String uniqueID) + throws RasQueryExecutionFailedException, RasConnectionFailedException + { + Debug.enterVerbose( "RasRNPImplementation.executeGetFreeServer start. realServer=" + realServer + ", uniqueID=" + uniqueID ); + try + { + Debug.talkVerbose( "RasRNPImplementation.executeGetFreeServer: rasmgr=" + rasMgr + ", port=" + rasMgrPort ); + Socket socket = new Socket(rasMgr,rasMgrPort); + Debug.talkVerbose( "RasRNPImplementation.executeGetFreeServer: socket=" + socket ); + PrintStream ps = new PrintStream(socket.getOutputStream()); + String accessFlag = (accessMode == Database.OPEN_READ_ONLY ? "ro":"rw"); + String body = databaseName + " RNP " + accessFlag + ' ' + uniqueID + " \0"; + if (realServer) + ps.print("POST getfreeserver RNP/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); + else + ps.print("POST getfreeserver2 RNP/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(); + + BufferedReader ds = new BufferedReader(new InputStreamReader(socket.getInputStream())); + int resultCode = getResultCode(ds); + String bodyLine = getBodyLine(ds); + Debug.talkVerbose( "RasRNPImplementation.executeGetFreeServer: bodyLine: " + bodyLine ); + + ps.close(); + ds.close(); + socket.close(); + Debug.talkVerbose( "RasRNPImplementation.executeGetFreeServer: socket closed: " + socket ); + + 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; + setConnectionParameters(host,Integer.parseInt(port)); + } + else + { + StringTokenizer t=new StringTokenizer(bodyLine," "); + String errorStr = t.nextToken(); + int errorCode = Integer.parseInt(errorStr); + if( resultCode < 1000 ) + { + Debug.talkCritical( "RasRNPImplementation.executeGetFreeServer: " + errorCode ); + Debug.leaveVerbose( "RasRNPImplementation.executeGetFreeServer: done. errorcode=" + errorCode ); + throw new RasConnectionFailedException(errorCode,null); + } + else + { + Debug.talkCritical( "RasRNPImplementation.executeGetFreeServer: " + errorCode ); + Debug.leaveVerbose( "RasRNPImplementation.executeGetFreeServer: done. errorcode=" + errorCode ); + throw new RasConnectionFailedException(RasGlobalDefs.REQUEST_FORMAT_ERROR," code=" + errorCode); + } + } + } + catch(MalformedURLException e) + { + Debug.talkCritical( "RasRNPImplementation.executeGetFreeServer: " + e.getMessage() ); + Debug.leaveVerbose( "RasRNPImplementation.executeGetFreeServer: done. " + e.getMessage() ); + throw new RasConnectionFailedException(RasGlobalDefs.MANAGER_CONN_FAILED,rasMgr); + } + catch(IOException e) + { + Debug.talkCritical( "RasRNPImplementation.executeGetFreeServer: " + e.getMessage() ); + Debug.leaveVerbose( "RasRNPImplementation.executeGetFreeServer: done. " + e.getMessage() ); + throw new RasClientInternalException("RasODMGImplementation","getFreeServer()",e.getMessage()); + } + catch(NumberFormatException e) + { + Debug.talkCritical( "RasRNPImplementation.executeGetFreeServer: cannot decode integer: " + e.getMessage() ); + Debug.leaveVerbose( "RasRNPImplementation.executeGetFreeServer: done. " + e.getMessage() ); + throw new RasClientInternalException("RasODMGImplementation","getFreeServer()",e.getMessage()); + } + Debug.leaveVerbose( "RasRNPImplementation.executeGetFreeServer done." ); + } + + public int getResultCode(BufferedReader ds) throws IOException + { + Debug.enterVerbose( "RasRNPImplementation.getResultCode: start." ); + + String s = ds.readLine(); + StringTokenizer t = new StringTokenizer(s," "); + String http = t.nextToken(); // FIXME: never used + String resultString = t.nextToken(" "); + int result = 0; + try + { + result = Integer.parseInt(resultString); + } + catch(NumberFormatException e) + { + Debug.talkCritical( "RasRNPImplementation.getResultCode: cannot decode integer: " + e.getMessage() ); + result = 0; // FIXME: set to some real error code + } + + Debug.leaveVerbose( "RasRNPImplementation.getResultCode: done. result=" + result ); + return result; + } + + public String getBodyLine(BufferedReader ds)throws IOException + { + Debug.enterVerbose( "RasRNPImplementation.getBodyLine: start." ); + + // obviously we are searching for what follows an empty line: + for(;;) + { + String s=ds.readLine(); + if(s==null) + { + Debug.talkCritical( "RasRNPImplementation.getBodyLine: done. Unexpected EOF in rasmgr answer." ); + Debug.leaveVerbose( "RasRNPImplementation.getBodyLine: done, with eof exception." ); + throw new IOException("Unexpected EOF in rasmgr answer."); + } + if(s.length()==0) + break; + } + String result = ds.readLine(); + + Debug.leaveVerbose( "RasRNPImplementation.getBodyLine: done. result=" + result ); + return result; + } + + private Object executeQueryRequest(String parameters) throws RasQueryExecutionFailedException + { + Debug.enterVerbose( "RasRNPImplementation.executeQueryRequest: start. parameters=" + parameters ); + + startRequest(cmd_queryhttp); + encoder.addParameterInt32(pmt_clientid,clientID); + try + { + encoder.addParameterOpaque(pmt_queryString,parameters.getBytes("8859_1")); + } + catch(UnsupportedEncodingException e) + { + Debug.talkCritical( "RasRNPImplementation.executeQueryRequest: " + e.getMessage() ); + Debug.leaveVerbose( "RasRNPImplementation.executeQueryRequest: done, " + e.getMessage() ); + throw new RasClientInternalException("RasRNPImplementation","executeQueryRequest()",e.getMessage()); + } + sendRequestGetAnswer(); + checkForError(); + decoder.getFirstParameter(); + Object result= getResponse(decoder.getDataOpaque()); + + Debug.leaveVerbose( "RasRNPImplementation.executeQueryRequest: done. result=" + result ); + return result; + } + + private Object getResponse(byte[] opaqueAnswer) + throws RasQueryExecutionFailedException + { + Debug.enterVerbose( "RasRNPImplementation.getResponse: start." ); + + Object result=null; + DataInputStream in =new DataInputStream(new ByteArrayInputStream(opaqueAnswer)); + byte[] b1 = new byte[1]; + byte[] b4 = new byte[4]; + byte endianess = 0; + String collType = null; + int numberOfResults = 0; + int dataSize = 0; + byte[] binData = null; + int readBytes = 0; + int readBytesTmp = 0; + DBag resultBag; + RasGMArray res = null; + try + { + in.read(b1); + int resultType = b1[0]; + switch( resultType ) + { + case RESPONSE_OK: + case RESPONSE_OK_NEGATIVE: + //Nothing todo + break; + + // +++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_MDDS: + // read Endianess + while(in.read(b1) == 0); + endianess = b1[0]; + + // read Collection Type + collType = RasUtils.readString(in); + + // read NumberOfResults + while(in.available() < 4); + in.read(b4); + numberOfResults = RasUtils.ubytesToInt(b4,endianess); + + // Initialize return-set and parameters + resultBag = new RasBag(); + String mddBaseType = null; + String domain = null; + String oid = ""; + RasOID roid = null; + + // do this for each result + for(int x = 0; x < numberOfResults; x++) + { + //read mddBaseType + mddBaseType = RasUtils.readString(in); + + // read spatialDomain + domain = RasUtils.readString(in); + + // read OID + oid = RasUtils.readString(in); + roid = new RasOID(oid); + + // read size of binData + while(in.available() < 4); + in.read(b4); + + dataSize = RasUtils.ubytesToInt(b4,endianess); + + // read binData + binData = new byte[dataSize]; + readBytes = 0; + readBytesTmp = 0; + + while( (readBytesTmp != -1) && (readBytes < dataSize) ) + { + readBytesTmp = in.read(binData,readBytes,dataSize-readBytes); + readBytes += readBytesTmp; + } + + RasType rType = RasType.getAnyType(mddBaseType); + RasBaseType rb = null; + + if(rType.getClass().getName().equals("rasj.RasMArrayType")) + { + RasMArrayType tmp = (RasMArrayType)rType; + rb = tmp.getBaseType(); + } + else + { + Debug.talkCritical( "RasRNPImplementation.getResponse: collection element is no MArray." ); + Debug.leaveVerbose( "RasRNPImplementation.getResponse: done, with exception." ); + throw new RasClientInternalException("RasHttpRequest","execute()","element of MDD Collection is no MArray"); + } + if(rb.isBaseType()) + { + if(rb.isStructType()) + { + RasStructureType sType = (RasStructureType)rb; + res = new RasGMArray(new RasMInterval(domain), 0); + res.setTypeLength(rb.getSize()); + res.setArraySize(dataSize); + res.setArray(binData); + //insert into result set + resultBag.add(res); + break; + } + else + { + // It is a primitiveType + RasPrimitiveType pType = (RasPrimitiveType)rb; + switch(pType.getTypeID()) + { + case RAS_BOOLEAN: + case RAS_BYTE: + case RAS_CHAR: + res = new RasMArrayByte(new RasMInterval(domain)); + break; + case RAS_SHORT: + res = new RasMArrayShort(new RasMInterval(domain)); + break; + + case RAS_USHORT: + byte[] tmData = new byte[dataSize*2]; + for(int i=0;i<dataSize*2;) + { + tmData[i] = 0; + tmData[i+1] = 0; + tmData[i+2] = binData[i/2]; + tmData[i+3] = binData[i/2+1]; + i = i+SIZE_OF_INTEGER; + } + binData = tmData; + res = new RasMArrayInteger(new RasMInterval(domain)); + break; + + case RAS_INT: + case RAS_LONG: + res = new RasMArrayInteger(new RasMInterval(domain)); + break; + case RAS_ULONG: + byte[] tmpData = new byte[dataSize*2]; + for(int i=0;i<dataSize*2;) + { + tmpData[i] = 0; + tmpData[i+1] = 0; + tmpData[i+2] = 0; + tmpData[i+3] = 0; + tmpData[i+4] = binData[i/2]; + tmpData[i+5] = binData[i/2+1]; + tmpData[i+6] = binData[i/2+2]; + tmpData[i+7] = binData[i/2+3]; + i = i+SIZE_OF_LONG; + } + binData = tmpData; + res = new RasMArrayLong(new RasMInterval(domain)); + break; + case RAS_FLOAT: + res = new RasMArrayFloat(new RasMInterval(domain)); + break; + case RAS_DOUBLE: + res = new RasMArrayDouble(new RasMInterval(domain)); + break; + default: + res = new RasGMArray(new RasMInterval(domain), pType.getSize()); + } + res.setArray(binData); + res.setOID(roid); + resultBag.add(res); + } + } + else + { + Debug.talkCritical( "RasRNPImplementation.getResponse: type is not base type." ); + Debug.leaveVerbose( "RasRNPImplementation.getResponse: done, type is not base type." ); + throw new RasClientInternalException("RasHttpRequest","execute()","Type of MDD is no Base Type"); + } + } // for + + result = resultBag; + in.close(); + + break; + + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_SKALARS: + // read Endianess + while(in.read(b1) == 0); + endianess = b1[0]; + // read Collection Type + collType = RasUtils.readString(in); + RasType rt = new RasType(); + try + { + rt = rt.getAnyType(collType); + } + catch(Exception e) + { + Debug.talkCritical( "RasRNPImplementation.getResponse: type not supported: " + rt ); + Debug.leaveVerbose( "RasRNPImplementation.getResponse: done, unsupported type" ); + throw new RasTypeNotSupportedException(rt + " as RasCollectionType"); + } + if(rt.getTypeID()!=RasGlobalDefs.RAS_COLLECTION) + { + Debug.leaveCritical( "RasRNPImplementation.getResponse: done. type not supported: " + rt ); + throw new RasTypeNotSupportedException(rt + " as RasCollectionType"); + } + + // read NumberOfResults + while(in.available() < 4) + ; + in.read(b4); + numberOfResults = RasUtils.ubytesToInt(b4,endianess); + + // Initailize return-list + resultBag = new RasBag(); + + // do this for each result + for(int x = 0; x < numberOfResults; x++) + { + // read elementType + String elementType = RasUtils.readString(in); + RasType et = new RasType(); + et = ((RasCollectionType)rt).getElementType(); + // read size of binData + while(in.available() < 4) + ; + in.read(b4); + dataSize = RasUtils.ubytesToInt(b4,endianess); + // read binData + binData = new byte[dataSize]; + readBytes = 0; + readBytesTmp = 0; + while( (readBytesTmp != -1) && (readBytes < dataSize) ) + { + readBytesTmp = in.read(binData,readBytes,dataSize-readBytes); + readBytes += readBytesTmp; + } + + ByteArrayInputStream bis = new ByteArrayInputStream(binData); + DataInputStream dis = new DataInputStream(bis); + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + switch(et.getTypeID()) + { + case RasGlobalDefs.RAS_MINTERVAL: + resultBag.add(new RasMInterval(new String(binData))); + break; + case RasGlobalDefs.RAS_SINTERVAL: + resultBag.add(new RasSInterval(new String(binData))); + break; + case RasGlobalDefs.RAS_POINT: + resultBag.add(new RasPoint(new String(binData))); + break; + case RasGlobalDefs.RAS_OID: + resultBag.add(new RasOID(new String(binData))); + break; + case RAS_BOOLEAN: + case RAS_BYTE: + case RAS_CHAR: + byte b = binData[0]; + resultBag.add(new Byte(b)); + break; + case RAS_DOUBLE: + double d = dis.readDouble(); + resultBag.add(new Double(d)); + break; + case RAS_FLOAT: + float f = dis.readFloat(); + resultBag.add(new Float(f)); + break; + case RAS_ULONG: + byte[] bu = new byte[8]; + bu[0] = 0; + bu[1] = 0; + bu[2] = 0; + bu[3] = 0; + bu[4] = dis.readByte(); + bu[5] = dis.readByte(); + bu[6] = dis.readByte(); + bu[7] = dis.readByte(); + ByteArrayInputStream bis2 = new ByteArrayInputStream(bu); + DataInputStream dis2 = new DataInputStream(bis2); + long ul = dis2.readLong(); + resultBag.add(new Long(ul)); + break; + case RAS_LONG: + case RAS_INT: + int i = dis.readInt(); + resultBag.add(new Integer(i)); + break; + case RAS_USHORT: + int j = dis.readUnsignedShort(); + resultBag.add(new Integer(j)); + break; + case RAS_SHORT: + short s = dis.readShort(); + resultBag.add(new Short(s)); + break; + default: + Debug.talkCritical( "RasRNPImplementation.getResponse: type not supported: " + et ); + Debug.leaveVerbose( "RasRNPImplementation.getResponse: done, unsupported type." ); + throw new RasTypeNotSupportedException(et + " as ElementType "); + } + } + result = resultBag; + // close stream + in.close(); + break; + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_ERROR: + // read Endianess + while(in.read(b1) == 0); + endianess = b1[0]; + // read Error Number + while(in.available() < 4) + ; + in.read(b4); + int errNo = RasUtils.ubytesToInt(b4,endianess); + // read Line Number + while(in.available() < 4) + ; + in.read(b4); + int lineNo = RasUtils.ubytesToInt(b4,endianess); + // read Column Number + while(in.available() < 4) + ; + in.read(b4); + int colNo = RasUtils.ubytesToInt(b4,endianess); + // read token + String token = RasUtils.readString(in); + Debug.leaveCritical( "RasRNPImplementation.getResponse: query failed, errNo=" + errNo + ", lineNo=" + lineNo + ", colNo=" + colNo + ", token=" + token ); + throw new RasQueryExecutionFailedException(errNo,lineNo,colNo,token); + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_INT: + // read Integer Value + while(in.available() < 4) + ; + in.read(b4); + result = new Integer(RasUtils.ubytesToInt(b4,endianess)); + break; + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_OID: + // read Values + String sys = RasUtils.readString(in); + String base = RasUtils.readString(in); + double d = in.readDouble(); + resultBag = new RasBag(); + resultBag.add(new RasOID(sys, base, d)); + result = resultBag; + // close stream + in.close(); + break; + default: + break; + } + } + catch( IOException e ) + { + Debug.talkCritical( "RasRNPImplementation.getResponse: " + e.getMessage() ); + Debug.leaveVerbose( "RasRNPImplementation.getResponse: done, communication exception." ); + throw new RasClientInternalException("RasRNPImplementation","getResponse()",e.getMessage()); + } + catch( RasResultIsNoIntervalException e ) + { + Debug.talkCritical( "RasRNPImplementation.getResponse: " + e.getMessage() ); + Debug.leaveVerbose( "RasRNPImplementation.getResponse: done, result not an interval." ); + throw new RasClientInternalException("RasRNPImplementation","getResponse()",e.getMessage()); + } + + Debug.leaveVerbose( "RasRNPImplementation.getResponse: done. result=" + result ); + return result; + } + + public void setUserIdentification(String userName, String plainPass) + { + Debug.enterVerbose( "RasRNPImplementation.setUserIdentification: start." ); + MD5 md5 = new MD5(); + String hex; + md5.Init(); + md5.Update(plainPass); + hex = md5.asHex(); + userIdentification= userName + ":" + hex; + Debug.leaveVerbose( "RasRNPImplementation.setUserIdentification: done." ); + } + + private String strHostID = null; + static private int idcounter = 0; + + /** + generate a unique request ID using IP address, some bit mangling + is done only once, this id then is used always + **/ + private String uniqueRequestID() + { + Debug.enterVerbose( "RasRNPImplementation.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) // cannot obtain IP address? + { + Random random = new Random(); // then use other mechanism + 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( "RasRNPImplementation.uniqueRequestID: done. result=" + strHostID ); + return strHostID; + } + + } // RasRNPImplementation + +//########################################################################################## +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() + { + 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; + } + + /** Create this State as a copy of another state */ + public MD5State (MD5State from) + { + this(); + + 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]; + } + }; // MD5State + +/** + * Implementation of RSA's MD5 hash generator + * + * @version $Revision: 1.8 $ + * @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); + } + 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; + 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]; + } + } + + + 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/src/rasj/rnp/Rnp.java b/java/src/rasj/rnp/Rnp.java new file mode 100644 index 0000000..7b2c311 --- /dev/null +++ b/java/src/rasj/rnp/Rnp.java @@ -0,0 +1,54 @@ +/* +* 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.rnp; + +import java.io.*; + +public class Rnp + { + public static final int rnpProtocolId = 0xc12d7f01; // this is swap(25112001); + + public static final int fgt_None = 0; + public static final int fgt_Command = 1; + public static final int fgt_OkAnswer = 2; + public static final int fgt_Error = 3; + public static final int fgt_DiscardedRequest = 4; + + public static final int dtt_None = 0; + public static final int dtt_Asciiz = 1; + public static final int dtt_Int32 = 2; + public static final int dtt_Float32 = 3; + public static final int dtt_Double64 = 4; + public static final int dtt_Opaque = 5; + } + diff --git a/java/src/rasj/rnp/RnpBaseClientComm.java b/java/src/rasj/rnp/RnpBaseClientComm.java new file mode 100644 index 0000000..1da636f --- /dev/null +++ b/java/src/rasj/rnp/RnpBaseClientComm.java @@ -0,0 +1,207 @@ +/* +* 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.rnp; + +import rasj.*; +import rasj.global.*; +import java.io.*; +import java.net.*; + + +public class RnpBaseClientComm + { + RnpEncoder encoder; + RnpDecoder decoder; + int serverID; + String rasServerHost; + int rasServerPort; + + public RnpBaseClientComm(int serverType) + { + Debug.enterVerbose( "RnpBaseClientComm.RnpBaseClientComm: start. serverType=" + serverType ); + encoder = new RnpEncoder(); + serverID = serverType; + Debug.leaveVerbose( "RnpBaseClientComm.RnpBaseClientComm: done." ); + } + + public void setConnectionParameters(String s, int p) + { + Debug.enterVerbose( "RnpBaseClientComm.setConnectionParameters: start. server=" + s + ", port=" + p ); + rasServerHost = s; + rasServerPort = p; + Debug.leaveVerbose( "RnpBaseClientComm.setConnectionParameters: done." ); + } + + public void startRequest(int commandCode) + { + Debug.enterVerbose( "RnpBaseClientComm.startRequest: start. cmdCode=" + commandCode ); + encoder.startMessage(serverID); + encoder.startFragment(Rnp.fgt_Command,commandCode); + Debug.leaveVerbose( "RnpBaseClientComm.startRequest: done." ); + } + + public void startMessage() + { + Debug.enterVerbose( "RnpBaseClientComm.startMessage: start." ); + encoder.startMessage(serverID); + Debug.leaveVerbose( "RnpBaseClientComm.startMessage: done." ); + } + + public void startFragment(int commandCode) + { + Debug.enterVerbose( "RnpBaseClientComm.startFragment: start. cmdCode=" + commandCode ); + encoder.startFragment(Rnp.fgt_Command,commandCode); + Debug.leaveVerbose( "RnpBaseClientComm.startFragment: done." ); + } + + public void endFragment() + { + Debug.enterVerbose( "RnpBaseClientComm.endFragment: start." ); + encoder.endFragment(); + Debug.leaveVerbose( "RnpBaseClientComm.endFragment: done." ); + } + + public void endMessage() + { + Debug.enterVerbose( "RnpBaseClientComm.endMessage: start." ); + encoder.endMessage(); + Debug.leaveVerbose( "RnpBaseClientComm.endMessage: done." ); + } + + public void turboSendRequestGetAnswer() + { + Debug.enterVerbose( "RnpBaseClientComm.turboSendRequestGetAnswer: start." ); + RnpMessage answer=communicate(rasServerHost,rasServerPort,encoder.message); + decoder = new RnpDecoder(answer); + Debug.leaveVerbose( "RnpBaseClientComm.turboSendRequestGetAnswer: done." ); + } + + public void sendRequestGetAnswer() + { + Debug.enterVerbose( "RnpBaseClientComm.sendRequestGetAnswer: start." ); + + encoder.endFragment(); + encoder.endMessage(); + RnpMessage answer=communicate(rasServerHost,rasServerPort,encoder.message); + decoder = new RnpDecoder(answer); + decoder.getFirstFragment(); + + Debug.leaveVerbose( "RnpBaseClientComm.sendRequestGetAnswer: done." ); + } + + public void checkForError() throws RasQueryExecutionFailedException + { + Debug.enterVerbose( "RnpBaseClientComm.checkForError: start." ); + if(decoder.getFragmentType() != Rnp.fgt_Error) + { + Debug.leaveVerbose( "RnpBaseClientComm.checkForError: done." ); + return; + } + decoder.getFirstParameter();// error type + int errorType = decoder.getParameterType(); + if(errorType == 3) //"ert_Other" + { + decoder.getNextParameter(); + String s = decoder.getDataAsString(); + Debug.leaveCritical( "RnpBaseClientComm.checkForError: done. query failed: " + s ); + throw new RasQueryExecutionFailedException(s); + } + else + { + Debug.leaveCritical( "RnpBaseClientComm.checkForError: done. query failed, unexpected error: " + errorType ); + throw new RasQueryExecutionFailedException(1000,0,0,""); + } + // we never get here + } + + public RnpMessage communicate(String server, int port, RnpMessage message) + { + Debug.enterVerbose( "RnpBaseClientComm.communicate: start. server=" + server + ", port=" + port ); + + Socket socket=null; + RnpMessage receivedMessage= null; + DataOutputStream dos = null; + + try + { + Debug.talkVerbose( "RnpBaseClientComm.communicate: server=" + server + ", port=" + port ); + socket=new Socket(server, port); + } + catch(UnknownHostException e11) + { + Debug.leaveCritical( "RnpBaseClientComm.communicate: error: socket target unknown: " + e11.getMessage() ); + throw new RasConnectionFailedException(RasGlobalDefs.MANAGER_CONN_FAILED,server); + } + catch(IOException e12) + { + Debug.leaveCritical( "RnpBaseClientComm.communicate: error: socket io exception: " + e12.getMessage() ); + throw new RasClientInternalException("RnpBaseClientComm","communicate()",e12.getMessage()); + } + + try + { + dos = new DataOutputStream(socket.getOutputStream()); + message.write(dos); + } + catch(IOException e2) + { + Debug.leaveCritical( "RnpBaseClientComm.communicate: error: cannot write to socket: " + e2.getMessage() ); + throw new RasClientInternalException("RnpBaseClientComm","communicate()",e2.getMessage()); + } + + try + { + DataInputStream dis = new DataInputStream(socket.getInputStream()); + receivedMessage = new RnpMessage(); + receivedMessage.read(dis); + //receivedMessage.print(); + dos.close(); + dis.close(); + } + catch(IOException e3) + { + Debug.leaveCritical( "RnpBaseClientComm.communicate: error: rcv io exception: " + e3.getMessage() ); + throw new RasClientInternalException("RnpBaseClientComm","communicate()", e3.getMessage() ); + } + catch(RnpException e4) + { + Debug.leaveCritical( "RnpBaseClientComm.communicate: error: RnpException: " + e4.getMessage() ); + throw new RasClientInternalException("RnpBaseClientComm","communicate()",e4.getMessage()); + } + + Debug.leaveVerbose( "RnpBaseClientComm.communicate: done. result=" + receivedMessage ); + return receivedMessage; + } + + } // RnpBaseClientComm + diff --git a/java/src/rasj/rnp/RnpDecoder.java b/java/src/rasj/rnp/RnpDecoder.java new file mode 100644 index 0000000..5eea077 --- /dev/null +++ b/java/src/rasj/rnp/RnpDecoder.java @@ -0,0 +1,170 @@ +/* +* 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.rnp; + +import java.io.*; + + +public class RnpDecoder + { + + public RnpMessage message; + private RnpFragment currentFragment; + private RnpParameter currentParameter; + private int fragmentIndex; + + + RnpDecoder(RnpMessage rnpmessage) + { + message=rnpmessage; + currentFragment = null; + currentParameter = null; + fragmentIndex = 0; + } + + void verify() throws RnpException + { + if(message.header.protocolId != Rnp.rnpProtocolId) + throw new RnpException("Not a RNP message"); + + if(message.header.messageEndianness != 0) + throw new RnpException("Incorrect endianness"); + + if(message.header.majorVersion != 1 || message.header.minorVersion != 0 || message.header.dataStart != RnpMessageHeader.length) + throw new RnpException("Incorrect message version"); + } + + int getServerType() + { + return message.header.serverType; + } + + byte getDesiredEndianness() + { + return message.header.desiredEndianness; + } + + byte getMessageEndianness() + { + return message.header.messageEndianness; + } + + int getMessageLength() + { + return message.header.totalMessageLength; + } + + int countFragments() + { + return message.header.nrFragments; + } + byte getMajorVersion() + { + return message.header.majorVersion; + } + byte getMinorVersion() + { + return message.header.minorVersion; + } + + RnpFragment getFirstFragment() + { + fragmentIndex = 0; + currentFragment = (RnpFragment)message.fragments.get(0); + return currentFragment; + } + + RnpFragment getNextFragment(RnpFragment fragment) + { + fragmentIndex++; + currentFragment = (RnpFragment)message.fragments.get(fragmentIndex); + return currentFragment; + } + + int getFragmentType() + { + //fgt_None, fgt_Command, fgt_OkAnswer, fgt_Error, fgt_DiscardedRequest + return currentFragment.getFragmentType(); + } + int countParameters() + { + return currentFragment.countParameters(); + } + RnpParameter getFirstParameter() + { + currentParameter = currentFragment.getFirstParameter(); + return currentParameter; + } + RnpParameter getNextParameter() + { + currentParameter = currentFragment.getNextParameter(); + return currentParameter; + } + int getParameterType() + { + return currentParameter.paramType; + } + int getDataLength() + { + return currentParameter.getDataLength(); + } + + int getDataType() + { + // dtt_None,dtt_Asciiz, dtt_Int32,dtt_Double64, dtt_Opaque + return currentParameter.dataType; + } + + int getDataAsInteger() + { + return ((ParameterInt32)currentParameter).data; + } + float getDataAsFloat() + { + return((ParameterFloat32)currentParameter).data; + } + double getDataAsDouble() + { + return((ParameterDouble64)currentParameter).data; + } + String getDataAsString() + { + return new String(((ParameterString)currentParameter).data); + } + byte[] getDataOpaque() + { + return((ParameterOpaque)currentParameter).data; + } + } + diff --git a/java/src/rasj/rnp/RnpEncoder.java b/java/src/rasj/rnp/RnpEncoder.java new file mode 100644 index 0000000..d27bfe2 --- /dev/null +++ b/java/src/rasj/rnp/RnpEncoder.java @@ -0,0 +1,102 @@ +/* +* 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.rnp; + +import java.io.*; +import java.util.*; + +public class RnpEncoder + { + public int serverType = 0; + RnpMessage message = null; + + public void startMessage(int serverType) + { + message=new RnpMessage(); + message.header = new RnpMessageHeader(serverType); + message.fragments = new Vector(); + } + public void setEndianess() + { + } + public void startFragment(int fragmentType, int command) + { + message.currentFragment = new RnpFragment(fragmentType,command); + } + void addFragment(RnpFragmentHeader fHeader) + { + message.header.nrFragments++; + message.header.dataLength += fHeader.totalLength; + message.header.totalMessageLength += fHeader.totalLength; + } + + void addParameterInt32(int parameterType, int data) + { + message.currentFragment.addParameterInt32(parameterType,data); + } + + void addParameterFloat32(int parameterType, float data) + { + message.currentFragment.addParameterFloat32(parameterType,data); + } + + void addParameterDouble64(int parameterType, double data) + { + message.currentFragment.addParameterDouble64(parameterType,data); + } + + void addParameterString(int parameterType, String data) + { + message.currentFragment.addParameterString(parameterType,data); + } + + void addParameterOpaque(int parameterType, byte[] data) + { + message.currentFragment.addParameterOpaque(parameterType,data); + } + + void endFragment() + { + if(message.currentFragment == null) return; // correct "assert" + message.fragments.add(message.currentFragment); + addFragment(message.currentFragment.getHeader()); + message.currentFragment = null; + } + + void endMessage() + { + } + + } + diff --git a/java/src/rasj/rnp/RnpException.java b/java/src/rasj/rnp/RnpException.java new file mode 100644 index 0000000..254c304 --- /dev/null +++ b/java/src/rasj/rnp/RnpException.java @@ -0,0 +1,44 @@ +/* +* 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.rnp; + + +public class RnpException extends Exception + { + public RnpException(String s) + { + super(s); + } + } + diff --git a/java/src/rasj/rnp/RnpFragment.java b/java/src/rasj/rnp/RnpFragment.java new file mode 100644 index 0000000..204744f --- /dev/null +++ b/java/src/rasj/rnp/RnpFragment.java @@ -0,0 +1,152 @@ +/* +* 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.rnp; + +import java.util.*; +import java.io.*; + + +public class RnpFragment + { + RnpFragmentHeader header; + Vector parameters; + int parameterIndex = 0; + + RnpFragment(int fragmentType, int command) + { + header = new RnpFragmentHeader(fragmentType, command); + parameters = new Vector(); + } + + RnpFragmentHeader getHeader() + { + return header; + } + + void addParameterInt32(int parameterType, int data) + { + addParameter(new ParameterInt32(parameterType,data)); + } + + void addParameterFloat32(int parameterType, float data) + { + addParameter(new ParameterFloat32(parameterType,data)); + } + + void addParameterDouble64(int parameterType, double data) + { + addParameter(new ParameterDouble64(parameterType,data)); + } + void addParameterString(int parameterType, String data) + { + addParameter(new ParameterString(parameterType,data)); + } + + void addParameterOpaque(int parameterType, byte[] data) + { + addParameter(new ParameterOpaque(parameterType,data)); + } + + private void addParameter(RnpParameter param) + { + parameters.add(param); + header.addParameter(param.getTotalLength()); + } + + void write(DataOutputStream dataStream) throws IOException + { + header.write(dataStream); + for(int i=0; i < header.countParameters(); i++) + { + RnpParameter param = (RnpParameter)parameters.get(i); + param.write(dataStream); + } + } + + void read(DataInputStream dataStream) throws IOException, RnpException + { + header.read(dataStream); + for(int i=0; i < header.countParameters(); i++) + { + RnpParameter param = RnpParameter.constructFromStream(dataStream); + parameters.add(param); + } + } + + void print() + { + header.print(); + for(int i=0; i < header.countParameters(); i++) + { + System.out.print(" " + i+ " "); + RnpParameter param = (RnpParameter)parameters.get(i); + param.print(); + } + } + + + int getFragmentType() + { + return header.fragmType; + } + + int getCommand() + { + return header.command; + } + + int countParameters() + { + return header.nrParams; + } + + int getFragmentLength() + { + return header.totalLength; + } + + RnpParameter getFirstParameter() + { + parameterIndex = 0; + return (RnpParameter)parameters.get(0); + } + + RnpParameter getNextParameter() + { + parameterIndex++; + return (RnpParameter)parameters.get(parameterIndex); + } + + } + diff --git a/java/src/rasj/rnp/RnpFragmentHeader.java b/java/src/rasj/rnp/RnpFragmentHeader.java new file mode 100644 index 0000000..e18e0f4 --- /dev/null +++ b/java/src/rasj/rnp/RnpFragmentHeader.java @@ -0,0 +1,93 @@ +/* +* 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.rnp; + +import java.util.*; +import java.io.*; + + +public class RnpFragmentHeader + { + int fragmType; //{FragmentType command, okAnswer, error} + int command; + int nrParams; + int totalLength; + + public static final int length = 16; + + RnpFragmentHeader(int fragmentType, int nCommand) + { + fragmType = fragmentType; + command = nCommand; + nrParams = 0; + totalLength = length; + } + + int countParameters() + { + return nrParams; + } + + void print() + { + System.out.print(" type=" + fragmType); + System.out.print(" Command=" + command); + System.out.print(" nrParams=" + nrParams); + System.out.print(" totalLength=" + totalLength); + System.out.println(); + } + + void write(DataOutputStream dataStream) throws IOException + { + dataStream.writeInt(fragmType); + dataStream.writeInt(command); + dataStream.writeInt(nrParams); + dataStream.writeInt(totalLength); + } + void read(DataInputStream dataStream) throws IOException + { + fragmType = dataStream.readInt(); + command = dataStream.readInt(); + nrParams = dataStream.readInt(); + totalLength = dataStream.readInt(); + } + + void addParameter(int size) + { + nrParams++; + totalLength += size; + } + } + + diff --git a/java/src/rasj/rnp/RnpMessage.java b/java/src/rasj/rnp/RnpMessage.java new file mode 100644 index 0000000..5739ee7 --- /dev/null +++ b/java/src/rasj/rnp/RnpMessage.java @@ -0,0 +1,83 @@ +/* +* 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.rnp; + + +import java.util.*; +import java.io.*; + + +public class RnpMessage + { + public RnpMessageHeader header; + public Vector fragments; + public RnpFragment currentFragment = null; + + void write(DataOutputStream dataStream) throws IOException + { + header.write(dataStream); + for(int i=0; i < header.countFragments(); i++) + { + RnpFragment frag = (RnpFragment)fragments.get(i); + frag.write(dataStream); + } + } + + void read(DataInputStream dataStream) throws IOException, RnpException + { + header = new RnpMessageHeader(0); + header.read(dataStream); + fragments = new Vector(); + for(int i=0; i < header.countFragments(); i++) + { + currentFragment = new RnpFragment(0,0); + currentFragment.read(dataStream); + fragments.add(currentFragment); + } + currentFragment = null; + } + + void print() + { + header.print(); + for(int i=0; i < header.countFragments(); i++) + { + System.out.print("Fragment " + i + " "); + RnpFragment frag = (RnpFragment)fragments.get(i); + frag.print(); + } + } + + } + diff --git a/java/src/rasj/rnp/RnpMessageHeader.java b/java/src/rasj/rnp/RnpMessageHeader.java new file mode 100644 index 0000000..5191940 --- /dev/null +++ b/java/src/rasj/rnp/RnpMessageHeader.java @@ -0,0 +1,150 @@ +/* +* 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.rnp; + + +import java.util.*; +import java.io.*; + + +public class RnpMessageHeader + { + int protocolId; + byte messageEndianness; + byte desiredEndianness; + byte majorVersion; + byte minorVersion; + int totalMessageLength; + int nrFragments; + int serverType; + int authInfoStart; + int authInfoLength; + int comprInfoStart; + int comprInfoLength; + int dataStart; + int dataLength; + //int _unused[5]; + + public static final int length = 64; + + RnpMessageHeader(int nServerType) + { + protocolId = Rnp.rnpProtocolId; + messageEndianness = 0; // big endianness + desiredEndianness = 0; // big also + majorVersion = 1; + minorVersion = 0; + totalMessageLength = length; + nrFragments = 0; + serverType = nServerType; + authInfoStart = 0; + authInfoLength = 0; + comprInfoStart = 0; + comprInfoLength = 0; + dataStart = length; + dataLength = 0; + } + + int countFragments() + { + return nrFragments; + } + + void print() + { + System.out.println("RNP Header"); + System.out.println(" totalLength=" + totalMessageLength); + System.out.println(" nrFragments=" + nrFragments); + System.out.println(" serverType=" + serverType); + System.out.println(" dataStart=" + dataStart); + System.out.println(" dataLength=" + dataLength); + System.out.println(""); + } + + void write(DataOutputStream dataStream) throws IOException + { + dataStream.writeInt(protocolId); + dataStream.writeByte(messageEndianness); + dataStream.writeByte(desiredEndianness); + dataStream.writeByte(majorVersion); + dataStream.writeByte(minorVersion); + + dataStream.writeInt(totalMessageLength); + dataStream.writeInt(nrFragments); + dataStream.writeInt(serverType); + dataStream.writeInt(authInfoStart); + dataStream.writeInt(authInfoLength); + dataStream.writeInt(comprInfoStart); + dataStream.writeInt(comprInfoLength); + dataStream.writeInt(dataStart); + dataStream.writeInt(dataLength); + + // the unused 5 ints + dataStream.writeInt(0); + dataStream.writeInt(0); + dataStream.writeInt(0); + dataStream.writeInt(0); + dataStream.writeInt(0); + + } + + void read(DataInputStream dataStream) throws IOException, RnpException + { + protocolId = dataStream.readInt(); + messageEndianness = dataStream.readByte(); + desiredEndianness = dataStream.readByte(); + majorVersion = dataStream.readByte(); + minorVersion = dataStream.readByte(); + + totalMessageLength = dataStream.readInt(); + nrFragments = dataStream.readInt(); + serverType = dataStream.readInt(); + authInfoStart = dataStream.readInt(); + authInfoLength = dataStream.readInt(); + comprInfoStart = dataStream.readInt(); + comprInfoLength = dataStream.readInt(); + dataStart = dataStream.readInt(); + dataLength = dataStream.readInt(); + + // the unused 5 ints + dataStream.readInt(); + dataStream.readInt(); + dataStream.readInt(); + dataStream.readInt(); + dataStream.readInt(); + + //verify(); + } + } + diff --git a/java/src/rasj/rnp/RnpParameter.java b/java/src/rasj/rnp/RnpParameter.java new file mode 100644 index 0000000..01cba64 --- /dev/null +++ b/java/src/rasj/rnp/RnpParameter.java @@ -0,0 +1,325 @@ +/* +* 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.rnp; + +import java.io.*; + +public abstract class RnpParameter + { + int paramType; + int dataType; + int dataLength; + int totalLength; + + public static final int headerSize = 16; + + protected RnpParameter(int pT, int dT, int dL,int tL) + { + paramType = pT; + dataType = dT; + dataLength = dL; + totalLength = tL; + } + + void print() + { + System.out.print(" Parameter type=" + paramType); + System.out.print(" data type=" + dataType); + System.out.print(" dataLength="+dataLength); + System.out.print(" totalLength=" + totalLength); + printSpecific(); + } + + void write(DataOutputStream dataStream) throws IOException + { + dataStream.writeInt(paramType); + dataStream.writeInt(dataType); + dataStream.writeInt(dataLength); + dataStream.writeInt(totalLength); + writeSpecific(dataStream); + } + + int getTotalLength() + { + return totalLength; + } + int getDataLength() + { + return dataLength; + } + int getPaddLength() + { + return totalLength - dataLength - headerSize; + } + + void computeTotalAlignedLength() + { + totalLength = (dataLength + headerSize + 3) & 0xFFFFFFFC; + } + + static RnpParameter constructFromStream(DataInputStream dataStream) throws IOException, RnpException + { + int paramType = dataStream.readInt(); + int dataType = dataStream.readInt(); + int dataLength = dataStream.readInt(); + int totalLength = dataStream.readInt(); + + RnpParameter result = null; + switch(dataType) + { + case Rnp.dtt_Int32: result = new ParameterInt32(paramType, dataType, dataLength, totalLength); + break; + case Rnp.dtt_Float32: result = new ParameterFloat32(paramType, dataType, dataLength, totalLength); + break; + case Rnp.dtt_Double64: result = new ParameterDouble64(paramType, dataType, dataLength, totalLength); + break; + case Rnp.dtt_Asciiz: result = new ParameterString(paramType, dataType, dataLength, totalLength); + break; + case Rnp.dtt_Opaque: result = new ParameterOpaque(paramType, dataType, dataLength, totalLength); + break; + default: throw new RnpException("Incorrect parameter data type: " + dataType); + } + result.readSpecific(dataStream); + //System.out.println("constructFromStream: "); result.print(); + return result; + } + + int getParameterType() { return paramType; } + int getDataType() { return dataType; } + + abstract void writeSpecific(DataOutputStream dataStream) throws IOException; + abstract void readSpecific(DataInputStream dataStream) throws IOException; + abstract void printSpecific(); + } + + + + class ParameterInt32 extends RnpParameter + { + int data; + public static final int length = 4; + + ParameterInt32(int parameterType, int nData) + { + super(parameterType,Rnp.dtt_Int32, length, length + headerSize); + data = nData; + } + + ParameterInt32(int pT, int dT, int dL, int tL) + { + super(pT, dT, dL,tL); + } + + void printSpecific() + { + System.out.println(" value=" + data); + } + + void writeSpecific(DataOutputStream dataStream) throws IOException + { + dataStream.writeInt(data); + } + + void readSpecific(DataInputStream dataStream) throws IOException + { + data = dataStream.readInt(); + } + + int getData() + { + return data; + } + } + + + class ParameterFloat32 extends RnpParameter + { + float data; + public static final int length = 4; + + ParameterFloat32(int parameterType, float nData) + { + super(parameterType,Rnp.dtt_Float32, length, length + headerSize); + data = nData; + } + + ParameterFloat32(int pT, int dT, int dL, int tL) + { + super(pT, dT, dL,tL); + } + + void printSpecific() + { + System.out.println(" value=" + data); + } + + void writeSpecific(DataOutputStream dataStream) throws IOException + { + dataStream.writeFloat(data); + } + + void readSpecific(DataInputStream dataStream) throws IOException + { + data = dataStream.readFloat(); + } + + float getData() + { + return data; + } + } + + + class ParameterDouble64 extends RnpParameter + { + double data; + public static final int length = 8; + + ParameterDouble64(int parameterType, double nData) + { + super(parameterType,Rnp.dtt_Double64, length, length + headerSize); + data = nData; + } + ParameterDouble64(int pT, int dT, int dL, int tL) + { + super(pT, dT, dL, tL); + } + + void printSpecific() + { + System.out.println(" value=" + data); + } + + void writeSpecific(DataOutputStream dataStream) throws IOException + { + dataStream.writeDouble(data); + } + + void readSpecific(DataInputStream dataStream) throws IOException + { + data = dataStream.readDouble(); + } + + double getData() + { + return data; + } + } + + class ParameterString extends RnpParameter + { + byte[] data; + + ParameterString(int parameterType, String nData) + { + super(parameterType,Rnp.dtt_Asciiz,0,0); + data = nData.getBytes(); + // do not forget: Strings are ASCIIZ in RNP!! + dataLength = data.length+1; + computeTotalAlignedLength(); + } + + ParameterString(int pT, int dT, int dL,int tL) + { + super(pT, dT, dL,tL); + } + + void printSpecific() + { + System.out.println(" value=" + getData()); + } + + void writeSpecific(DataOutputStream dataStream) throws IOException + { + dataStream.write(data,0,dataLength - 1); + dataStream.writeByte(0); + + for(int i=0;i<getPaddLength();i++) dataStream.writeByte(0); + } + + void readSpecific(DataInputStream dataStream) throws IOException + { + data = new byte[dataLength - 1]; + dataStream.readFully(data,0,dataLength - 1); + dataStream.readByte(); + for(int i=0;i<getPaddLength();i++) dataStream.readByte(); + } + + String getData() + { + return new String(data); + } + } + + class ParameterOpaque extends RnpParameter + { + byte[] data; + + ParameterOpaque(int parameterType, byte[] nData) + { + super(parameterType,Rnp.dtt_Opaque,nData.length,0); + data = nData; + computeTotalAlignedLength(); + } + + ParameterOpaque(int pT, int dT, int dL,int tL) + { + super(pT, dT, dL,tL); + } + + void printSpecific() + { + System.out.println(" value=(opaque data, size=" + data.length +")"); + } + + void writeSpecific(DataOutputStream dataStream) throws IOException + { + dataStream.write(data,0,dataLength); + for(int i=0;i<getPaddLength();i++) dataStream.writeByte(0); + } + + void readSpecific(DataInputStream dataStream) throws IOException + { + data = new byte[dataLength]; + dataStream.readFully(data,0,dataLength); + + for(int i=0;i<getPaddLength();i++) dataStream.readByte(); + } + + byte[] getData() + { + return data; + } + } + diff --git a/java/src/rasj/rnp/test/Client.java b/java/src/rasj/rnp/test/Client.java new file mode 100644 index 0000000..34c9c45 --- /dev/null +++ b/java/src/rasj/rnp/test/Client.java @@ -0,0 +1,104 @@ +/* +* 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: + * test socket communication. + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +import java.io.*; +import java.net.*; +import java.lang.*; +import java.util.*; + +public class Client +{ + private static final String DEFAULT_SERVER = "localhost"; + private static final int DEFAULT_PORT = 7001; + + private static String server = DEFAULT_SERVER; + private static int port = DEFAULT_PORT; + + private static void communicate() + { + System.out.println( "server=" + server + ", port=" + port ); + + try + { + Socket socket = new Socket( server, port ); + + PrintStream ps = new PrintStream(socket.getOutputStream()); + ps.print("Hello " + server + " at port " + port + " !\n" ); + ps.flush(); + + BufferedReader ds = new BufferedReader(new InputStreamReader(socket.getInputStream())); + System.out.println( "server delivered: '" + ds.readLine() ); + + ps.close(); + ds.close(); + socket.close(); + System.out.println( "socket closed." ); + } + catch(UnknownHostException e2) + { + System.out.println( "host unknown: " + e2.getMessage() ); + } + catch(IOException e1) + { + System.out.println( "io exception: " + e1.getMessage() ); + } + } + + public static void main( String args[] ) + { + System.out.println( "Socket test started." ); + + if (args.length != 0 && args.length != 2) + System.out.println( "usage: java Client [server port]" ); + else if (args.length == 2) + { + server = args[0]; + try + { + port = Integer.parseInt( args[1] ); + } + catch(NumberFormatException e) + { + System.err.println( "Error: illegal port parameter: " + args[1] ); + return; + } + } + + communicate(); + + System.out.println( "Socket test done." ); + } +} + + diff --git a/java/src/rasj/test/Makefile b/java/src/rasj/test/Makefile new file mode 100644 index 0000000..2538fb1 --- /dev/null +++ b/java/src/rasj/test/Makefile @@ -0,0 +1,116 @@ +# -*-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 +# +# COMMENTS: +# - incomplete! +# - not part of systemtest: TestHttp.java +# - test env settings to be taken from next higher Makefile when ready +# - move .log manually to .log.orig if you want to set this as new reference output +################################################################## +######################### Definitions ############################ + +# standard include with general options +include $(RMANBASE)/Makefile.inc + +SRCS = TestRasPoint.java TestRasInterval.java TestMArray.java \ + TestException.java TestDbTa.java TestOdmg.java TestQuery.java \ + MassLoadTest.java + +OBJS = ${SRCS:%.java=%.class} + +# test programs (java needs them without .class suffix) +TESTS = TestRasPoint TestRasInterval TestDbTa TestException +# TESTS = ${OBJS:%.class=%} + +MISCCLEAN = *.class *.log + +# FIXME: should make use of general variable +JAVA = java +# Java options needed for testing +JAVAOPTS = -cp .:$(CLASSPATH) + +# directory where HTML documentation is created +DOCDIR := $(DOCBASE)/java/rasj/test + +########################### Targets ############################## + +# compile everything +.PHONY : all +all: $(OBJS) + +# run the test for all classes, compare log generated with archived log, abort on first error +.PHONY: systemtest +systemtest: $(TESTS) + +# later this should be of that structure: +# $(JAVA) $(JAVAOPTS) $@ > $@.log && diff $@.log.orig $@.log + +TestRasPoint: TestRasPoint.class + $(JAVA) $(JAVAOPTS) $@ + +TestRasInterval: TestRasInterval.class + $(JAVA) $(JAVAOPTS) $@ + +TestMArray: TestMArray.class + $(JAVA) $(JAVAOPTS) $@ --server NONE_YET --database RASBASE --collname NONEXISTENT + +MassLoadTest: MassLoadTest.class + $(JAVA) $(JAVAOPTS) $@ --server $(SERVER) --port $(PORT) --database $(DATABASE) --user $(USER) --passwd $(PASSWD) + +TestException: TestException.class + $(JAVA) $(JAVAOPTS) $@ --server $(SERVER) --port $(PORT) --database $(DATABASE) --user $(USER) --passwd $(PASSWD) + +TestDbTa: TestDbTa.class + $(JAVA) $(JAVAOPTS) $@ --server $(SERVER) --port $(PORT) --database $(DATABASE) --user $(USER) --passwd $(PASSWD) + +TestOdmg: TestOdmg.class + $(JAVA) $(JAVAOPTS) $@ --server $(SERVER) --port $(PORT) --database $(DATABASE) --user $(USER) --passwd $(PASSWD) + +TestQuery: TestQuery.class + $(JAVA) $(JAVAOPTS) $@ + +# not part of systemtest: TestHttp.java + +# create javadoc HTML doc: +.PHONY: docu +docu: $(SRCS) + -mkdir -p $(DOCDIR_RASJTEST) + $(JAVADOC) -private -author -d $(DOCDIR_RASJTEST) -sourcepath . *.java + +# remove all that can be generated +clean: + -rm -f $(MISCCLEAN) + -rm -rf $(DOCDIR) + +# delete all files +empty: + -rm -f $(SRCS) $(MISCCLEAN) + +############################ Dependencies ####################### + +# general rules +include $(RMANBASE)/Makefile.rel diff --git a/java/src/rasj/test/Makefile.dep b/java/src/rasj/test/Makefile.dep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/java/src/rasj/test/Makefile.dep diff --git a/java/src/rasj/test/MassLoadTest.java b/java/src/rasj/test/MassLoadTest.java new file mode 100644 index 0000000..6ec4fbe --- /dev/null +++ b/java/src/rasj/test/MassLoadTest.java @@ -0,0 +1,324 @@ +/* +* 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>. +*/ +package rasj.test; + +import rasj.*; +import rasj.global.*; +import org.odmg.*; + +import java.util.*; +import java.io.*; + + +public class MassLoadTest implements RasGlobalDefs +{ + + public static void main(String[] args) + { + + String hostname = null; + String port = null; + Database mydb = null; + Transaction myta = null; + RasGMArray myMDD = null; + Implementation myApp = null; + OQLQuery myQuery = null; + String collectionName = "testCollection"; + int tileSize = 1000; + int overallSize = 200000; + int commitInterval = 50; + + + /******************************************* + * * + * Usage: MassLoadTest hostname [port] * + * * + *******************************************/ + + // we need the hostname + if(args.length>0 && args[0] == null) + { + System.out.println("Please provide the hostname as a parameter when calling this test-program."); + System.exit(-1); + } + else + hostname = args[0]; + + // is there a port specified? + if(args.length>1 && args[1] != null) + port = args[1]; + else + port = "8080"; + + try { + myApp = new RasImplementation("http://" + hostname + ":" + port); + mydb = myApp.newDatabase(); + System.err.println("Open Database ..."); + mydb.open("RASBASE",Database.OPEN_READ_WRITE); + System.err.println(" ok."); + myta = myApp.newTransaction(); + System.err.println("Begin transaction ..."); + myta.begin(); + System.err.println(" ok."); + + //create test collection + System.err.println("Create a test collection ..."); + myQuery = myApp.newOQLQuery(); + myQuery.create("create collection $1 GreySet"); + //myQuery.create("drop collection $1"); + + myQuery.bind(collectionName); + myQuery.execute(); + System.err.println(" ok."); + myta.commit(); + + // init insertion tile + System.err.println("create test arrays ..."); + myMDD = new RasGMArray(new RasMInterval("[0:" + (tileSize-1) + ",0:" + (tileSize-1) + "]"),1); + int cells = tileSize*tileSize; + byte[] mydata = new byte[cells]; + for(int i = 0; i < cells; i++) + mydata[i]=0; + myMDD.setArray(mydata); + myMDD.setObjectTypeName("GreyImage"); + + // now insert tiles + boolean first = true; + myta.begin(); + int dimX = 0; + int dimY = 0; + String domain = null; + int finished = 1; + + int counter = (int)Math.abs(overallSize/tileSize); + for(int x = 0; x < counter; x++) + { + dimX += tileSize; + dimY = 0; + for(int y = 0; y < counter; y++) + { + dimY += tileSize; + + // init mdd + RasGMArray myMDD2 = new RasGMArray(new RasMInterval("[" + String.valueOf(dimX-tileSize) + ":" + String.valueOf(dimX-1) + "," + + String.valueOf(dimY-tileSize) + ":" + String.valueOf(dimY-1) + "]"),1); + cells = tileSize*tileSize; + byte[] mydata2 = new byte[cells]; + for(int i = 0; i < cells; i++) + mydata2[i]=0; + myMDD2.setArray(mydata2); + myMDD2.setObjectTypeName("GreyImage"); + + // prepare query + myQuery = myApp.newOQLQuery(); + if(first) + { + myQuery.create("insert into $1 values $2"); + first = false; + } + else + myQuery.create("update $1 AS img SET img ASSIGN $2"); + myQuery.bind(collectionName); + myQuery.bind(myMDD2); + + // execute query + System.err.println("Inserting tile " + myMDD2.spatialDomain()); + myQuery.execute(); + finished += 1; + + // commit? + if(finished == commitInterval) + { + myta.commit(); + System.err.println("... committed, begin new transaction ..."); + myta = myApp.newTransaction(); + myta.begin(); + finished = 1; + } + + } + // now write the rest of y if there is something left: + if(dimY < overallSize-1) + { + RasGMArray myMDD3 = new RasGMArray(new RasMInterval("[" + String.valueOf(dimX-tileSize) + ":" + String.valueOf(dimX-1) + "," + + String.valueOf(dimY) + ":" + String.valueOf(overallSize-1) + "]"),1); + cells = tileSize*(overallSize-dimY); + byte[] mydata3 = new byte[cells]; + for(int i = 0; i < cells; i++) + mydata3[i]=0; + myMDD3.setArray(mydata3); + myMDD3.setObjectTypeName("GreyImage"); + + // prepare query + myQuery = myApp.newOQLQuery(); + if(first) + { + myQuery.create("insert into $1 values $2"); + first = false; + } + else + myQuery.create("update $1 AS img SET img ASSIGN $2"); + myQuery.bind(collectionName); + myQuery.bind(myMDD3); + + // execute query + System.err.println("Inserting tile " + myMDD3.spatialDomain()); + myQuery.execute(); + finished += 1; + + // commit? + if(finished == commitInterval) + { + myta.commit(); + System.err.println("... committed, begin new transaction ..."); + myta = myApp.newTransaction(); + myta.begin(); + finished = 1; + } + } + } + + // now write the rest of x if there is something left + dimY = 0; + if(dimX < overallSize-1) + { + for(int y = 0; y < counter; y++) + { + dimY += tileSize; + + // init mdd + RasGMArray myMDD4 = new RasGMArray(new RasMInterval("[" + String.valueOf(dimX) + ":" + String.valueOf(overallSize-1) + "," + + String.valueOf(dimY-tileSize) + ":" + String.valueOf(dimY-1) + "]"),1); + cells = (overallSize-dimX)*tileSize; + byte[] mydata4 = new byte[cells]; + for(int i = 0; i < cells; i++) + mydata4[i]=0; + myMDD4.setArray(mydata4); + myMDD4.setObjectTypeName("GreyImage"); + + // prepare query + myQuery = myApp.newOQLQuery(); + if(first) + { + myQuery.create("insert into $1 values $2"); + first = false; + } + else + myQuery.create("update $1 AS img SET img ASSIGN $2"); + myQuery.bind(collectionName); + myQuery.bind(myMDD4); + + // execute query + System.err.println("Inserting tile " + myMDD4.spatialDomain()); + myQuery.execute(); + finished += 1; + + // commit? + if(finished == commitInterval) + { + myta.commit(); + System.err.println("... committed, begin new transaction ..."); + myta = myApp.newTransaction(); + myta.begin(); + finished = 1; + } + } + + // now write the rest of y if available + if(dimY < overallSize-1) + { + RasGMArray myMDD5 = new RasGMArray(new RasMInterval("[" + String.valueOf(dimX) + ":" + String.valueOf(overallSize-1) + "," + + String.valueOf(dimY) + ":" + String.valueOf(overallSize-1) + "]"),1); + cells = (overallSize-dimX)*(overallSize-dimY); + byte[] mydata5 = new byte[cells]; + for(int i = 0; i < cells; i++) + mydata5[i]=0; + myMDD5.setArray(mydata5); + myMDD5.setObjectTypeName("GreyImage"); + + // prepare query + myQuery = myApp.newOQLQuery(); + if(first) + { + myQuery.create("insert into $1 values $2"); + first = false; + } + else + myQuery.create("update $1 AS img SET img ASSIGN $2"); + myQuery.bind(collectionName); + myQuery.bind(myMDD5); + + // execute query + System.err.println("Inserting tile " + myMDD5.spatialDomain()); + myQuery.execute(); + finished += 1; + } + } + + // READY! + myta.commit(); + System.err.println("FINISHED!"); + + + // drop test collection + myta = myApp.newTransaction(); + myta.begin(); + System.err.println("Drop test collection ..."); + myQuery = myApp.newOQLQuery(); + myQuery.create("drop collection $1"); + myQuery.bind(collectionName); + myQuery.execute(); + System.err.println(" ok."); + myta.commit(); + myta = myApp.newTransaction(); + myta.commit(); + + + + } + + catch ( Exception e ) { + System.out.println("ERROR: "); + System.out.println(e.getMessage()); + + if(myta.isOpen()) + { + System.err.println("Abort transaction ..."); + myta.abort(); + } + System.err.println("Close database ..."); + try { + mydb.close(); + System.err.println(" ok."); + } + catch ( Exception e2 ) { + } + System.err.println("Exiting..."); + System.exit(-1); + } + } + +} + + + diff --git a/java/src/rasj/test/Systemtest_rasj.java b/java/src/rasj/test/Systemtest_rasj.java new file mode 100644 index 0000000..50c33c5 --- /dev/null +++ b/java/src/rasj/test/Systemtest_rasj.java @@ -0,0 +1,295 @@ +package rasj.test; + +/* +* 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> + *********************************************************** */ + +import java.io.*; + +import rasj.*; +import rasj.global.*; +import org.odmg.*; + + +// auxiliary classes for exception testing +class TestRasResultIsNoCellException extends RasResultIsNoCellException +{ + TestRasResultIsNoCellException() + { + super(); + } +} + +class TestRasResultIsNoIntervalException extends RasResultIsNoIntervalException +{ + TestRasResultIsNoIntervalException() + { + super(); + } +} + +class TestRasClientInternalException extends RasClientInternalException +{ + TestRasClientInternalException(String msg) + { + super("Systemtest_rasj","TestExceptions",msg); + } +} + +// main program +/** + * class for testing rasj interface + * @version $$ + */ +public class Systemtest_rasj +{ + +public static void main(String[] args) + { + String server = null; + String port = "7001"; + boolean wrongUsage = false; + + // get args + if(args.length == 0) + wrongUsage = true; + for(int i = 0; i < args.length; i+=2) + { + if (args[i].equals("-server")) + server = args[i+1]; + else if (args[i].equals("-port")) + port = args[i+1]; + else + wrongUsage = true; + } + + if(wrongUsage) + { + System.err.println("Usage: Systemtest_rasj -s <servername> [ -p <port> ]"); + System.exit(-1); + } + + // start + Implementation myApp = new RasImplementation("http://" + server + ":" + port); + + testExceptions(myApp); + + testMArrays marrayTest = new testMArrays(server); + + testIntervals intervalTest = new testIntervals(); + + } + + // exception testing + static void testExceptions(Implementation imp) + { + + boolean resultIsOk = false; + Database myDb = null; + Transaction myTa = null; + OQLQuery myQu = null; + + System.err.println("\n### Testing exceptions:"); + + // RasConnectionFailedException + Implementation errorApp; + String logMsg; + try { + errorApp = new RasImplementation("wrongserver:8080"); + myDb = errorApp.newDatabase(); + logMsg = "Exception was not thrown"; + myDb.open("RASBASE",Database.OPEN_READ_WRITE); + } + catch(RasConnectionFailedException e1) { + resultIsOk = true; + logMsg = e1.getMessage(); + } + catch(ODMGException e2) { + logMsg = e2.getMessage(); + } + log("RasConnectionFailedException",resultIsOk,logMsg); + + // RasDimensionMismatchException + resultIsOk = false; + logMsg = "Exception was not thrown"; + try { + RasMInterval test1; + RasMInterval test2 = new RasMInterval("[1:20,1:20]"); + RasMInterval test3 = new RasMInterval("[1:4,1:9,1:6]"); + + test1 = test2.intersectionWith(test3); + } + catch(RasDimensionMismatchException e1) { + resultIsOk = true; + logMsg = e1.getMessage(); + } + catch(Exception e2) { + logMsg = e2.getClass().getName() + ", " + e2.getMessage(); + } + log("RasDimensionMismatchException",resultIsOk,logMsg); + + // RasIndexOutOfBoundsException + resultIsOk = false; + logMsg = "Exception was not thrown"; + try { + RasGMArray myMDD = new RasGMArray(new RasMInterval("[1:5,1:5]"),1); + byte[] retVal = myMDD.getCell(new RasPoint(4,7)); + } + catch(RasIndexOutOfBoundsException e1) { + resultIsOk = true; + logMsg = e1.getMessage(); + } + catch(RasResultIsNoIntervalException e2) { + //this cannot occur + } + catch(RasDimensionMismatchException e3) { + // this cannot occur + } + log("RasIndexOutOfBoundsException",resultIsOk,logMsg); + + // RasClientInternalException + resultIsOk = false; + logMsg = "Exception was not thrown"; + try { + throw new TestRasClientInternalException("This is a test error"); + } + catch(RasClientInternalException e1) { + resultIsOk = true; + logMsg = e1.getMessage(); + } + log("RasClientInternalException",resultIsOk,logMsg); + + // RasResultIsNoCellException + resultIsOk = false; + logMsg = "Exception was not thrown"; + try { + throw new TestRasResultIsNoCellException(); + } + catch(RasResultIsNoCellException e1) { + resultIsOk = true; + logMsg = e1.getMessage(); + } + log("RasResultIsNoCellException",resultIsOk,logMsg); + + // RasResultIsNoIntervalException + resultIsOk = false; + logMsg = "Exception was not thrown"; + try { + throw new TestRasResultIsNoIntervalException(); + } + catch(RasResultIsNoIntervalException e1) { + resultIsOk = true; + logMsg = e1.getMessage(); + } + log("RasResultIsNoIntervalException",resultIsOk,logMsg); + + // RasStreamInputOverflowException + resultIsOk = false; + logMsg = "Exception was not thrown"; + try { + RasMInterval int1 = new RasMInterval(2); + int1.stream(new RasSInterval("1:10")); + int1.stream(new RasSInterval("1:5")); + int1.stream(new RasSInterval("1:20")); + } + catch(RasResultIsNoIntervalException e1) { + // + } + catch(RasStreamInputOverflowException e3) { + resultIsOk = true; + logMsg = e3.getMessage(); + } + log("RasStreamInputOverflowException",resultIsOk,logMsg); + + + // RasTypeInvalidException + resultIsOk = false; + logMsg = "Exception was not thrown"; + try { + RasPrimitiveType myType = new RasPrimitiveType("myType",RasGlobalDefs.RAS_BOOLEAN); + myType.getFloat(new Object()); + } + catch(RasTypeInvalidException e3) { + resultIsOk = true; + logMsg = e3.getMessage(); + } + log("RasTypeInvalidException",resultIsOk,logMsg); + + // RasTypeNotSupportedException + resultIsOk = false; + logMsg = "Exception was not thrown"; + try { + throw new RasTypeNotSupportedException("RAS_TEST"); + } + catch(RasTypeNotSupportedException e3) { + resultIsOk = true; + logMsg = e3.getMessage(); + } + log("RasTypeNotSupportedException",resultIsOk,logMsg); + } + + + + + + static void log(String testObject, boolean resultOK, String message) + { + if(resultOK) + System.err.println(testObject + " ... OK\n (" + message + ")"); + else + { + System.err.println(testObject + " ... FAILED!\n (" + message + ")"); + System.err.println("Continue? [y/n]"); + BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); + try { + String answer = br.readLine(); + while(answer != "") + { + if(answer.equals("n")) + System.exit(1); + else if(!answer.equals("y")) + { + System.err.println("Please answer y or n: "); + answer = br.readLine(); + } + } + } + catch(IOException e1) { + // + } + + } + } + + +} diff --git a/java/src/rasj/test/TestDbTa.java b/java/src/rasj/test/TestDbTa.java new file mode 100644 index 0000000..846e337 --- /dev/null +++ b/java/src/rasj/test/TestDbTa.java @@ -0,0 +1,549 @@ +/* +* 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: + * test rasj ODMG-level interface (database, TA, and basic query logic). + * TO BE DONE! + * + * PREREQUISITES: + * - Must have a database with at least one HTTP server running. + * - database must know basic types, in particular: GreySet. + * - login must allow read/write access to database + * + * + * COMMENTS: + * - testing philosophy is to run all tests and report. no exit code / exception + * is used for error indication; look into the output for ERROR_TAG instead. + * - unexpected exceptions are not caught, hence will make gmake fail and show the error + * - every test that fails must print a line containing ERROR_TAG + * </pre> + *********************************************************** */ + +import java.lang.Integer; +import org.odmg.*; +import rasj.*; +import rasj.odmg.*; + +public class TestDbTa + { + /** + * prefixes for test output + **/ + static final String PREFIX_PROGRAM = "+++ +++ +++ "; + static final String PREFIX_TESTSET = "+++ +++ "; + static final String PREFIX_TESTCASE = "+++ "; + + /** + * std error tag printed if a test fails + **/ + static final String ERROR_TAG = "ERROR: "; + + /** + * default values (override with cmd line option) + **/ + static final String DEFAULT_HOST = "localhost"; + static final int DEFAULT_PORT = 7001; + static final String DEFAULT_BASE = "RASBASE"; + static final String DEFAULT_USER = "rasguest"; + static final String DEFAULT_PASSWD = "rasguest"; + + /** + * global ODMG implementation object for use by all methods + **/ + static RasImplementation myApp = null; + + /** + * main program for testing + * on error, an exception is thrown (java main() knows no exit status) + **/ + public static void main(String argv[]) throws Exception + { + String serv = DEFAULT_HOST; + int port = DEFAULT_PORT; + String base = DEFAULT_BASE; + String user = DEFAULT_USER; + String passwd = DEFAULT_PASSWD; + boolean wrongUsage = false; // error in cmd line params? + + for (int i=argv.length-1; i>=0; i--) + { + if (argv[i].equals("--server")) + serv = argv[i+1]; + else if (argv[i].equals("--port")) + { + try + { + port = Integer.parseInt(argv[i+1]); + } + catch(Exception e) + { + wrongUsage = true; + } + } + else if (argv[i].equals("--database")) + base = argv[i+1]; + else if (argv[i].equals("--user")) + user = argv[i+1]; + else if (argv[i].equals("--passwd")) + passwd = argv[i+1]; + } + + if (wrongUsage) + { + System.out.println( "Usage: TestDbTa [--server s] [--port p] [--database d] [--user u] [--passwd p]" ); + System.out.println( "defaults: server=" + DEFAULT_HOST + ", port=" + DEFAULT_PORT + ", database=" + DEFAULT_BASE + ", user=" + DEFAULT_USER + ", passwd=" + DEFAULT_PASSWD ); + System.exit(-1); + } + + System.out.println( "rasdaman system test v5.1revC: testing class ODMG logic." ); + System.out.println( PREFIX_PROGRAM + "system test started, using server " + serv + ", port " + port + ", database " + base + ", user=" + user + ", passwd=" + passwd ); + + myApp = new RasImplementation( "http://" + serv + ":" + port ); + myApp.setUserIdentification(user, passwd); + + // -- START test cases ------------------------------------------------- + testDatabase( myApp, base ); + testTransaction( myApp, base ); + testAccessMode( myApp, base ); + // -- END test cases --------------------------------------------------- + + System.out.println( PREFIX_PROGRAM + "system test done." ); + return; + } // main() + + /** + * test database open/close + * any eventual exception that is not caught here is an error, and will cause an abort + **/ + static void testDatabase( RasImplementation myApp, String database ) + // throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + Database myDb = null; + System.out.println( PREFIX_TESTSET + "testing database open/close started." ); + + System.out.print( PREFIX_TESTCASE + "open db, null name..." ); + try + { + myDb = myApp.newDatabase(); + myDb.open( null, Database.OPEN_READ_ONLY ); + System.out.println( ERROR_TAG + "does not catch this." ); + } + catch(Exception e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + // FIXME: PB6: inappropriate error message + System.out.print( PREFIX_TESTCASE + "open db, empty name..." ); + try + { + myDb = myApp.newDatabase(); + myDb.open( "", Database.OPEN_READ_ONLY ); + System.out.println( ERROR_TAG + "does not catch this." ); + } + catch(Exception e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "open db, nonexisting db..." ); + try + { + myDb = myApp.newDatabase(); + myDb.open( "NO_SUCH_DATABASE", Database.OPEN_READ_ONLY ); + System.out.println( ERROR_TAG + "does not catch this." ); + } + catch(Exception e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + // FIXME: PB6: inappropriate error message + // System.out.print( PREFIX_TESTCASE + "open db, negative accessMode value..." ); + // try + // { + // myDb = myApp.newDatabase(); + // myDb.open( database, -1 ); + // System.out.println( ERROR_TAG + "does not catch this." ); + // } + // catch(Exception e) + // { + // System.out.println( "OK, recognized: " + e.getMessage() ); + // } + + // FIXME: PB6: inappropriate error message + // System.out.print( PREFIX_TESTCASE + "open db, illegal accessMode..." ); + // try + // { + // myDb = myApp.newDatabase(); + // myDb.open( "NO_SUCH_DATABASE", 100 ); + // System.out.println( ERROR_TAG + "does not catch this." ); + // } + // catch(Exception e) + // { + // System.out.println( "OK, recognized: " + e.getMessage() ); + // } + + System.out.print( PREFIX_TESTCASE + "open db, good call..." ); + try + { + myDb = myApp.newDatabase(); + myDb.open( database, Database.OPEN_READ_ONLY ); + Transaction myTa = myApp.newTransaction(); + myTa.begin(); + myTa.abort(); + System.out.println( "OK, tested through beginTA." ); + } + catch(Exception e) + { + System.out.println( ERROR_TAG + "good call does not open db: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "close previously opened db..." ); + try + { + myDb.close(); + System.out.println( "OK." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "can we open a transaction after closing db..." ); + try + { + Transaction myTa = myApp.newTransaction(); + myTa.begin(); + System.out.println( ERROR_TAG + "unfortunately yes." ); + } + catch(Exception e) + { + System.out.println( "OK, we can't." ); + } + + System.out.print( PREFIX_TESTCASE + "close db already closed..." ); + try + { + myDb.close(); + System.out.println( ERROR_TAG + "repeated close possible, alas." ); + } + catch (Exception e) + { + System.out.println( "OK." ); + } + + System.out.println( PREFIX_TESTSET + "testing database open/close done.\n" ); + return; + } // testDatabase() + + /** + * test transaction open/close + * any eventual exception that is not caught here is an error, and will cause an abort + **/ + static void testTransaction( RasImplementation myApp, String database ) throws ODMGException + { + Database myDb = null; + Transaction myTa = null; + System.out.println( PREFIX_TESTSET + "testing transaction start." ); + + System.out.print( PREFIX_TESTCASE + "isOpen on open DB, closed TA..." ); + try + { + myDb = myApp.newDatabase(); + myDb.open( database, Database.OPEN_READ_ONLY ); + myTa = myApp.newTransaction(); + if ( myTa.isOpen() ) + System.out.println( ERROR_TAG + "TA open on closed DB." ); + else + System.out.println( "OK, is not open." ); + } + catch (Exception e) + { + System.out.println( "OK: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "isOpen on open DB/TA..." ); + try + { + myTa.begin(); + if ( myTa.isOpen() ) + System.out.println( "OK, is open." ); + else + System.out.println( ERROR_TAG + "TA not open after opening." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "sending query to check open TA..." ); + try + { + OQLQuery myQu = myApp.newOQLQuery(); + myQu.create( "select r from RAS_COLLECTIONNAMES as r" ); + DBag result = (DBag) myQu.execute(); + if ( result == null ) + System.out.println( ERROR_TAG + "standard query failed." ); + else + System.out.println( "OK, query done." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "open TA on an already open TA..." ); + try + { + myTa.begin(); + if ( myTa.isOpen() ) + System.out.println( "OK, should remain open." ); + else + System.out.println( ERROR_TAG + "TA not open after 2nd opening." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "abort TA..." ); + try + { + myTa.abort(); + if ( myTa.isOpen() ) + System.out.println( ERROR_TAG + "TA open after abort." ); + else + System.out.println( "OK, is not open." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "query on aborted TA..." ); + try + { + OQLQuery myQu = myApp.newOQLQuery(); + myQu.create( "select r from RAS_COLLECTIONNAMES as r" ); + DBag result = (DBag) myQu.execute(); + if ( result == null ) + System.out.println( "OK, standard query failed." ); + else + System.out.println( ERROR_TAG + "query got through." ); + } + catch (Exception e) + { + System.out.println( "OK, failed: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "abort TA on aborted TA..." ); + try + { + myTa.abort(); + if ( myTa.isOpen() ) + System.out.println( ERROR_TAG + "TA open after abort." ); + else + System.out.println( "OK, is not open." ); + } + catch (Exception e) + { + System.out.println( "OK, noticed: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "open new TA, send query..." ); + try + { + myTa.begin(); + if ( ! myTa.isOpen() ) + System.out.println( ERROR_TAG + "TA not open." ); + else + { + OQLQuery myQu = myApp.newOQLQuery(); + myQu.create( "select r from RAS_COLLECTIONNAMES as r" ); + DBag result = (DBag) myQu.execute(); + if ( result == null ) + System.out.println( ERROR_TAG + "standard query failed." ); + else + System.out.println( "OK." ); + } + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "commit TA..." ); + try + { + myTa.commit(); + if ( myTa.isOpen() ) + System.out.println( "OK, closed now. " ); + else + System.out.println( ERROR_TAG + "TA still open. " ); + OQLQuery myQu = myApp.newOQLQuery(); + myQu.create( "select r from RAS_COLLECTIONNAMES as r" ); + DBag result = (DBag) myQu.execute(); + if ( result == null ) + System.out.println( "OK, query failed." ); + else + System.out.println( ERROR_TAG + "query got through." ); + } + catch (TransactionNotInProgressException e) + { + System.out.println( "...OK, query failed: " + e.getMessage() ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.println( PREFIX_TESTSET + "testing transaction done.\n" ); + return; + } // testTransaction() + + /** + * test access modes + * any eventual exception that is not caught here is an error, and will cause an abort + **/ + static void testAccessMode( RasImplementation myApp, String database ) + // throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + Database myDb = null; + Transaction myTa = null; + System.out.println( PREFIX_TESTSET + "testing accessMode start." ); + + System.out.print( PREFIX_TESTCASE + "open readonly, read query..." ); + try + { + myDb = myApp.newDatabase(); + myDb.open( database, Database.OPEN_READ_ONLY ); + myTa = myApp.newTransaction(); + myTa.begin(); + + OQLQuery myQu = myApp.newOQLQuery(); + myQu.create( "select r from RAS_COLLECTIONNAMES as r" ); + DBag result = (DBag) myQu.execute(); + if ( result == null ) + System.out.println( ERROR_TAG + "query failed." ); + else + System.out.println( "OK, query got through." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "open readonly, update query (create collection)..." ); + try + { + myDb = myApp.newDatabase(); + myDb.open( database, Database.OPEN_READ_ONLY ); + myTa = myApp.newTransaction(); + myTa.begin(); + + OQLQuery myQu = myApp.newOQLQuery(); + myQu.create( "create collection TestDbTa_collection GreySet" ); + DBag result = (DBag) myQu.execute(); + } + catch (DatabaseIsReadOnlyException e) + { + System.out.println( "OK, update failed." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "commit TA, close DB..." ); + try + { + myTa.commit(); + myDb.close(); + System.out.println( "OK." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "open DB readwrite, open TA, read query..." ); + try + { + myDb.open( database, Database.OPEN_READ_WRITE ); + myTa = myApp.newTransaction(); + myTa.begin(); + + OQLQuery myQu = myApp.newOQLQuery(); + myQu.create( "select r from RAS_COLLECTIONNAMES as r" ); + DBag result = (DBag) myQu.execute(); + if ( result == null ) + System.out.println( ERROR_TAG + "query failed." ); + else + System.out.println( "OK, query got through." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "update query (create & drop collection)..." ); + try + { + OQLQuery myQu = myApp.newOQLQuery(); + myQu.create( "create collection TestDbTa_collection GreySet" ); + DBag result = (DBag) myQu.execute(); + + // we want to see that a commit really preserves changes: + System.out.print( "re-opening TA..." ); + myTa.commit(); + myTa.begin(); + + myQu.create( "drop collection TestDbTa_collection" ); + result = (DBag) myQu.execute(); + System.out.println( "OK, query got through." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "commit TA, close DB..." ); + try + { + myTa.commit(); + myDb.close(); + System.out.println( "OK." ); + } + catch (Exception e) + { + System.out.println( ERROR_TAG + e.getMessage() ); + } + + System.out.println( PREFIX_TESTSET + "testing accessMode done.\n" ); + return; + } // testAccessMode() + + } // TestDbTa diff --git a/java/src/rasj/test/TestException.java b/java/src/rasj/test/TestException.java new file mode 100644 index 0000000..9cfe894 --- /dev/null +++ b/java/src/rasj/test/TestException.java @@ -0,0 +1,361 @@ +/* +* 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: + * exception testing (was: Systemtest_rasj). + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +import java.io.*; + +import rasj.*; +import rasj.global.*; +import org.odmg.*; + + +// auxiliary classes for exception testing +class TestRasResultIsNoCellException extends RasResultIsNoCellException + { + TestRasResultIsNoCellException() + { + super(); + } + } + +class TestRasResultIsNoIntervalException extends RasResultIsNoIntervalException + { + TestRasResultIsNoIntervalException() + { + super(); + } + } + +class TestRasClientInternalException extends RasClientInternalException + { + TestRasClientInternalException(String msg) + { + super("TestException","TestExceptions",msg); + } + } + +/** + * class for testing rasj interface + * @version $$ + */ +public class TestException + { + /** + * prefixes for test output + **/ + static final String PREFIX_PROGRAM = "+++ +++ +++ "; + static final String PREFIX_TESTSET = "+++ +++ "; + static final String PREFIX_TESTCASE = "+++ "; + + /** + * std error tag printed if a test fails + **/ + static final String ERROR_TAG = "ERROR: "; + + /** + * default values (override with cmd line option) + **/ + static final String DEFAULT_HOST = "localhost"; + static final int DEFAULT_PORT = 7001; + static final String DEFAULT_BASE = "RASBASE"; + static final String DEFAULT_USER = "rasguest"; + static final String DEFAULT_PASSWD = "rasguest"; + + // main program + public static void main(String[] args) throws Exception + { + String server = DEFAULT_HOST; + int port = DEFAULT_PORT; + String base = DEFAULT_BASE; + String user = DEFAULT_USER; + String passwd = DEFAULT_PASSWD; + boolean wrongUsage = false; + + // get args + if(args.length == 0) + wrongUsage = true; + for(int i = 0; i < args.length; i+=2) + { + if (args[i].equals("--server")) + server = args[i+1]; + else if (args[i].equals("--port")) + { + try + { + port = Integer.parseInt(args[i+1]); + } + catch(Exception e) + { + wrongUsage = true; + } + } + else if (args[i].equals("--database")) + base = args[i+1]; + else if (args[i].equals("--user")) + user = args[i+1]; + else if (args[i].equals("--passwd")) + passwd = args[i+1]; + } + + if(wrongUsage) + { + System.err.println("Usage: TestException [--server s] [--port p] [--database d]"); + System.out.println( "defaults: server=" + DEFAULT_HOST + ", port=" + DEFAULT_PORT + ", database=" + DEFAULT_BASE ++ ", user=" + DEFAULT_USER + ", passwd=" + DEFAULT_PASSWD ); + System.exit(-1); + } + + + + System.out.println( "rasdaman system test v5.1revC: testing exceptions." ); + System.out.println( PREFIX_PROGRAM + "system test started, using server " + server + ", port " + port + ", database " + base + ", user=" + user + ", passwd=" + passwd ); + + // Implementation myApp = new RasImplementation("http://" + server + ":" + port); + RasImplementation myApp = new RasImplementation( "http://" + server + ":" + port ); + myApp.setUserIdentification(user, passwd); + + // -- START test cases ------------------------------------------------- + testExceptions( myApp, base ); + // -- END test cases --------------------------------------------------- + + System.out.println( PREFIX_PROGRAM + "system test done." ); + return; + } // main() + + /** + * test exceptions + * any eventual exception that is not caught here is an error, and will cause an abort + **/ + static void testExceptions( RasImplementation imp, String database ) throws Exception + { + boolean resultIsOk = false; + Database myDb = null; + Transaction myTa = null; + OQLQuery myQu = null; + + System.out.println( PREFIX_TESTSET + "testing exceptions started." ); + + System.out.print( PREFIX_TESTCASE + "provoking RasConnectionFailedException..." ); + RasImplementation errorApp; + String logMsg; + try + { + errorApp = new RasImplementation("wrongserver:8080"); + myDb = errorApp.newDatabase(); + myDb.open( database, Database.OPEN_READ_WRITE ); + System.out.println( ERROR_TAG + "does not catch this." ); + myDb.close(); + } + catch(RasConnectionFailedException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasDimensionMismatchException..." ); + try + { + RasMInterval test1; + RasMInterval test2 = new RasMInterval("[1:20,1:20]"); + RasMInterval test3 = new RasMInterval("[1:4,1:9,1:6]"); + test1 = test2.intersectionWith(test3); + System.out.println( ERROR_TAG + "does not catch this." ); + } + catch(RasDimensionMismatchException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasIndexOutOfBoundsException..." ); + try + { + RasGMArray myMDD = new RasGMArray(new RasMInterval("[1:5,1:5]"),1); + byte[] retVal = myMDD.getCell(new RasPoint(4,7)); + System.out.println( ERROR_TAG + "does not catch this." ); + } + catch(RasIndexOutOfBoundsException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasClientInternalException (via subclassed e.)..." ); + try + { + throw new TestRasClientInternalException("This is a test error"); + } + catch(RasClientInternalException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasResultIsNoCellException (via subclassed e.)..." ); + try + { + throw new TestRasResultIsNoCellException(); + } + catch(RasResultIsNoCellException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasResultIsNoIntervalException (via subclassed e.)..." ); + try + { + throw new TestRasResultIsNoIntervalException(); + } + catch(RasResultIsNoIntervalException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasStreamInputOverflowException..." ); + try + { + RasMInterval int1 = new RasMInterval(2); + int1.stream(new RasSInterval("1:10")); + int1.stream(new RasSInterval("1:5")); + int1.stream(new RasSInterval("1:20")); + System.out.println( ERROR_TAG + "does not catch this." ); + } + catch(RasStreamInputOverflowException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasTypeInvalidException..." ); + try + { + RasPrimitiveType myType = new RasPrimitiveType("myPrivateType",RasGlobalDefs.RAS_BOOLEAN); + myType.getFloat(new Object()); + System.out.println( ERROR_TAG + "does not catch this." ); + } + catch(RasTypeInvalidException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasTypeNotSupportedException..." ); + try + { + throw new RasTypeNotSupportedException("test"); + } + catch(RasTypeNotSupportedException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasIllegalULongValueException (faked)..." ); + try + { + throw new RasIllegalULongValueException( 42 ); + } + catch(RasIllegalULongValueException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasIllegalUShortValueException (faked)..." ); + try + { + throw new RasIllegalUShortValueException( 42 ); + } + catch(RasIllegalUShortValueException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasInvalidNameException (illegal chars in obj type name)..." ); + try + { + RasGMArray myMDD = new RasGMArray(new RasMInterval("[1:400,1:400]"),1); + myMDD.setObjectTypeName("_!_$_%_&_ _"); + System.out.println( ERROR_TAG + "does not catch this." ); + } + catch(RasInvalidNameException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + // FIXME: PB9 + System.out.print( PREFIX_TESTCASE + "provoking RasInvalidNameException (name too long)..." ); + try + { + RasGMArray myMDD = new RasGMArray(new RasMInterval("[1:400,1:400]"),1); + myMDD.setObjectTypeName("loooongname__1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_" ); + System.out.println( ERROR_TAG + "does not catch this." ); + } + catch(RasInvalidNameException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "provoking RasQueryExecutionFailedException..." ); + try + { + // Database myDb2 = imp.newDatabase(); + // myDb2.open( database, Database.OPEN_READ_ONLY ); + // Transaction myTa2 = imp.newTransaction(); + // myTa2.begin(); + + // OQLQuery myQu2 = imp.newOQLQuery(); + // myQu2.create( "select r r from RAS_COLLECTIONNAMES as r" ); + // DBag result = (DBag) myQu2.execute(); + + // myTa2.abort(); + // myDb2.close(); + System.out.print( "this is meant for a severe internal problem which I cannot provoke; will fake..." ); + throw new RasQueryExecutionFailedException( 1, 2, 3, "(fake)" ); + } + catch(RasQueryExecutionFailedException e) + { + System.out.println( "OK, recognized: " + e.getMessage() ); + } + + // protected exception in rasj, not accessible + // System.out.print( PREFIX_TESTCASE + "provoking RasTypeUnknownException..." ); + // try + // { + // // RasGMArray myMDD = new RasGMArray(new RasMInterval("[1:400,1:400]"),1); + // // myMDD.setObjectTypeName( "charrrrr" ); + // System.out.print( "superseded by RasTypeNotSupportedException - cannot catch it; will fake..." ); + // throw new RasTypeUnknownException("test"); + // } + // catch(RasTypeUnknownException e) + // { + // System.out.println( "OK, recognized: " + e.getMessage() ); + // } + + System.out.println( PREFIX_TESTSET + "testing exceptions done." ); + return; + } // testExceptions() + + } // TestException diff --git a/java/src/rasj/test/TestHttp.java b/java/src/rasj/test/TestHttp.java new file mode 100644 index 0000000..c446104 --- /dev/null +++ b/java/src/rasj/test/TestHttp.java @@ -0,0 +1,642 @@ +/* +* 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: + * - not part of the standard systemtest, because it does not use std + * interface but copies internal ras/clientcomm code + * </pre> + *********************************************************** */ + +import rasj.*; +import rasj.odmg.*; +import org.odmg.*; +import rasj.global.*; + +import java.io.*; +import java.util.*; + +import java.lang.*; +import java.net.*; +import rasj.clientcommhttp.*; + +/** + * This class handles a HTTP-request to the RasDaMan server. + * The specified RasDaMan server is contacted, the specified command is sent to + * the server, and the result of the query is retrieved and stored in a byte array. + * The specification of the communication protocol is given below. + * <P> + * + * @version $Revision: 1.1 $ + */ + +public class TestHttp implements RasCommDefs, RasGlobalDefs +{ + + static final String rcsid = "@(#)Package rasj.test, class TestHttp: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/test/TestHttp.java,v 1.1 2003/12/19 16:05:43 rasdev Exp $"; + + +/** + * The type of this client + */ + private String client = "RASCLIENT"; + +/** + * The result type ( MDD Collection, Skalar Collection, Error, Integer ). This field is set + * automatically when a query has been executed, so there's no setResultType method. + */ + private static byte resultType = 0; + +/** + * The result of the query +**/ + private static Object result = null; + + +/** + * This method sends a query to the RasDaMan Server and retrieves the results. + * + * @param con server connection + * @param parameters the parameters for the request as name/value pairs (for example "clientID=4354351&queryString=select img from test") + */ + public static void execute( String serverURL, String parameters ) + throws RasQueryExecutionFailedException, RasConnectionFailedException + { + System.out.println( "RasHttpRequest.execute: start. parameters=" + parameters ); + + BenchmarkTimer httpTimer = new BenchmarkTimer("httpRequest direct"); + BenchmarkTimer rcvTimer = new BenchmarkTimer("receive direct"); + + try + { + URL url = new URL( serverURL ); + + System.out.println( "RasHttpRequest.execute: sending to " + url + " POST request=" + parameters ); + + httpTimer.startTimer(); + + BenchmarkTimer sendTimer = new BenchmarkTimer("send direct"); + sendTimer.startTimer(); + + // Send the query + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestProperty("Content-type","application/octet-stream"); + con.setRequestProperty("User-Agent","RasDaMan Java Client"); + con.setRequestProperty("Version","1.0"); + con.setRequestMethod("POST"); + con.setDoInput(true); + con.setDoOutput(true); + con.setUseCaches(false); + + OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(),"8859_1"); + out.write(parameters,0,parameters.length()); + out.flush(); + out.close(); + + sendTimer.stopTimer(); + sendTimer.print(); + + rcvTimer.startTimer(); + + // Read response + BenchmarkTimer getInputTimer = new BenchmarkTimer("getInputStream direct"); + getInputTimer.startTimer(); + DataInputStream in = new DataInputStream(con.getInputStream()); + System.out.println("RasHttpRequest.execute: received " + in ); + getInputTimer.stopTimer(); + getInputTimer.print(); + + // read binData + // binData = new byte[dataSize]; + // readBytes = 0; + // readBytesTmp = 0; + // while( (readBytesTmp != -1) && (readBytes < dataSize) ) + // { + // readBytesTmp = in.read(binData,readBytes,dataSize-readBytes); + // readBytes += readBytesTmp; + // System.out.println("Read " + readBytesTmp +" Bytes:" + binData); + // } + // in.close(); + // con.disconnect(); + + /* variables for later use */ + byte[] b1 = new byte[1]; + byte[] b4 = new byte[4]; + byte endianess = 0; + String collType = null; + int numberOfResults = 0; + int dataSize = 0; + byte[] binData = null; + int readBytes = 0; + int readBytesTmp = 0; + DBag resultBag; + RasGMArray res = null; + + in.read(b1); + + resultType = b1[0]; + Debug.talkVerbose("RasHttpRequest.execute: resultType=" + resultType ); + switch( resultType ) + { + case RESPONSE_OK: + case RESPONSE_OK_NEGATIVE: + //Nothing todo + break; + + // +++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_MDDS: + Debug.talkVerbose("RasHttpRequest.execute: result type is MDD." ); + // read Endianess + while(in.read(b1) == 0) + ; + endianess = b1[0]; + + // read Collection Type + collType = RasUtils.readString(in); + Debug.talkVerbose("RasHttpRequest.execute: colltype=" + collType); + + // read NumberOfResults + while(in.available() < 4) + ; + in.read(b4); + numberOfResults = RasUtils.ubytesToInt(b4,endianess); + Debug.talkVerbose("RasHttpRequest.execute: number of results: " + numberOfResults); + + // Initialize return-set and parameters + resultBag = new RasBag(); + String mddBaseType = null; + String domain = null; + String oid = ""; + RasOID roid = null; + + // do this for each result + for(int x = 0; x < numberOfResults; x++) + { + Debug.talkVerbose("RasHttpRequest.execute: handling result #" + (x+1) ); + //read mddBaseType + mddBaseType = RasUtils.readString(in); + + // read spatialDomain + domain = RasUtils.readString(in); + + // read OID + oid = RasUtils.readString(in); + //System.err.println("OID is " + oid); + roid = new RasOID(oid); + + // read size of binData + while(in.available() < 4) + ; + in.read(b4); + + dataSize = RasUtils.ubytesToInt(b4,endianess); + + Debug.talkVerbose("RasHttpRequest.execute: mddBaseType is " + mddBaseType + ", spatialDomain=" + domain + ", size of BinData=" + dataSize ); + + // read binData + binData = new byte[dataSize]; + readBytes = 0; + readBytesTmp = 0; + + while( (readBytesTmp != -1) && (readBytes < dataSize) ) + { + readBytesTmp = in.read(binData,readBytes,dataSize-readBytes); + readBytes += readBytesTmp; + } + + Debug.talkVerbose("RasHttpRequest.execute: read " + readBytes + " bytes."); + + RasType rType = RasType.getAnyType(mddBaseType); + //System.out.println(rType); + RasBaseType rb = null; + + if(rType.getClass().getName().equals("rasj.RasMArrayType")) + { + RasMArrayType tmp = (RasMArrayType)rType; + rb = tmp.getBaseType(); + } + else + { + Debug.talkCritical("RasHttpRequest.execute: exception: element of MDD Collection is no MArray" ); + throw new RasClientInternalException("RasHttpRequest","execute()","element of MDD Collection is no MArray"); + } + + if(rb.isBaseType()) + { + if(rb.isStructType()) + { + // It is a structType + //System.err.println("It is a structType"); + RasStructureType sType = (RasStructureType)rb; + //System.out.println(sType); + res = new RasGMArray(new RasMInterval(domain), 0); + res.setTypeLength(rb.getSize()); + res.setArraySize(dataSize); + res.setArray(binData); + //insert into result set + resultBag.add(res); + break; + + } else + { + // It is a primitiveType + RasPrimitiveType pType = (RasPrimitiveType)rb; + + //System.err.println("It's a primitive type: " + pType); + switch(pType.getTypeID()) + { + case RAS_BOOLEAN: + case RAS_BYTE: + case RAS_CHAR: + //System.err.println("It's a byte array!"); + res = new RasMArrayByte(new RasMInterval(domain)); + break; + case RAS_SHORT: + //System.err.println("It's a short array!"); + res = new RasMArrayShort(new RasMInterval(domain)); + break; + + case RAS_USHORT: + //System.err.println("It's a ushort array!"); + byte[] tmData = new byte[dataSize*2]; + for(int i=0;i<dataSize*2;) + { + tmData[i] = 0; + tmData[i+1] = 0; + tmData[i+2] = binData[i/2]; + tmData[i+3] = binData[i/2+1]; + i = i+SIZE_OF_INTEGER; + } + binData = tmData; + res = new RasMArrayInteger(new RasMInterval(domain)); + break; + + case RAS_INT: + case RAS_LONG: + //System.err.println("It's a integer array!"); + res = new RasMArrayInteger(new RasMInterval(domain)); + break; + case RAS_ULONG: + //System.err.println("It's a ulong array!"); + byte[] tmpData = new byte[dataSize*2]; + for(int i=0;i<dataSize*2;) + { + tmpData[i] = 0; + tmpData[i+1] = 0; + tmpData[i+2] = 0; + tmpData[i+3] = 0; + tmpData[i+4] = binData[i/2]; + tmpData[i+5] = binData[i/2+1]; + tmpData[i+6] = binData[i/2+2]; + tmpData[i+7] = binData[i/2+3]; + i = i+SIZE_OF_LONG; + } + binData = tmpData; + res = new RasMArrayLong(new RasMInterval(domain)); + break; + case RAS_FLOAT: + //System.err.println("It's a float array!"); + res = new RasMArrayFloat(new RasMInterval(domain)); + break; + case RAS_DOUBLE: + //System.err.println("It's a double array!"); + res = new RasMArrayDouble(new RasMInterval(domain)); + break; + default: + //System.err.println("It's a GMArray!"); + res = new RasGMArray(new RasMInterval(domain), pType.getSize()); + //throw new RasTypeNotSupportedException(pType.getName()); + } + // set array data + res.setArray(binData); + // set oid + res.setOID(roid); + //insert into result set + resultBag.add(res); + } + + } + else throw new RasClientInternalException("RasHttpRequest","execute()","Type of MDD is no Base Type"); + } + + result = resultBag; + + // close stream + in.close(); + + break; + + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_SKALARS: + //System.err.println("Skalar = 2"); + // read Endianess + while(in.read(b1) == 0); + endianess = b1[0]; + + // read Collection Type + collType = RasUtils.readString(in); + RasType rt = new RasType(); + try + { + rt = rt.getAnyType(collType); + //System.err.println("Colltype is " + rt); + } + catch(Exception e) + { + throw new RasTypeNotSupportedException(rt + " as RasCollectionType"); + } + if(rt.getTypeID()!=RasGlobalDefs.RAS_COLLECTION) + throw new RasTypeNotSupportedException(rt + " as RasCollectionType"); + + // read NumberOfResults + while(in.available() < 4); + in.read(b4); + numberOfResults = RasUtils.ubytesToInt(b4,endianess); + //System.err.println("Number of results: " + numberOfResults); + + // Initailize return-list + resultBag = new RasBag(); + + // do this for each result + for(int x = 0; x < numberOfResults; x++) + { + // read elementType + String elementType = RasUtils.readString(in); + RasType et = new RasType(); + et = ((RasCollectionType)rt).getElementType(); + //System.err.println("ElementType is " + et); + + // read size of binData + while(in.available() < 4); + in.read(b4); + dataSize = RasUtils.ubytesToInt(b4,endianess); + //System.err.print("Size of BinData: "); + //System.err.println(dataSize); + + // read binData + binData = new byte[dataSize]; + readBytes = 0; + readBytesTmp = 0; + while( (readBytesTmp != -1) && (readBytes < dataSize) ) + { + readBytesTmp = in.read(binData,readBytes,dataSize-readBytes); + readBytes += readBytesTmp; + /* + System.err.println("Read " + readBytesTmp +" Bytes (" + + readBytes + " Bytes overall)"); + */ + } + + ByteArrayInputStream bis = new ByteArrayInputStream(binData); + DataInputStream dis = new DataInputStream(bis); + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + switch(et.getTypeID()) + { + case RasGlobalDefs.RAS_MINTERVAL: + resultBag.add(new RasMInterval(new String(binData))); + break; + case RasGlobalDefs.RAS_SINTERVAL: + resultBag.add(new RasSInterval(new String(binData))); + break; + case RasGlobalDefs.RAS_POINT: + resultBag.add(new RasPoint(new String(binData))); + break; + case RasGlobalDefs.RAS_OID: + resultBag.add(new RasOID(new String(binData))); + break; + case RAS_BOOLEAN: + case RAS_BYTE: + case RAS_CHAR: + byte b = binData[0]; + resultBag.add(new Byte(b)); + break; + case RAS_DOUBLE: + double d = dis.readDouble(); + resultBag.add(new Double(d)); + break; + case RAS_FLOAT: + float f = dis.readFloat(); + resultBag.add(new Float(f)); + break; + case RAS_ULONG: + byte[] bu = new byte[8]; + bu[0] = 0; + bu[1] = 0; + bu[2] = 0; + bu[3] = 0; + bu[4] = dis.readByte(); + bu[5] = dis.readByte(); + bu[6] = dis.readByte(); + bu[7] = dis.readByte(); + ByteArrayInputStream bis2 = new ByteArrayInputStream(bu); + DataInputStream dis2 = new DataInputStream(bis2); + long ul = dis2.readLong(); + resultBag.add(new Long(ul)); + break; + case RAS_LONG: + case RAS_INT: + int i = dis.readInt(); + resultBag.add(new Integer(i)); + break; + case RAS_USHORT: + int j = dis.readUnsignedShort(); + resultBag.add(new Integer(j)); + break; + case RAS_SHORT: + short s = dis.readShort(); + resultBag.add(new Short(s)); + break; + default: + throw new RasTypeNotSupportedException(et + " as ElementType "); + } + } + result = resultBag; + + // close stream + in.close(); + break; + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_ERROR: + Debug.talkCritical("RasHttpRequest.execute: execution failed. Error = 0"); + + // read Endianess + while(in.read(b1) == 0) + ; + endianess = b1[0]; + + // read Error Number + while(in.available() < 4) + ; + in.read(b4); + int errNo = RasUtils.ubytesToInt(b4,endianess); + + // read Line Number + while(in.available() < 4) + ; + in.read(b4); + int lineNo = RasUtils.ubytesToInt(b4,endianess); + + // read Column Number + while(in.available() < 4) + ; + in.read(b4); + int colNo = RasUtils.ubytesToInt(b4,endianess); + + // read token + String token = RasUtils.readString(in); + + Debug.talkCritical("RasHttpRequest.execute: Errno=" + errNo + ", lineNo=" + lineNo + ", colNo=" + colNo + ", Token=" + token); + + throw new RasQueryExecutionFailedException(errNo,lineNo,colNo,token); + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_INT: + // read Integer Value + //System.err.println("Now reading integer value..."); + while(in.available() < 4); + in.read(b4); + result = new Integer(RasUtils.ubytesToInt(b4,endianess)); + //System.err.println("Int Value is : " + result.getInt()); + break; + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case RESPONSE_OID: + // read Values + String sys = RasUtils.readString(in); + String base = RasUtils.readString(in); + double d = in.readDouble(); + //System.out.println(sys+base+"localOID als double = " + d); + resultBag = new RasBag(); + resultBag.add(new RasOID(sys, base, d)); + result = resultBag; + // close stream + in.close(); + break; + default: + Debug.talkCritical( "RasHttpRequest.execute: illegal response type: " + resultType ); + break; + + } + + con.disconnect(); // close connection to server -- PB 2003-jun-15 + } + catch( MalformedURLException e ) + { + Debug.leaveCritical( "RasHttpRequest.execute: leave. malformed URL: " + e.getMessage() ); + throw new RasConnectionFailedException(MANAGER_CONN_FAILED, serverURL ); + } + catch( IOException e ) + { + Debug.leaveCritical( "RasHttpRequest.execute: leave. IO exception: " + e.getMessage() ); + throw new RasClientInternalException("RasHttpRequest","execute()",e.getMessage()); + } + catch( RasResultIsNoIntervalException e ) + { + Debug.leaveCritical( "RasHttpRequest.execute: leave. result no interval: " + e.getMessage() ); + throw new RasClientInternalException("RasHttpRequest","execute()",e.getMessage()); + } + + rcvTimer.stopTimer(); + rcvTimer.print(); + + httpTimer.stopTimer(); + httpTimer.print(); + + System.out.println( "RasHttpRequest.execute: leave. resultType=" + resultType ); + } // execute() + + public static void main( String[] args ) + { + String server = "localhost"; + String port = "7001"; + String base = "RASBASE"; + String user = "rasguest"; + String passwd = "rasguest"; + String query = "select r from RAS_COLLECTIONNAMES as r"; + int count = 1; + + System.out.println( "Query test started." ); + + for (int i=args.length-1; i>=0; i--) + { + if (args[i].equals("--server")) + server = args[i+1]; + if (args[i].equals("--port")) + port = args[i+1]; + if (args[i].equals("--database")) + base = args[i+1]; + if (args[i].equals("--user")) + user = args[i+1]; + if (args[i].equals("--passwd")) + passwd = args[i+1]; + if (args[i].equals("--query")) + query = args[i+1]; + if (args[i].equals("--count")) + count = Integer.parseInt(args[i+1]); + } + + try + { + RasImplementation myApp = new RasImplementation("http://"+server+":"+port); + myApp.setUserIdentification(user, passwd); + + System.out.println( "opening database..." ); + Database myDb = myApp.newDatabase(); + myDb.open( base, Database.OPEN_READ_ONLY ); + + System.out.println( "starting transaction..." ); + Transaction myTa = myApp.newTransaction(); + myTa.begin(); + + String parameters = "Command=8&ClientID=1&QueryString=" + query; + String serverUrl = "http://" + server + ":" + 7102; // port; + + for (int i = 0; i < count; i++) + { + System.out.println( "sending query #" + i + "..." ); + execute( serverUrl, parameters ); + } + + System.out.println( "closing transaction..." ); + myTa.abort(); + + System.out.println( "closing database..." ); + myDb.close(); + System.out.println( "all done." ); + + } + catch(Exception e) + { + System.err.println( e.getMessage() ); + } + + System.out.println( "Query test done." ); + + } // main() + +} // TestHttp + diff --git a/java/src/rasj/test/TestMArray.java b/java/src/rasj/test/TestMArray.java new file mode 100644 index 0000000..e8f817f --- /dev/null +++ b/java/src/rasj/test/TestMArray.java @@ -0,0 +1,904 @@ +/* +* 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: class for testing special MArrays + * + * + * COMMENTS: + * - adapt to general testbed structure + * </pre> + *********************************************************** */ + +import java.io.*; +import java.net.*; +import rasj.clientcommhttp.*; +import rasj.odmg.*; +import org.odmg.*; +import rasj.*; +import java.util.*; + +/** + * class for testing special MArrays + * for testing please enable test data output in toString method of RASGMArray + * @version $$ + */ +public class TestMArray +{ + /** + * constants used in this test + **/ + // prefixes for test output + static final String PREFIX_PROGRAM = "+++ +++ +++ "; + static final String PREFIX_TESTSET = "+++ +++ "; + static final String PREFIX_TESTCASE = "+++ "; + + static final String DEFAULT_HOST = "localhost"; + static final String DEFAULT_BASE = "RASBASE"; + static final String DEFAULT_COLL = "test"; + /** + * std error tag printed if a test fails + **/ + static final String ERROR_TAG = "ERROR: "; + + /** + * main program for testing + * on error, an exception is thrown (java main() knows no exit status) + **/ + public static void main(String[] args) + { + String serv = DEFAULT_HOST; + String base = DEFAULT_BASE; + String coll = DEFAULT_COLL; + boolean wrongUsage = false; // error in cmd line params? + + for (int i=args.length-1; i>=0; i--) + { + if (args[i].equals("--server")) + serv = args[i+1]; + else if (args[i].equals("--database")) + base = args[i+1]; + else if (args[i].equals("--collname")) + coll = args[i+1]; + else + wrongUsage = true; + } + + if (wrongUsage) + { + System.out.println( "Usage: TestMArray [--server s] [--database d] [--collname c]" ); + System.out.println( "defaults: s=" + DEFAULT_HOST + ", d=" + DEFAULT_BASE + ", c=" + DEFAULT_COLL ); + return; + } + + System.out.println( "rasdaman system test v5.1revC: testing class MArray." ); + System.out.println( PREFIX_PROGRAM + "system test started, using server" + serv + ", database " + base + ", collection" + coll ); + + // -- START test cases ------------------------------------------------- + TestMArray marrayTest = new TestMArray(serv); + // -- END test cases --------------------------------------------------- + + System.out.println( PREFIX_PROGRAM + "system test done." ); + return; + } // main() + + public TestMArray(String server) + { + DBag resultBag = null; + Object result = null; + Transaction myTa = null; + Database myDb = null; + OQLQuery myQu = null; + + boolean equal = false; + + try + { + System.out.println("### Testing MArrays: ..."); + Implementation myApp = new RasImplementation("http://"+server+":7001"); + myDb = myApp.newDatabase(); + + System.out.println("Opening database ..."); + myDb.open("RASBASE", Database.OPEN_READ_WRITE); + myTa = myApp.newTransaction(); + + int width, height, len; + width = 18; + height = 18; + len = (width+1)*(height+1); + RasMInterval domain = new RasMInterval("[0:"+width+",0:"+height+"]"); + RasMInterval domain2 = new RasMInterval("[1:3,1:3]"); + RasStorageLayout stl = new RasStorageLayout(); + stl.setTileSize(128); + + + /** + * test the GMArray + */ + System.out.println("\n\n### Testing GMArray with OID: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + try + { + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + } + catch(ODMGException e) + { + myTa.abort(); + System.err.println("Collection test does not exist: " + e.getMessage()); + } + + myQu.create("create collection test GreySet"); + RasGMArray mddConst = new RasGMArray(domain, 1, stl); + //RasGMArray mddConst = new RasGMArray(domain, 1); + byte[] data = new byte[len]; + mddConst.setObjectTypeName("GreyImage"); + + // test: get new OID from the server for GMArray and insert + System.out.println("new OID from server: " + myApp.getObjectId(mddConst)); + + for(int j = 0; j < data.length; j++) + data[j] = (byte)j; + + mddConst.setArray(data); + /* + System.out.println("\nbyte array: "); + for(int j=0; j<mddConst.getArray().length; j++) + { + System.out.print(" "+ mddConst.getArray()[j]); + } + */ + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddConst); + myQu.bind(mddConst); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<mddConst.getArray().length; j++) + { + if(mddConst.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + if(!(myApp.getObjectId(mddConst).toString()).equals(myApp.getObjectId((RasGMArray)result).toString())) + equal = false; + System.out.println("result mdd: " + ((RasGMArray)mddConst).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + System.out.println("inserted and selected GMArray and OIDs are equal: " + equal); + //System.out.println("All results for test GMArray"); + } + + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasGMArray mddConst2 = new RasGMArray(mddConst); + mddConst2.setArray(data); + //System.out.println("\nbyte array2: "); + data = null; + equal = true; + for(int j=0; j<mddConst.getArray().length; j++) + { + //System.out.print(" "+ mddConst2.getArray()[j]); + if(mddConst.getArray()[j] != mddConst2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + /** + * test the MArrayByte + */ + System.out.println("\n\n### Testing MArrayByte: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test GreySet"); + RasMArrayByte mddByte = new RasMArrayByte(domain, stl); + byte[] dataByte = new byte[len]; + mddByte.setObjectTypeName("GreyImage"); + + for(int j = 0; j < dataByte.length; j++) + dataByte[j] = (byte)j; + + mddByte.setArray(dataByte); + + //System.out.println("\nbyte array: "); + //for(int j=0; j<mddByte.getArray().length; j++) + //{ + //System.out.print(" "+ mddByte.getArray()[j]); + //} + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddByte); + myQu.bind(mddByte); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + System.out.println("result mdd: " + ((RasGMArray)mddByte).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + equal = true; + for(int j=0; j<mddByte.getArray().length; j++) + { + if(mddByte.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + } + //System.out.println("All results for MArrayByte"); + System.out.println("inserted and selected MArrayByte are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayByte mddByte2 = new RasMArrayByte(mddByte); + mddByte2.setArray(dataByte); + //System.out.println("\nbyte array2: "); + dataByte = null; + equal = true; + for(int j=0; j<mddByte.getArray().length; j++) + { + //System.out.print(" "+ mddByte2.getArray()[j]); + if(mddByte.getArray()[j] != mddByte2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + /** + * test the MArrayInteger + */ + System.out.println("\n\n### Testing MArrayInteger: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test UShortSet"); + RasMArrayInteger mddInteger = new RasMArrayInteger(domain, stl); + int[] dataInteger = new int[len]; + //byte[] dataInteger = new byte[144]; + mddInteger.setObjectTypeName("UShortImage"); + + for(int j = 0; j < dataInteger.length; j++) + dataInteger[j] = j; + + mddInteger.setArray(dataInteger); + + //System.out.println("\nbyte array: "); + //for(int j=0; j<mddInteger.getArray().length; j++) + //{ + //System.out.print(" "+ mddInteger.getArray()[j]); + //} + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddInteger); + myQu.bind(mddInteger); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + System.out.println("result mdd: " + ((RasGMArray)mddInteger).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + equal = true; + for(int j=0; j<mddInteger.getArray().length; j++) + { + if(mddInteger.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + } + //System.out.println("All results for MArrayInteger"); + System.out.println("inserted and selected MArrayInteger are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayInteger mddInteger2 = new RasMArrayInteger(mddInteger); + mddInteger2.setArray(dataInteger); + dataInteger = null; + equal = true; + for(int j=0; j<mddInteger2.getArray().length; j++) + { + //System.out.print(" "+ mddInteger2.getArray()[j]); + if(mddInteger.getArray()[j] != mddInteger2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + /* + System.out.println("\nspecial array2: "); + for(int j=0; j<mddInteger2.getIntArray().length; j++) + { + System.out.print(" "+ mddInteger2.getIntArray()[j]); + } + */ + + /** + * test the MArrayDouble + */ + System.out.println("\n\n### Testing MArrayDouble: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test DoubleSet"); + RasMArrayDouble mddDouble = new RasMArrayDouble(domain, stl); + double[] dataDouble = new double[len]; + //byte[] dataDouble = new byte[288]; + mddDouble.setObjectTypeName("DoubleImage"); + + for(double j = 0; j < dataDouble.length; j++) + dataDouble[(int)j] = j; + + mddDouble.setArray(dataDouble); + + //System.out.println("\nbyte array: "); + //for(int j=0; j<mddDouble.getArray().length; j++) + //{ + //System.out.print(" "+ mddDouble.getArray()[j]); + //} + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddDouble); + myQu.bind(mddDouble); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<mddDouble.getDoubleArray().length; j++) + { + if(mddDouble.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + System.out.println("result mdd: " + ((RasGMArray)mddDouble).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + //System.out.println("All results for MArrayDouble"); + System.out.println("inserted and selected MArrayDouble are equal: " + equal); + } + + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayDouble mddDouble2 = new RasMArrayDouble(mddDouble); + mddDouble2.setArray(dataDouble); + //System.out.println("byte array2: "); + dataDouble = null; + equal = true; + for(int j=0; j<mddDouble2.getArray().length; j++) + { + //System.out.print(" "+ mddDouble2.getArray()[j]); + if(mddDouble.getArray()[j] != mddDouble2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + /* + System.out.println("\nspecial array2: "); + for(int j=0; j<mddDouble2.getDoubleArray().length; j++) + { + System.out.print(" "+ mddDouble2.getDoubleArray()[j]); + } + */ + + /** + * test the MArrayFloat + */ + System.out.println("\n\n### Testing MArrayFloat: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test FloatSet"); + RasMArrayFloat mddFloat = new RasMArrayFloat(domain, stl); + float[] dataFloat = new float[len]; + //byte[] dataFloat = new byte[144]; + mddFloat.setObjectTypeName("FloatImage"); + + for(float j = 0; j < dataFloat.length; j++) + dataFloat[(int)j] = j; + + mddFloat.setArray(dataFloat); + + //System.out.println("\nbyte array: "); + //for(int j=0; j<mddFloat.getArray().length; j++) + //{ + //System.out.print(" "+ mddFloat.getArray()[j]); + //} + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddFloat); + myQu.bind(mddFloat); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<mddFloat.getArray().length; j++) + { + if(mddFloat.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + System.out.println("result mdd: " + ((RasGMArray)mddFloat).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + //System.out.println("All results for MArrayFloat"); + System.out.println("inserted and selected MArrayFloat are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayFloat mddFloat2 = new RasMArrayFloat(mddFloat); + mddFloat2.setArray(dataFloat); + //System.out.println("\nbyte array2: "); + dataFloat = null; + equal = true; + for(int j=0; j<mddFloat2.getArray().length; j++) + { + //System.out.print(" "+ mddFloat2.getArray()[j]); + if(mddFloat.getArray()[j] != mddFloat2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + /* + System.out.println("\nspecial array2: "); + for(int j=0; j<mddFloat2.getFloatArray().length; j++) + { + System.out.print(" "+ mddFloat2.getFloatArray()[j]); + } + */ + + /** + * test the MArrayShort + */ + System.out.println("\n\n### Testing MArrayShort: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test ShortSet"); + RasMArrayShort mddShort = new RasMArrayShort(domain, stl); + //RasMArrayShort mddShort4 = new RasMArrayShort(domain, stl); + //RasMArrayShort mddShort3 = new RasMArrayShort(domain, stl); + short[] dataShort = new short[len]; + //short[] dataShort4 = new short[len]; + //short[] dataShort3 = new short[len]; + //byte[] dataShort = new byte[72]; + mddShort.setObjectTypeName("ShortImage"); + //mddShort4.setObjectTypeName("ShortImage"); + //mddShort3.setObjectTypeName("ShortImage"); + + //System.out.println("new OID from server: " + myApp.getObjectId(mddShort)); + //System.out.println("new OID from server: " + myApp.getObjectId(mddShort4)); + for(int j = 0; j < dataShort.length; j++) + dataShort[j] = (short)j; + + //for(int j = 0; j < dataShort.length; j++) + //dataShort[j] = 1; + //for(int j = 0; j < dataShort4.length; j++) + //dataShort4[j] = 2; + //for(int j = 0; j < dataShort3.length; j++) + //dataShort3[j] = 3; + + + mddShort.setArray(dataShort); + //mddShort4.setArray(dataShort4); + //mddShort3.setArray(dataShort3); + /* + System.out.println("\nbyte array: "); + for(int j=0; j<mddShort.getArray().length; j++) + { + System.out.print(" "+ mddShort.getArray()[j]); + } + */ + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + myQu = myApp.newOQLQuery(); + //System.out.println("\ncollection created"); + //myQu.create("insert into test values $1"); + myQu.create("insert into test values $1"); + //System.out.println("mdd before sending: " + mddShort); + //myQu.bind("test"); + myQu.bind(mddShort); + //myQu.bind(mddShort4); + //myQu.bind(mddShort3); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + /* + myTa.begin(); + myQu = myApp.newOQLQuery(); + myQu.create("insert into test values $1"); + myQu.bind(mddShort4); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + myTa.begin(); + myQu = myApp.newOQLQuery(); + myQu.create("insert into test values $1"); + myQu.bind(mddShort3); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + */ + //System.out.println("collection inserted"); + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<mddShort.getArray().length; j++) + { + if(mddShort.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + System.out.println("result mdd: " + ((RasGMArray)mddShort).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + //System.out.println("All results for MArrayShort"); + System.out.println("inserted and selected MArrayShort are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayShort mddShort2 = new RasMArrayShort(mddShort); + mddShort2.setArray(dataShort); + //System.out.println("\nbyte array2: "); + dataShort = null; + equal = true; + for(int j=0; j<mddShort2.getArray().length; j++) + { + //System.out.print(" "+ mddShort2.getArray()[j]); + if(mddShort.getArray()[j] != mddShort2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + /* + System.out.println("\nspecial array2: "); + for(int j=0; j<mddShort2.getShortArray().length; j++) + { + System.out.print(" "+ mddShort2.getShortArray()[j]); + } + */ + + /** + * test the MArrayLong + */ + System.out.println("\n\n### Testing MArrayLong: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test ULongSet"); + RasMArrayLong mddLong = new RasMArrayLong(domain, stl); + long[] dataLong = new long[len]; + //byte[] dataLong = new byte[288]; + mddLong.setObjectTypeName("ULongImage"); + + for(long j = 0; j < dataLong.length; j++) + dataLong[(int)j] = j; + mddLong.setArray(dataLong); + + /* + System.out.println("\nbyte array: "); + for(int j=0; j<mddLong.getArray().length; j++) + { + System.out.print(" "+ mddLong.getArray()[j]); + } + */ + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddLong); + myQu.bind(mddLong); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<((RasGMArray)result).getArray().length; j++) + { + if(mddLong.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + System.out.println("result mdd: " + ((RasGMArray)mddLong).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + //System.out.println("All results for MArrayLong"); + System.out.println("inserted MArrayInteger and selected MArrayLong are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayLong mddLong2 = new RasMArrayLong(mddLong); + mddLong2.setArray(dataLong); + //System.out.println("\nbyte array2: "); + dataLong = null; + equal = true; + for(int j=0; j<mddLong2.getArray().length; j++) + { + //System.out.print(" "+ mddLong2.getArray()[j]); + if(mddLong.getArray()[j] != mddLong2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + System.out.println("\nspecial array: "); + for(int j=0; j<((RasMArrayLong)result).getLongArray().length; j++) + { + System.out.print(" "+ ((RasMArrayLong)result).getLongArray()[j]); + } + + + /** + * testing intersection + */ + System.out.println("\n\n### Testing intersection:"); + mddConst2.intersectionWith(domain2); + mddByte2.intersectionWith(domain2); + mddDouble2.intersectionWith(domain2); + mddFloat2.intersectionWith(domain2); + mddInteger2.intersectionWith(domain2); + mddLong2.intersectionWith(domain2); + mddShort2.intersectionWith(domain2); + System.out.println("OK\n"); + + /** + * testing OIDs + */ + myQu = myApp.newOQLQuery(); + myQu.create("SELECT oid(img) FROM test AS img"); + //myQu.create("SELECT img FROM test AS img where (oid(img)=231425)"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + //System.out.println("OID: " + result); + } + //System.out.println("All results"); + + } + + /** + * get new OID + */ + System.out.println("### Testing OIDs:"); + myTa.begin(); + myApp.getObjectId(new RasGMArray()); + myTa.commit(); + + System.out.println( "Closing database ..." ); + myDb.close(); + + // get new OID without open TA + RasGMArray gmar = new RasGMArray(); + equal = true; + if(!myApp.getObjectId(gmar).equals(gmar.getOID().toString())) + equal = false; + System.out.println("same OID on client and server side: " + equal); + + } + catch (RasException e) + { + System.out.println("!!!!!!!!!!!!!!!!!!!!While testing!!!!!!!!!!!!!!!!!!"); + System.out.println("An RasException has occurred: " + e.getMessage()); + System.out.println("Try to abort the transaction ..."); + if(myTa != null) myTa.abort(); + + try + { + System.out.println("Try to close the database ..."); + if(myDb != null) myDb.close(); + } + catch ( org.odmg.ODMGException exp ) + { + System.err.println("Could not close the database: " + exp.getMessage()); + } + } + catch (RasRuntimeException e) + { + System.out.println("!!!!!!!!!!!!!!!!!!!!While testing!!!!!!!!!!!!!!!!!!"); + System.out.println("An RasRuntimeException has occurred: " + e.getMessage()); + System.out.println("Try to abort the transaction ..."); + if(myTa != null) myTa.abort(); + + try + { + System.out.println("Try to close the database ..."); + if(myDb != null) myDb.close(); + } + catch ( org.odmg.ODMGException exp ) + { + System.err.println("Could not close the database: " + exp.getMessage()); + } + } + catch (org.odmg.ODMGException e) + { + System.out.println("!!!!!!!!!!!!!!!!!!!!While testing!!!!!!!!!!!!!!!!!!"); + System.out.println("An ODMGException has occurred: " + e.getMessage()); + System.out.println("Try to abort the transaction ..."); + if(myTa != null) myTa.abort(); + + try + { + System.out.println("Try to close the database ..."); + if(myDb != null) myDb.close(); + } + catch ( org.odmg.ODMGException exp ) + { + System.err.println("Could not close the database: " + exp.getMessage()); + } + } + System.out.println( "Done." ); + + } +} + diff --git a/java/src/rasj/test/TestOdmg.java b/java/src/rasj/test/TestOdmg.java new file mode 100644 index 0000000..da10505 --- /dev/null +++ b/java/src/rasj/test/TestOdmg.java @@ -0,0 +1,430 @@ +/* +* 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>. +*/ +/************************************************************* + * + * + * PURPOSE: + * test rasj with some queries + * @param --server s - use server s (default: localhost) + * @param --port p - use server port p (default: 7001) + * @param --database d - use database d (default: RASBASE) + * @param --user u - log in as user u (default: rasguest) + * @param --passwd p - log in with password p (default: rasguest) + * + * PREREQUISITES: + * - needs an HTTP server + * - needs write access to database + * - database must know type GreySet + * + * + * COMMENTS: + * - no parameter line error handling + * was formerly in rasj/odmg/test, this has been merged + ************************************************************/ + +import rasj.*; +import rasj.global.*; +import org.odmg.*; +import rasj.odmg.*; + +import java.util.*; +import java.io.*; + +public class TestOdmg implements RasGlobalDefs + { + + /** + * prefixes for test output + **/ + static final String PREFIX_PROGRAM = "+++ +++ +++ "; + static final String PREFIX_TESTSET = "+++ +++ "; + static final String PREFIX_TESTCASE = "+++ "; + + /** + * std error tag printed if a test fails + **/ + static final String ERROR_TAG = "ERROR: "; + + /** + * default values (override with cmd line option) + **/ + static final String DEFAULT_HOST = "localhost"; + static final int DEFAULT_PORT = 7001; + static final String DEFAULT_BASE = "RASBASE"; + static final String DEFAULT_USER = "rasguest"; + static final String DEFAULT_PASSWD = "rasguest"; + + public static void main(String[] args) throws Exception + { + + String serv = DEFAULT_HOST; + int port = DEFAULT_PORT; + String base = DEFAULT_BASE; + String user = DEFAULT_USER; + String passwd = DEFAULT_PASSWD; + boolean wrongUsage = false; // error in cmd line params? + RasImplementation myImp = null; + + for (int i=args.length-1; i>=0; i--) + { + if (args[i].equals("--server")) + serv = args[i+1]; + else if (args[i].equals("--port")) + { + try + { + port = Integer.parseInt(args[i+1]); + } + catch(Exception e) + { + wrongUsage = true; + } + } + else if (args[i].equals("--database")) + base = args[i+1]; + else if (args[i].equals("--user")) + user = args[i+1]; + else if (args[i].equals("--passwd")) + passwd = args[i+1]; + } + + if (wrongUsage) + { + System.out.println( "Usage: ODMGtest [--server s] [--port p] [--database d] [--user u] [--passwd p]" ); + System.out.println( "defaults: server=" + DEFAULT_HOST + ", port=" + DEFAULT_PORT + ", database=" + DEFAULT_BASE ++ ", user=" + DEFAULT_USER + ", passwd=" + DEFAULT_PASSWD ); + System.exit(-1); + } + + System.out.println( "rasdaman system test v5.1revC: testing ODMG queries." ); + System.out.println( PREFIX_PROGRAM + "system test started, using server " + serv + ", port " + port + ", database " + base + ", user=" + user + ", passwd=" + passwd ); + + myImp = new RasImplementation("http://" + serv + ":" + port); + + // START tests ---------------------------------------------- + testQueries( myImp, base ); + // END tests ------------------------------------------------ + + System.out.println( PREFIX_PROGRAM + "system test done." ); + return; + } // main() + + /** + * test database queries + * any eventual exception that is not caught here is an error, and will cause an abort + **/ + static void testQueries( RasImplementation imp, String database ) throws Exception + { + System.out.println( PREFIX_TESTSET + "testing queries started." ); + + // objectTest(); // - just to test setObjectName() which now verifies that the name is a valid identifier + + Database mydb = null; + Transaction myta = null; + RasGMArray myMDD = null; + OQLQuery myQuery = null; + + + /********************* + * test update query * + *********************/ + // create some test data + try + { + System.out.println("Start creating test arrays ..."); + myMDD = new RasGMArray(new RasMInterval("[1:400,1:400]"),1); + byte[] mydata = new byte[160000]; + for(int y=0; y<400; y++) + { + for(int x=0; x<400; x++) + { + if((x>99 && x<151) || (x>299 && x<351)) + mydata[y*399+x]=100; + else + mydata[y*399+x]=0; + } + } + myMDD.setArray(mydata); + myMDD.setObjectTypeName("GreyImage"); + + RasStorageLayout myLayout = new RasStorageLayout(); + //myLayout.setTileSize(640000); + myLayout.setTileDomain("[1:100,1:70]"); + myMDD.setStorageLayout(myLayout); + + System.out.println("Created Test Data:"); + System.out.println(myMDD); + } + + catch ( Exception e ) + { + System.out.println("ERROR: "); + System.out.println(e.getMessage()); + System.exit(-1); + } + + // now access the database and start a transaction + try { + mydb = imp.newDatabase(); + System.out.println("Open Database ..."); + mydb.open( database, Database.OPEN_READ_WRITE ); + System.out.println(" ok."); + myta = imp.newTransaction(); + System.out.println("Begin transaction ..."); + myta.begin(); + System.out.println(" ok."); + } + + catch ( Exception e ) { + System.out.println("ERROR: "); + System.out.println(e.getMessage()); + + if(myta.isOpen()) + { + System.out.println("Abort transaction ..."); + myta.abort(); + } + System.out.println("Close database ..."); + try { + mydb.close(); + System.out.println(" ok."); + } + catch ( Exception e2 ) { + } + System.out.println("Exiting..."); + System.exit(-1); + } + + // create the test collection + try { + System.out.println("Create a new test collection ..."); + myQuery = imp.newOQLQuery(); + myQuery.create("create collection testCollection GreySet"); + //myQuery.create("create collection $1 GreySet"); + //myQuery.bind("testCollection"); + myQuery.execute(); + myta.commit(); + myta.begin(); + System.out.println(" ok."); + } + + catch ( Exception e) { + System.out.println("ERROR: "); + System.out.println(e.getMessage()); + System.out.println("Try to remove the test collection ..."); + try { + myQuery.create("drop collection testCollection"); + myQuery.execute(); + myta.commit(); + } + catch ( Exception e2 ) { + } + + if(myta.isOpen()) + { + System.out.println("Abort transaction ..."); + myta.abort(); + } + System.out.println("Close database ..."); + try { + mydb.close(); + System.out.println(" ok."); + } + catch ( Exception e3 ) { + } + + System.out.println("Exiting..."); + System.exit(-1); + } + + // testquery with empty result + /* + try { + System.out.println("Define a testquery with an empty result... "); + myQuery.create("select a from ImgRGBA as a where oid(a) <= 0"); + System.out.println("Send the query ..."); + DSet myResult = (DSet) myQuery.execute(); + + Iterator iter = myResult.iterator(); + System.out.println("Number of results: " + myResult.size()); + + + while(iter.hasNext()) + { + System.out.println("Ergebnis:"); + System.out.println(iter.next()); + } + + System.out.println(" ok."); + System.out.println("Commit transaction ..."); + System.out.println(" ok."); + } + + catch ( Exception e ) { + System.out.println("ERROR: "); + System.out.println(e.getMessage()); + + if(myta.isOpen()) + { + System.out.println("Abort transaction ..."); + myta.abort(); + } + System.out.println("Close database ..."); + try { + mydb.close(); + System.out.println(" ok."); + } + catch ( Exception e2 ) { + } + System.out.println("Exiting..."); + System.exit(-1); + } + */ + + // now insert MDDS and commit + try { + System.out.println("Define the update query and bind the parameters ..."); + myQuery.create("insert into testCollection VALUES $1"); + //myQuery.create("insert into testCollection VALUES $1"); + myQuery.bind(myMDD); + System.out.println(" ok."); + System.out.println("Send the query ..."); + myQuery.execute(); + System.out.println(" ok."); + System.out.println("Commit transaction ..."); + myta.commit(); + System.out.println(" ok."); + } + + catch ( Exception e ) { + System.out.println("ERROR: "); + System.out.println(e.getMessage()); + + if(myta.isOpen()) + { + System.out.println("Abort transaction ..."); + myta.abort(); + } + System.out.println("Close database ..."); + try { + mydb.close(); + System.out.println(" ok."); + } + catch ( Exception e2 ) { + } + System.out.println("Exiting..."); + System.exit(-1); + } + + // start new transaction and todo: read back the testimage + try { + System.out.println("Start new transaction ..."); + myta.begin(); + myQuery = imp.newOQLQuery(); + myQuery.create("select testCollection from testCollection"); + //myQuery.create("create collection $1 GreySet"); + //myQuery.bind("testCollection"); + myQuery.execute(); + myta.commit(); + System.out.println(" ok."); + myta.begin(); + + } + + catch ( Exception e ) { + System.out.println("ERROR: "); + System.out.println(e.getMessage()); + + if(myta.isOpen()) + { + System.out.println("Abort transaction ..."); + myta.abort(); + } + System.out.println("Close database ..."); + try { + mydb.close(); + System.out.println(" ok."); + } + catch ( Exception e2 ) { + } + System.out.println("Exiting..."); + System.exit(-1); + } + + // todo: compare to the original image + + // drop test collection + try { + System.out.println("Drop test collection ..."); + myQuery = imp.newOQLQuery(); + myQuery.create("drop collection testCollection"); + myQuery.execute(); + myta.commit(); + mydb.close(); + System.out.println(" ok."); + } + + catch ( Exception e) { + System.out.println("ERROR: "); + System.out.println(e.getMessage()); + + if(myta.isOpen()) + { + System.out.println("Abort transaction ..."); + myta.abort(); + } + System.out.println("Close database ..."); + try { + mydb.close(); + System.out.println(" ok."); + } + catch ( Exception e2 ) { + } + System.out.println("Exiting..."); + System.exit(-1); + } + + System.out.println( PREFIX_TESTSET + "testing queries done.\n" ); + return; + } // testQueries() + + public static void objectTest() + { + System.out.println("Set object name test - in"); + + RasObject dummy = new RasObject(); + + dummy.setObjectName("goodName"); + + System.out.println("Set name=" + dummy.getObjectName()); + + dummy.setObjectName("bad-Name"); + + System.out.println("Set name=" + dummy.getObjectName()); + + System.out.println("Set object name test - out"); + + } + +} // TestOdmg + diff --git a/java/src/rasj/test/TestQuery.java b/java/src/rasj/test/TestQuery.java new file mode 100644 index 0000000..362b99f --- /dev/null +++ b/java/src/rasj/test/TestQuery.java @@ -0,0 +1,143 @@ +/* +* 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>. +*/ +/************************************************************* + * + * + * PURPOSE: + * test rasj: simple open/read query/close cycle. + * rasj test program for executing a query against some rasdaman database. + * Note: database is opened readonly, so send only SELECT queries. + * + * @param --server s - use server s (default: localhost) + * @param --port p - use server port p (default: 7001) + * @param --database d - use database d (default: RASBASE) + * @param --user u - log in as user u (default: rasguest) + * @param --passwd p - log in with password p (default: rasguest) + * @param --query q - send SELECT query string q to server (default: "select r from RAS_COLLECTIONNAMES as r"") + * @param --count c - execute query c times (default: 1) + * + * + * COMMENTS: + * - no parameter line error handling + ************************************************************/ + +import rasj.*; +import rasj.odmg.*; +import org.odmg.*; +import java.util.*; +import java.io.*; + +public class TestQuery + { + + public static void main( String[] args ) + { + String server = "localhost"; + String port = "7001"; + String base = "RASBASE"; + String user = "rasguest"; + String passwd = "rasguest"; + String query = "select r from RAS_COLLECTIONNAMES as r"; + int count = 1; + + if (args.length == 0) + { + System.out.println( "usage: TestQuery [options]" ); + System.out.println( "options:" ); + System.out.println( " --server s - use server s (default: localhost)" ); + System.out.println( " --port p - use server port p (default: 7001)" ); + System.out.println( " --database d - use database d (default: RASBASE)" ); + System.out.println( " --user u - log in as user u (default: rasguest)" ); + System.out.println( " --passwd p - log in with password p (default: rasguest)" ); + System.out.println( " --query q - send SELECT query string q to server (default: select r from RAS_COLLECTIONNAMES as r)" ); + System.out.println( " --count c - execute query c times (default: 1)" ); + return; + } + + for (int i=args.length-1; i>=0; i--) + { + if (args[i].equals("--server")) + server = args[i+1]; + if (args[i].equals("--port")) + port = args[i+1]; + if (args[i].equals("--database")) + base = args[i+1]; + if (args[i].equals("--user")) + user = args[i+1]; + if (args[i].equals("--passwd")) + passwd = args[i+1]; + if (args[i].equals("--query")) + query = args[i+1]; + if (args[i].equals("--count")) + count = Integer.parseInt(args[i+1]); + } + + System.out.println( "Query test started with server=" + server + ", port=" + port + ", database=" + base + ", user=" + user + ", count=" + count + ", query=" + query ); + + try + { + RasImplementation myApp = new RasImplementation("http://"+server+":"+port); + myApp.setUserIdentification(user, passwd); + + System.out.println( "opening database..." ); + Database myDb = myApp.newDatabase(); + myDb.open( base, Database.OPEN_READ_WRITE ); + + System.out.println( "starting transaction..." ); + Transaction myTa = myApp.newTransaction(); + myTa.begin(); + + for (int i = 1; i <= count; i++) + { + + System.out.print( "sending query #" + i + "..." ); + OQLQuery myQu = myApp.newOQLQuery(); + myQu.create(query); + DBag result = (DBag) myQu.execute(); + + System.out.println( "result is: " + result ); + + } + + System.out.println( "closing transaction..." ); + myTa.commit(); + + // System.out.println( "sending query out of TA, must produce an error..." ); + // OQLQuery myQu2 = myApp.newOQLQuery(); + // myQu2.create(query); + // DBag result2 = (DBag) myQu2.execute(); + + System.out.println( "closing database..." ); + myDb.close(); + + } + catch(Exception e) + { + System.err.println( e.getMessage() ); + } + + System.out.println( "Query test done." ); + + } // main() + +} // TestQuery diff --git a/java/src/rasj/test/TestQuery.sh b/java/src/rasj/test/TestQuery.sh new file mode 100644 index 0000000..ca3b2fe --- /dev/null +++ b/java/src/rasj/test/TestQuery.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# TestQuery.sh: test rasj query interface +# where rasj.jar is expected: +export RASJ=$RMANBASE/java/rasj.jar +#export RASJ=~rasdaman/jlib/rasj.jar + +java -DRMANPROTOCOL=RNP -cp .:$RASJ:$CLASSPATH TestQuery --query "SELECT jpeg(( marray x in [0:599,0:599] values {255c,255c,0c} ) overlay scale(img0[2011:2315,2543:2847],[1:600,1:600]) * { 1c, 1c, 1c}) FROM vat_rgbdop2_8 AS img0" $* 2>&1 + diff --git a/java/src/rasj/test/TestRasInterval.java b/java/src/rasj/test/TestRasInterval.java new file mode 100644 index 0000000..27450fd --- /dev/null +++ b/java/src/rasj/test/TestRasInterval.java @@ -0,0 +1,314 @@ +/* +* 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: + * - on error, an exception is thrown (java main() knows no exit status) + * + * </pre> + *********************************************************** */ + +import java.util.StringTokenizer; +import java.lang.Integer; +import java.lang.Long; +import rasj.*; +import rasj.odmg.*; + +public class TestRasInterval + { + /** + * constants used in this test + **/ + // prefixes for test output + static final String PREFIX_PROGRAM = "+++ +++ +++ "; + static final String PREFIX_TESTSET = "+++ +++ "; + static final String PREFIX_TESTCASE = "+++ "; + + /** + * std error tag printed upon failure + **/ + static final String ERROR_TAG = "ERROR: "; + + /** + * main program for testing + * on error, an exception is thrown (java main() knows no exit status) + **/ + public static void main(String argv[]) throws Exception + { + System.out.println( "rasdaman system test v5.1revC: TestRasInterval." ); + System.out.println( PREFIX_PROGRAM + "system test started." ); + + // -- START test cases ------------------------------------------------- + testInterval(); + // -- END test cases --------------------------------------------------- + + System.out.println( PREFIX_PROGRAM + "system test done." ); + return; + } + + /** + * test the RasInterval class (no db access) + * any eventual exception that is not caught here is an error, and will cause an abort + **/ + static void testInterval() throws RasResultIsNoIntervalException, RasDimensionMismatchException, RasIndexOutOfBoundsException, RasStreamInputOverflowException + { + // create a new RasSInterval + System.out.println("\n############################ test sintervals: "); + RasSInterval s1 = new RasSInterval(100,200); + RasSInterval s2 = new RasSInterval("150:400"); + + // get upper bound + boolean b1 = false; + if(s2.high() == 400) + b1 = true; + System.out.println("upper bound is correct: " + b1); + + // test if lower bound is fixed + boolean b2; + b1 = false; + b1 = s2.isLowFixed(); + System.out.println("lower bound is fix: " + b1); + + // test if interval intersects with another interval + // (the return value shows the kind of intersection) + int j; + j = s1.intersectsWith(s2); + b1 = false; + if(j != -1) + b1 = true; + System.out.println("s1 intersects with s2: " + b1); + + RasSInterval sint1 = new RasSInterval(100,200); + RasSInterval sint2 = new RasSInterval("150 :400 "); + RasSInterval sint3 = new RasSInterval("50:180"); + + b1 = false; + sint1.setHigh('*'); + sint1.setLow(400); + if(sint1.low() == 400) + b1 = true; + sint1.setLow('*'); + sint1.setHigh(500); + if((sint1.high() == 500) && b1) + b1 = true; + else + b1 = false; + System.out.println("setLow and setHigh are OK: " + b1); + + sint1.setInterval('*',500); + b1 = !sint1.isLowFixed(); + b1 = sint1.isHighFixed() && b1; + System.out.println("low is open high is fixed: " + b1); + + b1 = false; + if(sint1.intersectsWith(sint1) != -1) + b1 = true; + + if(sint3.closureOf(sint2, sint1).equals(sint1) && + sint3.closureWith(sint2).equals(sint1) && + sint3.createClosure(sint2).equals(sint1)) + b1 = b1 && true; + + sint1.setInterval(90, 105); + sint2.setInterval(100, 110); + if(sint2.createDifference(sint1).equals(new RasSInterval(90, 100)) && + sint3.createIntersection(sint2).equals(new RasSInterval(100, 110))) + b1 = b1 && true; + + if(sint3.createUnion(sint2).equals(sint1) && + sint1.differenceOf(sint1, sint2).equals(new RasSInterval(90, 100)) && + sint1.differenceWith(sint2).equals(new RasSInterval(100, 110))) + b1 = b1 && true; + + if(sint3.intersectionOf(sint2, sint1).equals(new RasSInterval(100, 100)) && + sint3.intersectionWith(sint2).equals(new RasSInterval(100, 100))) + b1 = b1 && true; + + b1 = b1 && !sint3.equals(sint2); + if(sint3.unionOf(sint1, sint2).equals(new RasSInterval(90, 110)) && + sint3.unionWith(sint2).equals(new RasSInterval(90, 110))) + b1 = b1 && true; + System.out.println("operations of sintervals are correct: " + b1); + + + + // create new RasMInterval + System.out.println("\n############################ test mintervals: "); + RasMInterval mint1 = new RasMInterval("[567:3253,666:888]"); + RasMInterval mint2 = new RasMInterval("[678:4000,777:999]"); + RasMInterval mint3 = new RasMInterval("[777:900,888:1000]"); + RasMInterval mint4 = new RasMInterval(2); + b1 = false; + if((mint2.dimension() == 2) && (mint1.dimension() == 2)) + b1 = true; + System.out.println("dimensions of mintervals are correct: " + b1); + + b1 = false; + mint1 = new RasMInterval("[500:3000,600:800]"); + mint2 = new RasMInterval("[600:1000,700:750]"); + b1 = mint1.intersectsWith(mint2); + mint1 = new RasMInterval("[567:3253,666:888]"); + mint2 = new RasMInterval("[678:4000,777:999]"); + if(mint3.closureOf(mint2, mint1).toString().equals(new RasMInterval("[567:4000,666:999]").toString())) + b1 = b1 && true; + else b1 = false; + if(mint3.closureWith(mint2).toString().equals(new RasMInterval("[567:4000,666:999]").toString())) + b1 = b1 && true; + else b1 = false; + if(mint3.createClosure(mint2).toString().equals(new RasMInterval("[567:4000,666:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = new RasMInterval("[678:2000,777:888]"); + mint3 = mint3.createDifference(mint2); + if(mint3.toString().equals(new RasMInterval("[2000:4000,888:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = new RasMInterval("[678:2000,777:888]"); + mint3 = mint3.createDifference(mint2); + if(mint3.toString().equals(new RasMInterval("[2000:4000,888:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = new RasMInterval("[678:2000,777:888]"); + mint3 = mint3.createIntersection(mint2); + if(mint3.toString().equals(new RasMInterval("[678:2000,777:888]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = new RasMInterval("[678:2000,777:888]"); + mint2 = new RasMInterval("[1000:4000,750:999]"); + mint3 = mint3.createUnion(mint2); + if(mint3.toString().equals(new RasMInterval("[678:4000, 750:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint2 = new RasMInterval("[1000:4000,800:999]"); + mint1 = mint1.differenceOf(mint3, mint2); + if(mint1.toString().equals(new RasMInterval("[678:1000,750:800]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = mint3.intersectionOf(mint2, mint1); + if(mint3.toString().equals(new RasMInterval("[1000:1000,800:800]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = mint3.intersectionWith(mint2); + if(mint3.toString().equals(new RasMInterval("[1000:1000,800:800]").toString())) + b1 = b1 && true; + else b1 = false; + b1 = b1 && !mint3.equals(mint2); + mint3 = mint3.unionOf(mint1, mint2); + if(mint3.toString().equals(new RasMInterval("[678:4000,750:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = mint3.unionWith(mint2); + if(mint3.toString().equals(new RasMInterval("[678:4000,750:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint2 = mint2.differenceWith(mint3); + if(mint2.toString().equals(new RasMInterval("[678:1000,750:800]").toString())) + b1 = b1 && true; + else b1 = false; + System.out.println("operations of mintervals are correct: " + b1); + + // Types + /////////////////////////////////////////// + System.out.println("\n############################ test types: "); + String s = "marray <char, 1>"; + RasType rType = RasType.getAnyType(s); + RasBaseType rb; + + if(rType.getClass().getName().equals("rasj.RasMArrayType")) + { + RasMArrayType tmp = (RasMArrayType)rType; + rb = tmp.getBaseType(); + + System.out.println("OK"); + } + else + System.out.println("element of MDD Collection is no MArray."); + + boolean b3; + b3 = !rType.isStructType(); + System.out.println(b3); + + + // StorageLayout + /////////////////////////////////////////// + System.out.println("\n############################ test storage layout: "); + RasGMArray myMDD = new RasGMArray(new RasMInterval("[1:400,1:400]"),1); + byte[] mydata = new byte[160000]; + for(int y=0; y<400; y++) + { + for(int x=0; x<400; x++) + { + if((x>99 && x<151) || (x>299 && x<351)) + mydata[y*399+x]=100; + else + mydata[y*399+x]=0; + } + } + + myMDD.setArray(mydata); + myMDD.setObjectTypeName("GreyImage"); + + RasStorageLayout myLayout = new RasStorageLayout(); + + myLayout.setTileDomain("[1:100,1:70]"); + // you can either set the TileSize or the TileDomain + myLayout.setTileSize(32); + myMDD.setStorageLayout(myLayout); + if(myMDD.getStorageLayout().getTileSize() == 32) + System.out.println("OK"); + + + //GMarray//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + RasGMArray array1 = new RasGMArray(); + RasGMArray array2 = new RasGMArray(mint1, 8); + + myMDD.getCell(new RasPoint(1,1)); + + System.out.println("OK"); + + + //Ausgabe//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /* + System.out.println("Array1 " + array1); + System.out.println("Array2 " + array2); + + System.out.println("Punkt1 " + p1); + System.out.println("Punkt2 " + p2); + + System.out.println("Sinterval1 " + s1); + System.out.println("Sinterval2 " + s2); + System.out.println("Sinterval3 " + sint3); + + System.out.println("j = " + j); + //System.out.println("b1 = " + b1); + //System.out.println("b2 = " + b2); + System.out.println("b3 = " + b3); + */ + + } + + } // TestRasInterval diff --git a/java/src/rasj/test/TestRasPoint.java b/java/src/rasj/test/TestRasPoint.java new file mode 100644 index 0000000..6402bf0 --- /dev/null +++ b/java/src/rasj/test/TestRasPoint.java @@ -0,0 +1,373 @@ +/* +* 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: + * test rasj class RasPoint. + * + * + * COMMENTS: + * - testing philosophy is to run all tests and report. no exit code / exception + * is used for error indication; look into the output for ERROR_TAG instead. + * - unexpected exceptions are not caught, hence will make gmake fail and show the error + * - every test that fails must print a line containing ERROR_TAG + * </pre> + *********************************************************** */ + +import java.util.StringTokenizer; +import java.lang.Integer; +import java.lang.Long; +import rasj.*; +import rasj.odmg.*; + +public class TestRasPoint + { + /** + * constants used in this test + **/ + // prefixes for test output + static final String PREFIX_PROGRAM = "+++ +++ +++ "; + static final String PREFIX_TESTSET = "+++ +++ "; + static final String PREFIX_TESTCASE = "+++ "; + + static final int COORD_1 = 11; + static final int COORD_2 = 22; + static final int COORD_3 = 33; + static final int COORD_4 = 44; + static final int COORD_5 = 55; + + /** + * std error tag printed if a test fails + **/ + static final String ERROR_TAG = "ERROR: "; + + /** + * main program for testing + * on error, an exception is thrown (java main() knows no exit status) + **/ + public static void main(String argv[]) throws Exception + { + System.out.println( "rasdaman system test v5.1revC: testing class RasPoint." ); + System.out.println( PREFIX_PROGRAM + "system test started." ); + + // -- START test cases ------------------------------------------------- + testConstructor(); + // testcomparedWith(); + // testEquals(); + // testStream(); + // testSetItem(); + // testSetTo(); + testAdd(); + // testmult(); + // -- END test cases --------------------------------------------------- + + System.out.println( PREFIX_PROGRAM + "system test done." ); + return; + } + + /** + * test the RasPoint class constructor + * any eventual exception that is not caught here is an error, and will cause an abort + **/ + static void testConstructor() throws RasDimensionMismatchException, RasIndexOutOfBoundsException + { + System.out.println( PREFIX_TESTSET + "testing constructor started." ); + + // default constructor + System.out.print( PREFIX_TESTCASE + "default constructor..." ); + RasPoint p_default = new RasPoint(); + if (p_default == null) + System.out.println( ERROR_TAG + "result is null." ); + else if (! p_default.equals( p_default ) ) + System.out.println( ERROR_TAG + "point notEqual to itself." ); + else + System.out.println( "OK, result=" + p_default + ", dimension is " + p_default.dimension() ); + + // stream constructor + // ------------------ + + System.out.print( PREFIX_TESTCASE + "stream constructor, illegal dimension -1..." ); + try + { + RasPoint p_stream_m1 = new RasPoint( -1 ); + if (p_stream_m1 != null) + System.out.println( ERROR_TAG + "result is not null." ); + else + System.out.println( "OK." ); + } + catch(NegativeArraySizeException e) + { + System.out.println( "OK: " + e.getMessage() ); + } + + System.out.print( PREFIX_TESTCASE + "stream constructor, dimension 0..." ); + RasPoint p_stream_0 = new RasPoint( 0 ); + if (p_stream_0.dimension() != 0) + System.out.println( ERROR_TAG + "wrong dimension." ); + else + System.out.println( "OK." ); + + // --- easy-to-use constructor ------------------------------------------------------- + + // 2-D constructor + System.out.print( PREFIX_TESTCASE + "2D easy to use constructor..." ); + RasPoint p_2d_easy = new RasPoint( COORD_1, COORD_2 ); + if (p_2d_easy == null) + System.out.println( ERROR_TAG + "result is null." ); + else if (p_2d_easy.dimension() != 2) + System.out.println( ERROR_TAG + "dimension is not 2 but " + p_2d_easy.dimension() ); + else if (p_2d_easy.item(0) != COORD_1) + System.out.println( ERROR_TAG + "item(0) returns wrong component " + p_2d_easy.item(0) ); + else if (p_2d_easy.item(1) != COORD_2) + System.out.println( ERROR_TAG + "item(1) returns wrong component " + p_2d_easy.item(0) ); + else if (! p_2d_easy.equals( p_2d_easy ) ) + System.out.println( ERROR_TAG + "point not equal to itself." ); + else if ( p_2d_easy.notEquals( p_2d_easy ) ) + System.out.println( ERROR_TAG + "point notEqual to itself." ); + else + System.out.println( "OK, result=" + p_2d_easy ); + + // 3-D constructor + System.out.print( PREFIX_TESTCASE + "3D easy to use constructor..." ); + RasPoint p_3d_easy= new RasPoint( COORD_1, COORD_2, COORD_3 ); + if (p_3d_easy== null) + System.out.println( ERROR_TAG + "result is null." ); + else if (p_3d_easy.dimension() != 3) + System.out.println( ERROR_TAG + "dimension is not 3 but " + p_3d_easy.dimension() ); + else if (p_3d_easy.item(2) != COORD_3) + System.out.println( ERROR_TAG + "item(2) returns wrong component " + p_3d_easy.item(0) ); + else if (! p_3d_easy.equals( p_3d_easy) ) + System.out.println( ERROR_TAG + "point not equal to itself." ); + else if ( p_3d_easy.notEquals( p_3d_easy) ) + System.out.println( ERROR_TAG + "point notEqual to itself." ); + else + System.out.println( "OK, result=" + p_3d_easy); + + // 4-D constructor + System.out.print( PREFIX_TESTCASE + "4D easy to use constructor..." ); + RasPoint p_4d_easy = new RasPoint( COORD_1, COORD_2, COORD_3, COORD_4 ); + if (p_4d_easy == null) + System.out.println( ERROR_TAG + "result is null." ); + else if (p_4d_easy.dimension() != 4) + System.out.println( ERROR_TAG + "dimension is not 4 but " + p_4d_easy.dimension() ); + else if (p_4d_easy.item(3) != COORD_4) + System.out.println( ERROR_TAG + "item(3) returns wrong component " + p_4d_easy.item(0) ); + else if (! p_4d_easy.equals( p_4d_easy ) ) + System.out.println( ERROR_TAG + "point not equal to itself." ); + else if ( p_4d_easy.notEquals( p_4d_easy ) ) + System.out.println( ERROR_TAG + "point notEqual to itself." ); + else + System.out.println( "OK, result=" + p_4d_easy ); + + // 5-D constructor + System.out.print( PREFIX_TESTCASE + "5D easy to use constructor..." ); + RasPoint p_5d_easy = new RasPoint( COORD_1, COORD_2, COORD_3, COORD_4, COORD_5 ); + if (p_5d_easy == null) + System.out.println( ERROR_TAG + "result is null." ); + else if (p_5d_easy.dimension() != 5) + System.out.println( ERROR_TAG + "dimension is not 5 but " + p_5d_easy.dimension() ); + else if (p_5d_easy.item(4) != COORD_5) + System.out.println( ERROR_TAG + "item(4) returns wrong component " + p_5d_easy.item(0) ); + else if (! p_5d_easy.equals( p_5d_easy ) ) + System.out.println( ERROR_TAG + "point not equal to itself." ); + else if ( p_5d_easy.notEquals( p_5d_easy ) ) + System.out.println( ERROR_TAG + "point notEqual to itself." ); + else + System.out.println( "OK, result=" + p_5d_easy ); + + // --- string constructor ------------------------------------------------------- + + // illegal string format + // FIXME: bug PB4 + System.out.println( ERROR_TAG + "PB4: string constructor, illegal string formats." ); + + // System.out.print( PREFIX_TESTCASE + "string constructor, illegal string format (no [)..." ); + // RasPoint p_si = new RasPoint( COORD_1 + "," + COORD_2 + "]" ); + // System.out.println( "point is: " + p_si ); + // if (! p_si.equals( new RasPoint( "[" + COORD_1 + "," + COORD_2 + "]" ) ) ) + // System.out.println( ERROR_TAG + "wrong point value." ); + + // System.out.print( PREFIX_TESTCASE + "string constructor, illegal string format (no ])..." ); + // p_si = new RasPoint( "[" + COORD_1 + "," + COORD_2 ); + // System.out.println( "point is: " + p_si ); + // if (! p_si.equals( new RasPoint( "[" + COORD_1 + "," + COORD_2 + "]" ) ) ) + // System.out.println( ERROR_TAG + "wrong point value." ); + + // System.out.print( PREFIX_TESTCASE + "string constructor, illegal string format (no ,)..." ); + // p_si = new RasPoint( "[" + COORD_1 + " " + COORD_2 + "]" ); + // System.out.println( "point is: " + p_si ); + // if (! p_si.equals( new RasPoint( "[" + COORD_1 + "," + COORD_2 + "]" ) ) ) + // System.out.println( ERROR_TAG + "wrong point value." ); + + // System.out.print( PREFIX_TESTCASE + "string constructor, illegal string format (bad int)..." ); + // p_si = new RasPoint( "[" + "abc" + "," + "xyz" + "]" ); + // System.out.println( "point is: " + p_si ); + // if (! p_si.equals( p_si ) ) + // System.out.println( ERROR_TAG + "point not equal to itself." ); + + // System.out.print( PREFIX_TESTCASE + "string constructor, illegal string format (missing int)..." ); + // p_si = new RasPoint( "[" + "," + "]" ); + // System.out.println( "point is: " + p_si ); + // if (! p_si.equals( p_si ) ) + // System.out.println( ERROR_TAG + "point not equal to itself." ); + + // 2-D constructor + System.out.print( PREFIX_TESTCASE + "2D string constructor..." ); + RasPoint p_2d = new RasPoint( "[" + COORD_1 + "," + COORD_2 + "]" ); + if (p_2d == null) + System.out.println( ERROR_TAG + "result is null." ); + else if (p_2d.dimension() != 2) + System.out.println( ERROR_TAG + "dimension is not 2 but " + p_2d.dimension() ); + else if (p_2d.item(0) != COORD_1) + System.out.println( ERROR_TAG + "item(0) returns wrong component " + p_2d.item(0) ); + else if (p_2d.item(1) != COORD_2) + System.out.println( ERROR_TAG + "item(1) returns wrong component " + p_2d.item(0) ); + else if (! p_2d.equals( p_2d ) ) + System.out.println( ERROR_TAG + "point not equal to itself." ); + else if ( p_2d.notEquals( p_2d ) ) + System.out.println( ERROR_TAG + "point notEqual to itself." ); + else + System.out.println( "OK, result=" + p_2d ); + + // 3-D constructor + System.out.print( PREFIX_TESTCASE + "3D string constructor..." ); + RasPoint p_3d = new RasPoint( "[" + COORD_1 + "," + COORD_2 + "," + COORD_3 + "]" ); + if (p_3d == null) + System.out.println( ERROR_TAG + "result is null." ); + else if (p_3d.dimension() != 3) + System.out.println( ERROR_TAG + "dimension is not 3 but " + p_3d.dimension() ); + else if (p_3d.item(2) != COORD_3) + System.out.println( ERROR_TAG + "item(2) returns wrong component " + p_3d.item(0) ); + else if (! p_3d.equals( p_3d ) ) + System.out.println( ERROR_TAG + "point not equal to itself." ); + else if ( p_3d.notEquals( p_3d ) ) + System.out.println( ERROR_TAG + "point notEqual to itself." ); + else + System.out.println( "OK, result=" + p_3d ); + + // 4-D constructor + System.out.print( PREFIX_TESTCASE + "4D string constructor..." ); + RasPoint p_4d = new RasPoint( "[" + COORD_1 + "," + COORD_2 + "," + COORD_3 + "," + COORD_4 + "]" ); + if (p_4d == null) + System.out.println( ERROR_TAG + "result is null." ); + else if (p_4d.dimension() != 4) + System.out.println( ERROR_TAG + "dimension is not 4 but " + p_4d.dimension() ); + else if (p_4d.item(3) != COORD_4) + System.out.println( ERROR_TAG + "item(3) returns wrong component " + p_4d.item(0) ); + else if (! p_4d.equals( p_4d ) ) + System.out.println( ERROR_TAG + "point not equal to itself." ); + else if ( p_4d.notEquals( p_4d ) ) + System.out.println( ERROR_TAG + "point notEqual to itself." ); + else + System.out.println( "OK, result=" + p_4d ); + + // 5-D constructor + System.out.print( PREFIX_TESTCASE + "5D string constructor..." ); + RasPoint p_5d = new RasPoint( "[" + COORD_1 + "," + COORD_2 + "," + COORD_3 + "," + COORD_4 + "," + COORD_5 + "]" ); + if (p_5d == null) + System.out.println( ERROR_TAG + "result is null." ); + else if (p_5d.dimension() != 5) + System.out.println( ERROR_TAG + "dimension is not 5 but " + p_5d.dimension() ); + else if (p_5d.item(4) != COORD_5) + System.out.println( ERROR_TAG + "item(4) returns wrong component " + p_5d.item(0) ); + else if (! p_5d.equals( p_5d ) ) + System.out.println( ERROR_TAG + "point not equal to itself." ); + else if ( p_5d.notEquals( p_5d ) ) + System.out.println( ERROR_TAG + "point notEqual to itself." ); + else + System.out.println( "OK, result=" + p_5d ); + + // copy constructor + System.out.print( PREFIX_TESTCASE + "copy constructor..." ); + RasPoint p_cp = new RasPoint( p_2d ); + if (p_cp == null) + System.out.println( ERROR_TAG + "result is null." ); + else if (p_cp.dimension() != p_2d.dimension()) + System.out.println( ERROR_TAG + "dimension mismatch." ); + else if (p_cp.item(0) != p_2d.item(0)) + System.out.println( ERROR_TAG + "item(0) returns wrong component " + p_cp.item(0) ); + else if (p_cp.item(1) != p_2d.item(1)) + System.out.println( ERROR_TAG + "item(1) returns wrong component " + p_cp.item(1) ); + else if (! p_cp.equals( p_2d ) ) + System.out.println( ERROR_TAG + "point not equal to origin." ); + else if ( p_cp.notEquals( p_2d ) ) + System.out.println( ERROR_TAG + "point notEqual to origin." ); + else + System.out.println( "OK, result=" + p_cp ); + + System.out.println( PREFIX_TESTSET + "testing constructor done.\n" ); + return; + } // testConstructor() + + /** + * test Point addition -- TO BE DONE + * any eventual exception that is not caught here is an error, and will cause an abort + **/ + static void testAdd() throws RasDimensionMismatchException, RasIndexOutOfBoundsException, RasStreamInputOverflowException + { + System.out.println( PREFIX_TESTSET + "testing add started." ); + + RasPoint p1 = new RasPoint(COORD_3,COORD_4); + RasPoint p2 = new RasPoint(COORD_3,COORD_4); + p2 = p2.add(p2); + + // test if two points are equal + boolean b1 = false; + if(p2.comparedWith(p1) == 0) + b1 = p1.equals(p2); + else + b1 = false; + System.out.println("points are equal: " + b1); + + // get the dimension of a Point + int i; + b1 = false; + if((p1.dimension() == 2) && (2 == p2.dimension())) + b1 = true; + System.out.println("dimensions of points are correct: " + b1); + + b1 = false; + p2.setItem(1, 48); + if(p2.item(1) == 48) + b1 = true; + System.out.println("read and write access of points is OK: " + b1); + + b1 = false; + p2.setTo(p2.mult(p1)); + if(p2.equals(new RasPoint(443556, 42624))) + b1 = true; + System.out.println("mult and setTo is OK: " + b1); + + b1 = false; + RasPoint ps = new RasPoint( 3 ); + ps.stream( 42 ); + if(ps.item(0) == 42) + b1 = true; + System.out.println("stream initializing of points is OK: " + b1); + + System.out.println( PREFIX_TESTSET + "testing add done.\n" ); + return; + } // testAdd() + + } // TestRasPoint diff --git a/java/src/rasj/test/count.sh b/java/src/rasj/test/count.sh new file mode 100644 index 0000000..83b7ece --- /dev/null +++ b/java/src/rasj/test/count.sh @@ -0,0 +1,11 @@ +#!/bin/bash + + +awk < $1 ' +BEGIN { COUNT=0; MIN=1000; MAX=0; SMALL=0; LARGE=0;} + { COUNT++; + if ($6>1000) LARGE++; else SMALL++; + if ($6>MAX) MAX = $6; + if ($6<MIN) MIN = $6; + } +END { printf("count=%d, small=%d, large=%d, min=%d, max=%d, percent=%f\n", COUNT, SMALL, LARGE, MIN, MAX, LARGE/COUNT*100 ); } ' diff --git a/java/src/rasj/test/httptest.java b/java/src/rasj/test/httptest.java new file mode 100644 index 0000000..4754ec7 --- /dev/null +++ b/java/src/rasj/test/httptest.java @@ -0,0 +1,53 @@ +/* +* 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>. +*/ +package rasj.test; + +import rasj.*; +import rasj.clientcommhttp.*; + +public class httptest +{ + + public static void main(String[] args) + { + + + System.err.println("Start ..."); + RasHttpRequest test = new RasHttpRequest(); + try + { + test.execute("http://maitai.akglocal.de:8080/","SELECT img[0:200,0:200] FROM lva AS img"); + } + catch( RasQueryExecutionFailedException e) + { + System.err.println(e.getMessage()); + } + + + + + } + + + +} diff --git a/java/src/rasj/test/testEva.java b/java/src/rasj/test/testEva.java new file mode 100644 index 0000000..907afd0 --- /dev/null +++ b/java/src/rasj/test/testEva.java @@ -0,0 +1,229 @@ +/* +* 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>. +*/ +package rasj.test; + +import java.util.StringTokenizer; +import java.lang.Integer; +import java.lang.Long; +import rasj.*; +import rasj.odmg.*; + +public class testEva +{ + + public static void main(String argv[]) throws RasException + { + + // Points and Intervals + ////////////////////////////////////////////// + // create a new RasPoint + RasPoint p1 = new RasPoint("[666, 777]"); + RasPoint p2 = new RasPoint(5,4); + + // test if two points are equal + boolean b1; + b1 = p1.equals(p2); + + // get the dimension of a Point + int i; + i = p1.dimension(); + + + + // create a new RasSInterval + RasSInterval s1 = new RasSInterval(100,200); + RasSInterval s2 = new RasSInterval("150:400"); + + // get upper bound + long l1; + l1 = s2.high(); + + // test if lower bound is fixed + boolean b2; + b2 = s2.isLowFixed(); + + // test if interval intersects with another interval + // (the return value shows the kind of intersection) + int j; + j = s1.intersectsWith(s2); + + + // create new RasMInterval + RasMInterval m1 = new RasMInterval("[567:3253,666:777]"); + RasMInterval m2 = new RasMInterval(4); + + // get number of cells + long l2 = 1; + RasPoint m1Ext = m1.getExtent(); + for (int dimi =0; dimi < m1Ext.dimension() ; dimi++) + { + l2 = l2 * m1Ext.item(dimi); + } + + // Types + /////////////////////////////////////////// + String s = "marray <char, 1>"; + RasType rType = RasType.getAnyType(s); + RasBaseType rb; + + if(rType.getClass().getName().equals("rasj.RasMArrayType")) + { + RasMArrayType tmp = (RasMArrayType)rType; + rb = tmp.getBaseType(); + + System.out.println(rb); + } + else + System.out.println("element of MDD Collection is no MArray."); + + boolean b3; + b3 = rType.isStructType(); + + + + // StorageLayout + /////////////////////////////////////////// + RasGMArray myMDD = new RasGMArray(new RasMInterval("[1:400,1:400]"),1); + byte[] mydata = new byte[160000]; + for(int y=0; y<400; y++) + { + for(int x=0; x<400; x++) + { + if((x>99 && x<151) || (x>299 && x<351)) + mydata[y*399+x]=100; + else + mydata[y*399+x]=0; + } + } + + myMDD.setArray(mydata); + myMDD.setObjectTypeName("GreyImage"); + + RasStorageLayout myLayout = new RasStorageLayout(); + + myLayout.setTileSize(32); + // you can either set the TileSize or the TileDomain + myLayout.setTileDomain("[1:100,1:70]"); + //myMDD.setStorageLayout(); + + + i = p2.dimension(); + b1 = p1.equals(p2); + //System.out.println(p1); + //p1.setTo(p1.mult(p2)); + + //sinterval////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + RasSInterval sint1 = new RasSInterval(100,200); + RasSInterval sint2 = new RasSInterval("150 :400 "); + RasSInterval sint3 = new RasSInterval("50:250"); + + + + sint1.setHigh(500); + sint1.setLow(400); + sint1.setLow('*'); + sint1.setHigh('*'); + + sint1.setInterval('*',500); + + l1 = sint1.low(); + l2 = sint1.high(); + b1 = sint1.isLowFixed(); + + i = sint1.intersectsWith(sint1); + + //System.out.println(sint1); + //System.out.println(l1); + //System.out.println(l2); + //System.out.println(b1); + //System.out.println(i); + + sint3 = sint3.unionOf(sint1, sint2); + sint3 = sint3.unionWith(sint2); + sint3 = sint3.addToSelf(sint2); + sint3 = sint3.createUnion(sint2); + sint3 = sint3.add(sint2); + //sint3 = sint3.differenceOf(sint2, sint1); + //sint3 = sint3.differenceWith(sint1); + sint3 = sint3.intersectionOf(sint2, sint1); + sint3 = sint3.intersectionWith(sint2); + sint3 = sint3.multWithSelf(sint2); + sint3 = sint3.createIntersection(sint2); + sint3 = sint3.mult(sint2); + sint3 = sint3.closureOf(sint2, sint1); + sint3 = sint3.closureWith(sint2); + sint3 = sint3.createClosure(sint2); + + //Minterval////////////////////////////////////////////////////////////////////////////////////////////////////////////// + RasMInterval mint1 = new RasMInterval("[567 :3253,666 :777]"); + RasMInterval mint2 = new RasMInterval(4); + + //GMarray//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + RasGMArray array1 = new RasGMArray(); + RasGMArray array2 = new RasGMArray(mint1, 8); + + + byte[] bya = new byte[8]; + + + + l1 = 1; + RasPoint mint1Ext = mint1.getExtent(); + for (int dimi =0; dimi < mint1Ext.dimension() ; dimi++) + { + l1 = l1 * mint1Ext.item(dimi); + } + + array1.setTo(array2); + //bya = array2.getCell(p1); + array2.intersectionWith(mint1); + + + //Ausgabe//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + System.out.println("Array1 " + array1); + System.out.println("Array2 " + array2); + + + + System.out.println("Punkt1 " + p1); + System.out.println("Punkt2 " + p2); + + System.out.println("Sinterval1 " + s1); + System.out.println("Sinterval2 " + s2); + //System.out.println("Sinterval3 " + sint3); + + System.out.println("Minterval1 " + m1); + System.out.println("Minterval2 " + m2); + + + System.out.println("i = " + i); + System.out.println("j = " + j); + System.out.println("b1 = " + b1); + System.out.println("b2 = " + b2); + System.out.println("b3 = " + b3); + System.out.println("l1 = " + l1); + System.out.println("l2 = " + l2); + //System.out.println(bya); + + } +} diff --git a/java/src/rasj/test/testIntervals.java b/java/src/rasj/test/testIntervals.java new file mode 100644 index 0000000..a06d980 --- /dev/null +++ b/java/src/rasj/test/testIntervals.java @@ -0,0 +1,326 @@ +/* +* 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>. +*/ +package rasj.test; + +import java.util.StringTokenizer; +import java.lang.Integer; +import java.lang.Long; +import rasj.*; +import rasj.odmg.*; + +public class testIntervals +{ + + public static void main(String argv[]) throws RasException + { + testIntervals intervalTest = new testIntervals(); + } + + public testIntervals() + { + try + { + // Points and Intervals + ////////////////////////////////////////////// + System.out.println("\n############################ test points: "); + // create a new RasPoint + RasPoint p1 = new RasPoint("[666, 888]"); + RasPoint p2 = new RasPoint(333,444); + p2 = p2.add(p2); + + // test if two points are equal + boolean b1 = false; + if(p2.comparedWith(p1) == 0) + b1 = p1.equals(p2); + else + b1 = false; + System.out.println("points are equal: " + b1); + + // get the dimension of a Point + int i; + b1 = false; + if((p1.dimension() == 2) && (2 == p2.dimension())) + b1 = true; + System.out.println("dimensions of points are correct: " + b1); + + b1 = false; + p2.setItem(1, 48); + if(p2.item(1) == 48) + b1 = true; + System.out.println("read and write access of points is OK: " + b1); + + b1 = false; + p2.setTo(p2.mult(p1)); + if(p2.equals(new RasPoint(443556, 42624))) + b1 = true; + System.out.println("mult and setTo is OK: " + b1); + + b1 = false; + p1.stream(3); + if(p1.item(0) == 3) + b1 = true; + System.out.println("stream initializing of points is OK: " + b1); + + + // create a new RasSInterval + System.out.println("\n############################ test sintervals: "); + RasSInterval s1 = new RasSInterval(100,200); + RasSInterval s2 = new RasSInterval("150:400"); + + // get upper bound + b1 = false; + if(s2.high() == 400) + b1 = true; + System.out.println("upper bound is correct: " + b1); + + // test if lower bound is fixed + boolean b2; + b1 = false; + b1 = s2.isLowFixed(); + System.out.println("lower bound is fix: " + b1); + + // test if interval intersects with another interval + // (the return value shows the kind of intersection) + int j; + j = s1.intersectsWith(s2); + b1 = false; + if(j != -1) + b1 = true; + System.out.println("s1 intersects with s2: " + b1); + + RasSInterval sint1 = new RasSInterval(100,200); + RasSInterval sint2 = new RasSInterval("150 :400 "); + RasSInterval sint3 = new RasSInterval("50:180"); + + b1 = false; + sint1.setHigh('*'); + sint1.setLow(400); + if(sint1.low() == 400) + b1 = true; + sint1.setLow('*'); + sint1.setHigh(500); + if((sint1.high() == 500) && b1) + b1 = true; + else + b1 = false; + System.out.println("setLow and setHigh are OK: " + b1); + + sint1.setInterval('*',500); + b1 = !sint1.isLowFixed(); + b1 = sint1.isHighFixed() && b1; + System.out.println("low is open high is fixed: " + b1); + + b1 = false; + if(sint1.intersectsWith(sint1) != -1) + b1 = true; + + if(sint3.closureOf(sint2, sint1).equals(sint1) && + sint3.closureWith(sint2).equals(sint1) && + sint3.createClosure(sint2).equals(sint1)) + b1 = b1 && true; + + sint1.setInterval(90, 105); + sint2.setInterval(100, 110); + if(sint2.createDifference(sint1).equals(new RasSInterval(90, 100)) && + sint3.createIntersection(sint2).equals(new RasSInterval(100, 110))) + b1 = b1 && true; + + if(sint3.createUnion(sint2).equals(sint1) && + sint1.differenceOf(sint1, sint2).equals(new RasSInterval(90, 100)) && + sint1.differenceWith(sint2).equals(new RasSInterval(100, 110))) + b1 = b1 && true; + + if(sint3.intersectionOf(sint2, sint1).equals(new RasSInterval(100, 100)) && + sint3.intersectionWith(sint2).equals(new RasSInterval(100, 100))) + b1 = b1 && true; + + b1 = b1 && !sint3.equals(sint2); + if(sint3.unionOf(sint1, sint2).equals(new RasSInterval(90, 110)) && + sint3.unionWith(sint2).equals(new RasSInterval(90, 110))) + b1 = b1 && true; + System.out.println("operations of sintervals are correct: " + b1); + + + + // create new RasMInterval + System.out.println("\n############################ test mintervals: "); + RasMInterval mint1 = new RasMInterval("[567:3253,666:888]"); + RasMInterval mint2 = new RasMInterval("[678:4000,777:999]"); + RasMInterval mint3 = new RasMInterval("[777:900,888:1000]"); + RasMInterval mint4 = new RasMInterval(2); + b1 = false; + if((mint2.dimension() == 2) && (mint1.dimension() == 2)) + b1 = true; + System.out.println("dimensions of mintervals are correct: " + b1); + + b1 = false; + mint1 = new RasMInterval("[500:3000,600:800]"); + mint2 = new RasMInterval("[600:1000,700:750]"); + b1 = mint1.intersectsWith(mint2); + mint1 = new RasMInterval("[567:3253,666:888]"); + mint2 = new RasMInterval("[678:4000,777:999]"); + if(mint3.closureOf(mint2, mint1).toString().equals(new RasMInterval("[567:4000,666:999]").toString())) + b1 = b1 && true; + else b1 = false; + if(mint3.closureWith(mint2).toString().equals(new RasMInterval("[567:4000,666:999]").toString())) + b1 = b1 && true; + else b1 = false; + if(mint3.createClosure(mint2).toString().equals(new RasMInterval("[567:4000,666:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = new RasMInterval("[678:2000,777:888]"); + mint3 = mint3.createDifference(mint2); + if(mint3.toString().equals(new RasMInterval("[2000:4000,888:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = new RasMInterval("[678:2000,777:888]"); + mint3 = mint3.createDifference(mint2); + if(mint3.toString().equals(new RasMInterval("[2000:4000,888:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = new RasMInterval("[678:2000,777:888]"); + mint3 = mint3.createIntersection(mint2); + if(mint3.toString().equals(new RasMInterval("[678:2000,777:888]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = new RasMInterval("[678:2000,777:888]"); + mint2 = new RasMInterval("[1000:4000,750:999]"); + mint3 = mint3.createUnion(mint2); + if(mint3.toString().equals(new RasMInterval("[678:4000, 750:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint2 = new RasMInterval("[1000:4000,800:999]"); + mint1 = mint1.differenceOf(mint3, mint2); + if(mint1.toString().equals(new RasMInterval("[678:1000,750:800]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = mint3.intersectionOf(mint2, mint1); + if(mint3.toString().equals(new RasMInterval("[1000:1000,800:800]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = mint3.intersectionWith(mint2); + if(mint3.toString().equals(new RasMInterval("[1000:1000,800:800]").toString())) + b1 = b1 && true; + else b1 = false; + b1 = b1 && !mint3.equals(mint2); + mint3 = mint3.unionOf(mint1, mint2); + if(mint3.toString().equals(new RasMInterval("[678:4000,750:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint3 = mint3.unionWith(mint2); + if(mint3.toString().equals(new RasMInterval("[678:4000,750:999]").toString())) + b1 = b1 && true; + else b1 = false; + mint2 = mint2.differenceWith(mint3); + if(mint2.toString().equals(new RasMInterval("[678:1000,750:800]").toString())) + b1 = b1 && true; + else b1 = false; + System.out.println("operations of mintervals are correct: " + b1); + + // Types + /////////////////////////////////////////// + System.out.println("\n############################ test types: "); + String s = "marray <char, 1>"; + RasType rType = RasType.getAnyType(s); + RasBaseType rb; + + if(rType.getClass().getName().equals("rasj.RasMArrayType")) + { + RasMArrayType tmp = (RasMArrayType)rType; + rb = tmp.getBaseType(); + + System.out.println("OK"); + } + else + System.out.println("element of MDD Collection is no MArray."); + + boolean b3; + b3 = !rType.isStructType(); + System.out.println(b3); + + + // StorageLayout + /////////////////////////////////////////// + System.out.println("\n############################ test storage layout: "); + RasGMArray myMDD = new RasGMArray(new RasMInterval("[1:400,1:400]"),1); + byte[] mydata = new byte[160000]; + for(int y=0; y<400; y++) + { + for(int x=0; x<400; x++) + { + if((x>99 && x<151) || (x>299 && x<351)) + mydata[y*399+x]=100; + else + mydata[y*399+x]=0; + } + } + + myMDD.setArray(mydata); + myMDD.setObjectTypeName("GreyImage"); + + RasStorageLayout myLayout = new RasStorageLayout(); + + myLayout.setTileDomain("[1:100,1:70]"); + // you can either set the TileSize or the TileDomain + myLayout.setTileSize(32); + myMDD.setStorageLayout(myLayout); + if(myMDD.getStorageLayout().getTileSize() == 32) + System.out.println("OK"); + + + //GMarray//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + RasGMArray array1 = new RasGMArray(); + RasGMArray array2 = new RasGMArray(mint1, 8); + + myMDD.getCell(new RasPoint(1,1)); + + System.out.println("OK"); + + + //Ausgabe//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /* + System.out.println("Array1 " + array1); + System.out.println("Array2 " + array2); + + System.out.println("Punkt1 " + p1); + System.out.println("Punkt2 " + p2); + + System.out.println("Sinterval1 " + s1); + System.out.println("Sinterval2 " + s2); + System.out.println("Sinterval3 " + sint3); + + System.out.println("j = " + j); + //System.out.println("b1 = " + b1); + //System.out.println("b2 = " + b2); + System.out.println("b3 = " + b3); + */ + + + } + catch (RasException e) + { + System.out.println("!!!!!!!!!!!!!!!!!!!!While testing!!!!!!!!!!!!!!!!!!"); + System.out.println("An RasException has occurred: " + e.getMessage()); + } + } +} diff --git a/java/src/rasj/test/testMArrays.java b/java/src/rasj/test/testMArrays.java new file mode 100644 index 0000000..272ece1 --- /dev/null +++ b/java/src/rasj/test/testMArrays.java @@ -0,0 +1,871 @@ +package rasj.test; + +/* +* 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: class for testing special MArrays + * + * + * + * COMMENTS: + * + * </pre> + *********************************************************** */ + +import java.io.*; +import java.net.*; +import rasj.clientcommhttp.*; +import rasj.odmg.*; +import org.odmg.*; +import rasj.*; +import java.util.*; + +/** + * class for testing special MArrays + * for testing please enable test data output in toString method of RASGMArray + * @version $$ + */ +public class testMArrays +{ + public static void main(String[] args) + { + String serv = "localhost"; + String base = "RASBASE"; + String coll = "test"; + + for (int i=args.length-1; i>=0; i--) + { + //System.out.println(args[i]); + if (args[i].equals("-server")) + serv = args[i+1]; + if (args[i].equals("-database")) + base = args[i+1]; + if (args[i].equals("-collection")) + coll = args[i+1]; + } + //System.out.println(server+base+coll); + testMArrays marrayTest = new testMArrays(serv); + + } + + public testMArrays(String server) + { + DBag resultBag = null; + Object result = null; + Transaction myTa = null; + Database myDb = null; + OQLQuery myQu = null; + + boolean equal = false; + + try + { + System.out.println("### Testing MArrays: ..."); + Implementation myApp = new RasImplementation("http://"+server+":7001"); + myDb = myApp.newDatabase(); + + System.out.println("Opening database ..."); + myDb.open("RASBASE", Database.OPEN_READ_WRITE); + myTa = myApp.newTransaction(); + + int width, height, len; + width = 18; + height = 18; + len = (width+1)*(height+1); + RasMInterval domain = new RasMInterval("[0:"+width+",0:"+height+"]"); + RasMInterval domain2 = new RasMInterval("[1:3,1:3]"); + RasStorageLayout stl = new RasStorageLayout(); + stl.setTileSize(128); + + + /** + * test the GMArray + */ + System.out.println("\n\n### Testing GMArray with OID: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + try + { + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + } + catch(ODMGException e) + { + myTa.abort(); + System.err.println("Collection test does not exist: " + e.getMessage()); + } + + myQu.create("create collection test GreySet"); + RasGMArray mddConst = new RasGMArray(domain, 1, stl); + //RasGMArray mddConst = new RasGMArray(domain, 1); + byte[] data = new byte[len]; + mddConst.setObjectTypeName("GreyImage"); + + // test: get new OID from the server for GMArray and insert + System.out.println("new OID from server: " + myApp.getObjectId(mddConst)); + + for(int j = 0; j < data.length; j++) + data[j] = (byte)j; + + mddConst.setArray(data); + /* + System.out.println("\nbyte array: "); + for(int j=0; j<mddConst.getArray().length; j++) + { + System.out.print(" "+ mddConst.getArray()[j]); + } + */ + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddConst); + myQu.bind(mddConst); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<mddConst.getArray().length; j++) + { + if(mddConst.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + if(!(myApp.getObjectId(mddConst).toString()).equals(myApp.getObjectId((RasGMArray)result).toString())) + equal = false; + System.out.println("result mdd: " + ((RasGMArray)mddConst).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + System.out.println("inserted and selected GMArray and OIDs are equal: " + equal); + //System.out.println("All results for test GMArray"); + } + + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasGMArray mddConst2 = new RasGMArray(mddConst); + mddConst2.setArray(data); + //System.out.println("\nbyte array2: "); + data = null; + equal = true; + for(int j=0; j<mddConst.getArray().length; j++) + { + //System.out.print(" "+ mddConst2.getArray()[j]); + if(mddConst.getArray()[j] != mddConst2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + /** + * test the MArrayByte + */ + System.out.println("\n\n### Testing MArrayByte: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test GreySet"); + RasMArrayByte mddByte = new RasMArrayByte(domain, stl); + byte[] dataByte = new byte[len]; + mddByte.setObjectTypeName("GreyImage"); + + for(int j = 0; j < dataByte.length; j++) + dataByte[j] = (byte)j; + + mddByte.setArray(dataByte); + + //System.out.println("\nbyte array: "); + //for(int j=0; j<mddByte.getArray().length; j++) + //{ + //System.out.print(" "+ mddByte.getArray()[j]); + //} + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddByte); + myQu.bind(mddByte); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + System.out.println("result mdd: " + ((RasGMArray)mddByte).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + equal = true; + for(int j=0; j<mddByte.getArray().length; j++) + { + if(mddByte.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + } + //System.out.println("All results for MArrayByte"); + System.out.println("inserted and selected MArrayByte are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayByte mddByte2 = new RasMArrayByte(mddByte); + mddByte2.setArray(dataByte); + //System.out.println("\nbyte array2: "); + dataByte = null; + equal = true; + for(int j=0; j<mddByte.getArray().length; j++) + { + //System.out.print(" "+ mddByte2.getArray()[j]); + if(mddByte.getArray()[j] != mddByte2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + /** + * test the MArrayInteger + */ + System.out.println("\n\n### Testing MArrayInteger: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test UShortSet"); + RasMArrayInteger mddInteger = new RasMArrayInteger(domain, stl); + int[] dataInteger = new int[len]; + //byte[] dataInteger = new byte[144]; + mddInteger.setObjectTypeName("UShortImage"); + + for(int j = 0; j < dataInteger.length; j++) + dataInteger[j] = j; + + mddInteger.setArray(dataInteger); + + //System.out.println("\nbyte array: "); + //for(int j=0; j<mddInteger.getArray().length; j++) + //{ + //System.out.print(" "+ mddInteger.getArray()[j]); + //} + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddInteger); + myQu.bind(mddInteger); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + System.out.println("result mdd: " + ((RasGMArray)mddInteger).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + equal = true; + for(int j=0; j<mddInteger.getArray().length; j++) + { + if(mddInteger.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + } + //System.out.println("All results for MArrayInteger"); + System.out.println("inserted and selected MArrayInteger are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayInteger mddInteger2 = new RasMArrayInteger(mddInteger); + mddInteger2.setArray(dataInteger); + dataInteger = null; + equal = true; + for(int j=0; j<mddInteger2.getArray().length; j++) + { + //System.out.print(" "+ mddInteger2.getArray()[j]); + if(mddInteger.getArray()[j] != mddInteger2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + /* + System.out.println("\nspecial array2: "); + for(int j=0; j<mddInteger2.getIntArray().length; j++) + { + System.out.print(" "+ mddInteger2.getIntArray()[j]); + } + */ + + /** + * test the MArrayDouble + */ + System.out.println("\n\n### Testing MArrayDouble: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test DoubleSet"); + RasMArrayDouble mddDouble = new RasMArrayDouble(domain, stl); + double[] dataDouble = new double[len]; + //byte[] dataDouble = new byte[288]; + mddDouble.setObjectTypeName("DoubleImage"); + + for(double j = 0; j < dataDouble.length; j++) + dataDouble[(int)j] = j; + + mddDouble.setArray(dataDouble); + + //System.out.println("\nbyte array: "); + //for(int j=0; j<mddDouble.getArray().length; j++) + //{ + //System.out.print(" "+ mddDouble.getArray()[j]); + //} + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddDouble); + myQu.bind(mddDouble); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<mddDouble.getDoubleArray().length; j++) + { + if(mddDouble.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + System.out.println("result mdd: " + ((RasGMArray)mddDouble).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + //System.out.println("All results for MArrayDouble"); + System.out.println("inserted and selected MArrayDouble are equal: " + equal); + } + + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayDouble mddDouble2 = new RasMArrayDouble(mddDouble); + mddDouble2.setArray(dataDouble); + //System.out.println("byte array2: "); + dataDouble = null; + equal = true; + for(int j=0; j<mddDouble2.getArray().length; j++) + { + //System.out.print(" "+ mddDouble2.getArray()[j]); + if(mddDouble.getArray()[j] != mddDouble2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + /* + System.out.println("\nspecial array2: "); + for(int j=0; j<mddDouble2.getDoubleArray().length; j++) + { + System.out.print(" "+ mddDouble2.getDoubleArray()[j]); + } + */ + + /** + * test the MArrayFloat + */ + System.out.println("\n\n### Testing MArrayFloat: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test FloatSet"); + RasMArrayFloat mddFloat = new RasMArrayFloat(domain, stl); + float[] dataFloat = new float[len]; + //byte[] dataFloat = new byte[144]; + mddFloat.setObjectTypeName("FloatImage"); + + for(float j = 0; j < dataFloat.length; j++) + dataFloat[(int)j] = j; + + mddFloat.setArray(dataFloat); + + //System.out.println("\nbyte array: "); + //for(int j=0; j<mddFloat.getArray().length; j++) + //{ + //System.out.print(" "+ mddFloat.getArray()[j]); + //} + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddFloat); + myQu.bind(mddFloat); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<mddFloat.getArray().length; j++) + { + if(mddFloat.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + System.out.println("result mdd: " + ((RasGMArray)mddFloat).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + //System.out.println("All results for MArrayFloat"); + System.out.println("inserted and selected MArrayFloat are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayFloat mddFloat2 = new RasMArrayFloat(mddFloat); + mddFloat2.setArray(dataFloat); + //System.out.println("\nbyte array2: "); + dataFloat = null; + equal = true; + for(int j=0; j<mddFloat2.getArray().length; j++) + { + //System.out.print(" "+ mddFloat2.getArray()[j]); + if(mddFloat.getArray()[j] != mddFloat2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + /* + System.out.println("\nspecial array2: "); + for(int j=0; j<mddFloat2.getFloatArray().length; j++) + { + System.out.print(" "+ mddFloat2.getFloatArray()[j]); + } + */ + + /** + * test the MArrayShort + */ + System.out.println("\n\n### Testing MArrayShort: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test ShortSet"); + RasMArrayShort mddShort = new RasMArrayShort(domain, stl); + //RasMArrayShort mddShort4 = new RasMArrayShort(domain, stl); + //RasMArrayShort mddShort3 = new RasMArrayShort(domain, stl); + short[] dataShort = new short[len]; + //short[] dataShort4 = new short[len]; + //short[] dataShort3 = new short[len]; + //byte[] dataShort = new byte[72]; + mddShort.setObjectTypeName("ShortImage"); + //mddShort4.setObjectTypeName("ShortImage"); + //mddShort3.setObjectTypeName("ShortImage"); + + //System.out.println("new OID from server: " + myApp.getObjectId(mddShort)); + //System.out.println("new OID from server: " + myApp.getObjectId(mddShort4)); + for(int j = 0; j < dataShort.length; j++) + dataShort[j] = (short)j; + + //for(int j = 0; j < dataShort.length; j++) + //dataShort[j] = 1; + //for(int j = 0; j < dataShort4.length; j++) + //dataShort4[j] = 2; + //for(int j = 0; j < dataShort3.length; j++) + //dataShort3[j] = 3; + + + mddShort.setArray(dataShort); + //mddShort4.setArray(dataShort4); + //mddShort3.setArray(dataShort3); + /* + System.out.println("\nbyte array: "); + for(int j=0; j<mddShort.getArray().length; j++) + { + System.out.print(" "+ mddShort.getArray()[j]); + } + */ + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + myQu = myApp.newOQLQuery(); + //System.out.println("\ncollection created"); + //myQu.create("insert into test values $1"); + myQu.create("insert into test values $1"); + //System.out.println("mdd before sending: " + mddShort); + //myQu.bind("test"); + myQu.bind(mddShort); + //myQu.bind(mddShort4); + //myQu.bind(mddShort3); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + /* + myTa.begin(); + myQu = myApp.newOQLQuery(); + myQu.create("insert into test values $1"); + myQu.bind(mddShort4); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + myTa.begin(); + myQu = myApp.newOQLQuery(); + myQu.create("insert into test values $1"); + myQu.bind(mddShort3); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + */ + //System.out.println("collection inserted"); + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<mddShort.getArray().length; j++) + { + if(mddShort.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + System.out.println("result mdd: " + ((RasGMArray)mddShort).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + //System.out.println("All results for MArrayShort"); + System.out.println("inserted and selected MArrayShort are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayShort mddShort2 = new RasMArrayShort(mddShort); + mddShort2.setArray(dataShort); + //System.out.println("\nbyte array2: "); + dataShort = null; + equal = true; + for(int j=0; j<mddShort2.getArray().length; j++) + { + //System.out.print(" "+ mddShort2.getArray()[j]); + if(mddShort.getArray()[j] != mddShort2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + /* + System.out.println("\nspecial array2: "); + for(int j=0; j<mddShort2.getShortArray().length; j++) + { + System.out.print(" "+ mddShort2.getShortArray()[j]); + } + */ + + /** + * test the MArrayLong + */ + System.out.println("\n\n### Testing MArrayLong: ################################################"); + myQu = myApp.newOQLQuery(); + + myQu.create("drop collection test"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection dropped"); + + myQu.create("create collection test ULongSet"); + RasMArrayLong mddLong = new RasMArrayLong(domain, stl); + long[] dataLong = new long[len]; + //byte[] dataLong = new byte[288]; + mddLong.setObjectTypeName("ULongImage"); + + for(long j = 0; j < dataLong.length; j++) + dataLong[(int)j] = j; + mddLong.setArray(dataLong); + + /* + System.out.println("\nbyte array: "); + for(int j=0; j<mddLong.getArray().length; j++) + { + System.out.print(" "+ mddLong.getArray()[j]); + } + */ + + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("\ncollection created"); + myQu.create("insert into test values $1 "); + + //System.out.println("mdd before sending: " + mddLong); + myQu.bind(mddLong); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection inserted"); + + myQu = myApp.newOQLQuery(); + myQu.create("select img from test as img"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + //System.out.println("collection selected"); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + equal = true; + for(int j=0; j<((RasGMArray)result).getArray().length; j++) + { + if(mddLong.getArray()[j] != ((RasGMArray)result).getArray()[j]) + equal = false; + } + System.out.println("result mdd: " + ((RasGMArray)mddLong).toTestString()); + System.out.println("result mdd: " + ((RasGMArray)result).toTestString()); + } + //System.out.println("All results for MArrayLong"); + System.out.println("inserted MArrayInteger and selected MArrayLong are equal: " + equal); + } + + // testing copy constructor + System.out.println("### Testing copy constructor:"); + RasMArrayLong mddLong2 = new RasMArrayLong(mddLong); + mddLong2.setArray(dataLong); + //System.out.println("\nbyte array2: "); + dataLong = null; + equal = true; + for(int j=0; j<mddLong2.getArray().length; j++) + { + //System.out.print(" "+ mddLong2.getArray()[j]); + if(mddLong.getArray()[j] != mddLong2.getArray()[j]) + equal = false; + } + System.out.println("Copy constructor is OK: " + equal); + + System.out.println("\nspecial array: "); + for(int j=0; j<((RasMArrayLong)result).getLongArray().length; j++) + { + System.out.print(" "+ ((RasMArrayLong)result).getLongArray()[j]); + } + + + /** + * testing intersection + */ + System.out.println("\n\n### Testing intersection:"); + mddConst2.intersectionWith(domain2); + mddByte2.intersectionWith(domain2); + mddDouble2.intersectionWith(domain2); + mddFloat2.intersectionWith(domain2); + mddInteger2.intersectionWith(domain2); + mddLong2.intersectionWith(domain2); + mddShort2.intersectionWith(domain2); + System.out.println("OK\n"); + + /** + * testing OIDs + */ + myQu = myApp.newOQLQuery(); + myQu.create("SELECT oid(img) FROM test AS img"); + //myQu.create("SELECT img FROM test AS img where (oid(img)=231425)"); + myTa.begin(); + resultBag = (DBag)myQu.execute(); + myTa.commit(); + if (resultBag != null) + { + Iterator iter = resultBag.iterator(); + while (iter.hasNext()) + { + result = iter.next(); + //System.out.println("OID: " + result); + } + //System.out.println("All results"); + + } + + /** + * get new OID + */ + System.out.println("### Testing OIDs:"); + myTa.begin(); + myApp.getObjectId(new RasGMArray()); + myTa.commit(); + + System.out.println( "Closing database ..." ); + myDb.close(); + + // get new OID without open TA + RasGMArray gmar = new RasGMArray(); + equal = true; + if(!myApp.getObjectId(gmar).equals(gmar.getOID().toString())) + equal = false; + System.out.println("same OID on client and server side: " + equal); + + } + catch (RasException e) + { + System.out.println("!!!!!!!!!!!!!!!!!!!!While testing!!!!!!!!!!!!!!!!!!"); + System.out.println("An RasException has occurred: " + e.getMessage()); + System.out.println("Try to abort the transaction ..."); + if(myTa != null) myTa.abort(); + + try + { + System.out.println("Try to close the database ..."); + if(myDb != null) myDb.close(); + } + catch ( org.odmg.ODMGException exp ) + { + System.err.println("Could not close the database: " + exp.getMessage()); + } + } + catch (RasRuntimeException e) + { + System.out.println("!!!!!!!!!!!!!!!!!!!!While testing!!!!!!!!!!!!!!!!!!"); + System.out.println("An RasRuntimeException has occurred: " + e.getMessage()); + System.out.println("Try to abort the transaction ..."); + if(myTa != null) myTa.abort(); + + try + { + System.out.println("Try to close the database ..."); + if(myDb != null) myDb.close(); + } + catch ( org.odmg.ODMGException exp ) + { + System.err.println("Could not close the database: " + exp.getMessage()); + } + } + catch (org.odmg.ODMGException e) + { + System.out.println("!!!!!!!!!!!!!!!!!!!!While testing!!!!!!!!!!!!!!!!!!"); + System.out.println("An ODMGException has occurred: " + e.getMessage()); + System.out.println("Try to abort the transaction ..."); + if(myTa != null) myTa.abort(); + + try + { + System.out.println("Try to close the database ..."); + if(myDb != null) myDb.close(); + } + catch ( org.odmg.ODMGException exp ) + { + System.err.println("Could not close the database: " + exp.getMessage()); + } + } + System.out.println( "Done." ); + + } +} + |