Home » geronimo-2.2-source-release » org.apache.geronimo.deployment.remote » [javadoc | source]

    1   /**
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   package org.apache.geronimo.deployment.remote;
   18   
   19   import javax.servlet.http.HttpServlet;
   20   import javax.servlet.http.HttpServletRequest;
   21   import javax.servlet.http.HttpServletResponse;
   22   import javax.servlet.ServletException;
   23   import java.io.DataOutputStream;
   24   import java.io.DataInputStream;
   25   import java.io.File;
   26   import java.io.IOException;
   27   import java.io.BufferedOutputStream;
   28   import java.io.FileOutputStream;
   29   
   30   /**
   31    * A servlet that accepts file uploads.  It takes only POST requests, which should
   32    * contain a Java "DataOutput" formatted stream from RemoteDeployUtil containing:
   33    *
   34    * RemoteDeployer data stream format:
   35    *   0) an int, the version of this datastream format - REMOTE_DEPLOY_REQUEST_VER
   36    *   1) an int, the number of files being uploaded
   37    *   2) for each file:
   38    *     2.0) a UTF String, the filename of the file being uploaded
   39    *     2.1) a long, the length of the file in bytes
   40    *     2.2) byte[], byte count equal to the number above for the file
   41    *
   42    * RemoteDeployer response stream format:
   43    *   It returns a serialized stream containing:
   44    *   0) an int, the version of this datastream format - REMOTE_DEPLOY_RESPONSE_VER
   45    *   1) a UTF string, the status (should be "OK")
   46    *   2) an int, the number of files received
   47    *   3) for each file:
   48    *     3.1) a UTF String, the path to the file as saved to the server's filesystem
   49    *
   50    *   The file positions in the response will be the same as in the request.
   51    *   That is, a name for upload file #2 will be in response position #2.
   52    *
   53    * @version $Rev: 567944 $ $Date: 2007-08-20 21:22:33 -0700 (Mon, 20 Aug 2007) $
   54    */
   55   public class FileUploadServlet extends HttpServlet {
   56   
   57       /** Note:  The below versions should be kept in sync with those in RemoteDeployUtil.java **/
   58       // Starting RemoteDeploy datastream versions
   59       public static final int REMOTE_DEPLOY_REQUEST_VER_0 = 0;
   60       public static final int REMOTE_DEPLOY_RESPONSE_VER_0 = 0;
   61       // Current RemoteDeploy datastream versions
   62       public static final int REMOTE_DEPLOY_REQUEST_VER = 0;
   63       public static final int REMOTE_DEPLOY_RESPONSE_VER = 0;
   64   
   65   
   66       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   67           int fileCount = 0, filesCreated = 0;
   68           String names[] = null;
   69           String status = "OK";
   70   
   71           /* --------------------
   72            * RemoteDeploy Request
   73            * --------------------
   74            *
   75            * Note:  The below code has to match RemoteDeployUtil.java
   76            *
   77            * RemoteDeployer data stream format:
   78            *   0) an int, the version of this datastream format - REMOTE_DEPLOY_REQUEST_VER
   79            *   1) an int, the number of files being uploaded
   80            *   2) for each file:
   81            *     2.0) a UTF String, the filename of the file being uploaded
   82            *     2.1) a long, the length of the file in bytes
   83            *     2.2) byte[], byte count equal to the number above for the file
   84            */
   85           DataInputStream in = null;
   86           try {
   87               String fileName;
   88               in = new DataInputStream(request.getInputStream());
   89               // 0) an int, the version of this datastream format - REMOTE_DEPLOY_REQUEST_VER
   90               int reqVer = in.readInt();
   91               // whenever we update the stream version, the next line needs to
   92               // be changed to just - (reqVer >= REMOTE_DEPLOY_REQUEST_VER_0)
   93               // but until then, be more restrictive so we can handle old deployers
   94               // that don't send a version as the first thing, but a file count instead...
   95               if ((reqVer >= REMOTE_DEPLOY_REQUEST_VER_0) && (reqVer <= REMOTE_DEPLOY_REQUEST_VER)) {
   96                   // 1) an int, the number of files being uploaded
   97                   fileCount = in.readInt();
   98                   names = new String[fileCount];
   99                   // 2) for each file:
  100                   for(int i=0; i<fileCount; i++) {
  101                       // 2.0) a UTF String, the filename of the file being uploaded
  102                       fileName = in.readUTF();
  103                       // 2.1) a long, the length of the file in bytes
  104                       long length = in.readLong();
  105                       // create the local temp file
  106                       //File temp = File.createTempFile("remote-deploy", "");
  107                       // Note: Doing this because WAR files have to be their original names to
  108                       // handle the case where no web.xml or context root was provided
  109                       File temp = new File(System.getProperty("java.io.tmpdir"), fileName.trim());
  110                       temp.createNewFile();
  111                       temp.deleteOnExit();
  112                       names[i] = temp.getAbsolutePath();
  113                       // 2.2) raw bytes, equal to the number above for the file
  114                       readToFile(in, temp, length);
  115                       filesCreated++;
  116                   }
  117               }
  118           } catch (IOException e) {
  119               status = "ERROR: "+e.getMessage();
  120           } finally {
  121               if (in != null) {
  122                   in.close();
  123                   in = null;
  124               }
  125           }
  126   
  127           /* ---------------------
  128            * RemoteDeploy Response
  129            * ---------------------
  130            *
  131            * Note:  The below code has to match RemoteDeployUtil.java
  132            *
  133            * RemoteDeployer response stream format:
  134            *   It returns a serialized stream containing:
  135            *   0) an int, the version of this datastream format - REMOTE_DEPLOY_RESPONSE_VER
  136            *   1) a UTF string, the status (should be "OK")
  137            *   2) an int, the number of files received
  138            *   3) for each file:
  139            *     3.1) a UTF String, the path to the file as saved to the server's filesystem
  140            *   x) new data would be added here
  141            *
  142            *   The file positions in the response will be the same as in the request.
  143            *   That is, a name for upload file #2 will be in response position #2.
  144            */
  145           DataOutputStream out = null;
  146           try {
  147               out = new DataOutputStream(response.getOutputStream());
  148               // 0) an int, the version of this datastream format - REMOTE_DEPLOY_RESPONSE_VER
  149               out.writeInt(REMOTE_DEPLOY_RESPONSE_VER);
  150               // 1) a UTF string, the status (should be "OK")
  151               out.writeUTF(status);
  152               if (filesCreated == fileCount) {
  153                   // 2) an int, the number of files received
  154                   out.writeInt(fileCount);
  155                   // 3) for each file:
  156                   for (int i = 0; i < names.length; i++) {
  157                       // 3.1) a UTF String, the path to the file as saved to the server's filesystem
  158                       out.writeUTF(names[i]);
  159                   }
  160                   // x) new data would be added here
  161                   // only send newer data depending on the REQUEST_VER that came in
  162               } else {
  163                   // error occurred, so don't send back any filenames, just a zero count
  164                   // 2) an int, the number of files received
  165                   out.writeInt(0);
  166               }
  167           } finally {
  168               if (out != null) {
  169                   out.flush();
  170                   out.close();
  171                   out = null;
  172               }
  173           }
  174       }
  175   
  176       private static void readToFile(DataInputStream in, File temp, long length) throws IOException {
  177           BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(temp));
  178           int read;
  179           long total;
  180           try {
  181               byte[] buf = new byte[8192];
  182               total = 0;
  183               while((read = in.read(buf, 0, (int)Math.min(buf.length, length - total))) > -1) {
  184                   out.write(buf, 0, read);
  185                   total += read;
  186                   if(total == length) {
  187                       break;
  188                   }
  189               }
  190           } finally {
  191               try {out.flush();} catch (IOException e) {}
  192               out.close();
  193               out = null;
  194           }
  195           if(total != length) {
  196               throw new IOException("Unable to read entire upload file ("+total+"B expecting "+length+"B)");
  197           }
  198       }
  199   }
  200   

Home » geronimo-2.2-source-release » org.apache.geronimo.deployment.remote » [javadoc | source]