Revision 947da718

b/src/gr/grnet/pithos/web/client/AbstractPropertiesDialog.java
50 50

  
51 51
	protected static final String MULTIPLE_VALUES_TEXT = "(Multiple values)";
52 52

  
53
	/**
54
	 * Text box with the tags associated with the file
55
	 */
56
	protected TextBox tags = new TextBox();
57

  
58
	protected String initialTagText;
59

  
60
	/**
61
	 * A FlowPanel with all user tags
62
	 */
63
	protected FlowPanel allTagsContent;
64

  
65

  
66 53
	protected TabPanel inner = null;
67 54

  
68 55
    protected Pithos app;
b/src/gr/grnet/pithos/web/client/FilePropertiesDialog.java
42 42
import gr.grnet.pithos.web.client.rest.PostRequest;
43 43
import gr.grnet.pithos.web.client.rest.PutRequest;
44 44
import gr.grnet.pithos.web.client.rest.RestException;
45
import gr.grnet.pithos.web.client.tagtree.Tag;
46 45

  
46
import java.util.HashMap;
47 47
import java.util.List;
48 48
import java.util.Map;
49 49

  
50
import org.apache.commons.collections.map.HashedMap;
51

  
50 52
import com.google.gwt.core.client.GWT;
51 53
import com.google.gwt.core.client.Scheduler;
52 54
import com.google.gwt.event.dom.client.ClickEvent;
......
60 62
import com.google.gwt.user.client.ui.Button;
61 63
import com.google.gwt.user.client.ui.CheckBox;
62 64
import com.google.gwt.user.client.ui.DecoratedTabPanel;
63
import com.google.gwt.user.client.ui.DisclosurePanel;
64 65
import com.google.gwt.user.client.ui.FlexTable;
65
import com.google.gwt.user.client.ui.FlowPanel;
66 66
import com.google.gwt.user.client.ui.FocusPanel;
67 67
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
68 68
import com.google.gwt.user.client.ui.HorizontalPanel;
69
import com.google.gwt.user.client.ui.Image;
69 70
import com.google.gwt.user.client.ui.Label;
70 71
import com.google.gwt.user.client.ui.TextBox;
71 72
import com.google.gwt.user.client.ui.VerticalPanel;
......
110 111

  
111 112
    Images images = GWT.create(Images.class);
112 113

  
114
    private FlexTable metaTable;
113 115
	/**
114 116
	 * The widget's constructor.
115 117
	 */
......
206 208
        generalTable.setText(1, 0, "Folder");
207 209
        generalTable.setText(2, 0, "Owner");
208 210
        generalTable.setText(3, 0, "Last modified");
209
        generalTable.setText(4, 0, "Tags");
210 211

  
211 212
        name.setWidth("100%");
212 213
        name.setText(file.getName());
......
220 221
        final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
221 222
        generalTable.setText(3, 1, file.getLastModified() != null ? formatter.format(file.getLastModified()) : "");
222 223

  
223
		StringBuffer tagsBuffer = new StringBuffer();
224
        for (String t : file.getTags())
225
			tagsBuffer.append(t).append(", ");
226
		if (tagsBuffer.length() > 1)
227
			tagsBuffer.delete(tagsBuffer.length() - 2, tagsBuffer.length() - 1);
228
		initialTagText = tagsBuffer.toString();
229
		tags.setWidth("100%");
230
		tags.setText(initialTagText);
231
		generalTable.setWidget(4, 1, tags);
232

  
233 224
        generalTable.getFlexCellFormatter().setStyleName(0, 0, "props-labels");
234 225
        generalTable.getFlexCellFormatter().setStyleName(1, 0, "props-labels");
235 226
        generalTable.getFlexCellFormatter().setStyleName(2, 0, "props-labels");
......
239 230
        generalTable.getFlexCellFormatter().setStyleName(1, 1, "props-values");
240 231
        generalTable.getFlexCellFormatter().setStyleName(2, 1, "props-values");
241 232
        generalTable.getFlexCellFormatter().setStyleName(3, 1, "props-values");
242
        generalTable.getFlexCellFormatter().setStyleName(4, 1, "props-values");
243 233
        generalTable.setCellSpacing(4);
244 234

  
245 235
        generalPanel.add(generalTable);
246 236

  
247
        DisclosurePanel allTags = new DisclosurePanel("All tags");
248
        allTagsContent = new FlowPanel();
249
        allTagsContent.setWidth("100%");
