2 * Copyright 2011 Electronic Business Systems Ltd.
4 * This file is part of GSS.
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.
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.
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/>.
19 package gr.ebs.gss.server.webdav.milton;
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.QuotaExceededException;
26 import gr.ebs.gss.client.exceptions.RpcException;
27 import gr.ebs.gss.server.domain.FileHeader;
28 import gr.ebs.gss.server.domain.Folder;
29 import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
30 import gr.ebs.gss.server.domain.dto.FolderDTO;
31 import gr.ebs.gss.server.domain.dto.UserDTO;
32 import gr.ebs.gss.server.ejb.TransactionHelper;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.io.OutputStream;
38 import java.net.URLDecoder;
39 import java.util.ArrayList;
40 import java.util.Date;
41 import java.util.List;
43 import java.util.concurrent.Callable;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
48 import com.bradmcevoy.http.Auth;
49 import com.bradmcevoy.http.CollectionResource;
50 import com.bradmcevoy.http.CopyableResource;
51 import com.bradmcevoy.http.DeletableResource;
52 import com.bradmcevoy.http.GetableResource;
53 import com.bradmcevoy.http.LockInfo;
54 import com.bradmcevoy.http.LockResult;
55 import com.bradmcevoy.http.LockTimeout;
56 import com.bradmcevoy.http.LockToken;
57 import com.bradmcevoy.http.LockingCollectionResource;
58 import com.bradmcevoy.http.MakeCollectionableResource;
59 import com.bradmcevoy.http.MoveableResource;
60 import com.bradmcevoy.http.PropFindableResource;
61 import com.bradmcevoy.http.PutableResource;
62 import com.bradmcevoy.http.QuotaResource;
63 import com.bradmcevoy.http.Range;
64 import com.bradmcevoy.http.Request;
65 import com.bradmcevoy.http.Resource;
66 import com.bradmcevoy.http.XmlWriter;
67 import com.bradmcevoy.http.Request.Method;
68 import com.bradmcevoy.http.exceptions.BadRequestException;
69 import com.bradmcevoy.http.exceptions.ConflictException;
70 import com.bradmcevoy.http.exceptions.NotAuthorizedException;
77 public class GssFolderResource extends GssResource implements MakeCollectionableResource, PutableResource, CopyableResource, DeletableResource, MoveableResource, PropFindableResource, LockingCollectionResource, GetableResource, QuotaResource{
78 private static final Logger log = LoggerFactory.getLogger(GssFolderResource.class);
86 public GssFolderResource(String host, GSSResourceFactory factory, Object resource, UserDTO currentUser) {
87 super(host, factory, resource);
88 folder=(Folder) resource;
89 this.currentUser=currentUser;
92 public String checkRedirect(Request request) {
93 if( factory.getDefaultPage() != null ) {
94 return request.getAbsoluteUrl() + "/" + factory.getDefaultPage();
100 public Date getModifiedDate() {
101 if(folder!=null && folder.getAuditInfo()!=null)
102 return folder.getAuditInfo().getModificationDate();
106 public String getName() {
107 return folder.getName();
110 public String getUniqueId() {
111 return "folder:"+folder.getId().toString();
114 public void moveTo(final CollectionResource newParent, final String arg1) throws ConflictException, NotAuthorizedException, BadRequestException {
115 if( newParent instanceof GssFolderResource ) {
116 final GssFolderResource newFsParent = (GssFolderResource) newParent;
118 if(newFsParent.folder.getName().equals(folder.getParent().getName())){
119 if(!folder.getName().equals(arg1))
120 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
123 public Void call() throws Exception {
124 factory.getService().updateFolder(getCurrentUser().getId(), folder.getId(), arg1, null, null);
130 else new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
133 public Void call() throws Exception {
134 factory.getService().moveFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
139 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
141 } catch (InsufficientPermissionsException e) {
142 throw new NotAuthorizedException(this);
143 } catch (ObjectNotFoundException e) {
144 throw new BadRequestException(this);
145 } catch (DuplicateNameException e) {
146 throw new ConflictException(this);
147 } catch (RpcException e) {
148 throw new RuntimeException("System error");
149 } catch (GSSIOException e) {
150 throw new RuntimeException("Unable to Move");
151 } catch (Exception e) {
152 throw new RuntimeException("Unable to Move");
155 throw new RuntimeException("Destination is an unknown type. Must be a Folder, is a: " + newParent.getClass());
160 public void copyTo(final CollectionResource newParent, final String arg1) throws NotAuthorizedException, BadRequestException, ConflictException {
161 if( newParent instanceof GssFolderResource ) {
162 final GssFolderResource newFsParent = (GssFolderResource) newParent;
164 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
167 public Void call() throws Exception {
168 factory.getService().copyFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
173 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
174 } catch (InsufficientPermissionsException e) {
175 throw new NotAuthorizedException(this);
176 } catch (ObjectNotFoundException e) {
177 throw new BadRequestException(this);
178 } catch (DuplicateNameException e) {
179 throw new ConflictException(this);
180 } catch (RpcException e) {
181 throw new RuntimeException("System error");
182 } catch (GSSIOException e) {
183 throw new RuntimeException("Unable to Move");
184 } catch (Exception e) {
185 throw new RuntimeException("Unable to Move");
188 throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
193 public CollectionResource createCollection(final String name) throws NotAuthorizedException, ConflictException, BadRequestException {
194 ////log.info("CALLING CREATECOLLECTION:"+name);
196 final Folder folderParent = folder;
197 Folder created = new TransactionHelper<Folder>().tryExecute(new Callable<Folder>() {
199 public Folder call() throws Exception {
200 Folder f = factory.getService().createFolder(getCurrentUser().getId(), folder.getId(), name);
204 return new GssFolderResource(host, factory, created, getCurrentUser());
205 } catch (DuplicateNameException e) {
207 // XXX If the existing name is a folder we should be returning
208 // SC_METHOD_NOT_ALLOWED, or even better, just do the createFolder
209 // without checking first and then deal with the exceptions.
210 throw new ConflictException(this);
211 } catch (InsufficientPermissionsException e) {
213 throw new NotAuthorizedException(this);
214 } catch (ObjectNotFoundException e) {
217 } catch (RpcException e) {
219 throw new RuntimeException("System Error");
220 } catch (Exception e) {
222 throw new RuntimeException("System Error");
226 public Resource child(String name) {
227 for(Folder f : folder.getSubfolders())
228 if(f.getName().equals(name))
229 return new GssFolderResource(host, factory, f, getCurrentUser());
232 for(FileHeader f : factory.getService().getFiles(folder.getOwner().getId(), folder.getId(), true))
233 if(f.getName().equals(name))
234 return new GssFileResource(host, factory, f,getCurrentUser());
235 } catch (ObjectNotFoundException e) {
236 // TODO Auto-generated catch block
238 } catch (InsufficientPermissionsException e) {
239 // TODO Auto-generated catch block
241 } catch (RpcException e) {
242 // TODO Auto-generated catch block
245 ////log.info("CALLING CHILD return null");
249 public List<? extends Resource> getChildren() {
251 this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
252 } catch (ObjectNotFoundException e) {
253 // TODO Auto-generated catch block
255 } catch (InsufficientPermissionsException e) {
256 // TODO Auto-generated catch block
258 } catch (RpcException e) {
259 // TODO Auto-generated catch block
262 List<GssResource> result = new ArrayList<GssResource>();
263 for(Folder f : folder.getSubfolders())
265 result.add(new GssFolderResource(host, factory, f, getCurrentUser()));
267 for(FileHeader f : factory.getService().getFiles(getCurrentUser().getId(), folder.getId(), true))
268 result.add(new GssFileResource(host, factory, f,getCurrentUser()));
269 } catch (ObjectNotFoundException e) {
270 // TODO Auto-generated catch block
272 } catch (InsufficientPermissionsException e) {
273 // TODO Auto-generated catch block
275 } catch (RpcException e) {
276 // TODO Auto-generated catch block
282 public Resource createNew(final String name, InputStream in, Long length, final String contentType ) throws IOException, ConflictException, NotAuthorizedException, BadRequestException {
284 File uploadedFile = null;
286 uploadedFile = factory.getService().uploadFile(in, getCurrentUser().getId());
287 } catch (IOException ex) {
288 throw new IOException(ex);
289 } catch (ObjectNotFoundException e) {
291 throw new BadRequestException(this);
292 } catch (RpcException e) {
293 throw new RuntimeException("Unable to upload file");
295 final File uf = uploadedFile;
297 String pathFolder = folder.getPath();
298 if(!pathFolder.endsWith("/"))
299 pathFolder=pathFolder+"/";
300 String fname = pathFolder+name;
301 ////log.info("fname:"+fname+" "+URLDecoder.decode(fname));
304 ff2 = factory.getService().getResourceAtPath(folder.getOwner().getId(), URLDecoder.decode(fname), true);
306 catch(ObjectNotFoundException ex){
309 final Object ff = ff2;
310 FileHeader kmfile=null;
311 if(ff!=null && ff instanceof FileHeaderDTO){
312 kmfile = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
314 public FileHeader call() throws Exception{
315 return factory.getService().updateFileContents(getCurrentUser().getId(), ((FileHeader)ff).getId(), contentType, uf.length(), uf.getAbsolutePath());
320 kmfile = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
322 public FileHeader call() throws Exception{
323 return factory.getService().createFile(getCurrentUser().getId(), folder.getId(), name, contentType, uf.length(), uf.getAbsolutePath());
326 return new GssFileResource(host, factory, kmfile, getCurrentUser());
327 } catch (ObjectNotFoundException e) {
329 throw new BadRequestException(this);
330 } catch (InsufficientPermissionsException e) {
332 throw new NotAuthorizedException(this);
334 catch (DuplicateNameException e) {
335 // TODO Auto-generated catch block
337 throw new ConflictException(this);
339 catch(QuotaExceededException e){
341 throw new ConflictException(this);
345 throw new RuntimeException("System Error");
349 public void delete() throws NotAuthorizedException, ConflictException, BadRequestException {
351 factory.getService().deleteFolder(getCurrentUser().getId(), folder.getId());
352 } catch (InsufficientPermissionsException e) {
354 throw new NotAuthorizedException(this);
355 } catch (ObjectNotFoundException e) {
357 throw new BadRequestException(this);
358 } catch (RpcException e) {
360 throw new BadRequestException(this);
365 public Date getCreateDate() {
366 if(folder!=null && folder.getAuditInfo()!=null)
367 return folder.getAuditInfo().getCreationDate();
371 public LockToken createAndLock(final String name, LockTimeout timeout, LockInfo lockInfo ) throws NotAuthorizedException {
372 FileHeader kmfile=null;
374 kmfile = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
376 public FileHeader call() throws Exception {
377 return factory.getService().createEmptyFile(getCurrentUser().getId(), folder.getId(), name);
380 } catch (Exception e) {
381 // TODO Auto-generated catch block
384 ////log.info("CREATE AND LOCK:"+kmfileDTO.getId());
385 //File dest = new File( this.getFile(), name );
386 //createEmptyFile( );
387 GssFileResource newRes = new GssFileResource( host, factory, kmfile ,getCurrentUser());
388 LockResult res = newRes.lock( timeout, lockInfo );
389 return res.getLockToken();
393 public Long getContentLength() {
397 public String getContentType(String arg0) {
401 public Long getMaxAgeSeconds(Auth arg0) {
402 // TODO Auto-generated method stub
406 * Will generate a listing of the contents of this directory, unless
407 * the factory's allowDirectoryBrowsing has been set to false.
409 * If so it will just output a message saying that access has been disabled.
415 * @throws IOException
416 * @throws NotAuthorizedException
418 public void sendContent( OutputStream out, Range range, Map<String, String> params, String contentType ) throws IOException, NotAuthorizedException {
419 String subpath = folder.getPath();//getFile().getCanonicalPath().substring( factory.getRoot().getCanonicalPath().length() ).replace( '\\', '/' );
420 String uri = "/" + factory.getContextPath() + subpath;
421 XmlWriter w = new XmlWriter( out );
424 w.begin( "h1" ).open().writeText( this.getName() ).close();
426 for( Resource r : getChildren() ) {
430 w.begin( "a" ).writeAtt( "href", uri + "/" + r.getName() ).open().writeText( r.getName() ).close();
433 w.begin( "td" ).open().writeText( r.getModifiedDate() + "" ).close();
442 public Long getQuotaAvailable() {
443 if(getCurrentUser()!=null)
445 return factory.getService().getUserStatistics(getCurrentUser().getId()).getQuotaLeftSize();
446 } catch (ObjectNotFoundException e) {
447 // TODO Auto-generated catch block
449 } catch (RpcException e) {
450 // TODO Auto-generated catch block
456 public Long getQuotaUsed() {
457 if(getCurrentUser()!=null)
459 return factory.getService().getUserStatistics(getCurrentUser().getId()).getFileSize();
460 } catch (ObjectNotFoundException e) {
461 // TODO Auto-generated catch block
463 } catch (RpcException e) {
464 // TODO Auto-generated catch block
471 public boolean authorise(Request request, Method method, Auth auth) {
472 boolean result = factory.getSecurityManager().authorise(request, method, auth, this);
474 UserDTO user = getCurrentUser();
477 this.folder=factory.getService().getFolder(user.getId(), folder.getId());
478 } catch (ObjectNotFoundException e) {
480 } catch (InsufficientPermissionsException e) {
482 } catch (RpcException e) {