001: /*
002: * $Id: WicketTagComponentResolver.java,v 1.4 2005/01/18 08:04:29 jonathanlocke
003: * Exp $ $Revision: 458916 $ $Date: 2006-02-01 13:32:17 +0100 (Wed, 01 Feb 2006) $
004: *
005: * ==============================================================================
006: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007: * use this file except in compliance with the License. You may obtain a copy of
008: * the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations under
016: * the License.
017: */
018: package wicket.markup.resolver;
019:
020: import wicket.Component;
021: import wicket.MarkupContainer;
022: import wicket.Page;
023: import wicket.markup.ComponentTag;
024: import wicket.markup.IScopedComponent;
025: import wicket.markup.MarkupStream;
026: import wicket.markup.html.panel.Panel;
027:
028: /**
029: * Implement a component resolver which walks up the component tree until a Page
030: * or Panel and tries to find a component with a matching wicket id, effectivly
031: * providing something like scoping for wicket id resolution.
032: * <p>
033: * Note: This resolver is not activated by default. It has to be added by means of
034: * <code>Application.getComponentResolvers().add(new InheritComponentResolver())
035: * to be activated.</code>.
036: * <p>
037: * Example:
038: * <pre>
039: * MyPage()
040: * {
041: * add(new Label("hidden-by-cont1","hidden"));
042: * add(new Label("global","can be everywhere")); //the intresting case
043: *
044: * WebMarkupContainer cont1 = new WebMarkupContainer("cont1");
045: * add(cont1);
046: *
047: * cont1.add(new Label("hidden-by-cont1","cont1 hides"));
048: * cont1.add(new Label("same-id","cont1 same-id"));
049: *
050: * WebMarkupContainer cont2 = new WebMarkupContainer("cont2");
051: * add(cont2);
052: *
053: * cont2.add(new Label("same-id","cont2 same-id"));
054: * }
055: * </pre>
056: * <pre>
057: * HTML:
058: * <html>
059: * <body>
060: * <span wicket:id="hidden-by-cont1">Prints: hidden</span>
061: * <div wicket:id="cont1">
062: * <span wicket:id="hidden-by-cont1">Prints: cont1 hides</span>
063: * <span wicket:id="same-id">Prints: cont1 same-id</span>
064: * </div>
065: *
066: * <div wicket:id="cont2">
067: * <span wicket:id="global">Prints: can be everywhere</span>
068: * <span wicket:id="same-id">Prints: cont2 same-id</span>
069: * </div>
070: * </pre>
071: *
072: * So you can use the same ids in the same page. If the containing containers
073: * are not in the same hierarchy-line nothing changes. A comp with the same id
074: * hides the one of the parent-container with the same id.
075: *
076: * @see wicket.MarkupContainer#isTransparentResolver()
077: * @see wicket.markup.resolver.ParentResolver
078: *
079: * @author Christian Essl
080: * @author Juergen Donnerstag
081: */
082: public class ScopedComponentResolver implements IComponentResolver {
083: private static final long serialVersionUID = 1L;
084:
085: /**
086: * Construct.
087: */
088: public ScopedComponentResolver() {
089: super ();
090: }
091:
092: /**
093: *
094: * @see wicket.markup.resolver.IComponentResolver#resolve(wicket.MarkupContainer,
095: * wicket.markup.MarkupStream, wicket.markup.ComponentTag)
096: */
097: public boolean resolve(final MarkupContainer container,
098: final MarkupStream markupStream, final ComponentTag tag) {
099: // Try to find the component with the parent component.
100: final String id = tag.getId();
101: MarkupContainer parent = container;
102:
103: while (!(parent instanceof Page) && !(parent instanceof Panel)
104: && (parent != null)) {
105: parent = parent.getParent();
106: if (parent == null) {
107: return false;
108: }
109:
110: final Component component = parent.get(id);
111: if ((component != null)
112: && (component instanceof IScopedComponent)) {
113: IScopedComponent sc = (IScopedComponent) component;
114: if (sc.isRenderableInSubContainers()) {
115: component.render(markupStream);
116: return true;
117: }
118: }
119: }
120:
121: return false;
122: }
123: }
|