///////////////////////////////////////////////////////////////////////////// // 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.*; import java.util.Enumeration; import java.util.zip.DeflaterOutputStream; /** * The DataDDS class extends DDS to add new methods for retrieving data from * the server, and printing out the contents of the data. * * @version $Revision: 1.3 $ * @author jehamby * @see DDS */ public class DataDDS extends DDS { /** The ServerVersion returned from the open DODS connection. */ private ServerVersion ver; /** * Construct the DataDDS with the given server version. * @param ver the ServerVersion returned from the open DODS connection. */ public DataDDS(ServerVersion ver) { super(); this.ver = ver; } public DataDDS(ServerVersion ver, BaseTypeFactory btf) { super(btf); this.ver = ver; } /** * Returns the <code>ServerVersion</code> given in the constructor. * @return the <code>ServerVersion</code> given in the constructor. */ public final ServerVersion getServerVersion() { return ver; } /** * Read the data stream from the given InputStream. In the C++ version, * this code was in Connect. * * @param is the InputStream to read from * @param statusUI the StatusUI object to use, or null * @exception EOFException if EOF is found before the variable is completely * deserialized. * @exception IOException thrown on any other InputStream exception. * @exception DataReadException when invalid data is read, or if the user * cancels the download. * @exception DODSException if the DODS server returned an error. */ public void readData(InputStream is, StatusUI statusUI) throws IOException, EOFException, DODSException { // Buffer the input stream for better performance BufferedInputStream bufferedIS = new BufferedInputStream(is); // Use a DataInputStream for deserialize DataInputStream dataIS = new DataInputStream(bufferedIS); for(Enumeration e = getVariables(); e.hasMoreElements(); ) { if (statusUI != null && statusUI.userCancelled()) throw new DataReadException("User cancelled"); ClientIO bt = (ClientIO)e.nextElement(); bt.deserialize(dataIS, ver, statusUI); } // notify GUI of finished download if (statusUI != null) statusUI.finished(); } /** * Print the dataset just read. In the C++ version, this code was in * <code>geturl</code>. * * @param os the <code>PrintWriter</code> to use. */ public void printVal(PrintWriter os) { for (Enumeration e = getVariables(); e.hasMoreElements(); ) { BaseType bt = (BaseType)e.nextElement(); bt.printVal(os, "", true); } os.println(); } /** * Print the dataset using OutputStream. * @param os the <code>OutputStream</code> to use. */ public final void printVal(OutputStream os) { PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os))); printVal(pw); pw.flush(); } /** * Dump the dataset using externalize methods. This should create * a multipart Mime document with the binary representation of the * DDS that is currently in memory. * * @param os the <code>OutputStream</code> to use. * @param compress <code>true</code> if we should compress the output. * @param headers <code>true</code> if we should print HTTP headers. * @exception IOException thrown on any <code>OutputStream</code> exception. */ public final void externalize(OutputStream os, boolean compress, boolean headers) throws IOException { // First, print headers if (headers) { PrintWriter pw = new PrintWriter(new OutputStreamWriter(os)); pw.println("HTTP/1.0 200 OK"); pw.println("Server: " + ServerVersion.getCurrentVersion()); pw.println("Content-type: application/octet-stream"); pw.println("Content-Description: dods_data"); if (compress) { pw.println("Content-Encoding: deflate"); } pw.println(); pw.flush(); } // Buffer the output stream for better performance OutputStream bufferedOS; if (compress) { // deflate has its own buffering bufferedOS = new DeflaterOutputStream(os); } else { bufferedOS = new BufferedOutputStream(os); } // Redefine PrintWriter here, so the DDS is also compressed if necessary PrintWriter pw = new PrintWriter(new OutputStreamWriter(bufferedOS)); print(pw); // pw.println("Data:"); // JCARON CHANGED pw.flush(); bufferedOS.write("\nData:\n".getBytes()); // JCARON CHANGED bufferedOS.flush(); // Use a DataOutputStream for serialize DataOutputStream dataOS = new DataOutputStream(bufferedOS); for(Enumeration e = getVariables(); e.hasMoreElements(); ) { ClientIO bt = (ClientIO)e.nextElement(); bt.externalize(dataOS); } // Note: for DeflaterOutputStream, flush() is not sufficient to flush // all buffered data dataOS.close(); } }