Roger

Have attached what the modified "multi file uploader" class we used - looking at the comment it seems I used an original from Jgraphpad source, although I seem to recall I largely rewrote it. I might have a change history if it's of interest i.e. in terms of licensing or re-use.. The source code shows what I think is a fairly generic way to to multi file uploads.

Regards

-- Rob

Roger Martin wrote:
Hi Felix,

It is solely in the client side javascript and using flash.  The FancyUpload
builds a hidden queue in the DOM and then sends them one by one back to the
server as if the user did it.

I was hoping to hear more from Rob.

Planning on creating a patch.  There were a couple of JavaScript variable
collisions I need to work out and also test on more than Firefox...

On Wed, Sep 10, 2008 at 2:50 PM, Felix Meschberger <[EMAIL PROTECTED]>wrote:

Hi Roger,

Roger Martin schrieb:
Hi Felix developers,

In my local Felix development  I've been testing different ways to
change the web console to allow multiple files to be dragged from an
OS folder and upload them via the "Apache Felix Web Management
Console".  After searching, testing and running into many obsolete
documentations in this murky territory I found the FancyUpload by
http://digitarald.de/project/fancyupload/1-0/ works using a flash
method.  My first case, Firefox is working and I got all the other
noted browsers queued up for testing. FancyUpload has an MIT license
(http://www.opensource.org/licenses/mit-license.php).

If this feature is of interest, is the license ok?
I would be interested in seeing a patch, yes, of course ;-)

I assume beside the client side, you also had to modify the server side
to accept multiple files, right ?

Is there another preferred technology I should test?
I have no preference of course.

Regards
Felix

Also I know that Glassfish is possibly remodeling to fit the Felix
console in with the Glassfish Admin Console; perhaps this may fit
there?  Although I know that there are many profiles I as a Felix user
like to set up independent of glassfish for testing.  Each of these
profiles are very much like a unit test for scenarios involving a
subset of the composite apps I'm working on.  So a way to quickly set
them up via multi file upload and install works for me.  Perhaps for
others as well.



--


Ascert - Taking systems to the Edge
[EMAIL PROTECTED]
+44 (0)20 7488 3470
www.ascert.com

/* 
 * $Id: JGraphpadUploadAction.java,v 1.6 2005/08/07 15:02:38 gaudenz Exp $
 * Copyright (c) 2001-2005, Gaudenz Alder
 * 
 * All rights reserved.
 * 
 * See LICENSE file for license details. If you are unable to locate
 * this file please contact info (at) jgraph (dot) com.
 *
 * Contributor(s):
 *
 *      Rob Walker/Ascert LLC ([EMAIL PROTECTED])
 *          - parameterisation of alt formats, single post for multiple uploads,
 *            exclusion of path from filename, control of filename final path 
separator
 */
package com.ascert.vdrive.jgraph.uploadplugin;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;

import java.net.URL;
import java.net.URLConnection;

/**
 * Uploads files to specified URL either in single POST or across multiple 
POSTs.
 */
public class Uploader  {

    public static final String sepChars = 
"1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    public static final String NL = "\r\n";
    public static final String NLNL = NL + NL;

    /** The URL to upload to */
    public URL url;
    /** Current connection to URL */
    protected URLConnection urlConn;
    /** Output stream for current connection */
    protected DataOutputStream connOut;
    /** Boundary string for mime parts */
    protected String boundarySep;
    /** Size uploaded (not yet implemented) */
    protected int uploadedSize = 0;
    /** Any error reply string returned from server */
    public String errorReplyString;
    
        /**
         * Constructs a new Uploader
         * 
         * @param url
         *            The URL to upload to
         */
        public Uploader(String uploadURL) throws IOException {
        url = new URL(uploadURL);
        boundarySep = randomSep();
        }

    /**
     * Send a set of items in a single POST.
     */
    public void sendSinglePOST(UploadItem[] items) throws IOException {
        initPost();
        for (int ix = 0; ix < items.length; ix ++) {
            sendUploadItem(items[ix], true);
        }
        completePost();
    }
    
    /**
     * Send a set of items as multiple POSTs
     */
    public void sendMultiplePOSTs(UploadItem[] items) throws IOException {
        //TODO: should we catch and handle any exceptions, or just let them 
filter upwards?
        for (int ix = 0; ix < items.length; ix ++) {
            initPost();
            sendUploadItem(items[ix], false);
            completePost();
        }
    }

    
    protected void initPost() throws IOException {
        urlConn = url.openConnection();
        urlConn.setDoOutput (true);
        urlConn.setUseCaches (false);
        urlConn.setAllowUserInteraction(false);
        urlConn.setRequestProperty("Content-type",
                                "multipart/form-data; boundary=" + boundarySep);
        //TODO: seems ok not to set Content length, maybe check this??? 
        connOut = new DataOutputStream(urlConn.getOutputStream());
        uploadedSize = 0;
    }
    
    
    protected void completePost() throws IOException {
        // final item separator
        connOut.writeBytes("--");
        connOut.writeBytes(boundarySep);
        connOut.writeBytes("--");
        connOut.writeBytes(NL);
        connOut.flush();
        connOut.close();
        
        // read back any reply/errors
        String reply = null;
        errorReplyString = "";
        BufferedReader in = new BufferedReader(new 
InputStreamReader(urlConn.getInputStream()));
        
        while ((reply = in.readLine()) != null) {
            System.out.println("reply line: [" + reply + "]");
            if (reply.startsWith("ERROR ")) {
                errorReplyString = reply.substring("ERROR ".length());
            }
        }
        in.close();
    }
    
    
    protected void sendUploadItem(UploadItem item, boolean fileArray) throws 
IOException {
                String binary = "";
                if (item.mimeType.startsWith("image/") || 
            item.mimeType.startsWith("application")) {
                        binary = "Content-Transfer-Encoding: binary" + NL;
                }
        //TODO: other Twiki tags (noredirect,filename,filecomment)
        StringBuffer buf = new StringBuffer();
        // 1st Line 
        buf.append("--");
        buf.append(boundarySep);
        buf.append(NL);
        // 2nd Line
        if (fileArray) {
            buf.append("Content-Disposition: form-data; name=\"filepath[]\"; 
filename=\"");
        } else {
            buf.append("Content-Disposition: form-data; name=\"filepath\"; 
filename=\"");
        }
        buf.append(item.filename);
        buf.append("\"");
        buf.append(NL);
        // 3rd Line + empty line
        buf.append("Content-Type: " + item.mimeType);
        buf.append(NL);
        buf.append(binary);
        buf.append(NL);
        // Upload contents plus NL.
        connOut.writeBytes(buf.toString());
        System.out.println("header:");
        System.out.println(buf.toString());
        //TODO: maybe should send in chunks so we can update progress
        connOut.write(item.bData, 0 , item.bData.length);
        // end marker
        connOut.writeBytes(NL);
    }

    
    protected String randomSep()  {
        StringBuffer sep = new StringBuffer("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        int num;
        for(int ix = 0; ix < 11; ix++) {
            num = (int) (Math.random() * sepChars.length());
            sep.append(sepChars.substring(num, num+1));
        }
        return sep.toString();
    }
    
    /**
     * Container object for file upload data and details
     */
    public static class UploadItem {
        protected String filename;
        protected String mimeType;
        protected byte[] bData;
        
        protected UploadItem(String filename, String mimeType, byte[] bData) {
            this.filename = filename;
            this.mimeType = mimeType;
            this.bData = bData;
        }
    }

}

Reply via email to