You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Upload.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /* *************************************************************************
  2. IT Mill Toolkit
  3. Development of Browser User Intarfaces Made Easy
  4. Copyright (C) 2000-2006 IT Mill Ltd
  5. *************************************************************************
  6. This product is distributed under commercial license that can be found
  7. from the product package on license/license.txt. Use of this product might
  8. require purchasing a commercial license from IT Mill Ltd. For guidelines
  9. on usage, see license/licensing-guidelines.html
  10. *************************************************************************
  11. For more information, contact:
  12. IT Mill Ltd phone: +358 2 4802 7180
  13. Ruukinkatu 2-4 fax: +358 2 4802 7181
  14. 20540, Turku email: info@itmill.com
  15. Finland company www: www.itmill.com
  16. Primary source for information and releases: www.itmill.com
  17. ********************************************************************** */
  18. package com.itmill.toolkit.ui;
  19. import java.io.InputStream;
  20. import java.lang.reflect.Method;
  21. import java.util.Map;
  22. import com.itmill.toolkit.terminal.PaintException;
  23. import com.itmill.toolkit.terminal.PaintTarget;
  24. import com.itmill.toolkit.terminal.UploadStream;
  25. import java.io.IOException;
  26. import java.io.OutputStream;
  27. /** Component for client file uploading.
  28. *
  29. * @author IT Mill Ltd.
  30. * @version @VERSION@
  31. * @since 3.0
  32. */
  33. public class Upload extends AbstractComponent implements Component.Focusable {
  34. /** Upload buffer size. */
  35. private static final int BUFFER_SIZE = 64 * 1024; // 64k
  36. /** Should the field be focused on next repaint */
  37. private boolean focus = false;
  38. /** The tab order number of this field */
  39. private int tabIndex = 0;
  40. /** The output of the upload is redirected to this receiver. */
  41. private Receiver receiver;
  42. private long focusableId = -1;
  43. /* TODO: Add a default constructor, receive to temp file. */
  44. /** Creates a new instance of Upload that redirects the
  45. * uploaded data to given stream.
  46. *
  47. */
  48. public Upload(String caption, Receiver uploadReceiver) {
  49. this.focusableId = Window.getNewFocusableId(this);
  50. setCaption(caption);
  51. receiver = uploadReceiver;
  52. }
  53. /** Get component type.
  54. * @return Component type as string.
  55. */
  56. public String getTag() {
  57. return "upload";
  58. }
  59. /** Invoked when the value of a variable has changed. */
  60. public void changeVariables(Object source, Map variables) {
  61. // Check the variable name
  62. if (!variables.containsKey("stream"))
  63. return;
  64. // Get the upload stream
  65. UploadStream upload = (UploadStream) variables.get("stream");
  66. // Get file properties
  67. String filename = upload.getContentName();
  68. String type = upload.getContentType();
  69. // Get the output target stream
  70. OutputStream out = receiver.receiveUpload(filename, type);
  71. if (out == null)
  72. throw new RuntimeException("Error getting outputstream from upload receiver");
  73. InputStream in = upload.getStream();
  74. if (null==in) {
  75. // No file, for instance non-existent filename in html upload
  76. fireUploadInterrupted(filename, type, 0);
  77. return;
  78. }
  79. byte buffer[] = new byte[BUFFER_SIZE];
  80. int bytesRead = 0;
  81. long totalBytes = 0;
  82. try {
  83. while ((bytesRead = in.read(buffer)) > 0) {
  84. out.write(buffer, 0, bytesRead);
  85. totalBytes += bytesRead;
  86. }
  87. // Download successfull
  88. out.close();
  89. fireUploadSuccess(filename, type, totalBytes);
  90. requestRepaint();
  91. } catch (IOException e) {
  92. // Download interrupted
  93. fireUploadInterrupted(filename, type, totalBytes);
  94. }
  95. }
  96. /** Paint the content of this component.
  97. * @param target Target to paint the content on.
  98. * @throws PaintException The paint operation failed.
  99. */
  100. public void paintContent(PaintTarget target) throws PaintException {
  101. // The field should be focused
  102. if (focus)
  103. target.addAttribute("focus", true);
  104. // The tab ordering number
  105. if (this.tabIndex >= 0)
  106. target.addAttribute("tabindex", this.tabIndex);
  107. target.addUploadStreamVariable(this, "stream");
  108. }
  109. /** Interface that must be implemented by the upload receivers.
  110. * @author IT Mill Ltd.
  111. * @version @VERSION@
  112. * @since 3.0
  113. */
  114. public interface Receiver {
  115. /** Invoked when a new upload arrives.
  116. * @param filename The desired filename of the upload, usually as specified by the client.
  117. * @param MIMEType The MIME type of the uploaded file.
  118. * @return Stream to which the uploaded file should be written.
  119. */
  120. public OutputStream receiveUpload(String filename, String MIMEType);
  121. }
  122. /* Upload events ************************************************ */
  123. private static final Method UPLOAD_FINISHED_METHOD;
  124. private static final Method UPLOAD_FAILED_METHOD;
  125. private static final Method UPLOAD_SUCCEEDED_METHOD;
  126. static {
  127. try {
  128. UPLOAD_FINISHED_METHOD =
  129. FinishedListener.class.getDeclaredMethod(
  130. "uploadFinished",
  131. new Class[] { FinishedEvent.class });
  132. UPLOAD_FAILED_METHOD =
  133. FailedListener.class.getDeclaredMethod(
  134. "uploadFailed",
  135. new Class[] { FailedEvent.class });
  136. UPLOAD_SUCCEEDED_METHOD =
  137. SucceededListener.class.getDeclaredMethod(
  138. "uploadSucceeded",
  139. new Class[] { SucceededEvent.class });
  140. } catch (java.lang.NoSuchMethodException e) {
  141. // This should never happen
  142. throw new java.lang.RuntimeException("Internal error");
  143. }
  144. }
  145. /** Upload.Received event is sent when the upload receives a file,
  146. * regardless if the receival was successfull.
  147. * @author IT Mill Ltd.
  148. * @version @VERSION@
  149. * @since 3.0
  150. */
  151. public class FinishedEvent extends Component.Event {
  152. /**
  153. * Serial generated by eclipse.
  154. */
  155. private static final long serialVersionUID = 3257288015385670969L;
  156. /** Length of the received file. */
  157. private long length;
  158. /** MIME type of the received file. */
  159. private String type;
  160. /** Received file name */
  161. private String filename;
  162. public FinishedEvent(
  163. Upload source,
  164. String filename,
  165. String MIMEType,
  166. long length) {
  167. super(source);
  168. this.type = MIMEType;
  169. this.filename = filename;
  170. this.length = length;
  171. }
  172. /** Upload where the event occurred
  173. * @return Source of the event.
  174. */
  175. public Upload getUpload() {
  176. return (Upload) getSource();
  177. }
  178. /**
  179. * Returns the filename.
  180. */
  181. public String getFilename() {
  182. return filename;
  183. }
  184. /**
  185. * Returns the length.
  186. */
  187. public long getLength() {
  188. return length;
  189. }
  190. /**
  191. * Returns the type.
  192. */
  193. public String getMIMEType() {
  194. return type;
  195. }
  196. }
  197. /** Upload.Interrupted event is sent when the upload is received, but the
  198. * reception is interrupted for some reason.
  199. * @author IT Mill Ltd.
  200. * @version @VERSION@
  201. * @since 3.0
  202. */
  203. public class FailedEvent extends FinishedEvent {
  204. /**
  205. * Serial generated by eclipse.
  206. */
  207. private static final long serialVersionUID = 3833746590157386293L;
  208. public FailedEvent(
  209. Upload source,
  210. String filename,
  211. String MIMEType,
  212. long length) {
  213. super(source, filename, MIMEType, length);
  214. }
  215. }
  216. /** Upload.Success event is sent when the upload is received successfully.
  217. * @author IT Mill Ltd.
  218. * @version @VERSION@
  219. * @since 3.0
  220. */
  221. public class SucceededEvent extends FinishedEvent {
  222. /**
  223. * Serial generated by eclipse.
  224. */
  225. private static final long serialVersionUID = 3256445798169524023L;
  226. public SucceededEvent(
  227. Upload source,
  228. String filename,
  229. String MIMEType,
  230. long length) {
  231. super(source, filename, MIMEType, length);
  232. }
  233. }
  234. /** Receives events when the uploads are ready.
  235. * @author IT Mill Ltd.
  236. * @version @VERSION@
  237. * @since 3.0
  238. */
  239. public interface FinishedListener {
  240. /** Upload has finished.
  241. * @param event Upload finished event.
  242. */
  243. public void uploadFinished(FinishedEvent event);
  244. }
  245. /** Receives events when the uploads are finished, but unsuccessfull.
  246. * @author IT Mill Ltd.
  247. * @version @VERSION@
  248. * @since 3.0
  249. */
  250. public interface FailedListener {
  251. /** Upload has finished unsuccessfully.
  252. * @param event Upload failed event.
  253. */
  254. public void uploadFailed(FailedEvent event);
  255. }
  256. /** Receives events when the uploads are successfully finished.
  257. * @author IT Mill Ltd.
  258. * @version @VERSION@
  259. * @since 3.0
  260. */
  261. public interface SucceededListener {
  262. /** Upload successfull..
  263. * @param event Upload successfull event.
  264. */
  265. public void uploadSucceeded(SucceededEvent event);
  266. }
  267. /** Add upload received event listener
  268. * @param listener Listener to be added.
  269. */
  270. public void addListener(FinishedListener listener) {
  271. addListener(FinishedEvent.class, listener, UPLOAD_FINISHED_METHOD);
  272. }
  273. /** Remove upload received event listener
  274. * @param listener Listener to be removed.
  275. */
  276. public void removeListener(FinishedListener listener) {
  277. removeListener(FinishedEvent.class, listener, UPLOAD_FINISHED_METHOD);
  278. }
  279. /** Add upload interrupted event listener
  280. * @param listener Listener to be added.
  281. */
  282. public void addListener(FailedListener listener) {
  283. addListener(FailedEvent.class, listener, UPLOAD_FAILED_METHOD);
  284. }
  285. /** Remove upload interrupted event listener
  286. * @param listener Listener to be removed.
  287. */
  288. public void removeListener(FailedListener listener) {
  289. removeListener(FinishedEvent.class, listener, UPLOAD_FAILED_METHOD);
  290. }
  291. /** Add upload success event listener
  292. * @param listener Listener to be added.
  293. */
  294. public void addListener(SucceededListener listener) {
  295. addListener(SucceededEvent.class, listener, UPLOAD_SUCCEEDED_METHOD);
  296. }
  297. /** Remove upload success event listener
  298. * @param listener Listener to be removed.
  299. */
  300. public void removeListener(SucceededListener listener) {
  301. removeListener(SucceededEvent.class, listener, UPLOAD_SUCCEEDED_METHOD);
  302. }
  303. /** Emit upload received event. */
  304. protected void fireUploadReceived(
  305. String filename,
  306. String MIMEType,
  307. long length) {
  308. fireEvent(new Upload.FinishedEvent(this, filename, MIMEType, length));
  309. }
  310. /** Emit upload interrupted event. */
  311. protected void fireUploadInterrupted(
  312. String filename,
  313. String MIMEType,
  314. long length) {
  315. fireEvent(new Upload.FailedEvent(this, filename, MIMEType, length));
  316. }
  317. /** Emit upload success event. */
  318. protected void fireUploadSuccess(
  319. String filename,
  320. String MIMEType,
  321. long length) {
  322. fireEvent(new Upload.SucceededEvent(this, filename, MIMEType, length));
  323. }
  324. /** Returns the current receiver.
  325. * @return Receiver
  326. */
  327. public Receiver getReceiver() {
  328. return receiver;
  329. }
  330. /** Sets the receiver.
  331. * @param receiver The receiver to set
  332. */
  333. public void setReceiver(Receiver receiver) {
  334. this.receiver = receiver;
  335. }
  336. /**
  337. * @see com.itmill.toolkit.ui.Component.Focusable#focus()
  338. */
  339. public void focus() {
  340. Window w = getWindow();
  341. if (w != null) {
  342. w.setFocusedComponent(this);
  343. }
  344. }
  345. /**
  346. * @see com.itmill.toolkit.ui.Component.Focusable#getTabIndex()
  347. */
  348. public int getTabIndex() {
  349. return this.tabIndex;
  350. }
  351. /**
  352. * @see com.itmill.toolkit.ui.Component.Focusable#setTabIndex(int)
  353. */
  354. public void setTabIndex(int tabIndex) {
  355. this.tabIndex = tabIndex;
  356. }
  357. /**
  358. * @see com.itmill.toolkit.ui.Component.Focusable#getFocusableId()
  359. */
  360. public long getFocusableId() {
  361. return this.focusableId;
  362. }
  363. }