Revision 0393c0ed
b/web_client/src/gr/grnet/pithos/web/client/FileList.java | ||
---|---|---|
430 | 430 |
public void setFiles(final List<File> _files) { |
431 | 431 |
files = new ArrayList<File>(); |
432 | 432 |
for (File fres : _files) |
433 |
if (!fres.isInTrash()) |
|
434 |
files.add(fres); |
|
433 |
files.add(fres); |
|
435 | 434 |
Collections.sort(files, new Comparator<File>() { |
436 | 435 |
|
437 | 436 |
@Override |
b/web_client/src/gr/grnet/pithos/web/client/FileUploadDialog.java | ||
---|---|---|
257 | 257 |
|
258 | 258 |
protected File getFileForName(String name){ |
259 | 259 |
for (File f : folder.getFiles()) |
260 |
if (!f.isInTrash() && f.getName().equals(name))
|
|
260 |
if (f.getName().equals(name)) |
|
261 | 261 |
return f; |
262 | 262 |
return null; |
263 | 263 |
} |
b/web_client/src/gr/grnet/pithos/web/client/Pithos.java | ||
---|---|---|
104 | 104 |
public class Pithos implements EntryPoint, ResizeHandler { |
105 | 105 |
|
106 | 106 |
public static final String HOME_CONTAINER = "pithos"; |
107 |
|
|
108 |
public static final String TRASH_CONTAINER = "trash"; |
|
107 | 109 |
|
108 | 110 |
/** |
109 | 111 |
* Instantiate an application-level image bundle. This object will provide |
... | ... | |
503 | 505 |
@Override |
504 | 506 |
public void onSuccess(AccountResource _result) { |
505 | 507 |
account = _result; |
506 |
if (account.getContainers().isEmpty()) |
|
507 |
createHomeContainers(); |
|
508 |
if (!account.hasHomeContainer()) |
|
509 |
createHomeContainer(account); |
|
510 |
else if (!account.hasTrashContainer()) |
|
511 |
createTrashContainer(); |
|
508 | 512 |
else { |
509 | 513 |
folderTreeViewModel.initialize(account); |
510 | 514 |
} |
... | ... | |
523 | 527 |
Scheduler.get().scheduleDeferred(getAccount); |
524 | 528 |
} |
525 | 529 |
|
526 |
protected void createHomeContainers() {
|
|
527 |
String path = "/pithos";
|
|
530 |
protected void createHomeContainer(final AccountResource account) {
|
|
531 |
String path = "/" + Pithos.HOME_CONTAINER;
|
|
528 | 532 |
PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) { |
529 | 533 |
@Override |
530 | 534 |
public void onSuccess(@SuppressWarnings("unused") Resource result) { |
531 |
fetchAccount(); |
|
535 |
if (!account.hasTrashContainer()) |
|
536 |
createTrashContainer(); |
|
537 |
else |
|
538 |
fetchAccount(); |
|
532 | 539 |
} |
533 | 540 |
|
534 | 541 |
@Override |
... | ... | |
544 | 551 |
Scheduler.get().scheduleDeferred(createPithos); |
545 | 552 |
} |
546 | 553 |
|
547 |
/** |
|
554 |
protected void createTrashContainer() { |
|
555 |
String path = "/" + Pithos.TRASH_CONTAINER; |
|
556 |
PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) { |
|
557 |
@Override |
|
558 |
public void onSuccess(@SuppressWarnings("unused") Resource result) { |
|
559 |
fetchAccount(); |
|
560 |
} |
|
561 |
|
|
562 |
@Override |
|
563 |
public void onError(Throwable t) { |
|
564 |
GWT.log("Error creating pithos", t); |
|
565 |
if (t instanceof RestException) |
|
566 |
displayError("Error creating pithos: " + ((RestException) t).getHttpStatusText()); |
|
567 |
else |
|
568 |
displayError("System error Error creating pithos: " + t.getMessage()); |
|
569 |
} |
|
570 |
}; |
|
571 |
createPithos.setHeader("X-Auth-Token", getToken()); |
|
572 |
Scheduler.get().scheduleDeferred(createPithos); |
|
573 |
} |
|
574 |
|
|
575 |
/** |
|
548 | 576 |
* Creates an HTML fragment that places an image & caption together, for use |
549 | 577 |
* in a group header. |
550 | 578 |
* |
... | ... | |
768 | 796 |
public void onError(Throwable t) { |
769 | 797 |
GWT.log("", t); |
770 | 798 |
if (t instanceof RestException) { |
771 |
displayError("Unable to delete folder: "+((RestException) t).getHttpStatusText()); |
|
799 |
if (((RestException) t).getHttpStatusCode() != Response.SC_NOT_FOUND) |
|
800 |
displayError("Unable to delete folder: "+((RestException) t).getHttpStatusText()); |
|
801 |
else |
|
802 |
onSuccess(null); |
|
772 | 803 |
} |
773 | 804 |
else |
774 | 805 |
displayError("System error unable to delete folder: " + t.getMessage()); |
b/web_client/src/gr/grnet/pithos/web/client/commands/ToTrashCommand.java | ||
---|---|---|
40 | 40 |
import gr.grnet.pithos.web.client.foldertree.Folder; |
41 | 41 |
import gr.grnet.pithos.web.client.foldertree.Resource; |
42 | 42 |
import gr.grnet.pithos.web.client.rest.PostRequest; |
43 |
import gr.grnet.pithos.web.client.rest.PutRequest; |
|
43 | 44 |
import gr.grnet.pithos.web.client.rest.RestException; |
44 | 45 |
|
45 | 46 |
import java.util.Iterator; |
... | ... | |
95 | 96 |
} |
96 | 97 |
|
97 | 98 |
private void trashFolder(final Folder f, final Command callback) { |
98 |
String path = f.getUri() + "?update=";
|
|
99 |
PostRequest trashFolder = new PostRequest(app.getApiPath(), app.getUsername(), path) {
|
|
99 |
String path = "/" + Pithos.TRASH_CONTAINER + "/" + f.getPrefix() + "/" + f.getName();
|
|
100 |
PutRequest createFolder = new PutRequest(app.getApiPath(), app.getUsername(), path) {
|
|
100 | 101 |
@Override |
101 | 102 |
public void onSuccess(@SuppressWarnings("unused") Resource result) { |
102 | 103 |
Iterator<File> iter = f.getFiles().iterator(); |
... | ... | |
104 | 105 |
@Override |
105 | 106 |
public void execute() { |
106 | 107 |
Iterator<Folder> iterf = f.getSubfolders().iterator(); |
107 |
trashSubfolders(iterf, new Command() { |
|
108 |
@Override |
|
109 |
public void execute() { |
|
110 |
callback.execute(); |
|
111 |
} |
|
112 |
}); |
|
108 |
trashSubfolders(iterf, callback); |
|
113 | 109 |
} |
114 | 110 |
}); |
115 | 111 |
} |
... | ... | |
124 | 120 |
app.displayError("System error creating folder:" + t.getMessage()); |
125 | 121 |
} |
126 | 122 |
}; |
127 |
trashFolder.setHeader("X-Auth-Token", app.getToken()); |
|
128 |
trashFolder.setHeader("X-Object-Meta-Trash", "true"); |
|
129 |
Scheduler.get().scheduleDeferred(trashFolder); |
|
123 |
createFolder.setHeader("X-Auth-Token", app.getToken()); |
|
124 |
createFolder.setHeader("Accept", "*/*"); |
|
125 |
createFolder.setHeader("Content-Length", "0"); |
|
126 |
createFolder.setHeader("Content-Type", "application/folder"); |
|
127 |
Scheduler.get().scheduleDeferred(createFolder); |
|
130 | 128 |
} |
131 | 129 |
|
132 | 130 |
protected void trashFiles(final Iterator<File> iter, final Command callback) { |
133 | 131 |
if (iter.hasNext()) { |
134 | 132 |
File file = iter.next(); |
135 |
String path = file.getUri() + "?update=";
|
|
136 |
PostRequest trashFile = new PostRequest(app.getApiPath(), app.getUsername(), path) {
|
|
133 |
String path = "/" + Pithos.TRASH_CONTAINER + "/" + file.getPath();
|
|
134 |
PutRequest trashFile = new PutRequest(app.getApiPath(), app.getUsername(), path) {
|
|
137 | 135 |
@Override |
138 | 136 |
public void onSuccess(@SuppressWarnings("unused") Resource result) { |
139 | 137 |
trashFiles(iter, callback); |
... | ... | |
150 | 148 |
} |
151 | 149 |
}; |
152 | 150 |
trashFile.setHeader("X-Auth-Token", app.getToken()); |
153 |
trashFile.setHeader("X-Object-Meta-Trash", "true");
|
|
151 |
trashFile.setHeader("X-Move-From", file.getUri());
|
|
154 | 152 |
Scheduler.get().scheduleDeferred(trashFile); |
155 | 153 |
} |
156 |
else if (callback != null) {
|
|
154 |
else if (callback != null) { |
|
157 | 155 |
callback.execute(); |
158 | 156 |
} |
159 | 157 |
} |
b/web_client/src/gr/grnet/pithos/web/client/foldertree/AccountResource.java | ||
---|---|---|
35 | 35 |
|
36 | 36 |
package gr.grnet.pithos.web.client.foldertree; |
37 | 37 |
|
38 |
import gr.grnet.pithos.web.client.Pithos; |
|
39 |
|
|
38 | 40 |
import java.util.ArrayList; |
39 | 41 |
import java.util.Date; |
40 | 42 |
import java.util.List; |
... | ... | |
214 | 216 |
public List<Group> getGroups() { |
215 | 217 |
return groups; |
216 | 218 |
} |
219 |
|
|
220 |
public boolean hasHomeContainer() { |
|
221 |
for (Folder f : containers) |
|
222 |
if (f.getName().equals(Pithos.HOME_CONTAINER)) |
|
223 |
return true; |
|
224 |
return false; |
|
225 |
} |
|
226 |
|
|
227 |
public boolean hasTrashContainer() { |
|
228 |
for (Folder f : containers) |
|
229 |
if (f.getName().equals(Pithos.TRASH_CONTAINER)) |
|
230 |
return true; |
|
231 |
return false; |
|
232 |
} |
|
217 | 233 |
} |
b/web_client/src/gr/grnet/pithos/web/client/foldertree/File.java | ||
---|---|---|
39 | 39 |
import com.google.gwt.http.client.Response; |
40 | 40 |
import com.google.gwt.i18n.client.NumberFormat; |
41 | 41 |
import com.google.gwt.json.client.JSONObject; |
42 |
|
|
43 |
import gr.grnet.pithos.web.client.Pithos; |
|
44 |
|
|
42 | 45 |
import java.util.Date; |
43 | 46 |
import java.util.HashMap; |
44 | 47 |
import java.util.HashSet; |
... | ... | |
66 | 69 |
|
67 | 70 |
private String owner; |
68 | 71 |
|
69 |
private boolean inTrash; |
|
70 |
|
|
71 | 72 |
private String container; |
72 | 73 |
|
73 | 74 |
private Folder parent; |
... | ... | |
141 | 142 |
return !permissions.isEmpty(); |
142 | 143 |
} |
143 | 144 |
|
144 |
public boolean isInTrash() { |
|
145 |
return inTrash; |
|
146 |
} |
|
147 |
|
|
148 | 145 |
public void populate(Folder _parent, JSONObject o, String _owner, String _container) { |
149 | 146 |
this.parent = _parent; |
150 | 147 |
path = unmarshallString(o, "name"); |
... | ... | |
170 | 167 |
parsePermissions(rawPermissions); |
171 | 168 |
|
172 | 169 |
for (String key : o.keySet()) |
173 |
if (key.startsWith("x_object_meta_") && !key.equals("x_object_meta_trash"))
|
|
170 |
if (key.startsWith("x_object_meta_")) |
|
174 | 171 |
tags.add(key.substring("x_object_meta_".length()).trim().toLowerCase()); |
175 | 172 |
|
176 | 173 |
|
... | ... | |
226 | 223 |
this.owner = _owner; |
227 | 224 |
for (Header h : response.getHeaders()) { |
228 | 225 |
String header = h.getName(); |
229 |
if (header.startsWith("X-Object-Meta-") && !header.equals("X-Object-Meta-Trash"))
|
|
226 |
if (header.startsWith("X-Object-Meta-")) |
|
230 | 227 |
tags.add(header.substring("X-Object-Meta-".length()).trim().toLowerCase()); |
231 | 228 |
else if (header.equals("X-Object-Sharing")) { |
232 | 229 |
String rawPermissions = h.getValue(); |
... | ... | |
236 | 233 |
inheritedPermissionsFrom = h.getValue().trim(); |
237 | 234 |
} |
238 | 235 |
} |
239 |
String header = response.getHeader("X-Object-Meta-Trash"); |
|
240 |
if (header != null) |
|
241 |
inTrash = Boolean.valueOf(header); |
|
242 |
else |
|
243 |
inTrash = false; |
|
244 | 236 |
} |
245 | 237 |
|
246 | 238 |
public Folder getParent() { |
b/web_client/src/gr/grnet/pithos/web/client/foldertree/Folder.java | ||
---|---|---|
35 | 35 |
|
36 | 36 |
package gr.grnet.pithos.web.client.foldertree; |
37 | 37 |
|
38 |
import gr.grnet.pithos.web.client.Pithos; |
|
39 |
|
|
38 | 40 |
import java.util.Date; |
39 | 41 |
import java.util.HashMap; |
40 | 42 |
import java.util.Iterator; |
... | ... | |
77 | 79 |
|
78 | 80 |
private Set<File> files = new LinkedHashSet<File>(); |
79 | 81 |
|
80 |
private boolean inTrash = false; |
|
81 |
|
|
82 |
/* |
|
83 |
* Flag that indicates that this folder is the Trash |
|
84 |
*/ |
|
85 |
private boolean trash = false; |
|
86 |
|
|
87 | 82 |
private Set<String> tags = new LinkedHashSet<String>(); |
88 | 83 |
|
89 | 84 |
private String owner; |
... | ... | |
167 | 162 |
if (header != null) |
168 | 163 |
bytesUsed = Long.valueOf(header); |
169 | 164 |
|
170 |
header = response.getHeader("X-Object-Meta-Trash"); |
|
171 |
if (header != null && header.equals("true")) |
|
172 |
inTrash = true; |
|
173 |
|
|
174 | 165 |
header = response.getHeader("X-Container-Object-Meta"); |
175 | 166 |
if (header != null && header.length() > 0) { |
176 | 167 |
for (String t : header.split(",")) { |
... | ... | |
197 | 188 |
f.populate(this, o, _owner, container); |
198 | 189 |
subfolders.add(f); |
199 | 190 |
} |
200 |
else if (!(o.containsKey("x_object_meta_trash") && o.get("x_object_meta_trash").isString().stringValue().equals("true"))) {
|
|
191 |
else { |
|
201 | 192 |
File file = new File(); |
202 | 193 |
file.populate(this, o, _owner, container); |
203 | 194 |
files.add(file); |
204 | 195 |
} |
205 | 196 |
} |
206 | 197 |
} |
207 |
//This step is necessary to remove the trashed folders. Trashed folders are added initially because we need to |
|
208 |
//avoid having in the list the virtual folders of the form {"subdir":"folder1"} which have no indication of thrash |
|
209 |
Iterator<Folder> iter = subfolders.iterator(); |
|
210 |
while (iter.hasNext()) { |
|
211 |
Folder f = iter.next(); |
|
212 |
if (f.isInTrash()) |
|
213 |
iter.remove(); |
|
214 |
} |
|
215 | 198 |
} |
216 | 199 |
} |
217 | 200 |
|
... | ... | |
240 | 223 |
prefix = ""; |
241 | 224 |
} |
242 | 225 |
this.owner = _owner; |
243 |
if (o.containsKey("x_object_meta_trash") && o.get("x_object_meta_trash").isString().stringValue().equals("true")) |
|
244 |
inTrash = true; |
|
245 | 226 |
|
246 | 227 |
inheritedPermissionsFrom = unmarshallString(o, "x_object_shared_by"); |
247 | 228 |
String rawPermissions = unmarshallString(o, "x_object_sharing"); |
... | ... | |
286 | 267 |
return "/" + container + (prefix.length() == 0 ? "" : "/" + prefix); |
287 | 268 |
} |
288 | 269 |
|
289 |
public boolean isInTrash() { |
|
290 |
return inTrash; |
|
291 |
} |
|
292 |
|
|
293 | 270 |
public boolean isContainer() { |
294 | 271 |
return parent == null; |
295 | 272 |
} |
296 | 273 |
|
297 |
public boolean isTrash() { |
|
298 |
return trash; |
|
299 |
} |
|
300 |
|
|
301 |
public void setTrash(boolean trash) { |
|
302 |
this.trash = trash; |
|
303 |
} |
|
304 |
|
|
305 | 274 |
public void setContainer(String container) { |
306 | 275 |
this.container = container; |
307 | 276 |
} |
... | ... | |
336 | 305 |
public boolean isShared() { |
337 | 306 |
return !permissions.isEmpty(); |
338 | 307 |
} |
308 |
|
|
309 |
public boolean isTrash() { |
|
310 |
return isContainer() && name.equals(Pithos.TRASH_CONTAINER); |
|
311 |
} |
|
312 |
|
|
313 |
public boolean isHome() { |
|
314 |
return isContainer() && name.equals(Pithos.HOME_CONTAINER); |
|
315 |
} |
|
339 | 316 |
} |
b/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeViewModel.java | ||
---|---|---|
51 | 51 |
import com.google.gwt.core.client.Scheduler; |
52 | 52 |
import com.google.gwt.core.client.Scheduler.ScheduledCommand; |
53 | 53 |
import com.google.gwt.event.dom.client.ContextMenuEvent; |
54 |
import com.google.gwt.safehtml.shared.SafeHtml; |
|
54 | 55 |
import com.google.gwt.safehtml.shared.SafeHtmlBuilder; |
55 | 56 |
import com.google.gwt.user.client.Command; |
56 | 57 |
import com.google.gwt.user.client.ui.AbstractImagePrototype; |
... | ... | |
67 | 68 |
@Override |
68 | 69 |
public void render(@SuppressWarnings("unused") Context context, Folder folder, SafeHtmlBuilder safeHtmlBuilder) { |
69 | 70 |
String html; |
70 |
if (folder.isTrash()) |
|
71 |
html = AbstractImagePrototype.create(FolderTreeView.images.trash()).getHTML(); |
|
72 |
else |
|
73 |
html = AbstractImagePrototype.create(FolderTreeView.images.folderYellow()).getHTML(); |
|
71 |
SafeHtml name; |
|
72 |
if (folder.isHome()) { |
|
73 |
html = AbstractImagePrototype.create(FolderTreeView.images.home()).getHTML(); |
|
74 |
name = Templates.INSTANCE.nameSpan("Home"); |
|
75 |
} |
|
76 |
else if (folder.isTrash()) { |
|
77 |
html = AbstractImagePrototype.create(FolderTreeView.images.trash()).getHTML(); |
|
78 |
name = Templates.INSTANCE.nameSpan("Trash"); |
|
79 |
} |
|
80 |
else { |
|
81 |
html = AbstractImagePrototype.create(FolderTreeView.images.folderYellow()).getHTML(); |
|
82 |
name = Templates.INSTANCE.nameSpan(folder.getName()); |
|
83 |
} |
|
74 | 84 |
safeHtmlBuilder.appendHtmlConstant(html); |
75 |
safeHtmlBuilder.append(Templates.INSTANCE.nameSpan(folder.getName()));
|
|
85 |
safeHtmlBuilder.append(name);
|
|
76 | 86 |
} |
77 | 87 |
|
78 | 88 |
@Override |
... | ... | |
159 | 169 |
rootDataProvider.getList().clear(); |
160 | 170 |
rootDataProvider.getList().addAll(account.getContainers()); |
161 | 171 |
selectionModel.setSelected(rootDataProvider.getList().get(0), true); |
162 |
Folder f = new Folder("Trash"); |
|
163 |
f.setTrash(true); |
|
164 |
f.setContainer("trash"); |
|
165 |
rootDataProvider.getList().add(f); |
|
166 |
app.updateTags(); |
|
167 | 172 |
} |
168 | 173 |
}); |
169 | 174 |
} |
b/web_client/src/gr/grnet/pithos/web/client/mysharedtree/MysharedTreeView.java | ||
---|---|---|
112 | 112 |
|
113 | 113 |
@Source("gr/grnet/pithos/resources/folder_user.png") |
114 | 114 |
ImageResource sharedFolder(); |
115 |
|
|
116 |
@Source("gr/grnet/pithos/resources/trash.png") |
|
117 |
ImageResource trash(); |
|
118 | 115 |
} |
119 | 116 |
|
120 | 117 |
static Images images = GWT.create(Images.class); |
b/web_client/src/gr/grnet/pithos/web/client/othersharedtree/OtherSharedTreeView.java | ||
---|---|---|
113 | 113 |
@Source("gr/grnet/pithos/resources/folder_user.png") |
114 | 114 |
ImageResource sharedFolder(); |
115 | 115 |
|
116 |
@Source("gr/grnet/pithos/resources/trash.png") |
|
117 |
ImageResource trash(); |
|
118 |
|
|
119 | 116 |
@Source("gr/grnet/pithos/resources/edit_user.png") |
120 | 117 |
ImageResource user(); |
121 | 118 |
} |
b/web_client/src/gr/grnet/pithos/web/client/tagtree/Tag.java | ||
---|---|---|
68 | 68 |
// if (header != null) |
69 | 69 |
// bytesUsed = Long.valueOf(header); |
70 | 70 |
// |
71 |
// header = response.getHeader("X-Object-Meta-Trash"); |
|
72 |
// if (header != null && header.equals("true")) |
|
73 |
// inTrash = true; |
|
74 |
// |
|
75 | 71 |
// subfolders.clear(); //This is necessary in case we update a pre-existing Tag so that stale subfolders won't show up |
76 | 72 |
// files.clear(); |
77 | 73 |
// JSONValue json = JSONParser.parseStrict(response.getText()); |
... | ... | |
86 | 82 |
// f.populate(this, o, container); |
87 | 83 |
// subfolders.add(f); |
88 | 84 |
// } |
89 |
// else if (!(o.containsKey("x_object_meta_trash") && o.get("x_object_meta_trash").isString().stringValue().equals("true"))) {
|
|
85 |
// else { |
|
90 | 86 |
// File file = new File(); |
91 | 87 |
// file.populate(this, o, container); |
92 | 88 |
// files.add(file); |
93 | 89 |
// } |
94 | 90 |
// } |
95 | 91 |
// } |
96 |
// //This step is necessary to remove the trashed folders. Trashed folders are added initially because we need to |
|
97 |
// //avoid having in the list the virtual folders of the form {"subdir":"folder1"} which have no indication of thrash |
|
98 |
// Iterator<Tag> iter = subfolders.iterator(); |
|
99 |
// while (iter.hasNext()) { |
|
100 |
// Tag f = iter.next(); |
|
101 |
// if (f.isInTrash()) |
|
102 |
// iter.remove(); |
|
103 |
// } |
|
104 | 92 |
// } |
105 | 93 |
// } |
106 | 94 |
// |
... | ... | |
128 | 116 |
// container = name; |
129 | 117 |
// prefix = ""; |
130 | 118 |
// } |
131 |
// if (o.containsKey("x_object_meta_trash") && o.get("x_object_meta_trash").isString().stringValue().equals("true")) |
|
132 |
// inTrash = true; |
|
133 | 119 |
// } |
134 | 120 |
// |
135 | 121 |
// public static Tag createFromResponse(Response response, Tag result) { |
Also available in: Unified diff