Statistics
| Branch: | Tag: | Revision:

root / src / gr / grnet / pithos / web / client / foldertree / FolderTreeViewModel.java @ 2f4ea617

History | View | Annotate | Download (11.2 kB)

1 6084aa02 Christos Stathis
/*
2 cae2a8db Christos Stathis
 * Copyright 2011-2012 GRNET S.A. All rights reserved.
3 63366925 Christos Stathis
 *
4 63366925 Christos Stathis
 * Redistribution and use in source and binary forms, with or
5 63366925 Christos Stathis
 * without modification, are permitted provided that the following
6 63366925 Christos Stathis
 * conditions are met:
7 63366925 Christos Stathis
 *
8 63366925 Christos Stathis
 *   1. Redistributions of source code must retain the above
9 63366925 Christos Stathis
 *      copyright notice, this list of conditions and the following
10 63366925 Christos Stathis
 *      disclaimer.
11 63366925 Christos Stathis
 *
12 63366925 Christos Stathis
 *   2. Redistributions in binary form must reproduce the above
13 63366925 Christos Stathis
 *      copyright notice, this list of conditions and the following
14 63366925 Christos Stathis
 *      disclaimer in the documentation and/or other materials
15 63366925 Christos Stathis
 *      provided with the distribution.
16 63366925 Christos Stathis
 *
17 63366925 Christos Stathis
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18 63366925 Christos Stathis
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 63366925 Christos Stathis
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 63366925 Christos Stathis
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21 63366925 Christos Stathis
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 63366925 Christos Stathis
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 63366925 Christos Stathis
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 63366925 Christos Stathis
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 63366925 Christos Stathis
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 63366925 Christos Stathis
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 63366925 Christos Stathis
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 63366925 Christos Stathis
 * POSSIBILITY OF SUCH DAMAGE.
29 63366925 Christos Stathis
 *
30 63366925 Christos Stathis
 * The views and conclusions contained in the software and
31 63366925 Christos Stathis
 * documentation are those of the authors and should not be
32 63366925 Christos Stathis
 * interpreted as representing official policies, either expressed
33 63366925 Christos Stathis
 * or implied, of GRNET S.A.
34 6084aa02 Christos Stathis
 */
