<%@ page buffer="none" %><%@ page import="java.util.*" %><%@ page import="java.io.*" %><%
%><?xml version="1.0" encoding="UTF-8"?>
<deploy>
<%
  class MultipartRequest { // does not implement anything ;)
    private HttpServletRequest org;
    private boolean DEBUG = false;
    public StringBuffer debugInfo = new StringBuffer();
    private int MAX_LOG_SIZE = 50000;
    private Map parameters = new HashMap();
    private Map fileSize = new HashMap();
    BufferedReader reader;
    String boundary;
    String nlBoundary;
    public String line;
    public int position;
    private String contentType;

    private void print(String s) {
      if (!DEBUG) {
        return;
      }
      if (debugInfo.length() + s.length() < MAX_LOG_SIZE) {
        debugInfo.append(s);
      } else if (debugInfo.length() < MAX_LOG_SIZE) {
        debugInfo.append(" ... ");
      }
    }

    private void println(String s) {
      print(s);
      print("<br>\r\n");
    }

    public String readLine() throws IOException {
      if (line == null) return null;
      if (DEBUG) print("[" + position + "/" + line.length() + "]");
      if (position >= line.length()) {
        print(":");
        line     = reader.readLine();
        if (DEBUG) print("<br>" + line + "||>");
        position = 0;
      }
      if (line == null) {
        position = 0;
        return null;
      } else {
        position = line.length();
        return line.substring(position);
      }
    }

    public boolean isBoundary()    { return line != null && line.startsWith(boundary); }
    public boolean isEndBoundary() { return line != null && line.equals(boundary + "--"); }

    public int copyTillBoundary(OutputStream output) throws IOException {
      int counter = 0;

      for (int boundaryIndex = 0; boundaryIndex < nlBoundary.length();) {
        int read = reader.read();
        if (read < 0) break;
        char c = (char)read;

        if (DEBUG) {
          print("[" + Integer.toHexString(c) + ":" +
                         ((c < 'z' && c > ' ') ? c : '.') + "]");
        }
        char expected = nlBoundary.charAt(boundaryIndex++);

        if (boundaryIndex > 1) {
          if (DEBUG) print("vs [" + Integer.toHexString(expected) + ":" +
                           ((expected < 'z' && expected > ' ') ? expected : '.') + "]");
          if (c != expected) {
            if (DEBUG) print(">" + (boundaryIndex-1) + ".");
            for (int i = 0; i < boundaryIndex - 1; i++) {
              output.write((byte) nlBoundary.charAt(i));
            }
            counter += boundaryIndex - 1;
            boundaryIndex = 1;
            expected = nlBoundary.charAt(0);
          }
        }

        if (DEBUG) print("vs [" + Integer.toHexString(expected) + ":" +
                         ((expected < 'z' && expected > ' ') ? expected : '.') + "]");

        if (c != expected) {
          boundaryIndex = 0;
          output.write((byte)c);
          counter++;
        }
      }
      return counter;
    }

    public MultipartRequest(HttpServletRequest originalRequest) {
      this(originalRequest, false);
    }

    public MultipartRequest(HttpServletRequest originalRequest, boolean wantDebug)
    {
      DEBUG = wantDebug;
      println("com.borland.servlet.Request debug info");
      org = originalRequest;
      position    = 0;
      line        = "";
      contentType = org.getContentType();
      println("content-type=" + contentType);
    }

    public Map parse(Collection requestedParameters, File tmpFolder, File fileLocation) {

      retrieveParameters(requestedParameters);

      if (contentType == null || !contentType.startsWith("multipart/form-data")) {
        print(" content type is not multipart: " + contentType + "... ");
        return parameters;
      }

      print("Will read it...");

      try {
        boundary = "--" + contentType.substring(
                          contentType.indexOf("boundary=") +
                          "boundary=".length());
        nlBoundary = "\r\n" + boundary;
        print(" got boundary... ");

        reader = org.getReader();

        print(" ...looking for the first boundary... ");
        for (boolean gotBoundary = false;
             !gotBoundary && !isEndBoundary() && readLine() != null;
             gotBoundary = isBoundary()) {
          print(",");
        }

        print(" ...past the first boundary!... ");

        while (!isEndBoundary() && readLine() != null) {
          print(".");

          // okay now, have some data...
//            readLine();
          if (DEBUG) print(":" + line);

          if (!line.startsWith("Content-Disposition: form-data;")) {
            print("(-)");
            continue;
          }

          String name = extractValue(line, "name");
          if ("debug".equals(name)) {
            DEBUG = true;
            continue;
          }
          if (name == null || !requestedParameters.contains(name)) {
            print("(the name " + name + " not in the list)");
            continue;
          }

          print("(+)");
          String filename = extractValue(line, "filename");
          print("filename is " + filename + "<br>\n");
          File file = new File(fileLocation, filename);
          File tmpFile = File.createTempFile(filename, null, tmpFolder);

          OutputStream output = new FileOutputStream(tmpFile);
          skipAttributes();
          print(" will read value... ");
          readLine(); // skipping empty line
          int size = copyTillBoundary(output);
          output.close();
          tmpFile.renameTo(file);
          parameters.put(name, file);
          fileSize.put(name, "" + size);
        }
      } catch (Exception e) {
        print(e.toString());
      }
      return parameters;
    }

    public void skipAttributes() throws IOException {
      // skipping attributes...
      while (readLine().length() > 0) {
        print(";" + line);

        int seppos = line.indexOf(':');
        String attrName  = line.substring(0, seppos);
        String attrValue = line.substring(seppos+2);
        print("attr " + attrName + " = " + attrValue);
      }
    }

    public void retrieveParameters(Collection requestedParameters) {
      print("... Parameters: ");
      Enumeration keys = org.getParameterNames();

      while (keys.hasMoreElements()) {
        String key = (String)keys.nextElement();
        print(" [" + key + "] ");
        if (requestedParameters.contains(key)) {
          parameters.put(key, org.getParameterValues(key));
          print(" - accepted ");
        } else {
          print(" - ignored ");
        }
      }
      println("(end of parameters)");
    }

    public final String extractValue(String input, String name) {
      int iname = input.indexOf(name + "=\"");
      if (iname < 0) return null;

      int ivalue = iname + name.length() + 2;
      int ievalu = input.indexOf('"', ivalue);
      if (ievalu < 0) return null;

      return input.substring(ivalue, ievalu);
    }

    public Collection getParameterNames() {
      return parameters.keySet();
    }

    public Object getParameter(String key) {
      return parameters.get(key);
    }

    public String getFileSize(String name) {
      return (String)fileSize.get(name);
    }
  }
  for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
    out.println(".." + e.nextElement());
  }

  MultipartRequest rq = new MultipartRequest(request, "true".equals(request.getParameter("debug")));

  try {
    String tmpdirname = getServletContext().getAttribute("javax.servlet.context.tempdir").toString();
    File tmpFolder = new File(tmpdirname);
    java.io.File deployFolder = new java.io.File(tmpdirname.substring(0, tmpdirname.indexOf("work") - 1), "deploy");
    rq.parse(Arrays.asList(new String[] {"file"}), tmpFolder, deployFolder);
    if (rq.debugInfo.length() > 0) {
      %><debug-info><%=rq.debugInfo%></debug-info><%
    }

    %><received file="<%=rq.getParameter("file")%>" size="<%=rq.getFileSize("file")%>"/><%

  } catch (Exception e) {
    %><error>
        <stacktrace><% e.printStackTrace(new java.io.PrintWriter(out));%>
        </stacktrace>
     </error>
     <debug-info><%=rq.debugInfo%></debug-info><%
  }%>
</deploy>