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

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

Added a PID-link (if PID available) to the VCR details page. Fixes #590

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