Removed all static references to the Pithos class
[pithos-web-client] / src / gr / grnet / pithos / web / client / rest / GetCommand.java
1 /*
2  * Copyright 2011 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above
13  *      copyright notice, this list of conditions and the following
14  *      disclaimer in the documentation and/or other materials
15  *      provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * The views and conclusions contained in the software and
31  * documentation are those of the authors and should not be
32  * interpreted as representing official policies, either expressed
33  * or implied, of GRNET S.A.
34  */
35 package gr.grnet.pithos.web.client.rest;
36
37 import gr.grnet.pithos.web.client.Pithos;
38 import gr.grnet.pithos.web.client.rest.resource.FileResource;
39 import gr.grnet.pithos.web.client.rest.resource.FolderResource;
40 import gr.grnet.pithos.web.client.rest.resource.GroupResource;
41 import gr.grnet.pithos.web.client.rest.resource.GroupUserResource;
42 import gr.grnet.pithos.web.client.rest.resource.GroupsResource;
43 import gr.grnet.pithos.web.client.rest.resource.OtherUserResource;
44 import gr.grnet.pithos.web.client.rest.resource.OthersResource;
45 import gr.grnet.pithos.web.client.rest.resource.RestResource;
46 import gr.grnet.pithos.web.client.rest.resource.SearchResource;
47 import gr.grnet.pithos.web.client.rest.resource.SharedResource;
48 import gr.grnet.pithos.web.client.rest.resource.TagsResource;
49 import gr.grnet.pithos.web.client.rest.resource.TrashResource;
50 import gr.grnet.pithos.web.client.rest.resource.UploadStatusResource;
51 import gr.grnet.pithos.web.client.rest.resource.UserResource;
52 import gr.grnet.pithos.web.client.rest.resource.UserSearchResource;
53
54 import java.util.HashMap;
55 import java.util.Map;
56
57 import com.google.gwt.core.client.GWT;
58 import com.google.gwt.http.client.Request;
59 import com.google.gwt.http.client.RequestBuilder;
60 import com.google.gwt.http.client.Response;
61
62 public abstract class GetCommand<T extends RestResource> extends RestCommand{
63
64         boolean complete = false;
65         T result = null;
66         Throwable exception = null;
67         Class<T> aclass;
68         private final String path;
69         private String username;
70         private boolean requestSent = false;
71         T cached;
72         
73         private static final long MAX_CACHE_AGE = 1000;
74         
75         private static class RequestData {
76                 public String path;
77                 public String username;
78                 
79                 public RequestData(String _path, String _username) {
80                         path = _path;
81                         username = _username;
82                 }
83
84                 @Override
85                 public int hashCode() {
86                         final int prime = 31;
87                         int result = 1;
88                         result = prime * result + ((path == null) ? 0 : path.hashCode());
89                         result = prime * result + ((username == null) ? 0 : username.hashCode());
90                         return result;
91                 }
92
93                 @Override
94                 public boolean equals(Object obj) {
95                         if (this == obj)
96                                 return true;
97                         if (obj == null)
98                                 return false;
99                         if (getClass() != obj.getClass())
100                                 return false;
101                         RequestData other = (RequestData) obj;
102                         if (path == null) {
103                                 if (other.path != null)
104                                         return false;
105                         } else if (!path.equals(other.path))
106                                 return false;
107                         if (username == null) {
108                                 if (other.username != null)
109                                         return false;
110                         } else if (!username.equals(other.username))
111                                 return false;
112                         return true;
113                 }
114         }
115         
116         private static class ResponseData {
117                 public long timestamp;
118                 public Object result;
119                 public ResponseData(long _timestamp, Object _result) {
120                         timestamp = _timestamp;
121                         result = _result;
122                 }
123         }
124         
125         private static Map<RequestData, ResponseData> cache = new HashMap<RequestData, ResponseData>();
126         
127
128         public GetCommand(Pithos _app, Class<T> theclass, String pathToGet, T theCached){
129                 this(_app, theclass, pathToGet, true, theCached);
130         }
131
132         public GetCommand(Pithos _app, Class<T> theclass, String pathToGet, boolean showLoading, T theCached){
133         super(_app);
134                 setShowLoadingIndicator(showLoading);
135                 if(isShowLoadingIndicator())
136                         app.showLoadingIndicator("Getting ",pathToGet);
137                 this.aclass = theclass;
138                 if(pathToGet.indexOf("?") != -1)
139                         path = pathToGet;
140                 else
141                         path =fixPath(pathToGet);
142                 this.cached = theCached;
143         }
144
145         public GetCommand(Pithos _app, Class<T> theclass, String aUsername , String pathToGet, T theCached){
146                 this(_app, theclass, aUsername, pathToGet, true, theCached);
147         }
148
149         public GetCommand(Pithos _app, Class<T> theclass, String aUsername , String pathToGet, boolean showLoading, T theCached){
150         super(_app);
151                 setShowLoadingIndicator(showLoading);
152                 if(isShowLoadingIndicator())
153                         app.showLoadingIndicator("Getting ",pathToGet);
154                 this.aclass = theclass;
155                 path = fixPath(pathToGet);
156                 this.username = aUsername;
157                 this.cached = theCached;
158         }
159
160         private void sendRequest(){
161                 if(requestSent)
162                         return;
163                 requestSent=true;
164                 RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
165                 if(cached!=null && cached.getLastModifiedSince() != null)
166                         builder.setHeader("If-Modified-Since", cached.getLastModifiedSince());
167                 try {
168                         if(username == null)
169                                 handleHeaders(builder, path);
170                         else
171                                 handleHeaders(username, builder, path);
172                         builder.sendRequest("", new RestCallback(path) {
173
174                                 @Override
175                                 public Object deserialize(Response response) {
176                                         return deserializeResponse(path, response);
177                                 }
178
179                                 @Override
180                                 public void handleError(Request request, Throwable _exception) {
181                                         result = null;
182                                         complete = true;
183                                         exception = _exception;
184                                         if(_exception instanceof RestException)
185                                                 if(((RestException)_exception).getHttpStatusCode() == 304 && cached != null){
186                                                         GWT.log("Using cache:"+cached.getUri(), null);
187                                                         handleSuccess(cached);
188                                                         return;
189                                                 }
190                                         
191                                 }
192
193                                 @Override
194                                 public void handleSuccess(Object object) {
195                                         result = (T) object;
196                                         complete = true;
197                                 }
198
199                         });
200                 } catch (Exception ex) {
201                         complete = true;
202                         exception = ex;
203                 }
204         }
205         public boolean isComplete() {
206                 return complete;
207         }
208
209         public T getResult(){
210                 return result;
211         }
212
213         @Override
214         public boolean execute() {
215                 boolean com = isComplete();
216                 RequestData key = new RequestData(path, username);
217                 if (!com) {
218                         if (cache.containsKey(key)) {
219                                 ResponseData resp = cache.get(key);
220                                 if (resp==null) {
221                                         return true;
222                                 }
223                                 
224                                 // Cache hit
225                                 if (System.currentTimeMillis()-resp.timestamp>MAX_CACHE_AGE) {
226                                         // Cache stale, remove
227                                         cache.put(key,null);
228                                 }
229                                 else {
230                                         // Use cache data
231                                         if(isShowLoadingIndicator())
232                                                 app.hideLoadingIndicator();
233                                         if (resp.result instanceof Throwable) {
234                                                 // Error to be handled
235                                                 Throwable ex = (Throwable) resp.result;
236                                                 onError(ex);
237                                                 return false;
238                                         }
239                                         result = (T) resp.result;
240                                         if (result != null) {
241                                                 onComplete();
242                                         }
243                                         complete = true;
244                                         return false;
245                                 }
246                         }
247                 
248                         if(!requestSent) {
249                                 cache.put(key,null);
250                                 sendRequest();
251                         }
252                 }
253                 
254                 if(com){
255                         if(isShowLoadingIndicator())
256                                 app.hideLoadingIndicator();
257                         if(getResult() != null) {
258                                 // Add to cache
259                                 cache.put(key, new ResponseData(System.currentTimeMillis(), getResult()));
260                                 onComplete();
261                         }
262                         else {
263                                 cache.put(key, new ResponseData(System.currentTimeMillis(), exception));
264                                 onError(exception);
265                         }
266                         return false;
267                 }
268                 return true;
269         }
270
271         public Object deserializeResponse(String aPath, Response response) {
272                 RestResource result1 = null;
273                 if(aclass.equals(FolderResource.class)){
274                         result1 = new FolderResource(aPath);
275                         result1.createFromJSON(response.getText());
276                 }
277                 else if(aclass.equals(FileResource.class)){
278                         result1 = new FileResource(aPath);
279                         result1.createFromJSON(response.getHeader("X-Pithos-Metadata"));
280                 }
281                 else if(aclass.equals(GroupsResource.class)){
282                         result1 = new GroupsResource(aPath);
283                         result1.createFromJSON(response.getText());
284                 }
285                 else if(aclass.equals(TrashResource.class)){
286                         result1 = new TrashResource(aPath);
287                         result1.createFromJSON(response.getText());
288                 }
289                 else if(aclass.equals(SharedResource.class)){
290                         result1 = new SharedResource(aPath);
291                         result1.createFromJSON(response.getText());
292                 }
293                 else if(aclass.equals(OthersResource.class)){
294                         result1 = new OthersResource(aPath);
295                         result1.createFromJSON(response.getText());
296                 }
297                 else if(aclass.equals(OtherUserResource.class)){
298                         result1 = new OtherUserResource(aPath);
299                         result1.createFromJSON(response.getText());
300                 }
301                 else if(aclass.equals(GroupResource.class)){
302                         result1 = new GroupResource(aPath);
303                         result1.createFromJSON(response.getText());
304                 }
305                 else if(aclass.equals(GroupUserResource.class)){
306                         result1 = new GroupUserResource(aPath);
307                         result1.createFromJSON(response.getText());
308                 }
309                 else if(aclass.equals(UserResource.class)){
310                         result1 = new UserResource(aPath);
311                         result1.createFromJSON(response.getText());
312                 }
313                 else if(aclass.equals(TagsResource.class)){
314                         result1 = new TagsResource(aPath);
315                         result1.createFromJSON(response.getText());
316                 }
317                 else if(aclass.equals(SearchResource.class)){
318                         result1 = new SearchResource(aPath);
319                         result1.createFromJSON(response.getText());
320                 }
321                 else if(aclass.equals(UserSearchResource.class)){
322                         result1 = new UserSearchResource(aPath);
323                         result1.createFromJSON(response.getText());
324                 }
325                 else if(aclass.equals(UploadStatusResource.class)){
326                         result1 = new UploadStatusResource(aPath);
327                         result1.createFromJSON(response.getText());
328                 }
329                 return result1;
330         }
331
332         public T getCached() {
333                 return cached;
334         }
335
336         public void setCached(T theCached) {
337                 this.cached = theCached;
338         }
339         
340         public boolean usedCachedVersion(){
341                 if(exception !=null && exception instanceof RestException)
342                         if(((RestException)exception).getHttpStatusCode() == 304){
343                                 return true;
344                         }
345                 return false;
346         }
347 }