250
        for (Tag t : app.getAllTags()) {
251
            final Anchor tagAnchor = new Anchor(t.getName(), false);
252
            tagAnchor.addStyleName("pithos-tag");
253
            allTagsContent.add(tagAnchor);
254
            Label separator = new Label(", ");
255
            separator.addStyleName("pithos-tag");
256
            allTagsContent.add(separator);
257
            tagAnchor.addClickHandler(new ClickHandler() {
237
        Label meta = new Label("Meta data");
238
        generalPanel.add(meta);
239
		Image plus = new Image("images/plus.png");
240
		plus.addStyleName("pithos-addInvitationImg");
241
		generalPanel.add(plus);
242
		
243
		metaTable = new FlexTable();
244
		metaTable.setCellSpacing(0);
245
		metaTable.setHTML(0, 0, "Name");
246
		metaTable.getFlexCellFormatter().setStyleName(0, 0, "props-labels");
247
		metaTable.setText(0, 1, "Value");
248
		metaTable.getFlexCellFormatter().setStyleName(0, 1, "props-labels");
249
		int rows = 1;
250
		for (String metaKey : file.getMeta().keySet()) {
251
			addFormLine(metaTable, rows++, metaKey, file.getMeta().get(metaKey));
252
		}
253
		
254
		plus.addClickHandler(new ClickHandler() {
255
			
256
			@Override
257
			public void onClick(ClickEvent event) {
258
				addFormLine(metaTable, metaTable.getRowCount(), "", "");
259
			}
260
		});
258 261

  
259
                @Override
260
                public void onClick(@SuppressWarnings("unused") ClickEvent event) {
261
                    String existing = tags.getText().trim();
262
                    if (MULTIPLE_VALUES_TEXT.equals(existing))
263
                        existing = "";
264
                    String newTag = tagAnchor.getText().trim();
265
                    // insert the new tag only if it is not in the list
266
                    // already
267
                    if (existing.indexOf(newTag) == -1)
268
                        tags.setText(existing + (existing.length() > 0 ? ", " : "") + newTag);
269
                }
270
            });
271
        }
272
        allTags.setContent(allTagsContent);
273
        generalPanel.add(allTags);
262
		generalPanel.add(metaTable);
274 263
        generalPanel.setSpacing(4);
275 264
        return generalPanel;
276 265
    }
277 266

  
267
	private void addFormLine(final FlexTable table, int row, String name, String value) {
268
		TextBox nameBox = new TextBox();
269
		nameBox.setText(name);
270
		table.setWidget(row, 0, nameBox);
271
		table.getFlexCellFormatter().setStyleName(1, 0, "props-values");
272

  
273
		TextBox valueBox = new TextBox();
274
		valueBox.setText(value);
275
		table.setWidget(row, 1, valueBox);
276
		table.getFlexCellFormatter().setStyleName(1, 1, "props-values");
277
		
278
		Image delete = new Image("images/delete.png");
279
		delete.addStyleName("pithos-invitationDeleteImg");
280
		delete.addClickHandler(new ClickHandler() {
281
			
282
			@Override
283
			public void onClick(ClickEvent event) {
284
				int rowIndex = table.getCellForEvent(event).getRowIndex();
285
				table.removeRow(rowIndex);
286
			}
287
		});
288
		table.setWidget(row, 2, delete);
289
	}
