Upload.java
001 /*
002  *  Upload.java
003  *  Copyright (c) 1998-2008, The University of Sheffield.
004  *
005  *  This code is from the GATE project (http://gate.ac.uk/) and is free
006  *  software licenced under the GNU General Public License version 3. It is
007  *  distributed without any warranty. For more details see COPYING.txt in the
008  *  top level directory (or at http://gatewiki.sf.net/COPYING.txt).
009  */
010 
011 package gate.cow.gwt.client;
012 
013 import com.google.gwt.core.client.EntryPoint;
014 
015 import com.google.gwt.user.client.Window;
016 import com.google.gwt.user.client.HistoryListener;
017 import com.google.gwt.user.client.History;
018 import com.google.gwt.user.client.DOM;
019 import com.google.gwt.user.client.Element;
020 
021 import com.google.gwt.user.client.ui.Button;
022 import com.google.gwt.user.client.ui.ClickListener;
023 import com.google.gwt.user.client.ui.FileUpload;
024 import com.google.gwt.user.client.ui.FormHandler;
025 import com.google.gwt.user.client.ui.FormPanel;
026 import com.google.gwt.user.client.ui.FormSubmitCompleteEvent;
027 import com.google.gwt.user.client.ui.FormSubmitEvent;
028 import com.google.gwt.user.client.ui.Label;
029 import com.google.gwt.user.client.ui.RootPanel;
030 import com.google.gwt.user.client.ui.VerticalPanel;
031 import com.google.gwt.user.client.ui.Widget;
032 import com.google.gwt.user.client.ui.Hyperlink;
033 import com.google.gwt.user.client.ui.HorizontalPanel;
034 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
035 import com.google.gwt.user.client.ui.HasVerticalAlignment;
036 import com.google.gwt.user.client.ui.CheckBox;
037 
038 /**
039  * GUI for uploading a file to the server.
040  *
041  * Get information from the server with javascript variables
042  * in the show view and receive messages from PageService upload action.
043  */
044 public class Upload implements EntryPoint, HistoryListener {
045   private VerticalPanel vPanel;
046   private String uploadLink;
047 
048   /**
049    * Called when the javascript file is loaded in a web page.
050    */
051   public void onModuleLoad() {
052 
053     if (RootPanel.get("gwt-upload"== null) {
054       // if no link with id equal to gwt-upload then don't load
055       return;
056     }
057 
058     Hyperlink link = new Hyperlink("Upload""gwt-upload");
059     link.setStyleName("inline");
060     RootPanel.get("gwt-upload").add(link);
061     RootPanel.detachOnWindowClose(link);
062     uploadLink = getUploadLink();
063 
064     // main vertical panel
065     vPanel = new VerticalPanel();
066     vPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
067     vPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
068 
069     // form panel contained in the main vertical panel
070     final FormPanel formPanel = new FormPanel();
071     formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
072     formPanel.setMethod(FormPanel.METHOD_POST);
073     formPanel.setAction(uploadLink);
074     // use style from grails AJAX
075     formPanel.setStyleName("inlineForm");
076     vPanel.add(formPanel);
077 
078     // form components horizontal panel contained in the form panel
079     HorizontalPanel hPanel = new HorizontalPanel();
080     hPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
081     hPanel.setSpacing(5);
082     formPanel.setWidget(hPanel);
083 
084     // form components
085     Label label = new Label("File to upload:");
086     label.setStyleName("label");
087     hPanel.add(label);
088     final FileUpload fileUpload = new FileUpload();
089     fileUpload.setName("fileUpload");
090     fileUpload.setTitle(
091       "Choose a file or archive to upload in the current directory. " +
092       "Supported archive formats are zip, tar, tar.gz or tar.bz2");
093     hPanel.add(fileUpload);
094     CheckBox unzipCheckBox = new CheckBox("Unpack");
095     unzipCheckBox.setName("unpack");
096     unzipCheckBox.setChecked(false);
097     unzipCheckBox.ensureDebugId("unzipCheckBox");
098     unzipCheckBox.setTitle("Unpack the archive file in the current directory.");
099     hPanel.add(unzipCheckBox);
100     CheckBox overwriteCheckBox = new CheckBox("Overwrite");
101     overwriteCheckBox.setName("overwrite");
102     overwriteCheckBox.setChecked(false);
103     overwriteCheckBox.ensureDebugId("overwriteCheckBox");
104     overwriteCheckBox.setTitle("Overwrite existing files.");
105     hPanel.add(overwriteCheckBox);
106     Button submitButton = new Button("Submit");
107     submitButton.ensureDebugId("submitButton");
108     submitButton.setStyleName("button");
109     hPanel.add(submitButton);
110     Button cancelButton = new Button("Cancel");
111     cancelButton.ensureDebugId("cancelButton");
112     cancelButton.setStyleName("button");
113     hPanel.add(cancelButton);
114 
115     // submit the form when the user clicks on the submit button
116     submitButton.addClickListener(new ClickListener() {
117       public void onClick(Widget sender) {
118         formPanel.submit();
119       }
120     });
121 
122     // cancel upload by reloading the show view
123     cancelButton.addClickListener(new ClickListener() {
124       public void onClick(Widget sender) {
125         setLocation(uploadLink.replaceFirst("upload""show""?type=dir");
126       }
127     });
128 
129     // The GWT calls this form handler after the form
130     // is submitted in the button click listener implemented above.
131     formPanel.addFormHandler(new FormHandler() {
132       // When the submit starts, make sure the user
133       // selected a file to upload
134       public void onSubmit(FormSubmitEvent event) {
135         if (fileUpload.getFilename().trim().length() == 0) {
136           String message = "You must select a file.";
137           Window.alert(message);
138           event.setCancelled(true);
139         }
140       }
141 
142       // After the submit, get the JSON result and parse it.
143       public void onSubmitComplete(FormSubmitCompleteEvent event) {
144           // workaround for grails/spring/jsecurity upload problem
145           // reload the directory listing to exit the current webflow
146           // TODO: when this problem will be gone add "?type=dir" at the URL
147           setLocation(uploadLink.replaceFirst("upload""show"));
148       }
149     });
150 
151     History.addHistoryListener(this);
152   }
153 
154   /**
155    * Called when a GWT link is clicked.
156    @param s anchor value of the link
157    */
158   public void onHistoryChanged(String s) {
159     if (History.getToken().equals("gwt-upload")) {
160       clear(RootPanel.get("topPageSpecific").getElement());
161       RootPanel.get("topPageSpecific").add(vPanel);
162     }
163   }
164 
165   /**
166    * Removes all of the element's children.
167    *
168    @param parent a DOM element
169    @throws IllegalArgumentException if <code>parent</code> is null
170    */
171   public static void clear(Element parent) {
172     if (parent == null) {
173       throw new IllegalArgumentException();
174     }
175     Element firstChild;
176     while((firstChild = DOM.getFirstChild(parent)) != null) {
177       DOM.removeChild(parent, firstChild);
178     }
179   }
180 
181   /**
182    * Set the location of the current web page and thus leave this module.
183    @param location url of the new web page to load
184    */
185   private native void setLocation(String location/*-{
186      $wnd.location.href = location;
187   }-*/;
188 
189   /**
190    * Get the value of the uploadLink javascript variable.
191    @return value of the uploadLink javascript variable.
192    */
193   private native String getUploadLink() /*-{
194     return $wnd.uploadLink;
195   }-*/;
196 
197 }