35 6084aa02 Christos Stathis
36 6084aa02 Christos Stathis
package gr.grnet.pithos.web.client.foldertree;
37 6084aa02 Christos Stathis
38 7811b9d1 Christos Stathis
import gr.grnet.pithos.web.client.FolderContextMenu;
39 7811b9d1 Christos Stathis
import gr.grnet.pithos.web.client.Pithos;
40 7811b9d1 Christos Stathis
import gr.grnet.pithos.web.client.foldertree.FolderTreeView.Templates;
41 7811b9d1 Christos Stathis
import gr.grnet.pithos.web.client.rest.GetRequest;
42 7811b9d1 Christos Stathis
import gr.grnet.pithos.web.client.rest.RestException;
43 7811b9d1 Christos Stathis
44 4ca9cb37 Christos Stathis
import java.util.ArrayList;
45 7811b9d1 Christos Stathis
import java.util.HashMap;
46 7811b9d1 Christos Stathis
import java.util.Iterator;
47 7811b9d1 Christos Stathis
import java.util.Map;
48 7811b9d1 Christos Stathis
49 447407c8 Christos Stathis
import com.google.gwt.cell.client.AbstractCell;
50 447407c8 Christos Stathis
import com.google.gwt.cell.client.Cell;
51 6084aa02 Christos Stathis
import com.google.gwt.core.client.GWT;
52 6084aa02 Christos Stathis
import com.google.gwt.core.client.Scheduler;
53 447407c8 Christos Stathis
import com.google.gwt.event.dom.client.ContextMenuEvent;
54 9539e23d Christos Stathis
import com.google.gwt.http.client.Response;
55 f5023f13 Christos Stathis
import com.google.gwt.http.client.URL;
56 7b28ae07 Christos Stathis
import com.google.gwt.safehtml.shared.SafeHtml;
57 447407c8 Christos Stathis
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
58 5ebc9312 Christos Stathis
import com.google.gwt.user.client.Command;
59 447407c8 Christos Stathis
import com.google.gwt.user.client.ui.AbstractImagePrototype;
60 6084aa02 Christos Stathis
import com.google.gwt.view.client.ListDataProvider;
61 6084aa02 Christos Stathis
import com.google.gwt.view.client.SingleSelectionModel;
62 6084aa02 Christos Stathis
import com.google.gwt.view.client.TreeViewModel;
63 6084aa02 Christos Stathis
64 6084aa02 Christos Stathis
public class FolderTreeViewModel implements TreeViewModel {
65 6084aa02 Christos Stathis
66 7811b9d1 Christos Stathis
        protected Pithos app;
67 a7c43f26 Christos Stathis
    
68 447407c8 Christos Stathis
    private Cell<Folder> folderCell = new AbstractCell<Folder>(ContextMenuEvent.getType().getName()) {
69 447407c8 Christos Stathis
70 447407c8 Christos Stathis
       @Override
71 ebead1b5 Christos Stathis
        public void render(Context context, Folder folder, SafeHtmlBuilder safeHtmlBuilder) {
72 05cf9e5b Christos Stathis
            String html;
73 7b28ae07 Christos Stathis
            SafeHtml name;
74 7b28ae07 Christos Stathis
                if (folder.isHome()) {
75 7e8e9ff0 Christos Stathis
                        html = AbstractImagePrototype.create(FolderTreeView.images.folderYellow()).getHTML();
76 a92f9b30 Christos Stathis
                        name = Templates.INSTANCE.nameSpan("Pithos");
77 7b28ae07 Christos Stathis
                }
78 7b28ae07 Christos Stathis
                else if (folder.isTrash()) {
79 7b28ae07 Christos Stathis
                        html = AbstractImagePrototype.create(FolderTreeView.images.trash()).getHTML();
80 7b28ae07 Christos Stathis
                        name = Templates.INSTANCE.nameSpan("Trash");
81 7b28ae07 Christos Stathis
                }
82 7b28ae07 Christos Stathis
            else {
83 04f50dbe Christos Stathis
                    html = AbstractImagePrototype.create(folder.isShared() ? FolderTreeView.images.myShared() : FolderTreeView.images.folderYellow()).getHTML();
84 7b28ae07 Christos Stathis
                        name = Templates.INSTANCE.nameSpan(folder.getName());
85 7b28ae07 Christos Stathis
            }
86 a7b6e464 Christos Stathis
            safeHtmlBuilder.appendHtmlConstant(html).appendHtmlConstant("&nbsp;");
87 7b28ae07 Christos Stathis
            safeHtmlBuilder.append(name);
88 447407c8 Christos Stathis
        }
89 447407c8 Christos Stathis
90 447407c8 Christos Stathis
        @Override
91 a2f617f8 Christos Stathis
        public void onBrowserEvent(Cell.Context context, com.google.gwt.dom.client.Element parent, final Folder folder, com.google.gwt.dom.client.NativeEvent event, com.google.gwt.cell.client.ValueUpdater<Folder> valueUpdater) {
92 447407c8 Christos Stathis
            if (event.getType().equals(ContextMenuEvent.getType().getName())) {
93 a2f617f8 Christos Stathis
                    final int x = event.getClientX();
94 a2f617f8 Christos Stathis
                    final int y = event.getClientY();
95 b651e67f Christos Stathis
                FolderTreeViewModel.this.selectionModel.setSelected(folder, true);
96 a2f617f8 Christos Stathis
                app.scheduleFolderHeadCommand(folder, new Command() {
97 a2f617f8 Christos Stathis
                                        
98 a2f617f8 Christos Stathis
                                        @Override
99 a2f617f8 Christos Stathis
                                        public void execute() {
100 a2f617f8 Christos Stathis
                                FolderContextMenu menu = new FolderContextMenu(app, FolderTreeView.images, app.getSelectedTree(), folder);
101 a2f617f8 Christos Stathis
                                menu.setPopupPosition(x, y);
102 a2f617f8 Christos Stathis
                                menu.show();
103 a2f617f8 Christos Stathis
                                        }
104 a2f617f8 Christos Stathis
                                });
105 447407c8 Christos Stathis
            }
106 447407c8 Christos Stathis
        }
107 447407c8 Christos Stathis
    };
108 447407c8 Christos Stathis
109 7811b9d1 Christos Stathis
    protected ListDataProvider<Folder> rootDataProvider = new ListDataProvider<Folder>();
110 7c818c14 Christos Stathis
111 cf49bbc9 Christos Stathis
    private Map<Folder, ListDataProvider<Folder>> dataProviderMap = new HashMap<Folder, ListDataProvider<Folder>>();
112 b651e67f Christos Stathis
113 7811b9d1 Christos Stathis
    protected SingleSelectionModel<Folder> selectionModel;
114 875a0179 Christos Stathis
115 a7c43f26 Christos Stathis
    public FolderTreeViewModel(Pithos _app, SingleSelectionModel<Folder> selectionModel) {
116 a7c43f26 Christos Stathis
        app = _app;
117 875a0179 Christos Stathis
        this.selectionModel = selectionModel;
118 6084aa02 Christos Stathis
    }
119 7c818c14 Christos Stathis
120 6084aa02 Christos Stathis
    @Override
121 6084aa02 Christos Stathis
    public <T> NodeInfo<?> getNodeInfo(T value) {
122 6084aa02 Christos Stathis
        if (value == null) {
123 6084aa02 Christos Stathis
            Folder f = new Folder("Loading ...");
124 7c818c14 Christos Stathis
            rootDataProvider.getList().add(f);
125 447407c8 Christos Stathis
            return new DefaultNodeInfo<Folder>(rootDataProvider, folderCell, selectionModel, null);
126 6084aa02 Christos Stathis
        }
127 7811b9d1 Christos Stathis
                final Folder f = (Folder) value;
128 7811b9d1 Christos Stathis
                if (dataProviderMap.get(f) == null) {
129 cf49bbc9 Christos Stathis
                    dataProviderMap.put(f, new ListDataProvider<Folder>());
130 7811b9d1 Christos Stathis
                }
131 cf49bbc9 Christos Stathis
                final ListDataProvider<Folder> dataProvider = dataProviderMap.get(f);
132 fb0060d7 Christos Stathis
                //This prevents the loading indicator
133 fb0060d7 Christos Stathis
//                dataProvider.getList().clear();
134 fb0060d7 Christos Stathis
//                dataProvider.getList().addAll(f.getSubfolders());
135 cf49bbc9 Christos Stathis
                fetchFolder(f, dataProvider, false, null);
136 7811b9d1 Christos Stathis
                return new DefaultNodeInfo<Folder>(dataProvider, folderCell, selectionModel, null);
137 6084aa02 Christos Stathis
    }
138 6084aa02 Christos Stathis
139 6084aa02 Christos Stathis
    @Override
140 6084aa02 Christos Stathis
    public boolean isLeaf(Object o) {
141 6084aa02 Christos Stathis
        if (o instanceof Folder) {
142 6084aa02 Christos Stathis
            Folder f = (Folder) o;
143 6084aa02 Christos Stathis
            return f.getSubfolders().isEmpty();
144 6084aa02 Christos Stathis
        }
145 6084aa02 Christos Stathis
        return false;
146 6084aa02 Christos Stathis
    }
147 6084aa02 Christos Stathis
148 0ec61115 Christos Stathis
        private native void log(String msg) /*-{
149 0ec61115 Christos Stathis
        $wnd.console.log(msg);
150 0ec61115 Christos Stathis
        }-*/;
151 0ec61115 Christos Stathis
152 7811b9d1 Christos Stathis
    protected void fetchFolder(final Iterator<Folder> iter, final Command callback) {
153 8e61880b Christos Stathis
        if (iter.hasNext()) {
154 8e61880b Christos Stathis
            final Folder f = iter.next();
155 8e61880b Christos Stathis
156 f5023f13 Christos Stathis
            String path = "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(f.getPrefix());
157 63ee965c Christos Stathis
            GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, app.getApiPath(), f.getOwner(), path, f) {
158 8e61880b Christos Stathis
                @Override
159 ebead1b5 Christos Stathis
                public void onSuccess(Folder _result) {
160 5ebc9312 Christos Stathis
                    fetchFolder(iter, callback);
161 8e61880b Christos Stathis
                }
162 8e61880b Christos Stathis
163 8e61880b Christos Stathis
                @Override
164 8e61880b Christos Stathis
                public void onError(Throwable t) {
165 8e61880b Christos Stathis
                    GWT.log("Error getting folder", t);
166 3f8622d4 Christos Stathis
                                        app.setError(t);
167 8e61880b Christos Stathis
                    if (t instanceof RestException)
168 a7c43f26 Christos Stathis
                        app.displayError("Error getting folder: " + ((RestException) t).getHttpStatusText());
169 8e61880b Christos Stathis
                    else
170 a7c43f26 Christos Stathis
                        app.displayError("System error fetching folder: " + t.getMessage());
171 8e61880b Christos Stathis
                }
172 9539e23d Christos Stathis
173 9539e23d Christos Stathis
                                @Override
174 9539e23d Christos Stathis
                                protected void onUnauthorized(Response response) {
175 9539e23d Christos Stathis
                                        app.sessionExpired();
176 9539e23d Christos Stathis
                                }
177 8e61880b Christos Stathis
            };
178 875a0179 Christos Stathis
            getFolder.setHeader("X-Auth-Token", app.getToken());
179 8e61880b Christos Stathis
            Scheduler.get().scheduleDeferred(getFolder);
180 8e61880b Christos Stathis
        }
181 5ebc9312 Christos Stathis
        else if (callback != null)
182 5ebc9312 Christos Stathis
            callback.execute();
183 5ebc9312 Christos Stathis
    }