290

  
278 291
    private VerticalPanel createSharingPanel() {
279 292
        VerticalPanel permPanel = new VerticalPanel();
280 293

  
......
395 408
                published = readForAll.getValue();
396 409
        final Boolean finalPublished = published;
397 410

  
398
        String[] tagset = null;
399
		if (!tags.getText().equals(initialTagText))
400
			tagset = tags.getText().trim().split(",");
401
        final String[] newTags = tagset;
411
        final Map<String, String> newMeta = new HashMap<String, String>();
412
        for (int row = 1; row < metaTable.getRowCount(); row++) {
413
        	String key = ((TextBox) metaTable.getWidget(row, 0)).getText().trim();
414
        	String value = ((TextBox) metaTable.getWidget(row, 1)).getText().trim();
415
        	newMeta.put(key, value);
416
        }
402 417

  
403 418
        if (newFilename != null) {
404 419
            final String path = file.getParent().getUri() + "/" + newFilename;
405 420
            PutRequest updateFile = new PutRequest(app.getApiPath(), app.getUsername(), path) {
406 421
                @Override
407 422
                public void onSuccess(@SuppressWarnings("unused") Resource result) {
408
                    updateMetaData(app.getApiPath(), file.getOwner(), path + "?update=", newTags, finalPublished, perms);
423
                    updateMetaData(app.getApiPath(), file.getOwner(), path + "?update=", newMeta, finalPublished, perms);
409 424
                }
410 425

  
411 426
                @Override
......
425 440
            Scheduler.get().scheduleDeferred(updateFile);
426 441
        }
427 442
        else
428
            updateMetaData(app.getApiPath(), app.getUsername(), file.getUri() + "?update=", newTags, finalPublished, perms);
443
            updateMetaData(app.getApiPath(), app.getUsername(), file.getUri() + "?update=", newMeta, finalPublished, perms);
429 444
	}
430 445

  
431
	protected void updateMetaData(String api, String owner, String path, String[] newTags, Boolean published, Map<String, Boolean[]> newPermissions) {
432
        if (newTags != null || published != null || newPermissions != null) {
446
	protected void updateMetaData(String api, String owner, String path, Map<String, String> newMeta, Boolean published, Map<String, Boolean[]> newPermissions) {
447
        if (newMeta != null || published != null || newPermissions != null) {
433 448
            PostRequest updateFile = new PostRequest(api, owner, path) {
434 449
                @Override
435 450
                public void onSuccess(@SuppressWarnings("unused") Resource result) {
......
448 463
				}
449 464
            };
450 465
            updateFile.setHeader("X-Auth-Token", app.getToken());
451
            for (String t : file.getTags()) {
466
            for (String t : file.getMeta().keySet()) {
452 467
        		updateFile.setHeader("X-Object-Meta-" + URL.encodePathSegment(t.trim()), "~");
453 468
            }
454
            if (newTags != null)
455
                for (String t : newTags)
456
                	if (t.length() > 0)
457
                		updateFile.setHeader("X-Object-Meta-" + URL.encodePathSegment(t.trim()), "true");
469
            for (String key : newMeta.keySet())
470
                updateFile.setHeader("X-Object-Meta-" + URL.encodePathSegment(key.trim()), URL.encodePathSegment(newMeta.get(key)));
471
            
458 472
            if (published != null)
459 473
                updateFile.setHeader("X-Object-Public", published.toString());
460 474
            if (newPermissions != null) {
b/src/gr/grnet/pithos/web/client/FilesPropertiesDialog.java
142 142

  
143 143
        generalPanel.add(generalTable);
144 144

  
145
		DisclosurePanel allTags = new DisclosurePanel("All tags");
146
		allTagsContent = new FlowPanel();
147
		allTags.setContent(allTagsContent);
148
		generalPanel.add(allTags);
149
		generalPanel.setSpacing(4);
150

  
151 145
        return generalPanel;
152 146
    }
153 147

  
b/src/gr/grnet/pithos/web/client/ToolsMenu.java
101 101
	        Boolean[] permissions = folder.getPermissions().get(app.getUsername());
102 102
	    	boolean canWrite = folder.getOwner().equals(app.getUsername()) || (permissions!= null && permissions[1] != null && permissions[1]);
103 103
	    	boolean isFolderTreeSelected = selectedTree.equals(app.getFolderTreeView());
104
	    	boolean otherSharedTreeSelected = selectedTree.equals(app.getOtherSharedTreeView());
105 104
	    	
106 105
	        if (!folder.isInTrash()) {
107 106
	        	if (canWrite) {
b/src/gr/grnet/pithos/web/client/foldertree/File.java
46 46
import com.google.gwt.http.client.URL;
47 47
import com.google.gwt.i18n.client.NumberFormat;
48 48
import com.google.gwt.json.client.JSONObject;
49
import com.google.gwt.json.client.JSONValue;
49 50

  
50 51
public class File extends Resource {
51 52
    private String name;
......
72 73

  
73 74
    private Folder parent;
74 75

  
75
    private Set<String> tags = new HashSet<String>();
76
    private Map<String, String> meta = new HashMap<String, String>();
76 77

  
77 78
    private boolean published;
78 79

  
......
166 167
        if (rawPermissions != null)
167 168
            parsePermissions(rawPermissions);
168 169

  
169
        for (String key : o.keySet())
170
            if (key.startsWith("x_object_meta_"))
171
                tags.add(URL.decodePathSegment(key.substring("x_object_meta_".length())).trim().toLowerCase());
172

  
173
        
170
        JSONValue metaValue = o.get("x_object_meta");
171
        if (metaValue != null) {
172
        	JSONObject metaObj = metaValue.isObject();
173
        	if (metaObj != null) {
174
        		for (String key: metaObj.keySet()) {
175
                    meta.put(key, unmarshallString(metaObj, key));
176
        		}
177
        	}
178
        }
174 179
    }
175 180

  
176 181
    private void parsePermissions(String rawPermissions) {
......
224 229
        for (Header h : response.getHeaders()) {
225 230
            String header = h.getName();
226 231
            if (header.startsWith("X-Object-Meta-"))
227
                tags.add(URL.decodePathSegment(header.substring("X-Object-Meta-".length())));
232
                meta.put(URL.decodePathSegment(header.substring("X-Object-Meta-".length())), URL.decodePathSegment(h.getValue()));
228 233
            else if (header.equals("X-Object-Sharing")) {
229 234
                String rawPermissions = h.getValue();
230 235
                parsePermissions(URL.decodePathSegment(rawPermissions));
......
239 244
        return parent;
240 245
    }
241 246

  
242
    public Set<String> getTags() {
243
        return tags;
247
    public Map<String, String> getMeta() {
248
        return meta;
244 249
    }
245 250

  
246 251
    public boolean isPublished() {

Also available in: Unified diff