Statistics
| Branch: | Tag: | Revision:

root / src / org / gss_project / gss / server / webdav / milton / GssFileResource.java @ 1206:292dec4eae08

History | View | Annotate | Download (10.9 kB)

1
/*
2
 * Copyright 2011 Electronic Business Systems Ltd.
3
 *
4
 * This file is part of GSS.
5
 *
6
 * GSS is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * GSS is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
package org.gss_project.gss.server.webdav.milton;
20

    
21
import org.gss_project.gss.common.exceptions.DuplicateNameException;
22
import org.gss_project.gss.common.exceptions.GSSIOException;
23
import org.gss_project.gss.common.exceptions.InsufficientPermissionsException;
24
import org.gss_project.gss.common.exceptions.ObjectNotFoundException;
25
import org.gss_project.gss.common.exceptions.RpcException;
26
import org.gss_project.gss.server.domain.FileHeader;
27
import org.gss_project.gss.server.domain.User;
28
import org.gss_project.gss.server.ejb.TransactionHelper;
29

    
30
import java.io.BufferedInputStream;
31
import java.io.IOException;
32
import java.io.InputStream;
33
import java.io.OutputStream;
34
import java.util.Date;
35
import java.util.Map;
36
import java.util.concurrent.Callable;
37

    
38
import org.apache.commons.io.IOUtils;
39
import org.jboss.remoting.transport.coyote.ClientAbortException;
40
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
42

    
43
import com.bradmcevoy.http.Auth;
44
import com.bradmcevoy.http.CollectionResource;
45
import com.bradmcevoy.http.CopyableResource;
46
import com.bradmcevoy.http.DeletableResource;
47
import com.bradmcevoy.http.GetableResource;
48
import com.bradmcevoy.http.MoveableResource;
49
import com.bradmcevoy.http.PropFindableResource;
50
import com.bradmcevoy.http.PropPatchableResource;
51
import com.bradmcevoy.http.Range;
52
import com.bradmcevoy.http.Request;
53
import com.bradmcevoy.http.Request.Method;
54
import com.bradmcevoy.http.exceptions.BadRequestException;
55
import com.bradmcevoy.http.exceptions.ConflictException;
56
import com.bradmcevoy.http.exceptions.NotAuthorizedException;
57
import com.bradmcevoy.http.webdav.PropPatchHandler.Fields;
58

    
59

    
60
/**
61
 * @author kman
62
 *
63
 */
64
public class GssFileResource extends GssResource implements CopyableResource, DeletableResource, GetableResource, MoveableResource, PropFindableResource, PropPatchableResource {
65
        /**
66
         * Size of file transfer buffer in bytes.
67
         */
68
        private static final int BUFFER_SIZE = 4096;
69

    
70
        /**
71
         * The output buffer size to use when serving resources.
72
         */
73
        protected int output = 2048;
74

    
75
        /**
76
         * The input buffer size to use when serving resources.
77
         */
78
        private int input = 2048;
79
        
80
        FileHeader file;
81
        private static final Logger log = LoggerFactory.getLogger(GssFileResource.class);
82
        /**
83
         * @param host
84
         * @param factory
85
         * @param resource
86
         */
87
        public GssFileResource(String host, GSSResourceFactory factory, Object resource, User currentUser) {
88
                super(host, factory, resource);
89
                this.file = (FileHeader) resource;
90
                this.currentUser = currentUser;
91
                
92
        }
93
        @Override
94
        public String checkRedirect(Request arg0) {
95
                // TODO Auto-generated method stub
96
                return null;
97
        }
98
        @Override
99
        public Date getModifiedDate() {
100
                return file.getAuditInfo().getModificationDate();
101
        }
102
        @Override
103
        public String getName() {
104
                return file.getName();
105
        }
106
        @Override
107
        public String getUniqueId() {
108
                return "file:"+file.getId().toString();
109
        }
110
        @Override
111
        public void moveTo(final CollectionResource newParent, final String arg1) throws ConflictException, NotAuthorizedException, BadRequestException {
112
                if( newParent instanceof GssFolderResource ) {
113
                        final GssFolderResource newFsParent = (GssFolderResource) newParent;
114
                        try {
115
                                 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
116

    
117
                                        @Override
118
                                        public Void call() throws Exception {
119
                                                if(newFsParent.folder.getId().equals(file.getFolder().getId())){
120
                                                        getService().updateFile(getCurrentUser().getId(), file.getId(), arg1, null, new Date(), null, null, null);
121
                                                }
122
                                                else{
123
                                                        getService().moveFile(getCurrentUser().getId(), file.getId(), newFsParent.folder.getId(), arg1);
124
                                                }
125
                                                return null;
126
                                        }
127
                                        
128
                                });
129
                                GssFileResource.this.file = getService().getFile(getCurrentUser().getId(), file.getId());
130
                                
131
                        } catch (InsufficientPermissionsException e) {
132
                                throw new NotAuthorizedException(this);
133
                        } catch (ObjectNotFoundException e) {
134
                                throw new BadRequestException(this);
135
                        } catch (DuplicateNameException e) {
136
                                throw new ConflictException(this);
137
                        } catch (RpcException e) {
138
                                throw new RuntimeException("System error");
139
                        } catch (GSSIOException e) {
140
                                throw new RuntimeException("Unable to Move");
141
                        } catch (Exception e) {
142
                                throw new RuntimeException("Unable to Move");
143
                        }
144
        } else {
145
            throw new RuntimeException("Destination is an unknown type. Must be a Folder, is a: " + newParent.getClass());
146
        }
