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.ejb.TransactionHelper;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.OutputStream;
35 import java.util.ArrayList;
36 import java.util.Date;
37 import java.util.List;
39 import java.util.concurrent.Callable;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 import com.bradmcevoy.http.Auth;
45 import com.bradmcevoy.http.CollectionResource;
46 import com.bradmcevoy.http.CopyableResource;
47 import com.bradmcevoy.http.DeletableResource;
48 import com.bradmcevoy.http.GetableResource;
49 import com.bradmcevoy.http.LockInfo;
50 import com.bradmcevoy.http.LockResult;
51 import com.bradmcevoy.http.LockTimeout;
52 import com.bradmcevoy.http.LockToken;
53 import com.bradmcevoy.http.LockingCollectionResource;
54 import com.bradmcevoy.http.MakeCollectionableResource;
55 import com.bradmcevoy.http.MoveableResource;
56 import com.bradmcevoy.http.PropFindableResource;
57 import com.bradmcevoy.http.PutableResource;
58 import com.bradmcevoy.http.Range;
59 import com.bradmcevoy.http.Request;
60 import com.bradmcevoy.http.Resource;
61 import com.bradmcevoy.http.XmlWriter;
62 import com.bradmcevoy.http.exceptions.BadRequestException;
63 import com.bradmcevoy.http.exceptions.ConflictException;
64 import com.bradmcevoy.http.exceptions.NotAuthorizedException;
71 public class GssFolderResource extends GssResource implements MakeCollectionableResource, PutableResource, CopyableResource, DeletableResource, MoveableResource, PropFindableResource, LockingCollectionResource, GetableResource{
72 private static final Logger log = LoggerFactory.getLogger(GssFolderResource.class);
80 public GssFolderResource(String host, GSSResourceFactory factory, Object resource) {
81 super(host, factory, resource);
82 folder=(FolderDTO) resource;
85 public String checkRedirect(Request request) {
86 if( factory.getDefaultPage() != null ) {
87 return request.getAbsoluteUrl() + "/" + factory.getDefaultPage();
93 public Date getModifiedDate() {
94 return folder.getAuditInfo().getModificationDate();
97 public String getName() {
98 return folder.getName();
101 public String getUniqueId() {
102 return "folder:"+folder.getId().toString();
105 public void moveTo(final CollectionResource newParent, final String arg1) throws ConflictException, NotAuthorizedException, BadRequestException {
106 if( newParent instanceof GssFolderResource ) {
107 final GssFolderResource newFsParent = (GssFolderResource) newParent;
109 if(newFsParent.folder.getName().equals(folder.getParent().getName())){
110 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
113 public Void call() throws Exception {
114 factory.getService().updateFolder(getCurrentUser().getId(), folder.getId(), arg1, null, null);
120 else new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
123 public Void call() throws Exception {
124 factory.getService().moveFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
125 log.info("MOVING OK:"+arg1);
131 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
132 log.info("MOVING:"+folder.getName());
134 } catch (InsufficientPermissionsException e) {
135 throw new NotAuthorizedException(this);
136 } catch (ObjectNotFoundException e) {
137 throw new BadRequestException(this);
138 } catch (DuplicateNameException e) {
139 throw new ConflictException(this);
140 } catch (RpcException e) {
141 throw new RuntimeException("System error");
142 } catch (GSSIOException e) {
143 throw new RuntimeException("Unable to Move");
144 } catch (Exception e) {
145 throw new RuntimeException("Unable to Move");
148 throw new RuntimeException("Destination is an unknown type. Must be a Folder, is a: " + newParent.getClass());
153 public void copyTo(final CollectionResource newParent, final String arg1) throws NotAuthorizedException, BadRequestException, ConflictException {
154 if( newParent instanceof GssFolderResource ) {
155 final GssFolderResource newFsParent = (GssFolderResource) newParent;
157 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
160 public Void call() throws Exception {
161 factory.getService().copyFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
166 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
167 } catch (InsufficientPermissionsException e) {
168 throw new NotAuthorizedException(this);
169 } catch (ObjectNotFoundException e) {
170 throw new BadRequestException(this);
171 } catch (DuplicateNameException e) {
172 throw new ConflictException(this);
173 } catch (RpcException e) {
174 throw new RuntimeException("System error");
175 } catch (GSSIOException e) {
176 throw new RuntimeException("Unable to Move");
177 } catch (Exception e) {
178 throw new RuntimeException("Unable to Move");
181 throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
186 public CollectionResource createCollection(final String name) throws NotAuthorizedException, ConflictException, BadRequestException {
188 final FolderDTO folderParent = folder;
189 FolderDTO created = new TransactionHelper<FolderDTO>().tryExecute(new Callable<FolderDTO>() {
191 public FolderDTO call() throws Exception {
192 FolderDTO f = factory.getService().createFolder(getCurrentUser().getId(), folder.getId(), name);
196 return new GssFolderResource(host, factory, created);
197 } catch (DuplicateNameException e) {
199 // XXX If the existing name is a folder we should be returning
200 // SC_METHOD_NOT_ALLOWED, or even better, just do the createFolder
201 // without checking first and then deal with the exceptions.
202 throw new ConflictException(this);
203 } catch (InsufficientPermissionsException e) {
205 throw new NotAuthorizedException(this);
206 } catch (ObjectNotFoundException e) {
209 } catch (RpcException e) {
211 throw new RuntimeException("System Error");
212 } catch (Exception e) {
214 throw new RuntimeException("System Error");
218 public Resource child(String name) {
219 for(FolderDTO f : folder.getSubfolders())
220 if(f.getName().equals(name))
221 return new GssFolderResource(host, factory, f);
224 for(FileHeaderDTO f : factory.getService().getFiles(folder.getOwner().getId(), folder.getId(), true))
225 if(f.getName().equals(name))
226 return new GssFileResource(host, factory, f);
227 } catch (ObjectNotFoundException e) {
228 // TODO Auto-generated catch block
230 } catch (InsufficientPermissionsException e) {
231 // TODO Auto-generated catch block
233 } catch (RpcException e) {
234 // TODO Auto-generated catch block
241 public List<? extends Resource> getChildren() {
243 this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
244 } catch (ObjectNotFoundException e) {
245 // TODO Auto-generated catch block
247 } catch (InsufficientPermissionsException e) {
248 // TODO Auto-generated catch block
250 } catch (RpcException e) {
251 // TODO Auto-generated catch block
254 List<GssResource> result = new ArrayList<GssResource>();
255 for(FolderDTO f : folder.getSubfolders())
257 result.add(new GssFolderResource(host, factory, f));
259 for(FileHeaderDTO f : factory.getService().getFiles(getCurrentUser().getId(), folder.getId(), true))
260 result.add(new GssFileResource(host, factory, f));
261 } catch (ObjectNotFoundException e) {
262 // TODO Auto-generated catch block
264 } catch (InsufficientPermissionsException e) {
265 // TODO Auto-generated catch block
267 } catch (RpcException e) {
268 // TODO Auto-generated catch block
274 public Resource createNew(final String name, InputStream in, Long length, final String contentType ) throws IOException, ConflictException, NotAuthorizedException, BadRequestException {
276 File uploadedFile = null;
278 uploadedFile = factory.getService().uploadFile(in, getCurrentUser().getId());
279 } catch (IOException ex) {
280 throw new IOException(ex);
281 } catch (ObjectNotFoundException e) {
283 throw new BadRequestException(this);
284 } catch (RpcException e) {
285 throw new RuntimeException("Unable to upload file");
287 final File uf = uploadedFile;
289 String pathFolder = folder.getPath();
290 if(!pathFolder.endsWith("/"))
291 pathFolder=pathFolder+"/";
292 String fname = pathFolder+name;
295 ff2 = factory.getService().getResourceAtPath(folder.getOwner().getId(), fname, true);
297 catch(ObjectNotFoundException ex){
300 final Object ff = ff2;
301 FileHeaderDTO kmfileDTO=null;
302 if(ff!=null && ff instanceof FileHeaderDTO){
303 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
305 public FileHeaderDTO call() throws Exception{
306 return factory.getService().updateFileContents(getCurrentUser().getId(), ((FileHeaderDTO)ff).getId(), contentType, uf.length(), uf.getAbsolutePath());
311 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
313 public FileHeaderDTO call() throws Exception{
314 return factory.getService().createFile(getCurrentUser().getId(), folder.getId(), name, contentType, uf.length(), uf.getAbsolutePath());
317 return new GssFileResource(host, factory, kmfileDTO);
318 } catch (ObjectNotFoundException e) {
319 throw new BadRequestException(this);
320 } catch (InsufficientPermissionsException e) {
321 throw new NotAuthorizedException(this);
323 catch (DuplicateNameException e) {
324 // TODO Auto-generated catch block
326 throw new ConflictException(this);
328 catch(QuotaExceededException e){
329 throw new ConflictException(this);
332 throw new RuntimeException("System Error");
336 public void delete() throws NotAuthorizedException, ConflictException, BadRequestException {
338 factory.getService().deleteFolder(getCurrentUser().getId(), folder.getId());
339 } catch (InsufficientPermissionsException e) {
341 throw new NotAuthorizedException(this);
342 } catch (ObjectNotFoundException e) {
344 throw new BadRequestException(this);
345 } catch (RpcException e) {
347 throw new BadRequestException(this);
352 public Date getCreateDate() {
353 if(folder!=null && folder.getAuditInfo()!=null)
354 return folder.getAuditInfo().getCreationDate();
358 public LockToken createAndLock(final String name, LockTimeout timeout, LockInfo lockInfo ) throws NotAuthorizedException {
359 log.info("CREATE AND LOCK");
360 final File tmp = new File("/tmp/"+new java.util.Random().nextInt());
361 FileHeaderDTO kmfileDTO=null;
363 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
365 public FileHeaderDTO call() throws Exception {
366 return factory.getService().createFile(getCurrentUser().getId(), folder.getId(), name, "text/html", tmp.length(), tmp.getAbsolutePath());
369 } catch (Exception e) {
370 // TODO Auto-generated catch block
373 log.info("CREATE AND LOCK:"+kmfileDTO.getId());
374 //File dest = new File( this.getFile(), name );
375 //createEmptyFile( );
376 GssFileResource newRes = new GssFileResource( host, factory, kmfileDTO );
377 LockResult res = newRes.lock( timeout, lockInfo );
378 return res.getLockToken();
382 public Long getContentLength() {
386 public String getContentType(String arg0) {
390 public Long getMaxAgeSeconds(Auth arg0) {
391 // TODO Auto-generated method stub
395 * Will generate a listing of the contents of this directory, unless
396 * the factory's allowDirectoryBrowsing has been set to false.
398 * If so it will just output a message saying that access has been disabled.
404 * @throws IOException
405 * @throws NotAuthorizedException
407 public void sendContent( OutputStream out, Range range, Map<String, String> params, String contentType ) throws IOException, NotAuthorizedException {
408 String subpath = folder.getPath();//getFile().getCanonicalPath().substring( factory.getRoot().getCanonicalPath().length() ).replace( '\\', '/' );
409 String uri = "/" + factory.getContextPath() + subpath;
410 XmlWriter w = new XmlWriter( out );
413 w.begin( "h1" ).open().writeText( this.getName() ).close();
415 for( Resource r : getChildren() ) {
419 w.begin( "a" ).writeAtt( "href", uri + "/" + r.getName() ).open().writeText( r.getName() ).close();
422 w.begin( "td" ).open().writeText( r.getModifiedDate() + "" ).close();