001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.extensions.breadcrumb; 018 019import java.util.ArrayList; 020import java.util.List; 021 022/** 023 * Default breadcrumb model implementation that should be good for 99% of the use cases out there. 024 * 025 * @author eelcohillenius 026 */ 027public class DefaultBreadCrumbsModel implements IBreadCrumbModel 028{ 029 private static final long serialVersionUID = 1L; 030 031 /** The currently active participant, if any (possibly null). */ 032 private IBreadCrumbParticipant activeParticipant = null; 033 034 /** Holds the current list of crumbs. */ 035 private final List<IBreadCrumbParticipant> crumbs = new ArrayList<>(); 036 037 /** listeners utility. */ 038 private final BreadCrumbModelListenerSupport listenerSupport = new BreadCrumbModelListenerSupport(); 039 040 /** 041 * Construct. 042 */ 043 public DefaultBreadCrumbsModel() 044 { 045 } 046 047 /** 048 * @see org.apache.wicket.extensions.breadcrumb.IBreadCrumbModel#addListener(org.apache.wicket.extensions.breadcrumb.IBreadCrumbModelListener) 049 */ 050 @Override 051 public final void addListener(final IBreadCrumbModelListener listener) 052 { 053 listenerSupport.addListener(listener); 054 } 055 056 /** 057 * @see org.apache.wicket.extensions.breadcrumb.IBreadCrumbModel#allBreadCrumbParticipants() 058 */ 059 @Override 060 public final List<IBreadCrumbParticipant> allBreadCrumbParticipants() 061 { 062 return crumbs; 063 } 064 065 /** 066 * @see org.apache.wicket.extensions.breadcrumb.IBreadCrumbModel#getActive() 067 */ 068 @Override 069 public IBreadCrumbParticipant getActive() 070 { 071 return activeParticipant; 072 } 073 074 /** 075 * @see org.apache.wicket.extensions.breadcrumb.IBreadCrumbModel#removeListener(org.apache.wicket.extensions.breadcrumb.IBreadCrumbModelListener) 076 */ 077 @Override 078 public final void removeListener(final IBreadCrumbModelListener listener) 079 { 080 listenerSupport.removeListener(listener); 081 } 082 083 /** 084 * @see org.apache.wicket.extensions.breadcrumb.IBreadCrumbModel#setActive(org.apache.wicket.extensions.breadcrumb.IBreadCrumbParticipant) 085 */ 086 @Override 087 public final void setActive(final IBreadCrumbParticipant breadCrumbParticipant) 088 { 089 // see if the bread crumb was already added, and if so, 090 // clean up the stack after (on top of) this bred crumb 091 // and notify listeners of the removal 092 int len = crumbs.size() - 1; 093 int i = len; 094 while (i > -1) 095 { 096 IBreadCrumbParticipant temp = crumbs.get(i); 097 098 // if we found the bread crumb 099 if (breadCrumbParticipant.equals(temp)) 100 { 101 // remove the bread crumbs after this one 102 int j = len; 103 while (j > i) 104 { 105 // remove and fire event 106 IBreadCrumbParticipant removed = crumbs.remove(j--); 107 listenerSupport.fireBreadCrumbRemoved(removed); 108 } 109 110 // activate the bread crumb participant 111 activate(breadCrumbParticipant); 112 113 // we're done; the provided bread crumb is on top 114 // and the content is replaced, so just return this function 115 return; 116 } 117 118 i--; 119 } 120 121 // arriving here means we weren't able to find the bread crumb 122 // add the new crumb 123 crumbs.add(breadCrumbParticipant); 124 125 // and notify listeners 126 listenerSupport.fireBreadCrumbAdded(breadCrumbParticipant); 127 128 // activate the bread crumb participant 129 activate(breadCrumbParticipant); 130 } 131 132 /** 133 * Activates the bread crumb participant. 134 * 135 * @param breadCrumbParticipant 136 * The participant to activate 137 */ 138 protected final void activate(final IBreadCrumbParticipant breadCrumbParticipant) 139 { 140 // get old value 141 IBreadCrumbParticipant previousParticipant = activeParticipant; 142 143 // and set the provided participant as the active one 144 activeParticipant = breadCrumbParticipant; 145 146 // fire bread crumb activated event 147 listenerSupport.fireBreadCrumbActivated(previousParticipant, breadCrumbParticipant); 148 149 // signal the bread crumb participant that it is selected as the 150 // currently active one 151 breadCrumbParticipant.onActivate(previousParticipant); 152 } 153}