147
                
148
        }
149
        @Override
150
        public void copyTo(final CollectionResource newParent, final String arg1) throws NotAuthorizedException, BadRequestException, ConflictException {
151
                if( newParent instanceof GssFolderResource ) {                        
152
                        final GssFolderResource newFsParent = (GssFolderResource) newParent;
153
                        try {
154
                                 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
155

    
156
                                        @Override
157
                                        public Void call() throws Exception {
158
                                                getService().copyFile(getCurrentUser().getId(), file.getId(), newFsParent.folder.getId(), arg1);
159
                                                return null;
160
                                        }
161
                                        
162
                                });
163
                                 GssFileResource.this.file = getService().getFile(getCurrentUser().getId(), file.getId());
164
                        } catch (InsufficientPermissionsException e) {
165
                                throw new NotAuthorizedException(this);
166
                        } catch (ObjectNotFoundException e) {
167
                                throw new BadRequestException(this);
168
                        } catch (DuplicateNameException e) {
169
                                throw new ConflictException(this);
170
                        } catch (RpcException e) {
171
                                throw new RuntimeException("System error");
172
                        } catch (GSSIOException e) {
173
                                throw new RuntimeException("Unable to Move");
174
                        } catch (Exception e) {
175
                                throw new RuntimeException("Unable to Move");
176
                        }
177
        } else {
178
            throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
179
        }
180
                
181
        }
182
        @Override
183
        public void delete() throws NotAuthorizedException, ConflictException, BadRequestException {
184
                try {
185
                        new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
186

    
187
                                @Override
188
                                public Void call() throws Exception {
189
                                        getService().deleteFile(getCurrentUser().getId(), file.getId());
190
                                        return null;
191
                                }
192
                        });
193
                } catch (ObjectNotFoundException e) {
194
                        throw new BadRequestException(this);                        
195
                } catch (InsufficientPermissionsException e) {
196
                        throw new NotAuthorizedException(this);
197
                } catch (RpcException e) {
198
                        throw new BadRequestException(this);
199
                }
200
                catch (Exception e) {                        
201
                        throw new BadRequestException(this);
202
                }
203
        }
204
        @Override
205
        public Long getContentLength() {
206
                return file.getCurrentBody().getFileSize();
207
        }
208
        @Override
209
        public String getContentType(String preferredList ) {
210
        return file.getCurrentBody().getMimeType();
211
        }
212
        @Override
213
        public Long getMaxAgeSeconds(Auth arg0) {
214
                return factory.maxAgeSeconds( this );
215
        }
216
        @Override
