source: VirtualCollectionRegistry/tags/VirtualCollectionRegistry-0.4.0-alpha2/VirtualCollectionRegistry/src/main/java/eu/clarin/cmdi/virtualcollectionregistry/gui/pages/VirtualCollectionDetailsPage.java @ 5557

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

tag for VCR alpha 2

  • 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.