184 5ebc9312 Christos Stathis
185 5fab761b Christos Stathis
    public void initialize(final AccountResource account, final Command callback) {
186 4ca9cb37 Christos Stathis
        Iterator<Folder> iter = account.getContainers().listIterator();
187 5ebc9312 Christos Stathis
        fetchFolder(iter, new Command() {
188 5ebc9312 Christos Stathis
            @Override
189 5ebc9312 Christos Stathis
            public void execute() {
190 5ebc9312 Christos Stathis
                rootDataProvider.getList().clear();
191 067bbb04 Christos Stathis
                Folder t = null;
192 067bbb04 Christos Stathis
                for (Folder c : account.getContainers()) {
193 067bbb04 Christos Stathis
                        if (c.isHome())
194 067bbb04 Christos Stathis
                            rootDataProvider.getList().add(0, c); //Pithos is always first
195 067bbb04 Christos Stathis
                        else if (c.isTrash())
196 067bbb04 Christos Stathis
                                t = c; //Keep trash for adding in the end
197 067bbb04 Christos Stathis
                        else
198 067bbb04 Christos Stathis
                                rootDataProvider.getList().add(c);
199 067bbb04 Christos Stathis
                }
200 067bbb04 Christos Stathis
                if (t != null)
201 067bbb04 Christos Stathis
                            rootDataProvider.getList().add(t);
202 5ebc9312 Christos Stathis
                selectionModel.setSelected(rootDataProvider.getList().get(0), true);
203 5fab761b Christos Stathis
                if (callback != null)
204 5fab761b Christos Stathis
                        callback.execute();
205 05cf9e5b Christos Stathis
            }
206 5ebc9312 Christos Stathis
        });
207 7c818c14 Christos Stathis
    }
