source: VirtualCollectionRegistry/trunk/VirtualCollectionRegistry/src/main/java/eu/clarin/cmdi/virtualcollectionregistry/gui/pages/VirtualCollectionDetailsPage.java @ 5504

Last change on this file since 5504 was 5504, checked in by Twan Goosen, 10 years ago

Access to view or edit page for any collection allowed to admin
Refs #589

  • Property svn:eol-style set to native
File size: 15.5 KB
Line 
1package eu.clarin.cmdi.virtualcollectionregistry.gui.pages;
2
3import eu.clarin.cmdi.virtualcollectionregistry.gui.Application;
4import eu.clarin.cmdi.virtualcollectionregistry.gui.DateConverter;
5import eu.clarin.cmdi.virtualcollectionregistry.gui.DetachableVirtualCollectionModel;
6import eu.clarin.cmdi.virtualcollectionregistry.gui.VolatileEntityModel;
7import eu.clarin.cmdi.virtualcollectionregistry.gui.border.AjaxToggleBorder;
8import eu.clarin.cmdi.virtualcollectionregistry.model.Creator;
9import eu.clarin.cmdi.virtualcollectionregistry.model.Resource;
10import eu.clarin.cmdi.virtualcollectionregistry.model.VirtualCollection;
11import eu.clarin.cmdi.virtualcollectionregistry.model.VirtualCollection.Type;
12import java.sql.Date;
13import java.util.Collection;
14import java.util.Iterator;
15import java.util.LinkedList;
16import java.util.List;
17import java.util.Locale;
18import org.apache.wicket.Component;
19import org.apache.wicket.IPageMap;
20import org.apache.wicket.Page;
21import org.apache.wicket.PageParameters;
22import org.apache.wicket.PageReference;
23import org.apache.wicket.Session;
24import org.apache.wicket.authorization.UnauthorizedActionException;
25import org.apache.wicket.behavior.AbstractBehavior;
26import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
27import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
28import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
29import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
30import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
31import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
32import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
33import org.apache.wicket.markup.ComponentTag;
34import org.apache.wicket.markup.html.basic.Label;
35import org.apache.wicket.markup.html.basic.MultiLineLabel;
36import org.apache.wicket.markup.html.border.Border;
37import org.apache.wicket.markup.html.link.ExternalLink;
38import org.apache.wicket.markup.html.link.Link;
39import org.apache.wicket.markup.html.link.PopupSettings;
40import org.apache.wicket.markup.html.list.ListItem;
41import org.apache.wicket.markup.html.list.ListView;
42import org.apache.wicket.markup.html.list.OddEvenListItem;
43import org.apache.wicket.markup.repeater.Item;
44import org.apache.wicket.model.ComponentPropertyModel;
45import org.apache.wicket.model.CompoundPropertyModel;
46import org.apache.wicket.model.IModel;
47import org.apache.wicket.model.Model;
48import org.apache.wicket.model.PropertyModel;
49import org.apache.wicket.util.convert.IConverter;
50import org.apache.wicket.util.string.Strings;
51
52@SuppressWarnings("serial")
53public class VirtualCollectionDetailsPage extends BasePage {
54
55    public static final String PARAM_VC_ID = "id";
56    public static final String PARAM_BACK_PAGE_ID = "backPage";
57    public static final String PARAM_BACK_PAGE_VERSION = "backPageVersion";
58    public static final String PARAM_BACK_PAGE_PAGEMAP_NAME = "backPageMapName";
59    private static final String CSS_CLASS = "collectionDetails";
60    private static final IConverter convDate = new DateConverter();
61    private final HideIfEmptyBehavior hideIfEmpty = new HideIfEmptyBehavior();
62
63    private static final IConverter convEnum = new IConverter() {
64        @Override
65        public String convertToString(Object o, Locale locale) {
66            final Enum<?> enumObj = (Enum<?>) o;
67            final String key
68                    = enumObj.getDeclaringClass().getSimpleName() + "."
69                    + enumObj.name();
70            final String value = Application.get().getResourceSettings()
71                    .getLocalizer().getString(key, null);
72            return Strings.escapeMarkup(value).toString();
73        }
74
75        @Override
76        public Object convertToObject(String s, Locale locale) {
77            return null;
78        }
79    };
80
81    /*
82     * Actually, we really want the behavior to hide the component on
83     * the beforeRender() call, but we always get an exception from Wicket
84     * that we are not supposed to change the page hierarchy anymore. This
85     * class is a hack to avoid this exception.
86     */
87    private static final class HideIfEmptyBehavior extends AbstractBehavior {
88
89        private final List<Component> components = new LinkedList<Component>();
90
91        @Override
92        public void bind(Component component) {
93            super.bind(component);
94            components.add(component);
95        }
96
97        public void hideEmptyComponents() {
98            for (Component component : components) {
99                Object obj = component.getDefaultModelObject();
100                if (obj == null) {
101                    component.setVisible(false);
102                } else {
103                    if (obj instanceof Collection<?>) {
104                        if (((Collection<?>) obj).isEmpty()) {
105                            component.setVisible(false);
106                        }
107                    }
108                }
109            }
110        }
111
112        @Override
113        public void cleanup() {
114            super.cleanup();
115            components.clear();
116        }
117    } // class VirtualCollectionDetailsPage.HideIfEmptyBehavior
118
119    private static class CustomLabel extends Label {
120
121        public CustomLabel(String id) {
122            super(id);
123        }
124
125        @Override
126        public IConverter getConverter(Class<?> type) {
127            if (VirtualCollection.Type.class.isAssignableFrom(type)
128                    || VirtualCollection.Purpose.class.isAssignableFrom(type)
129                    || VirtualCollection.Reproducibility.class.isAssignableFrom(type)) {
130                return convEnum;
131            }
132            if (Date.class.isAssignableFrom(type)) {
133                return convDate;
134            }
135            return super.getConverter(type);
136        }
137    } // class VirtualCollectionDetailsPage.TypeLabel
138
139    public VirtualCollectionDetailsPage(PageParameters params) {
140        this(getVirtualCollectionModel(params), getPageReference(params));
141    }
142
143    public VirtualCollectionDetailsPage(final IModel<VirtualCollection> model, final PageReference previousPage) {
144        super(new CompoundPropertyModel<VirtualCollection>(model));
145        if (model == null) {
146            setResponsePage(Application.get().getHomePage());
147        } else {
148            checkAccess(model.getObject());
149        }
150
151        final Link<Void> backLink = new Link<Void>("back") {
152            @Override
153            public void onClick() {
154                if (previousPage == null) {
155                    setResponsePage(getApplication().getHomePage());
156                } else {
157                    setResponsePage(previousPage.getPage());
158                }
159            }
160        };
161        add(backLink);
162
163        addGeneralProperties(model);
164        addCreators();
165        addResources(model);
166        addGeneratedBy(model);
167    }
168
169    private void addGeneralProperties(final IModel<VirtualCollection> model) {
170        final Border general = new AjaxToggleBorder("generalBorder",
171                new Model<String>("General"), CSS_CLASS);
172        add(general);
173        general.add(new Label("name"));
174        general.add(new CustomLabel("type"));
175        general.add(new CustomLabel("creationDate"));
176        general.add(new MultiLineLabel("description").add(hideIfEmpty));
177        general.add(new CustomLabel("purpose").add(hideIfEmpty));
178        general.add(new CustomLabel("reproducibility").add(hideIfEmpty));
179        general.add(new Label("reproducibilityNotice").add(hideIfEmpty));
180
181        final ExternalLink pidLink = new ExternalLink("pidLink", new PropertyModel<String>(model, "persistentIdentifier.actionableURI"));
182        pidLink.add(new Label("persistentIdentifier.URI"));
183        pidLink.add(hideIfEmpty);
184        general.add(pidLink);
185
186        addKeywords(general);
187    }
188
189    private void addKeywords(final Border general) {
190        final ListView<String> keywords = new ListView<String>("keywords") {
191            @Override
192            protected void populateItem(ListItem<String> item) {
193                item.add(new Label("keyword", item.getModelObject()));
194            }
195        };
196        keywords.add(hideIfEmpty);
197        general.add(keywords);
198    }
199
200    private void addCreators() {
201        final Border creators = new AjaxToggleBorder("creatorsBorder",
202                new Model<String>("Creators"), CSS_CLASS);
203        add(creators);
204        creators.add(new ListView<Creator>("creators") {
205            @Override
206            protected void populateItem(ListItem<Creator> item) {
207                item.add(new Label("person"));
208                item.add(new MultiLineLabel("address").add(hideIfEmpty));
209                item.add(new Label("organisation").add(hideIfEmpty));
210                item.add(new Label("email").add(hideIfEmpty));
211                item.add(new Label("telephone").add(hideIfEmpty));
212                final IModel<String> siteModel
213                        = new ComponentPropertyModel<String>("website");
214                item.add(new ExternalLink("website", siteModel, siteModel)
215                        .setPopupSettings(new PopupSettings())
216                        .add(hideIfEmpty));
217                item.add(new Label("role").add(hideIfEmpty));
218            }
219
220            @Override
221            protected IModel<Creator> getListItemModel(
222                    IModel<? extends List<Creator>> listViewModel, int index) {
223                final List<Creator> creators = listViewModel.getObject();
224                return new CompoundPropertyModel<Creator>(
225                        new VolatileEntityModel<>(creators.get(index)));
226            }
227
228            @Override
229            protected ListItem<Creator> newItem(int index) {
230                final IModel<Creator> model
231                        = getListItemModel(getModel(), index);
232                return new OddEvenListItem<Creator>(index, model) {
233                    @Override
234                    protected void onComponentTag(ComponentTag tag) {
235                        super.onComponentTag(tag);
236                        if (getIndex() == 0) {
237                            tag.append("class", "first", " ");
238                        }
239                    }
240                };
241            }
242        });
243    }
244
245    private void addResources(final IModel<VirtualCollection> model) {
246        final Border resources = new AjaxToggleBorder("resourcesBorder",
247                new Model<String>("Resources"), CSS_CLASS + " resources");
248        add(resources);
249
250        @SuppressWarnings("rawtypes")
251        final IColumn[] cols = new IColumn[2];
252        cols[1] = new PropertyColumn<Resource>(
253                Model.of("Type"), "type") {
254                    @Override
255                    public void populateItem(Item<ICellPopulator<Resource>> item,
256                            String componentId, IModel<Resource> model) {
257                        final Resource.Type type = model.getObject().getType();
258                        item.add(new Label(componentId,
259                                        convEnum.convertToString(type, getLocale())));
260                    }
261
262                    @Override
263                    public String getCssClass() {
264                        return "type";
265                    }
266                   
267                   
268                };
269        cols[0] = new AbstractColumn<Resource>(Model.of("Reference")) {
270
271            @Override
272            public void populateItem(Item<ICellPopulator<Resource>> item, String componentId, IModel<Resource> rowModel) {
273                item.add(new ReferenceLinkPanel(componentId, rowModel));
274            }
275
276        };
277
278        final SortableDataProvider<Resource> resourcesProvider = new SortableDataProvider<Resource>() {
279            @Override
280            public Iterator<? extends Resource>
281                    iterator(int first, int count) {
282                return model.getObject().getResources().listIterator(first);
283            }
284
285            @Override
286            public IModel<Resource> model(Resource resource) {
287                return new VolatileEntityModel<Resource>(resource);
288            }
289
290            @Override
291            public int size() {
292                return model.getObject().getResources().size();
293            }
294        };
295
296        final DataTable<Resource> resourcesTable
297                = new AjaxFallbackDefaultDataTable<Resource>("resourcesTable",
298                        cols, resourcesProvider, 64);
299        resources.add(resourcesTable);
300        resources.setVisible(model.getObject().getType() == Type.EXTENSIONAL);
301    }
302
303    private void addGeneratedBy(final IModel<VirtualCollection> model) {
304        final Border generated = new AjaxToggleBorder("generatedByBorder",
305                new Model<String>("Intensional Collection Query"), CSS_CLASS);
306        add(generated);
307        generated.add(new Label("generatedBy.description"));
308        generated.add(new Label("generatedBy.uri").add(hideIfEmpty));
309        generated.add(new Label("generatedBy.query.profile").add(hideIfEmpty));
310        generated.add(new Label("generatedBy.query.value").add(hideIfEmpty));
311        generated.setVisible(model.getObject().getType() == Type.INTENSIONAL);
312    }
313
314    private static IModel<VirtualCollection> getVirtualCollectionModel(PageParameters params) {
315        final Long collectionId = params.getAsLong(PARAM_VC_ID);
316        if (collectionId == null) {
317            Session.get().error("Collection could not be retrieved, id not provided");
318            return null;
319        }
320        return new DetachableVirtualCollectionModel(collectionId);
321    }
322
323    private static PageReference getPageReference(PageParameters params) {
324        final Integer pageId = params.getAsInteger(PARAM_BACK_PAGE_ID);
325        final Integer pageVersion = params.getAsInteger(PARAM_BACK_PAGE_VERSION);
326        final String pageMap = params.getString(PARAM_BACK_PAGE_PAGEMAP_NAME);
327        if (pageId != null && pageVersion != null) {
328            for (IPageMap map : Session.get().getPageMaps()) {
329                if (pageMap == null && map.getName() == null || pageMap != null && pageMap.equals(map.getName())) {
330                    final Page page = map.get(pageId, pageVersion);
331                    if (page != null) {
332                        return page.getPageReference();
333                    }
334                }
335            }
336        }
337        return null;
338    }
339
340    public static PageParameters createPageParameters(VirtualCollection vc, PageReference pageReference) {
341        final PageParameters params = new PageParameters();
342        params.put(VirtualCollectionDetailsPage.PARAM_VC_ID, vc.getId());
343
344        if (pageReference != null) {
345            params.put(VirtualCollectionDetailsPage.PARAM_BACK_PAGE_ID, pageReference.getPageNumber());
346            params.put(VirtualCollectionDetailsPage.PARAM_BACK_PAGE_VERSION, pageReference.getPageVersion());
347            if (pageReference.getPageMapName() != null) {
348                params.put(VirtualCollectionDetailsPage.PARAM_BACK_PAGE_PAGEMAP_NAME, pageReference.getPageMapName());
349            }
350        }
351        return params;
352    }
353
354    /**
355     *
356     * @param vc collection to check for
357     * @throws UnauthorizedActionException if the VC is private and the current
358     * user is not the owner
359     */
360    private void checkAccess(final VirtualCollection vc) throws UnauthorizedActionException {
361        if (vc.isPrivate()
362                && !isUserAdmin()
363                && !getSession().isCurrentUser(vc.getOwner())) {
364            // user trying to access other user's collection
365            throw new UnauthorizedActionException(this, Component.RENDER);
366        }
367    }
368
369    @Override
370    protected void onBeforeRender() {
371        super.onBeforeRender();
372        hideIfEmpty.hideEmptyComponents();
373    }
374
375} // class VirtualCollectionDetailsPage
Note: See TracBrowser for help on using the repository browser.