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 }