208 875a0179 Christos Stathis
209 875a0179 Christos Stathis
    public Folder getSelection() {
210 875a0179 Christos Stathis
        return selectionModel.getSelectedObject();
211 875a0179 Christos Stathis
    }
212 b651e67f Christos Stathis
213 6acd4df3 Christos Stathis
    public void updateFolder(final Folder folder, boolean showfiles, final Command callback, final boolean openParent) {
214 b651e67f Christos Stathis
        if (dataProviderMap.get(folder) == null) {
215 cf49bbc9 Christos Stathis
            dataProviderMap.put(folder, new ListDataProvider<Folder>());
216 b651e67f Christos Stathis
        }
217 cf49bbc9 Christos Stathis
        final ListDataProvider<Folder> dataProvider = dataProviderMap.get(folder);
218 adb597b8 Christos Stathis
        fetchFolder(folder, dataProvider, showfiles, new Command() {
219 adb597b8 Christos Stathis
                        
220 adb597b8 Christos Stathis
                        @Override
221 adb597b8 Christos Stathis
                        public void execute() {
222 6acd4df3 Christos Stathis
                                if (openParent)
223 6acd4df3 Christos Stathis
                                        app.getFolderTreeView().openFolder(folder);
224 adb597b8 Christos Stathis
                                if (callback != null)
225 adb597b8 Christos Stathis
                                        callback.execute();
226 adb597b8 Christos Stathis
                        }
227 adb597b8 Christos Stathis
                });
228 b651e67f Christos Stathis
    }
