Imported changesets 6ad7cf34a8f5, d535941636f3, f3a4422f7b1a from the default branch
[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.client.exceptions.ObjectNotFoundException;
23 import gr.ebs.gss.client.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                         log.error("unable to access ejb service",e);
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                                 
215                         } catch (final NamingException e) {
216                                 log.error("Unable to retrieve the ExternalAPI EJB", e);
217                                 throw new RpcException("An error occurred while contacting the naming service");
218                         }
219                 }
220
221                 private void updateAccounting(final User user, final Date date, final long bandwidthDiff) {
222                         try {
223                                 new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
224                                         @Override
225                                         public Void call() throws Exception {
226                                                 getService().updateAccounting(user, date, bandwidthDiff);
227                                                 return null;
228                                         }
229                                 });
230                         } catch (RuntimeException e) {
231                                 throw e;
232                         } catch (Exception e) {
233                                 // updateAccounting() doesn't throw any checked exceptions
234                                 assert false;
235                         }
236                 }
237
238                 
239                 /**
240                  * Retrieve the securityManager.
241                  *
242                  * @return the securityManager
243                  */
244                 public SecurityManager getSecurityManager() {
245                         return securityManager;
246                 }
247
248                 
249                 /**
250                  * Retrieve the lockManager.
251                  *
252                  * @return the lockManager
253                  */
254                 public LockManager getLockManager() {
255                         return lockManager;
256                 }
257
258                 
259                 /**
260                  * Retrieve the maxAgeSeconds.
261                  *
262                  * @return the maxAgeSeconds
263                  */
264                 public Long getMaxAgeSeconds() {
265                         return maxAgeSeconds;
266                 }
267
268                 
269                 /**
270                  * Retrieve the contextPath.
271                  *
272                  * @return the contextPath
273                  */
274                 public String getContextPath() {
275                         return contextPath;
276                 }
277
278                 
279                 /**
280                  * Retrieve the allowDirectoryBrowsing.
281                  *
282                  * @return the allowDirectoryBrowsing
283                  */
284                 public boolean isAllowDirectoryBrowsing() {
285                         return allowDirectoryBrowsing;
286                 }
287
288                 
289                 /**
290                  * Retrieve the defaultPage.
291                  *
292                  * @return the defaultPage
293                  */
294                 public String getDefaultPage() {
295                         return defaultPage;
296                 }
297                 
298                 public String getRealm(String host) {
299                 return securityManager.getRealm(host);
300             }
301
302                 
303                 /**
304                  * Modify the securityManager.
305                  *
306                  * @param securityManager the securityManager to set
307                  */
308                 public void setSecurityManager(SecurityManager securityManager) {
309                         this.securityManager = securityManager;
310                 }
311
312                 
313                 /**
314                  * Modify the lockManager.
315                  *
316                  * @param lockManager the lockManager to set
317                  */
318                 public void setLockManager(LockManager lockManager) {
319                         this.lockManager = lockManager;
320                 }
321
322                 
323                 /**
324                  * Modify the maxAgeSeconds.
325                  *
326                  * @param maxAgeSeconds the maxAgeSeconds to set
327                  */
328                 public void setMaxAgeSeconds(Long maxAgeSeconds) {
329                         this.maxAgeSeconds = maxAgeSeconds;
330                 }
331
332                 
333                 /**
334                  * Modify the contextPath.
335                  *
336                  * @param contextPath the contextPath to set
337                  */
338                 public void setContextPath(String contextPath) {
339                         this.contextPath = contextPath;
340                 }
341
342                 
343                 /**
344                  * Modify the defaultPage.
345                  *
346                  * @param defaultPage the defaultPage to set
347                  */
348                 public void setDefaultPage(String defaultPage) {
349                         this.defaultPage = defaultPage;
350                 }
351                 
352                 
353                 /**
354                  * Retrieve the httpManager.
355                  *
356                  * @return the httpManager
357                  */
358                 public HttpManager getHttpManager() {
359                         return httpManager;
360                 }
361                 
362                 
363                 /**
364                  * Modify the httpManager.
365                  *
366                  * @param httpManager the httpManager to set
367                  */
368                 public void setHttpManager(HttpManager httpManager) {
369                         this.httpManager = httpManager;
370                 }
371                 
372                 
373         
374                 public static String getUsernameFromAuthHeader(String header) {
375                         String first = header.split(",")[0];
376                         int indx = first.indexOf("\"");
377                         return first.substring(indx+1,first.length()-1);
378                 }
379 }