com.userweave.components.navigation.breadcrumb.BreadcrumbPanel.java Source code

Java tutorial

Introduction

Here is the source code for com.userweave.components.navigation.breadcrumb.BreadcrumbPanel.java

Source

/*******************************************************************************
 * This file is part of UserWeave.
 *
 *     UserWeave is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     UserWeave is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with UserWeave.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2012 User Prompt GmbH | Psychologic IT Expertise
 *******************************************************************************/
package com.userweave.components.navigation.breadcrumb;

import java.util.Iterator;
import java.util.LinkedList;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.Model;

import com.userweave.components.callback.EntityEvent;
import com.userweave.components.callback.EventHandler;
import com.userweave.domain.EntityBase;
import com.userweave.domain.Project;
import com.userweave.domain.Study;

/**
 * Breadcrumb navigation. To Display the path,
 * recurse from an entity back to the first 
 * project.
 * 
 * @author opr
 *
 */
public class BreadcrumbPanel extends Panel {
    private static final long serialVersionUID = 1L;

    private class LabelFragment extends Fragment {
        private static final long serialVersionUID = 1L;

        public LabelFragment(String id, String displayValue) {
            super(id, "labelFragment", BreadcrumbPanel.this);

            add(new Label("label", displayValue));
        }
    }

    private class LinkFragment extends Fragment {
        private static final long serialVersionUID = 1L;

        public LinkFragment(String id, String displayValue, final EntityBase entity, final EventHandler callback) {
            super(id, "linkFragment", BreadcrumbPanel.this);

            @SuppressWarnings("serial")
            AjaxLink link = new AjaxLink("link") {
                @Override
                public void onClick(AjaxRequestTarget target) {
                    EntityEvent.Selected(target, entity).fire(callback);
                }
            };

            link.add(new Label("displayName", displayValue));

            add(link);
        }
    }

    /**
     * Stop recursion after this number of steps.
     */
    private static final int MAX_RECURSION_DEPTH = 10;

    /**
     * Default Constructor.
     * 
     * @param id
     *       Component id.
     * @param entity
     *       Entity to build navigation from.
     * @param callback
     *       Callback to fire, if a navigation link is clicked.
     */
    public BreadcrumbPanel(String id, EntityBase entity, final EventHandler callback) {
        super(id);

        init(entity, callback);
    }

    /**
     * Builds the navigation by recursing from the entity
     * through all parent entities.
     * 
     * @param entity
     *       Entity to start recursion from.
     * @param callback
     *       Callback to fire, when a link is clicked.
     */
    private void init(EntityBase entity, final EventHandler callback) {
        WebMarkupContainer homePageLinkContainer = new WebMarkupContainer("homePageLinkContainer");

        AjaxLink homePageLink = getHomePageLink(callback);

        homePageLinkContainer.add(homePageLink);

        add(homePageLinkContainer);

        if (entity == null) {
            add(new WebMarkupContainer("crumb"));

            homePageLinkContainer.add(new AttributeAppender("class", true, new Model("homePageActive"), " "));

            return;
        }

        LinkedList<BreadcrumbListItem> breadcrumbs = getBreadcrumbs(entity);

        RepeatingView rv = new RepeatingView("crumb");

        add(rv);

        Iterator<BreadcrumbListItem> iterator = breadcrumbs.iterator();

        while (iterator.hasNext()) {
            final BreadcrumbListItem item = iterator.next();

            Component next;

            StringBuilder cssClass = new StringBuilder("crumb");

            // last element is not clickable
            if (!iterator.hasNext()) {
                next = new LabelFragment(rv.newChildId(), item.getName());

                cssClass.append(" lastCrumb");
            } else {
                next = new LinkFragment(rv.newChildId(), item.getName(), item.getEntity(), callback);
            }

            rv.add(next);

            if (cssClass != null) {
                next.add(new AttributeAppender("class", true, new Model(cssClass), " "));
            }
        }
    }

    /**
     * Link to redirect to project overview.
     */
    @SuppressWarnings("serial")
    private AjaxLink getHomePageLink(final EventHandler callback) {
        AjaxLink homeLink = new AjaxLink("home") {
            @Override
            public void onClick(AjaxRequestTarget target) {
                EntityEvent.Selected(target, null).fire(callback);
            }
        };

        return homeLink;
    }

    private LinkedList<BreadcrumbListItem> getBreadcrumbs(EntityBase entity) {
        LinkedList<BreadcrumbListItem> breadcrumbs = new LinkedList<BreadcrumbListItem>();

        int depth = 0;

        EntityBase processedEntity = entity;

        // populates the breadcrumb list with breadcrumbs
        while (processedEntity != null && depth < MAX_RECURSION_DEPTH) {
            BreadcrumbListItem item;

            if (processedEntity instanceof Project) {
                Project project = (Project) processedEntity;

                item = new BreadcrumbListItem(project.getName(), processedEntity);

                breadcrumbs.addFirst(item);

                processedEntity = project.getParentProject();
            } else if (processedEntity instanceof Study) {
                Study study = (Study) processedEntity;

                item = new BreadcrumbListItem(study.getName(), processedEntity);

                breadcrumbs.addFirst(item);

                processedEntity = ((Study) processedEntity).getParentProject();
            } else {
                processedEntity = null;
            }

            depth++;
        }

        return breadcrumbs;
    }
}