217
        public void sendContent(OutputStream out, Range range, Map<String, String> params, String contentType ) throws IOException {
218
        InputStream in = null;
219
        try {
220
            in = getService().getFileContents(getCurrentUser().getId(), file.getId());
221
            if( range != null ) {
222
                    copy(in, out, range);
223
            } else {
224
                    copyRange(in, out);
225
            }
226
            out.flush();
227
            IOUtils.closeQuietly( in );
228
        } catch (ObjectNotFoundException e) {
229
                        // TODO Auto-generated catch block
230
                } catch (InsufficientPermissionsException e) {
231
                        // TODO Auto-generated catch block
232
                } catch (RpcException e) {
233
                        // TODO Auto-generated catch block
234
                } 
235
                catch(ClientAbortException ex){
236
                        //do nothing
237
                }
238
                finally {
239
            IOUtils.closeQuietly( in );
240
            IOUtils.closeQuietly( out );
241
        }
242
                
243
        }
244
        
245
        protected void copy(InputStream resourceInputStream, OutputStream ostream, Range range) throws IOException {
246
                IOException exception = null;
247
                InputStream istream = new BufferedInputStream(resourceInputStream, input);
248
                exception = copyRange(istream, ostream, range.getStart(), range.getFinish());
249
                // Clean up the input stream
250
                istream.close();
251
                // Rethrow any exception that has occurred
252
                if (exception != null)
253
                        throw exception;
254
        }
255
        protected void copy(InputStream resourceInputStream, OutputStream ostream) throws IOException{
256
                IOException exception = null;
257
                InputStream istream = new BufferedInputStream(resourceInputStream, input);
258
                // Copy the input stream to the output stream
259
                exception = copyRange(istream, ostream);
260
                // Clean up the input stream
261
                istream.close();
262
                // Rethrow any exception that has occurred
263
                if (exception != null)
264
                        throw exception;
265
        }
266
        
267
        private IOException copyRange(InputStream istream, OutputStream ostream) {
268
                // Copy the input stream to the output stream
269
                IOException exception = null;
270
                byte buffer[] = new byte[input];
271
                int len = buffer.length;
272
                while (true)
273
                        try {
274
                                len = istream.read(buffer);
275
                                if (len == -1)
276
                                        break;
277
                                ostream.write(buffer, 0, len);
278
                        } catch (IOException e) {
279
                                exception = e;
280
                                len = -1;
281
                                break;
282
                        }
283
                return exception;
284
        }
285
        
286
        private IOException copyRange(InputStream istream, OutputStream ostream, long start, long end) {
287
                log.debug("Serving bytes:" + start + "-" + end);
288
                try {
289
                        istream.skip(start);
290
                } catch (IOException e) {
291
                        return e;
292
                }
293
                IOException exception = null;
294
                long bytesToRead = end - start + 1;
295
                byte buffer[] = new byte[input];
296
                int len = buffer.length;
297
                while (bytesToRead > 0 && len >= buffer.length) {
298
                        try {
299
                                len = istream.read(buffer);
300
                                if (bytesToRead >= len) {
301
                                        ostream.write(buffer, 0, len);
302
                                        bytesToRead -= len;
303
                                } else {
304
                                        ostream.write(buffer, 0, (int) bytesToRead);
305
                                        bytesToRead = 0;
306
                                }
307
                        } catch (IOException e) {
308
                                exception = e;
309
                                len = -1;
310
                        }
311
                        if (len < buffer.length)
312
                                break;
313
                }
314
                return exception;
315
        }
316
        @Override
317
        public Date getCreateDate() {
318
                // TODO Auto-generated method stub
319
                return file.getAuditInfo().getCreationDate();
320
        }
321
        @Override
322
        public void setProperties(Fields arg0) {
323
                // TODO Auto-generated method stub
324
                
325
        }
326
        
327
        
328
        @Override
329
        public boolean authorise(Request request, Method method, Auth auth) {
330
        boolean result = factory.getSecurityManager().authorise(request, method, auth, this);
331
        if(result){
332
                User user = getCurrentUser();
333
                //check permission
334
                try {
335
                                getService().getFile(user.getId(), file.getId());
336
                        } catch (ObjectNotFoundException e) {
337
                                return false;
338
                        } catch (InsufficientPermissionsException e) {
339
                                return false;
340
                        } catch (RpcException e) {
341
                                return false;
342
                        }
343
                        return true;
344
        }
345
        return result;
346
    }
347
}