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.dto.FileHeaderDTO;
28 import gr.ebs.gss.server.domain.dto.FolderDTO;
29 import gr.ebs.gss.server.domain.dto.UserDTO;
30 import gr.ebs.gss.server.ejb.TransactionHelper;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.OutputStream;
36 import java.net.URLDecoder;
37 import java.util.ArrayList;
38 import java.util.Date;
39 import java.util.List;
41 import java.util.concurrent.Callable;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 import com.bradmcevoy.http.Auth;
47 import com.bradmcevoy.http.CollectionResource;
48 import com.bradmcevoy.http.CopyableResource;
49 import com.bradmcevoy.http.DeletableResource;
50 import com.bradmcevoy.http.GetableResource;
51 import com.bradmcevoy.http.LockInfo;
52 import com.bradmcevoy.http.LockResult;
53 import com.bradmcevoy.http.LockTimeout;
54 import com.bradmcevoy.http.LockToken;
55 import com.bradmcevoy.http.LockingCollectionResource;
56 import com.bradmcevoy.http.MakeCollectionableResource;
57 import com.bradmcevoy.http.MoveableResource;
58 import com.bradmcevoy.http.PropFindableResource;
59 import com.bradmcevoy.http.PutableResource;
60 import com.bradmcevoy.http.QuotaResource;
61 import com.bradmcevoy.http.Range;
62 import com.bradmcevoy.http.Request;
63 import com.bradmcevoy.http.Resource;
64 import com.bradmcevoy.http.XmlWriter;
65 import com.bradmcevoy.http.Request.Method;
66 import com.bradmcevoy.http.exceptions.BadRequestException;
67 import com.bradmcevoy.http.exceptions.ConflictException;
68 import com.bradmcevoy.http.exceptions.NotAuthorizedException;
75 public class GssFolderResource extends GssResource implements MakeCollectionableResource, PutableResource, CopyableResource, DeletableResource, MoveableResource, PropFindableResource, LockingCollectionResource, GetableResource, QuotaResource{
76 private static final Logger log = LoggerFactory.getLogger(GssFolderResource.class);
84 public GssFolderResource(String host, GSSResourceFactory factory, Object resource) {
85 super(host, factory, resource);
86 folder=(FolderDTO) resource;
89 public String checkRedirect(Request request) {
90 if( factory.getDefaultPage() != null ) {
91 return request.getAbsoluteUrl() + "/" + factory.getDefaultPage();
97 public Date getModifiedDate() {
98 if(folder!=null && folder.getAuditInfo()!=null)
99 return folder.getAuditInfo().getModificationDate();
103 public String getName() {
104 return folder.getName();
107 public String getUniqueId() {
108 return "folder:"+folder.getId().toString();
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;
115 if(newFsParent.folder.getName().equals(folder.getParent().getName())){
116 if(!folder.getName().equals(arg1))
117 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
120 public Void call() throws Exception {
121 factory.getService().updateFolder(getCurrentUser().getId(), folder.getId(), arg1, null, null);
127 else new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
130 public Void call() throws Exception {
131 factory.getService().moveFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
136 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
138 } catch (InsufficientPermissionsException e) {
139 throw new NotAuthorizedException(this);
140 } catch (ObjectNotFoundException e) {
141 throw new BadRequestException(this);
142 } catch (DuplicateNameException e) {
143 throw new ConflictException(this);
144 } catch (RpcException e) {
145 throw new RuntimeException("System error");
146 } catch (GSSIOException e) {
147 throw new RuntimeException("Unable to Move");
148 } catch (Exception e) {
149 throw new RuntimeException("Unable to Move");
152 throw new RuntimeException("Destination is an unknown type. Must be a Folder, is a: " + newParent.getClass());
157 public void copyTo(final CollectionResource newParent, final String arg1) throws NotAuthorizedException, BadRequestException, ConflictException {
158 if( newParent instanceof GssFolderResource ) {
159 final GssFolderResource newFsParent = (GssFolderResource) newParent;
161 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
164 public Void call() throws Exception {
165 factory.getService().copyFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
170 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
171 } catch (InsufficientPermissionsException e) {
172 throw new NotAuthorizedException(this);
173 } catch (ObjectNotFoundException e) {
174 throw new BadRequestException(this);
175 } catch (DuplicateNameException e) {
176 throw new ConflictException(this);
177 } catch (RpcException e) {
178 throw new RuntimeException("System error");
179 } catch (GSSIOException e) {
180 throw new RuntimeException("Unable to Move");
181 } catch (Exception e) {
182 throw new RuntimeException("Unable to Move");
185 throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
190 public CollectionResource createCollection(final String name) throws NotAuthorizedException, ConflictException, BadRequestException {
192 final FolderDTO folderParent = folder;
193 FolderDTO created = new TransactionHelper<FolderDTO>().tryExecute(new Callable<FolderDTO>() {
195 public FolderDTO call() throws Exception {
196 FolderDTO f = factory.getService().createFolder(getCurrentUser().getId(), folder.getId(), name);
200 return new GssFolderResource(host, factory, created);
201 } catch (DuplicateNameException e) {
203 // XXX If the existing name is a folder we should be returning
204 // SC_METHOD_NOT_ALLOWED, or even better, just do the createFolder
205 // without checking first and then deal with the exceptions.
206 throw new ConflictException(this);
207 } catch (InsufficientPermissionsException e) {
209 throw new NotAuthorizedException(this);
210 } catch (ObjectNotFoundException e) {
213 } catch (RpcException e) {
215 throw new RuntimeException("System Error");
216 } catch (Exception e) {
218 throw new RuntimeException("System Error");
222 public Resource child(String name) {
223 for(FolderDTO f : folder.getSubfolders())
224 if(f.getName().equals(name))
225 return new GssFolderResource(host, factory, f);
228 for(FileHeaderDTO f : factory.getService().getFiles(folder.getOwner().getId(), folder.getId(), true))
229 if(f.getName().equals(name))
230 return new GssFileResource(host, factory, f);
231 } catch (ObjectNotFoundException e) {
232 // TODO Auto-generated catch block
234 } catch (InsufficientPermissionsException e) {
235 // TODO Auto-generated catch block
237 } catch (RpcException e) {
238 // TODO Auto-generated catch block
245 public List<? extends Resource> getChildren() {
247 this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
248 } catch (ObjectNotFoundException e) {
249 // TODO Auto-generated catch block
251 } catch (InsufficientPermissionsException e) {
252 // TODO Auto-generated catch block
254 } catch (RpcException e) {
255 // TODO Auto-generated catch block
258 List<GssResource> result = new ArrayList<GssResource>();
259 for(FolderDTO f : folder.getSubfolders())
261 result.add(new GssFolderResource(host, factory, f));
263 for(FileHeaderDTO f : factory.getService().getFiles(getCurrentUser().getId(), folder.getId(), true))
264 result.add(new GssFileResource(host, factory, f));
265 } catch (ObjectNotFoundException e) {
266 // TODO Auto-generated catch block
268 } catch (InsufficientPermissionsException e) {
269 // TODO Auto-generated catch block
271 } catch (RpcException e) {
272 // TODO Auto-generated catch block
278 public Resource createNew(final String name, InputStream in, Long length, final String contentType ) throws IOException, ConflictException, NotAuthorizedException, BadRequestException {
280 File uploadedFile = null;
282 uploadedFile = factory.getService().uploadFile(in, getCurrentUser().getId());
283 } catch (IOException ex) {
284 throw new IOException(ex);
285 } catch (ObjectNotFoundException e) {
287 throw new BadRequestException(this);
288 } catch (RpcException e) {
289 throw new RuntimeException("Unable to upload file");
291 final File uf = uploadedFile;
293 String pathFolder = folder.getPath();
294 if(!pathFolder.endsWith("/"))
295 pathFolder=pathFolder+"/";
296 String fname = pathFolder+name;
297 log.info("fname:"+fname+" "+URLDecoder.decode(fname));
300 ff2 = factory.getService().getResourceAtPath(folder.getOwner().getId(), URLDecoder.decode(fname), true);
302 catch(ObjectNotFoundException ex){
305 final Object ff = ff2;
306 FileHeaderDTO kmfileDTO=null;
307 if(ff!=null && ff instanceof FileHeaderDTO){
308 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
310 public FileHeaderDTO call() throws Exception{
311 return factory.getService().updateFileContents(getCurrentUser().getId(), ((FileHeaderDTO)ff).getId(), contentType, uf.length(), uf.getAbsolutePath());
316 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
318 public FileHeaderDTO call() throws Exception{
319 return factory.getService().createFile(getCurrentUser().getId(), folder.getId(), name, contentType, uf.length(), uf.getAbsolutePath());
322 return new GssFileResource(host, factory, kmfileDTO);
323 } catch (ObjectNotFoundException e) {
324 throw new BadRequestException(this);
325 } catch (InsufficientPermissionsException e) {
326 throw new NotAuthorizedException(this);
328 catch (DuplicateNameException e) {
329 // TODO Auto-generated catch block
331 throw new ConflictException(this);
333 catch(QuotaExceededException e){
334 throw new ConflictException(this);
337 throw new RuntimeException("System Error");
341 public void delete() throws NotAuthorizedException, ConflictException, BadRequestException {
343 factory.getService().deleteFolder(getCurrentUser().getId(), folder.getId());
344 } catch (InsufficientPermissionsException e) {
346 throw new NotAuthorizedException(this);
347 } catch (ObjectNotFoundException e) {
349 throw new BadRequestException(this);
350 } catch (RpcException e) {
352 throw new BadRequestException(this);
357 public Date getCreateDate() {
358 if(folder!=null && folder.getAuditInfo()!=null)
359 return folder.getAuditInfo().getCreationDate();
363 public LockToken createAndLock(final String name, LockTimeout timeout, LockInfo lockInfo ) throws NotAuthorizedException {
364 FileHeaderDTO kmfileDTO=null;
366 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
368 public FileHeaderDTO call() throws Exception {
369 return factory.getService().createEmptyFile(getCurrentUser().getId(), folder.getId(), name);
372 } catch (Exception e) {
373 // TODO Auto-generated catch block
376 log.info("CREATE AND LOCK:"+kmfileDTO.getId());
377 //File dest = new File( this.getFile(), name );
378 //createEmptyFile( );
379 GssFileResource newRes = new GssFileResource( host, factory, kmfileDTO );
380 LockResult res = newRes.lock( timeout, lockInfo );
381 return res.getLockToken();
385 public Long getContentLength() {
389 public String getContentType(String arg0) {
393 public Long getMaxAgeSeconds(Auth arg0) {
394 // TODO Auto-generated method stub
398 * Will generate a listing of the contents of this directory, unless
399 * the factory's allowDirectoryBrowsing has been set to false.
401 * If so it will just output a message saying that access has been disabled.
407 * @throws IOException
408 * @throws NotAuthorizedException
410 public void sendContent( OutputStream out, Range range, Map<String, String> params, String contentType ) throws IOException, NotAuthorizedException {
411 String subpath = folder.getPath();//getFile().getCanonicalPath().substring( factory.getRoot().getCanonicalPath().length() ).replace( '\\', '/' );
412 String uri = "/" + factory.getContextPath() + subpath;
413 XmlWriter w = new XmlWriter( out );
416 w.begin( "h1" ).open().writeText( this.getName() ).close();
418 for( Resource r : getChildren() ) {
422 w.begin( "a" ).writeAtt( "href", uri + "/" + r.getName() ).open().writeText( r.getName() ).close();
425 w.begin( "td" ).open().writeText( r.getModifiedDate() + "" ).close();
434 public Long getQuotaAvailable() {
435 if(getCurrentUser()!=null)
437 return factory.getService().getUserStatistics(getCurrentUser().getId()).getQuotaLeftSize();
438 } catch (ObjectNotFoundException e) {
439 // TODO Auto-generated catch block
441 } catch (RpcException e) {
442 // TODO Auto-generated catch block
448 public Long getQuotaUsed() {
449 if(getCurrentUser()!=null)
451 return factory.getService().getUserStatistics(getCurrentUser().getId()).getFileSize();
452 } catch (ObjectNotFoundException e) {
453 // TODO Auto-generated catch block
455 } catch (RpcException e) {
456 // TODO Auto-generated catch block
463 public boolean authorise(Request request, Method method, Auth auth) {
464 boolean result = factory.getSecurityManager().authorise(request, method, auth, this);
466 UserDTO user = getCurrentUser();
469 this.folder=factory.getService().getFolder(user.getId(), folder.getId());
470 } catch (ObjectNotFoundException e) {
472 } catch (InsufficientPermissionsException e) {
474 } catch (RpcException e) {