Statistics
| Branch: | Tag: | Revision:

root / src / gr / ebs / gss / server / webdav / milton / GssFileResource.java @ 4cf1e12e

History | View | Annotate | Download (10.7 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 gr.ebs.gss.server.webdav.milton;
20

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