Upload component event

Hi …

I’m trying to do very simple thing …

I want to use an upload component to put file from user computer to server.
I’m using the standard component Immediate Upload.

In the vaadin sample, you can find the example i used :
http://demo.vaadin.com/sampler#UploadWithProgressMonitoring

I just want to modify the example like following :

  1. Put the upload progress bar (and infos) in a modal window
  2. Change outputstream in a fileoutputstream to write file on disk

So i made some changes … The Window works very well … but when i change the OutPutStream of the Receiver to a FileOutputStream, the file is uploaded, and after the end, the window is shown (and closed immediatly because the upload is finished …)

I don’t know why !

You can find the entire class following :

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.ProgressIndicator;
import com.vaadin.ui.Upload;
import com.vaadin.ui.Upload.FailedEvent;
import com.vaadin.ui.Upload.FinishedEvent;
import com.vaadin.ui.Upload.Receiver;
import com.vaadin.ui.Upload.StartedEvent;
import com.vaadin.ui.Upload.SucceededEvent;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;

@SuppressWarnings("serial")
public class UploadWithProgress extends VerticalLayout
{
	private LineBreakCounter			counter			= new LineBreakCounter();

	private UploadWithProgressWindow	uploadWindow	= null;
	private Upload						upload			= new Upload(null, counter);

	private boolean						isInterrupted	= false;

	private String						dirDest			= null;
	private String						fileDest		= null;

	public UploadWithProgress(String dirDest, String fileDest)
	{
		setSpacing(true);

		this.dirDest = dirDest;
		this.fileDest = fileDest;

		// make analyzing start immediatedly when file is selected
		upload.setImmediate(true);
		// upload.setIcon(new ThemeResource("icons/16/document-add.png"));
		upload.setButtonCaption("Upload File");
		addComponent(upload);

		upload.addListener(new Upload.StartedListener()
		{
			public void uploadStarted(StartedEvent event)
			{
				uploadWindow = new UploadWithProgressWindow();
				uploadWindow.startUpload(event.getFilename());
				getApplication().getMainWindow().addWindow(uploadWindow);
			}
		});

		upload.addListener(new Upload.ProgressListener()
		{
			public void updateProgress(long readBytes, long contentLength)
			{
				uploadWindow.updateUpload(readBytes, contentLength);
			}
		});

		upload.addListener(new Upload.SucceededListener()
		{
			public void uploadSucceeded(SucceededEvent event)
			{
				getWindow().showNotification("Upload successful !", Notification.TYPE_HUMANIZED_MESSAGE);
			}
		});

		upload.addListener(new Upload.FailedListener()
		{
			public void uploadFailed(FailedEvent event)
			{
				if (isInterrupted)
					getWindow().showNotification("Upload INTERRUPTED !", Notification.TYPE_WARNING_MESSAGE);
				else
					getWindow().showNotification("Upload ERROR !", Notification.TYPE_ERROR_MESSAGE);
			}
		});

		upload.addListener(new Upload.FinishedListener()
		{
			public void uploadFinished(FinishedEvent event)
			{
				uploadWindow.finishUpload();
				uploadWindow.close();
			}
		});

	}

	public class LineBreakCounter implements Receiver
	{

		private String	fileName;
		private String	mtype;

		private int		counter;
		private int		total;

		/**
		 * return an OutputStream that simply counts lineends
		 */
		public OutputStream receiveUpload(String filename, String MIMEType)
		{
			counter = 0;
			total = 0;
			fileName = filename;
			mtype = MIMEType;

			File path = new File(getFullPathDest());
			if (!path.exists())
				path.mkdirs();

			OutputStream oi = null;

			try
			{
				oi = new FileOutputStream(getFullPathDest() + "/" + getFileDest() + getExtention())
				{
					private static final int	searchedByte	= '\n';

					@Override
					public void write(int b) throws IOException
					{
						total++;
						if (b == searchedByte)
							counter++;

						if (total % 1000 == 0)
						{
							try
							{
								Thread.sleep(100);
							} catch (InterruptedException e)
							{
								e.printStackTrace();
							}
						}
					}
				};
			} catch (Exception e)
			{
				e.printStackTrace();
			}

			return oi;
		}

		public String getFileName()
		{
			return fileName;
		}

		public String getExtention()
		{
			return fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
		}

		public String getMimeType()
		{
			return mtype;
		}

		public int getLineBreakCount()
		{
			return counter;
		}
	}

	public class UploadWithProgressWindow extends Window
	{
		private Label				state				= new Label();
		private Label				fileName			= new Label();
		private Label				textualProgress		= new Label();

		private ProgressIndicator	pi					= new ProgressIndicator();

		final Button				cancelProcessing	= new Button("Cancel");

		public UploadWithProgressWindow()
		{
			super();
			setModal(true);
			setResizable(false);
			setReadOnly(true);
			setWidth("410px");
			setIcon(new ThemeResource("icons/32/hourglass.png"));
			setCaption("File upload");

			FormLayout l = new FormLayout();
			l.setSizeFull();
			l.setMargin(true);
			HorizontalLayout stateLayout = new HorizontalLayout();

			cancelProcessing.addListener(new Button.ClickListener()
			{
				public void buttonClick(ClickEvent event)
				{
					upload.interruptUpload();
					isInterrupted = true;
				}
			});
			cancelProcessing.setVisible(false);
			cancelProcessing.setStyleName("small");

			stateLayout.setSpacing(true);
			stateLayout.addComponent(state);
			stateLayout.addComponent(cancelProcessing);
			stateLayout.setCaption("Current state");
			state.setValue("Idle");
			l.addComponent(stateLayout);
			fileName.setCaption("File name");
			l.addComponent(fileName);
			pi.setCaption("Progress");
			pi.setVisible(false);
			l.addComponent(pi);
			textualProgress.setVisible(false);
			l.addComponent(textualProgress);

			addComponent(l);
		}

		public void finishUpload()
		{
			state.setValue("Idle");
			pi.setVisible(false);
			textualProgress.setVisible(false);
			cancelProcessing.setVisible(false);
		}

		public void updateUpload(long readBytes, long contentLength)
		{
			// this method gets called several times during the update
			pi.setValue(new Float(readBytes / (float) contentLength));
			textualProgress.setValue("Processed " + readBytes + " bytes of " + contentLength);
		}

		public void startUpload(String filename)
		{
			// this method gets called immediatedly after upload is
			// started
			pi.setValue(0f);
			pi.setVisible(true);
			pi.setPollingInterval(500); // hit server frequantly to get
			textualProgress.setVisible(true);
			// updates to client
			state.setValue("Uploading");
			fileName.setValue(filename);

			cancelProcessing.setVisible(true);

			isInterrupted = false;
		}

		@Override
		protected void close()
		{
			getApplication().getMainWindow().removeWindow(uploadWindow);
		}
	}

	public String getFileDest()
	{
		return fileDest;
	}

	public void setFileDest(String fileDest)
	{
		this.fileDest = fileDest;
	}

	public String getDirDest()
	{
		return dirDest;
	}

	public void setDirDest(String dirDest)
	{
		this.dirDest = dirDest;
	}

	private String getFullPathDest()
	{
		return getWebappPath() + "/datas/" + getDirDest();
	}

	private String getWebappPath()
	{
		return getApplication().getContext().getBaseDirectory().getAbsolutePath();
	}

}

Than you can use the component easily :

UploadWithProgress upload = new UploadWithProgress(folder, filename);

Please don’t take care of some things in the code … I’m evaluating VAADIN for the moment !

I don’t know how solve this issue …

Thank you a lot.