Index: src/edu/ucsb/nceas/metacat/metacatURL.java
===================================================================
--- src/edu/ucsb/nceas/metacat/metacatURL.java	(revision 457)
+++ src/edu/ucsb/nceas/metacat/metacatURL.java	(revision 458)
@@ -1,3 +1,17 @@
+/**
+ *  '$RCSfile$'
+ *    Purpose: A Class that implements a URL for use in identifying metacat
+ *             files. It also handles http urls
+ *  Copyright: 2000 Regents of the University of California and the
+ *             National Center for Ecological Analysis and Synthesis
+ *    Authors: Chad Berkley
+ *    Release: @release@
+ *
+ *   '$Author$'
+ *     '$Date$'
+ * '$Revision$'
+ */
+
 package edu.ucsb.nceas.metacat;
 
 import java.net.MalformedURLException;
@@ -51,6 +65,22 @@
     {//if this is an http url
       params[0][0] = "httpurl";
       params[0][1] = url.substring(0, url.length());
+      for(int i=url.length()-1; i>0; i--)
+      {
+        if(url.charAt(i) == '/')
+        {
+          i=0;
+        }
+        else
+        {
+          String exchange = temp;
+          temp = "";
+          temp += url.charAt(i);
+          temp += exchange;
+        }
+      }
+      params[1][0] = "filename";
+      params[1][1] = temp;
     }
     else
     {//other urls that meet the metacat type url structure.
Index: src/edu/ucsb/nceas/metacat/MetaCatServlet.java
===================================================================
--- src/edu/ucsb/nceas/metacat/MetaCatServlet.java	(revision 457)
+++ src/edu/ucsb/nceas/metacat/MetaCatServlet.java	(revision 458)
@@ -20,6 +20,8 @@
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
 import java.io.DataInputStream;
 import java.util.Enumeration;
 import java.util.Hashtable;
@@ -33,6 +35,7 @@
 import java.sql.SQLException;
 import java.lang.reflect.*;
 import java.net.*;
+import java.util.zip.*;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
@@ -43,6 +46,7 @@
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 import javax.servlet.http.HttpUtils;
+import javax.servlet.ServletOutputStream;
 
 import oracle.xml.parser.v2.XSLStylesheet;
 import oracle.xml.parser.v2.XSLException;
@@ -180,7 +184,7 @@
       }
     }    
     // Get a handle to the output stream back to the client
-    PrintWriter out = response.getWriter();
+    //PrintWriter out = response.getWriter();
     //response.setContentType("text/html");
   
     String name = null;
@@ -222,12 +226,13 @@
     String username = null;
     String groupname = null;
     if (action.equals("Login") || action.equals("Login Client")) {
-      handleLoginAction(out, params, request, response);
+      handleLoginAction(response.getWriter(), params, request, response);
     // handle logout action  
     } else if (action.equals("Logout") || action.equals("Logout Client")) {
       HttpSession sess = request.getSession(false);
       if (sess != null) { sess.invalidate();  }    
       if (action.equals("Logout Client")) {
+        PrintWriter out = response.getWriter();
         out.println("<?xml version=\"1.0\"?>");
         out.println("<success>");
         out.println("User logout.");
@@ -255,20 +260,22 @@
     // to a particular action handler
     if(action.equals("query"))
     {
-      handleQuery(out, params, response, username, groupname); 
+      handleQuery(response.getWriter(), params, response, username, groupname); 
     } 
     else if(action.equals("squery"))
     {
       if(params.containsKey("query"))
       {
-        handleSQuery(out, params, response, username, groupname); 
+        handleSQuery(response.getWriter(), params, response, username, groupname); 
       }
       else
       {
+        PrintWriter out = response.getWriter();
         out.println("Illegal action squery without \"query\" parameter");
       }
     }
     else if (action.equals("getdocument")) {
+      PrintWriter out = response.getWriter();
       try {
         handleGetDocumentAction(out, params, response);
       } catch (ClassNotFoundException e) {
@@ -278,6 +285,7 @@
       }
     } 
     else if (action.equals("getrelateddocument")) {
+      PrintWriter out = response.getWriter();
       try {
         handleGetRelatedDocumentAction(out, params, response);
       } catch (ClassNotFoundException e) {
@@ -287,6 +295,7 @@
       }
     }
     else if (action.equals("insert") || action.equals("update")) {
+      PrintWriter out = response.getWriter();
       if ( !username.equals("public") && (username != null) ) {
         handleInsertOrUpdateAction(out, params, response, username, groupname);
       } else {  
@@ -293,6 +302,7 @@
         out.println("Permission denied for " + action);
       }  
     } else if (action.equals("delete")) {
+      PrintWriter out = response.getWriter();
       if ( !username.equals("public") && (username != null) ) {
         handleDeleteAction(out, params, response, username, groupname);
       } else {  
@@ -299,8 +309,10 @@
         out.println("Permission denied for " + action);
       }  
     } else if (action.equals("validate")) {
+      PrintWriter out = response.getWriter();
       handleValidateAction(out, params, response); 
     } else if (action.equals("getabstract")) {
+      PrintWriter out = response.getWriter();
       try{
         handleViewAbstractAction(out, params, response);
       }
@@ -309,18 +321,23 @@
         out.println("error viewing abstract: " + e.getMessage());
       }
     } else if (action.equals("getdatadoc")) {
+      response.setContentType("application/zip");
+      ServletOutputStream out = response.getOutputStream();
       handleGetDataDocumentAction(out, params, response);  
     } else if (action.equals("getdoctypes")) {
+      PrintWriter out = response.getWriter();
       handleGetDoctypesAction(out, params, response);  
     } else if (action.equals("getdataguide")) {
+      PrintWriter out = response.getWriter();
       handleGetDataGuideAction(out, params, response);  
     } else if (action.equals("Login") || action.equals("Login Client")) {
     } else {
+      PrintWriter out = response.getWriter();
       out.println("Error: action not registered.  Please report this error.");
     }
 
     // Close the stream to the client
-    out.close();
+    //out.close();
   }
   
   /**
@@ -653,7 +670,9 @@
           if(murlParams[0].equals("httpurl"))
           {//httpurl is the param name for an http url.
             URL urlconn = new URL(murlParams[1]);  //create a new url obj.
-            DataInputStream htmldoc = new DataInputStream(urlconn.openStream());
+            //DataInputStream htmldoc = new DataInputStream(urlconn.openStream());
+            BufferedReader htmldoc = new BufferedReader(
+                                   new InputStreamReader(urlconn.openStream()));
             //bind a data stream.
             try
             { //display the document
@@ -925,9 +944,107 @@
 
   /** 
    * Handle the document request and return the results to the requestor
+   * If a docid is passed in through the params then that document
+   * will be retrieved form the DB and put in the zip file.
+   * In addition if 1 or more relations parameters are passed, those file
+   * will be zipped as well.  Currently this is only implemented for 
+   * metacat:// and http:// files.  Support should be added for srb:// files
+   * as well.
    */
