Re-structured the whole thing
[pithos] / src / gr / ebs / gss / server / webdav / milton / GSSResourceFactory.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 static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
22 import gr.ebs.gss.common.exceptions.ObjectNotFoundException;
23 import gr.ebs.gss.common.exceptions.RpcException;
24 import gr.ebs.gss.server.domain.FileHeader;
25 import gr.ebs.gss.server.domain.Folder;
26 import gr.ebs.gss.server.domain.User;
27 import gr.ebs.gss.server.ejb.ExternalAPI;
28 import gr.ebs.gss.server.ejb.TransactionHelper;
29
30 import java.util.Date;
31 import java.util.concurrent.Callable;
32
33 import javax.naming.Context;
34 import javax.naming.InitialContext;
35 import javax.naming.NamingException;
36 import javax.rmi.PortableRemoteObject;
37
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 import com.bradmcevoy.http.HttpManager;
42 import com.bradmcevoy.http.Resource;
43 import com.bradmcevoy.http.ResourceFactory;
44 import com.bradmcevoy.http.SecurityManager;
45 import com.ettrema.http.fs.LockManager;
46
47
48 /**
49  * @author kman
50  *
51  */
52 public class GSSResourceFactory implements ResourceFactory {
53         private static final Logger log = LoggerFactory.getLogger(GSSResourceFactory.class);
54         
55         SecurityManager securityManager;
56     LockManager lockManager;
57     Long maxAgeSeconds;
58     String contextPath;
59     boolean allowDirectoryBrowsing;
60     String defaultPage;
61     HttpManager httpManager;
62         @Override
63         public Resource getResource(String host, String url) {
64                 
65
66
67                 log.debug("getResource: host: " + host + " - url:" + url);
68         url = stripContext(url);
69         if(url==null||url.trim().equals("")||url.equals("/")){
70                 url="/";
71         }
72         /*//log.info("URL:"+url);
73         if(url.equals("/OthersShared")||url.equals("/OthersShared/")){
74                 //log.info("[returning others]");
75                 return new GssOthersResource(host, this);
76         }
77         if(url.startsWith("/OthersShared")){
78                 
79         }*/
80         try {
81                 User user =null;
82                 if(HttpManager.request().getAuthorization()!=null && HttpManager.request().getAuthorization().getTag()==null){
83                         String username = HttpManager.request().getAuthorization().getUser();
84                         if(username !=null)
85                                 user = getService().getUserByUserName(username);
86                 }
87                 else if(HttpManager.request().getAuthorization()!=null&&HttpManager.request().getAuthorization().getTag()!=null){
88                         user =(User) HttpManager.request().getAuthorization().getTag();
89                 }
90         
91                 if(user==null){
92                         //create a resource based on path if no resource exists at this path it will be handled by subsequent webdav method calls
93                                 return new GssRootFolderResource(host, this, null,url);
94                 }
95                         
96                 Object r = getResourceGss(url,user);
97                 if(r==null){
98                         
99                         return null;
100                 }
101                 if(r instanceof Folder){
102                         
103                         return new GssFolderResource(host, this,r ,user);
104                 }
105                 else
106                         return new GssFileResource(host, this,r,user);
107                 } catch (RpcException e) {
108                         e.printStackTrace();
109                 }
110                 return null;
111     }
112         public Long maxAgeSeconds(GssResource resource) {
113         return maxAgeSeconds;
114     }
115         protected Object getResourceGss(String path, User user) throws RpcException{
116
117                 if(user ==null){
118                         if(HttpManager.request().getAuthorization()!=null && HttpManager.request().getAuthorization().getTag()==null){
119                                 String username = HttpManager.request().getAuthorization().getUser();
120                                 if(username !=null)
121                                         user = getService().getUserByUserName(username);
122                         }
123                         else if(HttpManager.request().getAuthorization()!=null&&HttpManager.request().getAuthorization().getTag()!=null){
124                                 user =(User) HttpManager.request().getAuthorization().getTag();
125                         }
126                 }
127                 
128                 if(user==null){
129                         return null;
130                 }
131                 boolean exists = true;
132                 Object resource = null;
133                 try {
134                         resource = getService().getResourceAtPath(user.getId(), path, true);
135                 } catch (ObjectNotFoundException e) {
136                         exists = false;
137                 } catch (RpcException e) {
138                         
139                         return null;
140                 }
141
142                 if (!exists) {
143                         
144                         return null;
145                 }
146                 if(resource instanceof Folder){
147                         try {
148                                 resource = getService().expandFolder((Folder) resource);
149                         } catch (ObjectNotFoundException e) {
150                                 // TODO Auto-generated catch block
151                                 return null;
152                         }
153                 }
154                 else if(resource instanceof FileHeader){
155                         try {
156                                 resource = getService().expandFile((FileHeader) resource);
157                         } catch (ObjectNotFoundException e) {
158                                 // TODO Auto-generated catch block
159                                 return null;
160                         }
161                 }
162                 return resource;
163         }
164         
165         
166          private String stripContext( String url ) {
167                 if( this.contextPath != null && contextPath.length() > 0 ) {
168                     url = url.replaceFirst( '/' + contextPath, "");
169                     log.debug( "stripped context: " + url);
170                     return url;
171                 } else {
172                     return url;
173                 }
174             }
175          
176          /**
177                  * For a provided path, remove the last element and return the rest, that is
178                  * the path of the parent folder.
179                  *
180                  * @param path the specified path
181                  * @return the path of the parent folder
182                  * @throws ObjectNotFoundException if the provided string contains no path
183                  *             delimiters
184                  */
185                 protected String getParentPath(String path) throws ObjectNotFoundException {
186                         int lastDelimiter = path.lastIndexOf('/');
187                         if (lastDelimiter == 0)
188                                 return "/";
189                         if (lastDelimiter == -1)
190                                 // No path found.
191                                 throw new ObjectNotFoundException("There is no parent in the path: " + path);
192                         else if (lastDelimiter < path.length() - 1)
193                                 // Return the part before the delimiter.
194                                 return path.substring(0, lastDelimiter);
195                         else {
196                                 // Remove the trailing delimiter and then recurse.
197                                 String strippedTrail = path.substring(0, lastDelimiter);
198                                 return getParentPath(strippedTrail);
199                         }
200                 }
201                 
202                 /**
203                  * A helper method that retrieves a reference to the ExternalAPI bean and
204                  * stores it for future use.
205                  *
206                  * @return an ExternalAPI instance
207                  * @throws RpcException in case an error occurs
208                  */
209                 protected ExternalAPI getService() throws RpcException {
210                         try {
211                                 final Context ctx = new InitialContext();
212                                 final Object ref = ctx.lookup(getConfiguration().getString("externalApiPath"));
213                                 return (ExternalAPI) PortableRemoteObject.narrow(ref, ExternalAPI.class);
214                         } catch (final NamingException e) {
215                                 log.error("Unable to retrieve the ExternalAPI EJB", e);
216                                 throw new RpcException("An error occurred while contacting the naming service");
217                         }
218                 }
219
220                 private void updateAccounting(final User user, final Date date, final long bandwidthDiff) {
221                         try {
222                                 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
223                                         @Override
224                                         public Void call() throws Exception {
225                                                 getService().updateAccounting(user, date, bandwidthDiff);
226                                                 return null;
227                                         }
228                                 });
229                         } catch (RuntimeException e) {
230                                 throw e;
231                         } catch (Exception e) {
232                                 // updateAccounting() doesn't throw any checked exceptions
233                                 assert false;
234                         }
235                 }
236
237                 
238                 /**
239                  * Retrieve the securityManager.
240                  *
241                  * @return the securityManager
242                  */
243                 public SecurityManager getSecurityManager() {
244                         return securityManager;
245                 }
246
247                 
248                 /**
249                  * Retrieve the lockManager.
250                  *
251                  * @return the lockManager
252                  */
253                 public LockManager getLockManager() {
254                         return lockManager;
255                 }
256
257                 
258                 /**
259                  * Retrieve the maxAgeSeconds.
260                  *
261                  * @return the maxAgeSeconds
262                  */
263                 public Long getMaxAgeSeconds() {
264                         return maxAgeSeconds;
265                 }
266
267                 
268                 /**
269                  * Retrieve the contextPath.
270                  *
271                  * @return the contextPath
272                  */
273                 public String getContextPath() {
274                         return contextPath;
275                 }
276
277                 
278                 /**
279                  * Retrieve the allowDirectoryBrowsing.
280                  *
281                  * @return the allowDirectoryBrowsing
282                  */
283                 public boolean isAllowDirectoryBrowsing() {
284                         return allowDirectoryBrowsing;
285                 }
286
287                 
288                 /**
289                  * Retrieve the defaultPage.
290                  *
291                  * @return the defaultPage
292                  */
293                 public String getDefaultPage() {
294                         return defaultPage;
295                 }
296                 
297                 public String getRealm(String host) {
298                 return securityManager.getRealm(host);
299             }
300
301                 
302                 /**
303                  * Modify the securityManager.
304                  *
305                  * @param securityManager the securityManager to set
306                  */
307                 public void setSecurityManager(SecurityManager securityManager) {
308                         this.securityManager = securityManager;
309                 }
310
311                 
312                 /**
313                  * Modify the lockManager.
314                  *
315                  * @param lockManager the lockManager to set
316                  */
317                 public void setLockManager(LockManager lockManager) {
318                         this.lockManager = lockManager;
319                 }
320
321                 
322                 /**
323                  * Modify the maxAgeSeconds.
324                  *
325                  * @param maxAgeSeconds the maxAgeSeconds to set
326                  */
327                 public void setMaxAgeSeconds(Long maxAgeSeconds) {
328                         this.maxAgeSeconds = maxAgeSeconds;
329                 }
330
331                 
332                 /**
333                  * Modify the contextPath.
334                  *
335                  * @param contextPath the contextPath to set
336                  */
337                 public void setContextPath(String contextPath) {
338                         this.contextPath = contextPath;
339                 }
340
341                 
342                 /**
343                  * Modify the defaultPage.
344                  *
345                  * @param defaultPage the defaultPage to set
346                  */
347                 public void setDefaultPage(String defaultPage) {
348                         this.defaultPage = defaultPage;
349                 }
350                 
351                 
352                 /**
353                  * Retrieve the httpManager.
354                  *
355                  * @return the httpManager
356                  */
357                 public HttpManager getHttpManager() {
358                         return httpManager;
359                 }
360                 
361                 
362                 /**
363                  * Modify the httpManager.
364                  *
365                  * @param httpManager the httpManager to set
366                  */
367                 public void setHttpManager(HttpManager httpManager) {
368                         this.httpManager = httpManager;
369                 }
370                 
371                 
372         
373                 public static String getUsernameFromAuthHeader(String header) {
374                         String first = header.split(",")[0];
375                         int indx = first.indexOf("\"");
376                         return first.substring(indx+1,first.length()-1);
377                 }
378 }