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.RpcException;
26 import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
27 import gr.ebs.gss.server.domain.dto.FolderDTO;
28 import gr.ebs.gss.server.ejb.TransactionHelper;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.OutputStream;
34 import java.util.ArrayList;
35 import java.util.Date;
36 import java.util.List;
38 import java.util.concurrent.Callable;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
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.LockInfo;
49 import com.bradmcevoy.http.LockResult;
50 import com.bradmcevoy.http.LockTimeout;
51 import com.bradmcevoy.http.LockToken;
52 import com.bradmcevoy.http.LockingCollectionResource;
53 import com.bradmcevoy.http.MakeCollectionableResource;
54 import com.bradmcevoy.http.MoveableResource;
55 import com.bradmcevoy.http.PropFindableResource;
56 import com.bradmcevoy.http.PutableResource;
57 import com.bradmcevoy.http.Range;
58 import com.bradmcevoy.http.Request;
59 import com.bradmcevoy.http.Resource;
60 import com.bradmcevoy.http.XmlWriter;
61 import com.bradmcevoy.http.exceptions.BadRequestException;
62 import com.bradmcevoy.http.exceptions.ConflictException;
63 import com.bradmcevoy.http.exceptions.NotAuthorizedException;
70 public class GssFolderResource extends GssResource implements MakeCollectionableResource, PutableResource, CopyableResource, DeletableResource, MoveableResource, PropFindableResource, LockingCollectionResource, GetableResource{
71 private static final Logger log = LoggerFactory.getLogger(GssFolderResource.class);
79 public GssFolderResource(String host, GSSResourceFactory factory, Object resource) {
80 super(host, factory, resource);
81 folder=(FolderDTO) resource;
84 public String checkRedirect(Request request) {
85 if( factory.getDefaultPage() != null ) {
86 return request.getAbsoluteUrl() + "/" + factory.getDefaultPage();
92 public Date getModifiedDate() {
93 return folder.getAuditInfo().getModificationDate();
96 public String getName() {
97 return folder.getName();
100 public String getUniqueId() {
101 return folder.getId().toString();
104 public void moveTo(final CollectionResource newParent, final String arg1) throws ConflictException, NotAuthorizedException, BadRequestException {
105 if( newParent instanceof GssFolderResource ) {
106 log.info("MOVING:"+arg1);
107 final GssFolderResource newFsParent = (GssFolderResource) newParent;
108 log.info("NEW PARENT IS:"+newFsParent.folder.getName());
109 /*File dest = new File(newFsParent.getFile(), newName);
110 boolean ok = this.file.renameTo(dest);
111 if( !ok ) throw new RuntimeException("Failed to move to: " + dest.getAbsolutePath());
114 if(newFsParent.folder.getName().equals(folder.getParent().getName())){
115 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
118 public Void call() throws Exception {
119 factory.getService().updateFolder(getCurrentUser().getId(), folder.getId(), arg1, null, null);
120 log.info("RENAMING OK:"+arg1);
127 //this.folder = factory.getService().updateFolder(user.getId(), folder.getId(), arg1, null, null);
128 else new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
131 public Void call() throws Exception {
132 factory.getService().moveFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
133 log.info("MOVING OK:"+arg1);
139 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
140 log.info("MOVING:"+folder.getName());
142 } catch (InsufficientPermissionsException e) {
143 // TODO Auto-generated catch block
145 } catch (ObjectNotFoundException e) {
146 // TODO Auto-generated catch block
148 } catch (DuplicateNameException e) {
149 // TODO Auto-generated catch block
151 } catch (RpcException e) {
152 // TODO Auto-generated catch block
154 } catch (GSSIOException e) {
155 // TODO Auto-generated catch block
157 } catch (Exception e) {
158 // TODO Auto-generated catch block
162 throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
167 public void copyTo(final CollectionResource newParent, final String arg1) throws NotAuthorizedException, BadRequestException, ConflictException {
168 if( newParent instanceof GssFolderResource ) {
169 log.info("COPYING:"+arg1);
170 final GssFolderResource newFsParent = (GssFolderResource) newParent;
171 log.info("NEW PARENT IS:"+newFsParent.folder.getName());
172 /*File dest = new File(newFsParent.getFile(), newName);
173 boolean ok = this.file.renameTo(dest);
174 if( !ok ) throw new RuntimeException("Failed to move to: " + dest.getAbsolutePath());
177 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
180 public Void call() throws Exception {
181 factory.getService().copyFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
182 log.info("COPYING OK:"+arg1);
188 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
189 log.info("MOVING:"+folder.getName());
191 } catch (InsufficientPermissionsException e) {
192 // TODO Auto-generated catch block
194 } catch (ObjectNotFoundException e) {
195 // TODO Auto-generated catch block
197 } catch (DuplicateNameException e) {
198 // TODO Auto-generated catch block
200 } catch (RpcException e) {
201 // TODO Auto-generated catch block
203 } catch (GSSIOException e) {
204 // TODO Auto-generated catch block
206 } catch (Exception e) {
207 // TODO Auto-generated catch block
211 throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
216 public CollectionResource createCollection(final String name) throws NotAuthorizedException, ConflictException, BadRequestException {
218 final FolderDTO folderParent = folder;
219 FolderDTO created = new TransactionHelper<FolderDTO>().tryExecute(new Callable<FolderDTO>() {
221 public FolderDTO call() throws Exception {
222 FolderDTO f = factory.getService().createFolder(getCurrentUser().getId(), folder.getId(), name);
226 return new GssFolderResource(host, factory, created);
227 } catch (DuplicateNameException e) {
229 // XXX If the existing name is a folder we should be returning
230 // SC_METHOD_NOT_ALLOWED, or even better, just do the createFolder
231 // without checking first and then deal with the exceptions.
232 throw new ConflictException(this);
233 } catch (InsufficientPermissionsException e) {
235 throw new NotAuthorizedException(this);
236 } catch (ObjectNotFoundException e) {
239 } catch (RpcException e) {
242 } catch (Exception e) {
248 public Resource child(String name) {
249 for(FolderDTO f : folder.getSubfolders())
250 if(f.getName().equals(name))
251 return new GssFolderResource(host, factory, f);
254 for(FileHeaderDTO f : factory.getService().getFiles(folder.getOwner().getId(), folder.getId(), true))
255 if(f.getName().equals(name))
256 return new GssFileResource(host, factory, f);
257 } catch (ObjectNotFoundException e) {
258 // TODO Auto-generated catch block
260 } catch (InsufficientPermissionsException e) {
261 // TODO Auto-generated catch block
263 } catch (RpcException e) {
264 // TODO Auto-generated catch block
271 public List<? extends Resource> getChildren() {
273 this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
274 } catch (ObjectNotFoundException e) {
275 // TODO Auto-generated catch block
277 } catch (InsufficientPermissionsException e) {
278 // TODO Auto-generated catch block
280 } catch (RpcException e) {
281 // TODO Auto-generated catch block
284 List<GssResource> result = new ArrayList<GssResource>();
285 for(FolderDTO f : folder.getSubfolders())
287 result.add(new GssFolderResource(host, factory, f));
289 for(FileHeaderDTO f : factory.getService().getFiles(getCurrentUser().getId(), folder.getId(), true))
290 result.add(new GssFileResource(host, factory, f));
291 } catch (ObjectNotFoundException e) {
292 // TODO Auto-generated catch block
294 } catch (InsufficientPermissionsException e) {
295 // TODO Auto-generated catch block
297 } catch (RpcException e) {
298 // TODO Auto-generated catch block
304 public Resource createNew(final String name, InputStream in, Long length, final String contentType ) throws IOException, ConflictException, NotAuthorizedException, BadRequestException {
306 File uploadedFile = null;
308 uploadedFile = factory.getService().uploadFile(in, getCurrentUser().getId());
309 } catch (IOException ex) {
310 throw new IOException(ex);
311 } catch (ObjectNotFoundException e) {
312 // TODO Auto-generated catch block
314 } catch (RpcException e) {
315 // TODO Auto-generated catch block
318 final File uf = uploadedFile;
320 String pathFolder = folder.getPath();
321 if(!pathFolder.endsWith("/"))
322 pathFolder=pathFolder+"/";
323 String fname = pathFolder+name;
326 ff2 = factory.getService().getResourceAtPath(folder.getOwner().getId(), fname, true);
328 catch(ObjectNotFoundException ex){
331 final Object ff = ff2;
332 log.info("**************FOUND FILE:"+ff);
333 FileHeaderDTO kmfileDTO=null;
334 if(ff!=null && ff instanceof FileHeaderDTO){
335 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
337 public FileHeaderDTO call() throws Exception {
338 log.info("**************UPDATING:"+ff);
339 return factory.getService().updateFileContents(getCurrentUser().getId(), ((FileHeaderDTO)ff).getId(), contentType, uf.length(), uf.getAbsolutePath());
344 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
346 public FileHeaderDTO call() throws Exception {
347 log.info("**************CREATING:"+ff);
348 return factory.getService().createFile(getCurrentUser().getId(), folder.getId(), name, contentType, uf.length(), uf.getAbsolutePath());
351 return new GssFileResource(host, factory, kmfileDTO);
352 } catch (Exception e) {
358 public void delete() throws NotAuthorizedException, ConflictException, BadRequestException {
360 factory.getService().deleteFolder(getCurrentUser().getId(), folder.getId());
361 } catch (InsufficientPermissionsException e) {
363 throw new NotAuthorizedException(this);
364 } catch (ObjectNotFoundException e) {
366 throw new BadRequestException(this);
367 } catch (RpcException e) {
369 throw new BadRequestException(this);
374 public Date getCreateDate() {
375 if(folder!=null && folder.getAuditInfo()!=null)
376 return folder.getAuditInfo().getCreationDate();
380 public LockToken createAndLock(final String name, LockTimeout timeout, LockInfo lockInfo ) throws NotAuthorizedException {
381 final File tmp = new File("/tmp/"+new java.util.Random().nextInt());
382 FileHeaderDTO kmfileDTO=null;
384 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
386 public FileHeaderDTO call() throws Exception {
387 return factory.getService().createFile(getCurrentUser().getId(), folder.getId(), name, "text/html", tmp.length(), tmp.getAbsolutePath());
390 } catch (Exception e) {
391 // TODO Auto-generated catch block
394 //File dest = new File( this.getFile(), name );
395 //createEmptyFile( );
396 GssFileResource newRes = new GssFileResource( host, factory, kmfileDTO );
397 LockResult res = newRes.lock( timeout, lockInfo );
398 return res.getLockToken();
402 public Long getContentLength() {
406 public String getContentType(String arg0) {
410 public Long getMaxAgeSeconds(Auth arg0) {
411 // TODO Auto-generated method stub
415 * Will generate a listing of the contents of this directory, unless
416 * the factory's allowDirectoryBrowsing has been set to false.
418 * If so it will just output a message saying that access has been disabled.
424 * @throws IOException
425 * @throws NotAuthorizedException
427 public void sendContent( OutputStream out, Range range, Map<String, String> params, String contentType ) throws IOException, NotAuthorizedException {
428 String subpath = folder.getPath();//getFile().getCanonicalPath().substring( factory.getRoot().getCanonicalPath().length() ).replace( '\\', '/' );
429 String uri = "/" + factory.getContextPath() + subpath;
430 XmlWriter w = new XmlWriter( out );
433 w.begin( "h1" ).open().writeText( this.getName() ).close();
435 for( Resource r : getChildren() ) {
439 w.begin( "a" ).writeAtt( "href", uri + "/" + r.getName() ).open().writeText( r.getName() ).close();
442 w.begin( "td" ).open().writeText( r.getModifiedDate() + "" ).close();