-  private void handleGetDataDocumentAction(PrintWriter out, Hashtable params, 
+  private void handleGetDataDocumentAction(ServletOutputStream out, 
+               Hashtable params, 
                HttpServletResponse response) {
+  //find the related files, get them from their source and zip them into 
+  //a zip file.
+  try
+  {
+    Connection conn = util.getConnection();
+    String currentDocid = ((String[])params.get("docid"))[0];
+    ZipOutputStream zout = new ZipOutputStream(out);
+    byte[] bytestring = null;
+    ZipEntry zentry = null;
+    DocumentImpl xmldoc = null;
+    String[] reldocs = null;
+    
+    if(params.containsKey("relation"))
+    { //get the relations from the parameters.
+      reldocs = ((String[])params.get("relation"));
+    }
+    else
+    { //let the for loop know that there are no relations to zip
+      reldocs = new String[0];
+    }
+
+    //write the base file to the zip file.
+    xmldoc = new DocumentImpl(conn, currentDocid);
+    bytestring = (xmldoc.toString()).getBytes();
+    zentry = new ZipEntry(currentDocid + ".xml");
+    //create a new zip entry and write the file to the stream
+    zentry.setSize(bytestring.length);
+    zout.putNextEntry(zentry);
+    zout.write(bytestring, 0, bytestring.length);
+    zout.closeEntry(); //get ready for the next entry. 
+
+    //zip up the related documents
+    for(int i=0; i<reldocs.length; i++)
+    {
+      metacatURL murl = new metacatURL(((String)reldocs[i]));
+      if(murl.getURLType().equals("metacat"))
+      {
+        //get the document from the database
+        xmldoc = new DocumentImpl(conn, (murl.getParam(0))[1]);
+        bytestring = (xmldoc.toString()).getBytes();
+        zentry = new ZipEntry((murl.getParam(0))[1] + ".xml");
+        //create a new zip entry and write the file to the stream
+        zentry.setSize(bytestring.length);
+        zout.putNextEntry(zentry);
+        zout.write(bytestring, 0, bytestring.length);
+        zout.closeEntry(); //get ready for the next entry.
+      }
+      else if(murl.getURLType().equals("http"))
+      {
+        String[] murlParams = murl.getParam(0);
+        if(murlParams[0].equals("httpurl"))
+        {//httpurl is the param name for an http url.
+          URL urlconn = new URL(murlParams[1]);  //create a new url obj.
+          BufferedReader htmldoc = new BufferedReader(
+                                   new InputStreamReader(urlconn.openStream()));
+          //get the data from the web server
+          try
+          { //zip the document
+            String line=null;
+            zentry = new ZipEntry((murl.getParam(1))[1]);
+            //get just the filename from the URL.
+            zout.putNextEntry(zentry);
+            //make a new entry in the zip file stream
+            while((line = htmldoc.readLine()) != null)
+            {
+              bytestring = (line.toString()).getBytes();
+              zout.write(bytestring, 0, bytestring.length);
+              //write out the file line by line
+            }
+            zout.closeEntry(); //close the entry in the file
+          }
+          catch(Exception e)
+          {
+            util.debugMessage("error downloading html document"); 
+          }
+        }
+      }
+    }
+    zout.finish();  //terminate the zip file
+    zout.close();   //close the stream.
+    util.returnConnection(conn); //return the connection to the pool
+  }
+  catch(Exception e)
+  {
+    System.out.println("Error creating zip file: " + e.getMessage()); 
+    e.printStackTrace(System.out);
+  }
+           
+   /*
+   //////////old code using a shell script/////////////////////////////////
+   
       boolean error_flag = false;
       String error_message = "";
       // Get the document indicated
@@ -975,6 +1092,7 @@
                         e.getMessage();
       }
     } // end defaultdatapath not null if
+    */
   }
   
   /** 
