use /tmp for tmp file
[pithos] / src / gr / ebs / gss / server / webdav / milton / GssFolderResource.java
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.FolderDTO;
28 import gr.ebs.gss.server.ejb.TransactionHelper;
29
30 import java.io.File;
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;
37 import java.util.Map;
38 import java.util.concurrent.Callable;
39
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.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;
64
65
66 /**
67  * @author kman
68  *
69  */
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);
72         FolderDTO folder;
73         
74         /**
75          * @param host
76          * @param factory
77          * @param resource
78          */
79         public GssFolderResource(String host, GSSResourceFactory factory, Object resource) {
80                 super(host, factory, resource);
81                 folder=(FolderDTO) resource;
82         }
83         @Override
84         public String checkRedirect(Request request) {
85                 if( factory.getDefaultPage() != null ) {
86             return request.getAbsoluteUrl() + "/" + factory.getDefaultPage();
87         } else {
88             return null;
89         }
90         }
91         @Override
92         public Date getModifiedDate() {
93                 return folder.getAuditInfo().getModificationDate();
94         }
95         @Override
96         public String getName() {
97                 return folder.getName();
98         }
99         @Override
100         public String getUniqueId() {
101                 return folder.getId().toString();
102         }
103         @Override
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());
112             this.file = dest;*/
113                         try {
114                                 if(newFsParent.folder.getName().equals(folder.getParent().getName())){
115                                         new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
116
117                                                 @Override
118                                                 public Void call() throws Exception {
119                                                         factory.getService().updateFolder(getCurrentUser().getId(), folder.getId(), arg1, null, null);
120                                                         log.info("RENAMING OK:"+arg1);
121                                                         
122                                                         return null;
123                                                 }
124                                                 
125                                         });
126                                 }
127                                 //this.folder = factory.getService().updateFolder(user.getId(), folder.getId(), arg1, null, null);
128                                 else new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
129
130                                         @Override
131                                         public Void call() throws Exception {
132                                                 factory.getService().moveFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
133                                                 log.info("MOVING OK:"+arg1);
134                                                 
135                                                 return null;
136                                         }
137                                         
138                                 });
139                                 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
140                                 log.info("MOVING:"+folder.getName());
141                                 
142                         } catch (InsufficientPermissionsException e) {
143                                 // TODO Auto-generated catch block
144                                 e.printStackTrace();
145                         } catch (ObjectNotFoundException e) {
146                                 // TODO Auto-generated catch block
147                                 e.printStackTrace();
148                         } catch (DuplicateNameException e) {
149                                 // TODO Auto-generated catch block
150                                 e.printStackTrace();
151                         } catch (RpcException e) {
152                                 // TODO Auto-generated catch block
153                                 e.printStackTrace();
154                         } catch (GSSIOException e) {
155                                 // TODO Auto-generated catch block
156                                 e.printStackTrace();
157                         } catch (Exception e) {
158                                 // TODO Auto-generated catch block
159                                 e.printStackTrace();
160                         }
161         } else {
162             throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
163         }
164                 
165         }
166         @Override
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());
175             this.file = dest;*/
176                         try {
177                                  new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
178
179                                         @Override
180                                         public Void call() throws Exception {
181                                                 factory.getService().copyFolder(getCurrentUser().getId(), folder.getId(), newFsParent.folder.getId(), arg1);
182                                                 log.info("COPYING OK:"+arg1);
183                                                 
184                                                 return null;
185                                         }
186                                         
187                                 });
188                                 GssFolderResource.this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
189                                 log.info("MOVING:"+folder.getName());
190                                 
191                         } catch (InsufficientPermissionsException e) {
192                                 // TODO Auto-generated catch block
193                                 e.printStackTrace();
194                         } catch (ObjectNotFoundException e) {
195                                 // TODO Auto-generated catch block
196                                 e.printStackTrace();
197                         } catch (DuplicateNameException e) {
198                                 // TODO Auto-generated catch block
199                                 e.printStackTrace();
200                         } catch (RpcException e) {
201                                 // TODO Auto-generated catch block
202                                 e.printStackTrace();
203                         } catch (GSSIOException e) {
204                                 // TODO Auto-generated catch block
205                                 e.printStackTrace();
206                         } catch (Exception e) {
207                                 // TODO Auto-generated catch block
208                                 e.printStackTrace();
209                         }
210         } else {
211             throw new RuntimeException("Destination is an unknown type. Must be a FsDirectoryResource, is a: " + newParent.getClass());
212         }
213                 
214         }
215         @Override
216         public CollectionResource createCollection(final String name) throws NotAuthorizedException, ConflictException, BadRequestException {
217                 try {
218                         final FolderDTO folderParent = folder;
219                         FolderDTO created = new TransactionHelper<FolderDTO>().tryExecute(new Callable<FolderDTO>() {
220                                 @Override
221                                 public FolderDTO call() throws Exception {
222                                         FolderDTO f = factory.getService().createFolder(getCurrentUser().getId(), folder.getId(), name);
223                                         return f;
224                                 }
225                         });
226                         return new GssFolderResource(host, factory, created);
227                 } catch (DuplicateNameException e) {
228                         e.printStackTrace();
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) {
234                         e.printStackTrace();
235                         throw new NotAuthorizedException(this);
236                 } catch (ObjectNotFoundException e) {
237                         e.printStackTrace();
238                         return null;
239                 } catch (RpcException e) {
240                         e.printStackTrace();
241                         return null;
242                 } catch (Exception e) {
243                         e.printStackTrace();
244                         return null;
245                 }
246         }
247         @Override
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);
252                 
253                         try {
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
259                                 e.printStackTrace();
260                         } catch (InsufficientPermissionsException e) {
261                                 // TODO Auto-generated catch block
262                                 e.printStackTrace();
263                         } catch (RpcException e) {
264                                 // TODO Auto-generated catch block
265                                 e.printStackTrace();
266                         }
267                 
268                 return null;
269         }
270         @Override
271         public List<? extends Resource> getChildren() {
272                 try {
273                         this.folder = factory.getService().getFolder(getCurrentUser().getId(), folder.getId());
274                 } catch (ObjectNotFoundException e) {
275                         // TODO Auto-generated catch block
276                         e.printStackTrace();
277                 } catch (InsufficientPermissionsException e) {
278                         // TODO Auto-generated catch block
279                         e.printStackTrace();
280                 } catch (RpcException e) {
281                         // TODO Auto-generated catch block
282                         e.printStackTrace();
283                 }
284                 List<GssResource> result = new ArrayList<GssResource>();
285                 for(FolderDTO f : folder.getSubfolders())
286                         if(!f.isDeleted())
287                                 result.add(new GssFolderResource(host, factory, f));
288                 try {
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
293                         e.printStackTrace();
294                 } catch (InsufficientPermissionsException e) {
295                         // TODO Auto-generated catch block
296                         e.printStackTrace();
297                 } catch (RpcException e) {
298                         // TODO Auto-generated catch block
299                         e.printStackTrace();
300                 }
301                 return result;
302         }
303         @Override
304         public Resource createNew(final String name, InputStream in, Long length, final String contentType ) throws IOException, ConflictException, NotAuthorizedException, BadRequestException {
305                 
306         File uploadedFile = null;
307         try {
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
313                         e.printStackTrace();
314                 } catch (RpcException e) {
315                         // TODO Auto-generated catch block
316                         e.printStackTrace();
317                 }
318                 final File uf = uploadedFile;
319                 try {
320                         String pathFolder = folder.getPath();
321                         if(!pathFolder.endsWith("/"))
322                                 pathFolder=pathFolder+"/";
323                         String fname = pathFolder+name;
324                         Object ff2;
325                         try{
326                                 ff2 = factory.getService().getResourceAtPath(folder.getOwner().getId(), fname, true);
327                         }
328                         catch(ObjectNotFoundException ex){
329                                 ff2=null;
330                         }
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>() {
336                                         @Override
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());
340                                         }
341                                 });
342                         }
343                         else
344                                 kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
345                                         @Override
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());
349                                         }
350                                 });
351                         return new GssFileResource(host, factory, kmfileDTO);
352                 } catch (Exception e) {
353                         e.printStackTrace();
354                 }
355                 return null;
356         }
357         @Override
358         public void delete() throws NotAuthorizedException, ConflictException, BadRequestException {
359                 try {
360                         factory.getService().deleteFolder(getCurrentUser().getId(), folder.getId());
361                 } catch (InsufficientPermissionsException e) {
362                         e.printStackTrace();
363                         throw new NotAuthorizedException(this);
364                 } catch (ObjectNotFoundException e) {
365                         e.printStackTrace();
366                         throw new BadRequestException(this);
367                 } catch (RpcException e) {
368                         e.printStackTrace();
369                         throw new BadRequestException(this);
370                 }
371                 
372         }
373         @Override
374         public Date getCreateDate() {
375                 if(folder!=null && folder.getAuditInfo()!=null)
376                         return folder.getAuditInfo().getCreationDate();
377                 return null;
378         }
379         @Override
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;
383                 try {
384                         kmfileDTO = new TransactionHelper<FileHeaderDTO>().tryExecute(new Callable<FileHeaderDTO>() {
385                                 @Override
386                                 public FileHeaderDTO call() throws Exception {
387                                         return factory.getService().createFile(getCurrentUser().getId(), folder.getId(), name, "text/html", tmp.length(), tmp.getAbsolutePath());
388                                 }
389                         });
390                 } catch (Exception e) {
391                         // TODO Auto-generated catch block
392                         e.printStackTrace();
393                 }
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();
399                 
400         }
401         @Override
402         public Long getContentLength() {
403                 return null;
404         }
405         @Override
406         public String getContentType(String arg0) {
407                  return "text/html";
408         }
409         @Override
410         public Long getMaxAgeSeconds(Auth arg0) {
411                 // TODO Auto-generated method stub
412                 return null;
413         }
414         /**
415     * Will generate a listing of the contents of this directory, unless
416     * the factory's allowDirectoryBrowsing has been set to false.
417     *
418     * If so it will just output a message saying that access has been disabled.
419     *
420     * @param out
421     * @param range
422     * @param params
423     * @param contentType
424     * @throws IOException
425     * @throws NotAuthorizedException
426     */
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 );
431        w.open( "html" );
432        w.open( "body" );
433        w.begin( "h1" ).open().writeText( this.getName() ).close();
434        w.open( "table" );
435        for( Resource r : getChildren() ) {
436            w.open( "tr" );
437
438            w.open( "td" );
439            w.begin( "a" ).writeAtt( "href", uri + "/" + r.getName() ).open().writeText( r.getName() ).close();
440            w.close( "td" );
441
442            w.begin( "td" ).open().writeText( r.getModifiedDate() + "" ).close();
443            w.close( "tr" );
444        }
445        w.close( "table" );
446        w.close( "body" );
447        w.close( "html" );
448        w.flush();
449    }
450
451 }