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