///////////////////////////////////////////////////////////////////////////// // Copyright (c) 1998, California Institute of Technology. // ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. // // Please read the full copyright notice in the file COPYRIGHT // in this directory. // // Author: Jake Hamby, NASA/Jet Propulsion Laboratory // Jake.Hamby@jpl.nasa.gov ///////////////////////////////////////////////////////////////////////////// package dods.dap; import java.io.*; /** * This abstract class defines the basic data type features for the DODS data * access protocol (DAP) data types. All of the DAP type classes * (<code>DFloat64</code>, <code>DArray</code>, etc.) subclass it or one of * its two abstract descendents, <code>DVector</code> or * <code>DConstructor</code>. * <p> * These classes and their methods give a user the capacity to set up * sophisticated data types. They do <em>not</em> provide sophisticated ways to * access and use this data. On the server side, in many cases, the class * instances will have no data in them at all until the <code>serialize</code> * method is called to send data to the client. On the client side, most DODS * application programs will unpack the data promptly into whatever local * data structure the programmer deems the most useful. * <p> * Descendents of this class should implement the <code>ClientIO</code> * interface. That interface defines a <code>deserialize</code> method used * by a DODS client to retrieve the variable's declaration and value(s) from * a DODS server. * * @version $Revision: 1.3 $ * @author jehamby * @see DDS * @see ClientIO */ public abstract class BaseType implements Cloneable { /** The name of this variable. */ private String _name; /** The parent (container class) of this object, if one exists */ private BaseType _myParent; /** Constructs a new <code>BaseType</code> with no name. */ public BaseType() { this(""); } /** * Constructs a new <code>BaseType</code> with name <code>n</code>. * @param n the name of the variable. */ public BaseType(String n) { _name = n; _myParent = null; } /** * Returns a clone of this <code>BaseType</code>. A deep copy is performed * on all data inside the variable. * * @return a clone of this <code>BaseType</code>. */ public Object clone() { try { BaseType bt = (BaseType)super.clone(); return bt; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } } /** * Returns the name of the class instance. * @return the name of the class instance. */ public final String getName() { return _name; } /** * Sets the name of the class instance. * @param n the name of the class instance. */ public final void setName(String n) { _name = n; } /** * Returns the DODS type name of the class instance as a <code>String</code>. * @return the DODS type name of the class instance as a <code>String</code>. */ abstract public String getTypeName(); /** * Returns the number of variables contained in this object. For simple and * vector type variables, it always returns 1. To count the number * of simple-type variable in the variable tree rooted at this variable, set * <code>leaves</code> to <code>true</code>. * * @param leaves If true, count all the simple types in the `tree' of * variables rooted at this variable. * @return the number of contained variables. */ public int elementCount(boolean leaves) { return 1; } /** * Returns the number of variables contained in this object. For simple and * vector type variables, it always returns 1. * * @return the number of contained variables. */ public final int elementCount() { return elementCount(false); } /** * Returns a string representation of the variables value. This * is really foreshadowing functionality for Server types, but * as it may come in useful for clients it is added here. Simple * types (example: DFloat32) will return a single value. DConstuctor * and DVector types will be flattened. DStrings and DURL's will * have double quotes around them. */ /* abstract public void toASCII(PrintWriter pw, boolean addName, String rootName, boolean newLine); String toASCIIAddRootName(PrintWriter pw, boolean addName, String rootName){ if(addName){ rootName = toASCIIFlatName(rootName); pw.print(rootName); } return(rootName); } String toASCIIFlatName(String rootName){ String s; if(rootName != null){ s = rootName + "." + getName(); } else { s = getName(); } return(s); } */ /** * Write the variable's declaration in a C-style syntax. This * function is used to create textual representation of the Data * Descriptor Structure (DDS). See <em>The DODS User Manual</em> for * information about this structure. * * @param os The <code>PrintWriter</code> on which to print the * declaration. * @param space Each line of the declaration will begin with the * characters in this string. Usually used for leading spaces. * @param print_semi a boolean value indicating whether to print a * semicolon at the end of the declaration. * @param constrained a boolean value indicating whether to print * the declartion dependent on the projection information. <b>This * is only used by Server side code.</b> * @see DDS */ public void printDecl(PrintWriter os, String space, boolean print_semi, boolean constrained) { //System.out.println("BaseType.printDecl()..."); os.print(space + getTypeName() + " " + getName()); if (print_semi) os.println(";"); } /** * Write the variable's declaration in a C-style syntax. This * function is used to create textual representation of the Data * Descriptor Structure (DDS). See <em>The DODS User Manual</em> for * information about this structure. * * @param os The <code>PrintWriter</code> on which to print the * declaration. * @param space Each line of the declaration will begin with the * characters in this string. Usually used for leading spaces. * @param print_semi a boolean value indicating whether to print a * semicolon at the end of the declaration. * @see DDS */ public void printDecl(PrintWriter os, String space, boolean print_semi) { printDecl(os,space,print_semi,false); } /** * Print the variable's declaration. Same as * <code>printDecl(os, space, true)</code>. * * @param os The <code>PrintWriter</code> on which to print the * declaration. * @param space Each line of the declaration will begin with the * characters in this string. Usually used for leading spaces. * @see DDS#print(PrintWriter) */ public final void printDecl(PrintWriter os, String space) { printDecl(os, space, true, false); } /** * Print the variable's declaration. Same as * <code>printDecl(os, " ", true)</code>. * * @param os The <code>PrintWriter</code> on which to print the * declaration. * @see DDS#print(PrintWriter) */ public final void printDecl(PrintWriter os) { printDecl(os, " ", true, false); } /** * Print the variable's declaration using <code>OutputStream</code>. * * @param os The <code>OutputStream</code> on which to print the * declaration. * @param space Each line of the declaration will begin with the * characters in this string. Usually used for leading spaces. * @param print_semi a boolean value indicating whether to print a * semicolon at the end of the declaration. * @see DDS#print(PrintWriter) */ public final void printDecl(OutputStream os, String space, boolean print_semi, boolean constrained) { PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os))); printDecl(pw, space, print_semi,constrained); pw.flush(); } /** * Print the variable's declaration using <code>OutputStream</code>. * * @param os The <code>OutputStream</code> on which to print the * declaration. * @param space Each line of the declaration will begin with the * characters in this string. Usually used for leading spaces. * @param print_semi a boolean value indicating whether to print a * semicolon at the end of the declaration. * @see DDS#print(PrintWriter) */ public final void printDecl(OutputStream os, String space, boolean print_semi) { printDecl(os, space, print_semi,false); } /** * Print the variable's declaration. Same as * <code>printDecl(os, space, true)</code>. * * @param os The <code>OutputStream</code> on which to print the * declaration. * @param space Each line of the declaration will begin with the * characters in this string. Usually used for leading spaces. * @see DDS#print(PrintWriter) */ public final void printDecl(OutputStream os, String space) { PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os))); printDecl(pw, space); pw.flush(); } /** * Print the variable's declaration. Same as * <code>printDecl(os, " ", true)</code>. * * @param os The <code>OutputStream</code> on which to print the * declaration. * @see DDS#print(PrintWriter) */ public final void printDecl(OutputStream os) { PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os))); printDecl(pw); pw.flush(); } /** * Prints the value of the variable, with its declaration. This * function is primarily intended for debugging DODS applications and * text-based clients such as geturl. * * @param os the <code>PrintWriter</code> on which to print the value. * @param space this value is passed to the <code>printDecl</code> method, * and controls the leading spaces of the output. * @param print_decl_p a boolean value controlling whether the * variable declaration is printed as well as the value. */ abstract public void printVal(PrintWriter os, String space, boolean print_decl_p); /** * Print the variable's value. Same as * <code>printVal(os, space, true)</code>. * * @param os the <code>PrintWriter</code> on which to print the value. * @param space this value is passed to the <code>printDecl</code> method, * and controls the leading spaces of the output. * @see DataDDS#printVal(PrintWriter) */ public final void printVal(PrintWriter os, String space) { printVal(os, space, true); } /** * Print the variable's value using <code>OutputStream</code>. * * @param os the <code>OutputStream</code> on which to print the value. * @param space this value is passed to the <code>printDecl</code> method, * and controls the leading spaces of the output. * @param print_decl_p a boolean value controlling whether the * variable declaration is printed as well as the value. * @see DataDDS#printVal(PrintWriter) */ public final void printVal(OutputStream os, String space, boolean print_decl_p) { PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os))); printVal(pw, space, print_decl_p); pw.flush(); } /** * Print the variable's value using <code>OutputStream</code>. * * @param os the <code>OutputStream</code> on which to print the value. * @param space this value is passed to the <code>printDecl</code> method, * and controls the leading spaces of the output. * @see DataDDS#printVal(PrintWriter) */ public final void printVal(OutputStream os, String space) { PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os))); printVal(pw, space); pw.flush(); } /** * Checks for internal consistency. This is important to check for complex * constructor classes. * For example, an <code>DInt32</code> instance would return false if it had * no name defined. A <code>DGrid</code> instance might return false for * more complex reasons, such as having Map arrays of the wrong * size or shape. * <p> * This method is used by the <code>DDS</code> class, and will rarely, if * ever, be explicitly called by a DODS application program. A * variable must pass this test before it is sent, but there may be * many other stages in a retrieve operation where it would fail. * * @param all For complex constructor types ( * <code>DGrid</code>, <code>DSequence</code>, <code>DStructure</code>), * this flag indicates whether to check the * semantics of the member variables, too. * @exception BadSemanticsException if semantics are bad, explains why. * @see DDS#checkSemantics(boolean) */ public void checkSemantics(boolean all) throws BadSemanticsException { if (_name == null) throw new BadSemanticsException("BaseType.checkSemantics(): Every variable must have a name"); } /** * Check semantics. Same as <code>checkSemantics(false)</code>. * @exception BadSemanticsException if semantics are bad, explains why. * @see BaseType#checkSemantics(boolean) */ public final void checkSemantics() throws BadSemanticsException { checkSemantics(false); } /** * Constructs a new <code>PrimitiveVector</code> object optimized for the * particular data type of this <code>BaseType</code>. For example, a * <code>DByte</code> class would create a new * <code>BytePrimitiveVector</code> in this call. This allows for a very * optimized, yet type-safe, implementation of <code>DVector</code> * functionality. For non-primitive types, such as * <code>DArray</code>, <code>DGrid</code>, <code>DSequence</code>, and * <code>DStructure</code>, the default implementation returns a * <code>BaseTypePrimitiveVector</code> object which can * deserialize an array of complex types. * * @return a new <code>PrimitiveVector</code> object for the variable type. */ public PrimitiveVector newPrimitiveVector() { return new BaseTypePrimitiveVector(this); } public void setParent(BaseType bt) { _myParent = bt; } public BaseType getParent() { return(_myParent); } public String getLongName(){ boolean done = false; BaseType parent = _myParent; String longName = _name; while(parent != null){ longName = parent.getName() + "." + longName; parent = parent.getParent(); } return(longName); } }