229 b651e67f Christos Stathis
230 cf49bbc9 Christos Stathis
    public void fetchFolder(final Folder f, final ListDataProvider<Folder> dataProvider, final boolean showfiles, final Command callback) {
231 f5023f13 Christos Stathis
        String path = "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(f.getPrefix());
232 f5023f13 Christos Stathis
        GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, app.getApiPath(), f.getOwner(), path, f) {
233 b651e67f Christos Stathis
            @Override
234 f5023f13 Christos Stathis
            public void onSuccess(final Folder _result) {
235 f5023f13 Christos Stathis
                if (showfiles)
236 f5023f13 Christos Stathis
                    app.showFiles(_result);
237 2dd70d7a Christos Stathis
                int defaultSize = app.getFolderTreeView().tree.getDefaultNodeSize();
238 2dd70d7a Christos Stathis
                int size = _result.getSubfolders().size();
239 2dd70d7a Christos Stathis
                if (size > defaultSize)
240 2dd70d7a Christos Stathis
                        app.getFolderTreeView().tree.setDefaultNodeSize(size);
241 4ca9cb37 Christos Stathis
                Iterator<Folder> iter = new ArrayList<Folder>(_result.getSubfolders()).listIterator();
242 f5023f13 Christos Stathis
                fetchFolder(iter, new Command() {
243 b651e67f Christos Stathis
                    @Override
244 f5023f13 Christos Stathis
                    public void execute() {
245 cf49bbc9 Christos Stathis
                        dataProvider.getList().clear();
246 cf49bbc9 Christos Stathis
                        dataProvider.getList().addAll(_result.getSubfolders());
247 f5023f13 Christos Stathis
                        if (callback != null)
248 f5023f13 Christos Stathis
                                callback.execute();
249 b651e67f Christos Stathis
                    }
250 f5023f13 Christos Stathis
                });
251 f5023f13 Christos Stathis
            }
252 9539e23d Christos Stathis
253 f5023f13 Christos Stathis
            @Override
254 f5023f13 Christos Stathis
            public void onError(Throwable t) {
255 2f4ea617 Christos Stathis
                    if (retries >= MAX_RETRIES) {
256 2f4ea617 Christos Stathis
                        GWT.log("Error getting folder", t);
257 2f4ea617 Christos Stathis
                                        app.setError(t);
258 2f4ea617 Christos Stathis
                        if (t instanceof RestException)
259 2f4ea617 Christos Stathis
                            app.displayError("Error getting folder: " + ((RestException) t).getHttpStatusText());
260 2f4ea617 Christos Stathis
                        else
261 2f4ea617 Christos Stathis
                            app.displayError("System error fetching folder: " + t.getMessage());
262 2f4ea617 Christos Stathis
                    }
263 2f4ea617 Christos Stathis
                    else {//retry
264 2f4ea617 Christos Stathis
                            GWT.log("Retry " + retries);
265 2f4ea617 Christos Stathis
                            Scheduler.get().scheduleDeferred(this);
266 2f4ea617 Christos Stathis
                    }
267 b651e67f Christos Stathis
            }
268 f5023f13 Christos Stathis
269 f5023f13 Christos Stathis
                        @Override
270 f5023f13 Christos Stathis
                        protected void onUnauthorized(Response response) {
271 2f4ea617 Christos Stathis
                                if (retries >= MAX_RETRIES)
272 2f4ea617 Christos Stathis
                                        app.sessionExpired();
273 2f4ea617 Christos Stathis
                    else //retry
274 2f4ea617 Christos Stathis
                            Scheduler.get().scheduleDeferred(this);
275 f5023f13 Christos Stathis
                        }
276 f5023f13 Christos Stathis
        };
277 f5023f13 Christos Stathis
        getFolder.setHeader("X-Auth-Token", app.getToken());
278 f5023f13 Christos Stathis
        Scheduler.get().scheduleDeferred(getFolder);
279 b651e67f Christos Stathis
    }
280 6084aa02 Christos Stathis
}