View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.frontend.fileupload;
20  
21  import java.io.InputStream;
22  
23  import org.mycore.common.MCRException;
24  import org.mycore.common.processing.MCRAbstractProcessable;
25  import org.mycore.frontend.MCRWebsiteWriteProtection;
26  
27  /**
28   * This class does the server-side of uploading files from a client browser,
29   * which runs the upload applet. This is an abstract base class that must be
30   * subclassed to implement the storage of files at the server side for miless,
31   * MyCoRe or other usages of the upload framework. Every instance of
32   * MCRUploadHandler handles one singe upload session with the applet.
33   * 
34   * @author Harald Richter
35   * @author Frank Lützenkirchen
36   * 
37   * @version $Revision$ $Date$
38   * 
39   * @see MCRUploadHandlerManager
40   */
41  public abstract class MCRUploadHandler extends MCRAbstractProcessable {
42  
43      /** The unique ID of this upload session * */
44      protected String uploadID;
45  
46      /** The url where to go after upload is finished. * */
47      protected String url;
48  
49      private int numFiles;
50  
51      /** Creates a new upload handler and registers it at the handler manager * */
52      protected MCRUploadHandler() {
53          if (MCRWebsiteWriteProtection.isActive()) {
54              throw new MCRException("System is currently in read-only mode");
55          }
56  
57          uploadID = Long.toString(System.currentTimeMillis(), 36);
58          MCRUploadHandlerManager.register(this);
59          this.setName(uploadID);
60      }
61  
62      /** Returns the unique ID of this upload session * */
63      public final String getID() {
64          return uploadID;
65      }
66  
67      /** Returns the url where to go after upload is finished * */
68      public String getRedirectURL() {
69          return url;
70      }
71  
72      /**
73       * Starts the upload session.
74       * 
75       * @param numberOfFiles
76       *            the number of files that will be uploaded
77       */
78      public void startUpload(int numberOfFiles) {
79          this.numFiles = numberOfFiles;
80      }
81  
82      /**
83       * Increments the uploaded number of files. Use this method with care!
84       * In general a fixed number of files to upload should be set with
85       * {@link #startUpload(int)}.
86       * 
87       * @return the new number of files to upload
88       */
89      public int incrementNumFiles() {
90          return ++this.numFiles;
91      }
92  
93      /**
94       * Decrements the uploaded number of files. Use this method with care!
95       * In general a fixed number of files to upload should be set with
96       * {@link #startUpload(int)}.
97       * 
98       * @return the new number of files to upload
99       */
100     public int decrementNumFiles() {
101         return --this.numFiles;
102     }
103 
104     /**
105      * Returns the number of files which will be uploaded
106      * 
107      * @return number of files to upload
108      */
109     public int getNumFiles() {
110         return this.numFiles;
111     }
112 
113     /**
114      * This method is called to ask if this
115      * file should be uploaded and will be accepted by the server. The default
116      * implementation always returns true (always upload file), but subclasses
117      * should overwrite this method to decide whether the file's content must be
118      * uploaded. Decision can be based on the MD5 checksum, so unchanged files do not have to be
119      * uploaded again.
120      * 
121      * @param path
122      *            the path and filename of the file
123      * @param checksum
124      *            the MD5 checksum computed at the client side
125      * @param length 
126      *            the length of the file in bytes (file size)
127      * @return true, if the file should be uploaded, false if the file should be
128      *         skipped
129      */
130     public boolean acceptFile(String path, String checksum, long length) throws Exception {
131         return true;
132     }
133 
134     /**
135      * This method is called so that the
136      * UploadHandler subclass can store the file on the server side.
137      * When the UploadHandler could read less than length bytes from the
138      * InputStream at the time the InputStream has no data any more, the user
139      * at the remote side canceled upload during file transfer. The UploadHandler
140      * then can decide to delete the file, but must return the number of 
141      * bytes stored. The UploadHandler can also compare the MD5 checksum calculated
142      * at the client side with its own checksum, to detect magical transfer errors.
143      * 
144      * This method requires a database transaction.
145      * 
146      * @param path
147      *            the path and filename of the file
148      * @param in
149      *            the inputstream to read the content of the file from
150      * @param length
151      *            the total file size as number of bytes. This may be 0,
152      *            meaning that the file is empty or the file size is not known.
153      * @param md5
154      *            the md5 checksum calculated at the client side. This
155      *            may be null, meaning that the md5 checksum is not known.
156      * @return 
157      *            the number of bytes that have been stored.
158      */
159     public abstract long receiveFile(String path, InputStream in, long length, String md5) throws Exception;
160 
161     /**
162      * After finishing uploading all files, this method is called so
163      * that the UploadHandler subclass can finish work and commit all saved
164      * files.
165      * 
166      */
167     public abstract void finishUpload() throws Exception;
168 
169     /**
170      * This method is called so that the UploadHandler subclass can finish 
171      * or cancel work. The implementation is optional, by default finishUpload()
172      * is called 
173      * 
174      */
175     public void cancelUpload() throws Exception {
176         finishUpload();
177     }
178 
179     /**
180      * Automatically unregister this upload handler from the
181      * UploadHandlerManager.
182      */
183     public void unregister() {
184         MCRUploadHandlerManager.unregister(uploadID);
185     }
186 
187 }