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 */ 017/** 018 * 019 */ 020package org.apache.wicket.extensions.breadcrumb.panel; 021 022import org.apache.wicket.Component; 023import org.apache.wicket.MarkupContainer; 024import org.apache.wicket.extensions.breadcrumb.IBreadCrumbParticipant; 025import org.apache.wicket.markup.html.panel.Panel; 026import org.apache.wicket.util.visit.IVisit; 027import org.apache.wicket.util.visit.IVisitor; 028 029/** 030 * Base implementation for {@link Panel}/ {@link Component} based {@link IBreadCrumbParticipant} 031 * that decouples the implementation from the actual panel class. 032 * 033 * @author eelcohillenius 034 */ 035public abstract class BreadCrumbParticipantDelegate implements IBreadCrumbParticipant 036{ 037 private static final long serialVersionUID = 1L; 038 039 private final Component component; 040 041 /** 042 * Construct. 043 * 044 * @param component 045 */ 046 public BreadCrumbParticipantDelegate(final Component component) 047 { 048 if (component == null) 049 { 050 throw new IllegalArgumentException("component must be not null"); 051 } 052 this.component = component; 053 } 054 055 /** 056 * @see org.apache.wicket.extensions.breadcrumb.IBreadCrumbParticipant#getComponent() 057 */ 058 @Override 059 public Component getComponent() 060 { 061 return component; 062 } 063 064 /** 065 * If the previous participant is not null (and a component, which it should be), replace that 066 * component on it's parent with this one. 067 * 068 * @see org.apache.wicket.extensions.breadcrumb.IBreadCrumbParticipant#onActivate(org.apache.wicket.extensions.breadcrumb.IBreadCrumbParticipant) 069 */ 070 @Override 071 public void onActivate(final IBreadCrumbParticipant previous) 072 { 073 if (previous != null) 074 { 075 MarkupContainer parent = previous.getComponent().getParent(); 076 if (parent != null) 077 { 078 final String thisId = component.getId(); 079 if (parent.get(thisId) != null) 080 { 081 parent.replace(component); 082 } 083 else 084 { 085 // try to search downwards to match the id 086 // NOTE unfortunately, we can't rely on the path pre 2.0 087 Component c = parent.visitChildren(new IVisitor<Component, Component>() 088 { 089 @Override 090 public void component(final Component component, 091 final IVisit<Component> visit) 092 { 093 if (component.getId().equals(thisId)) 094 { 095 visit.stop(component); 096 } 097 } 098 }); 099 if (c == null) 100 { 101 // not found... do a reverse search (upwards) 102 c = parent.visitParents(MarkupContainer.class, 103 new IVisitor<MarkupContainer, Component>() 104 { 105 @Override 106 public void component(final MarkupContainer component, 107 final IVisit<Component> visit) 108 { 109 if (component.getId().equals(thisId)) 110 { 111 visit.stop(component); 112 } 113 } 114 }); 115 } 116 117 // replace if found 118 if (c != null) 119 { 120 c.replaceWith(component); 121 } 122 } 123 } 124 } 125 else if (component.getParent() != null) 126 { 127 component.getParent().replace(component); 128 } 129 } 130}