/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.isis.viewer.wicket.ui.components.bookmarkedpages; import org.apache.wicket.Component; import org.apache.wicket.Page; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptReferenceHeaderItem; import org.apache.wicket.markup.head.OnDomReadyHeaderItem; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.image.Image; import org.apache.wicket.markup.html.link.AbstractLink; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.resource.CssResourceReference; import org.apache.wicket.request.resource.JavaScriptResourceReference; import org.apache.wicket.request.resource.ResourceReference; import org.apache.wicket.util.string.Strings; import org.apache.isis.core.metamodel.adapter.oid.RootOid; import org.apache.isis.core.metamodel.spec.ObjectSpecId; import org.apache.isis.core.metamodel.spec.ObjectSpecification; import org.apache.isis.core.runtime.persistence.ObjectNotFoundException; import org.apache.isis.viewer.wicket.model.models.BookmarkTreeNode; import org.apache.isis.viewer.wicket.model.models.BookmarkedPagesModel; import org.apache.isis.viewer.wicket.model.models.ImageResourceCache; import org.apache.isis.viewer.wicket.model.models.PageType; import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry; import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract; import org.apache.isis.viewer.wicket.ui.util.CssClassAppender; import org.apache.isis.viewer.wicket.ui.util.Links; public class BookmarkedPagesPanel extends PanelAbstract<BookmarkedPagesModel> { private static final long serialVersionUID = 1L; private static final String ID_BOOKMARK_LIST = "bookmarkList"; private static final String ID_BOOKMARKS_HELP_TEXT = "helpText"; private static final String ID_BOOKMARKED_PAGE_LINK = "bookmarkedPageLink"; private static final String ID_CLEAR_BOOKMARK_LINK = "clearBookmarkLink"; private static final String ID_BOOKMARKED_PAGE_ITEM = "bookmarkedPageItem"; private static final String ID_BOOKMARKED_PAGE_TITLE = "bookmarkedPageTitle"; private static final String ID_BOOKMARKED_PAGE_ICON = "bookmarkedPageImage"; private static final String CLEAR_BOOKMARKS = "clearBookmarks"; private static final JavaScriptResourceReference SLIDE_PANEL_JS = new JavaScriptResourceReference(BookmarkedPagesPanel.class, "slide-panel.js"); @com.google.inject.Inject private PageClassRegistry pageClassRegistry; public BookmarkedPagesPanel(final String id, final BookmarkedPagesModel bookmarkedPagesModel) { super(id, bookmarkedPagesModel); buildGui(); } @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); response.render(OnDomReadyHeaderItem.forScript("$('.bookmarkRibbon').height($('.navbar.navbar-fixed-top').height()-5);")); } private void buildGui() { final BookmarkedPagesModel bookmarkedPagesModel = getModel(); Component helpText = addHelpText(bookmarkedPagesModel); addOrReplace(helpText); final WebMarkupContainer container = new WebMarkupContainer(ID_BOOKMARK_LIST) { private static final long serialVersionUID = 1L; @Override public void renderHead(IHeaderResponse response) { response.render(CssHeaderItem.forReference(new CssResourceReference(BookmarkedPagesPanel.class, "BookmarkedPagesPanel.css"))); response.render(JavaScriptReferenceHeaderItem.forReference(SLIDE_PANEL_JS)); } }; // allow to be updated by AjaxLink container.setOutputMarkupId(true); add(container); final AjaxLink<Void> clearAllBookmarksLink = new AjaxLink<Void>(CLEAR_BOOKMARKS){ private static final long serialVersionUID = 1L; @Override public void onClick(AjaxRequestTarget target) { BookmarkedPagesPanel.this.getModel().clear(); setEnabled(false); target.add(container, this); } }; clearAllBookmarksLink.setOutputMarkupId(true); add(clearAllBookmarksLink); clearAllBookmarksLink.setOutputMarkupId(true); if(getModel().isEmpty()) { clearAllBookmarksLink.setVisible(false); } final ListView<BookmarkTreeNode> listView = new ListView<BookmarkTreeNode>(ID_BOOKMARKED_PAGE_ITEM, bookmarkedPagesModel) { private static final long serialVersionUID = 1L; @Override protected void populateItem(ListItem<BookmarkTreeNode> item) { final BookmarkTreeNode node = item.getModelObject(); try { final PageType pageType = node.getPageType(); final Class<? extends Page> pageClass = pageClassRegistry.getPageClass(pageType); final AjaxLink<Object> clearBookmarkLink = new AjaxLink<Object>(ID_CLEAR_BOOKMARK_LINK) { private static final long serialVersionUID = 1L; @Override public void onClick(AjaxRequestTarget target) { bookmarkedPagesModel.remove(node); if(bookmarkedPagesModel.isEmpty()) { permanentlyHide(CLEAR_BOOKMARKS); } target.add(container, clearAllBookmarksLink); } }; if(node.getDepth() == 0) { clearBookmarkLink.add(new CssClassAppender("clearBookmark")); } else { clearBookmarkLink.setEnabled(true); } item.add(clearBookmarkLink); PageParameters pageParameters = node.getPageParameters(); final AbstractLink link = Links.newBookmarkablePageLink(ID_BOOKMARKED_PAGE_LINK, pageParameters, pageClass); ObjectSpecification objectSpec = null; RootOid oid = node.getOidNoVer(); if(oid != null) { ObjectSpecId objectSpecId = oid.getObjectSpecId(); objectSpec = getSpecificationLoader().lookupBySpecId(objectSpecId); } final ResourceReference imageResource = imageCache.resourceReferenceForSpec(objectSpec); final Image image = new Image(ID_BOOKMARKED_PAGE_ICON, imageResource) { private static final long serialVersionUID = 1L; @Override protected boolean shouldAddAntiCacheParameter() { return false; } }; link.addOrReplace(image); String title = node.getTitle(); final Label label = new Label(ID_BOOKMARKED_PAGE_TITLE, title); link.add(label); item.add(link); if(bookmarkedPagesModel.isCurrent(pageParameters)) { item.add(new CssClassAppender("disabled")); } item.add(new CssClassAppender("bookmarkDepth" + node.getDepth())); } catch(ObjectNotFoundException ex) { // ignore // this is a partial fix for an infinite redirect loop. // should be a bit smarter here, though; see ISIS-596. } } }; container.add(listView); } protected Component addHelpText(final BookmarkedPagesModel bookmarkedPagesModel) { IModel<String> helpTextModel = new AbstractReadOnlyModel<String>() { @Override public String getObject() { return bookmarkedPagesModel.isEmpty() ? "You have no bookmarks!" : ""; } }; Label helpText = new Label(ID_BOOKMARKS_HELP_TEXT, helpTextModel) { @Override protected void onConfigure() { super.onConfigure(); setVisible(!Strings.isEmpty(getDefaultModelObjectAsString())); } }; helpText.setOutputMarkupPlaceholderTag(true); return helpText; } // /////////////////////////////////////////////// // Dependency Injection // /////////////////////////////////////////////// @com.google.inject.Inject private ImageResourceCache imageCache; }