001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry.util;
016
017 import java.io.Serializable;
018
019 import org.apache.hivemind.util.Defense;
020 import org.apache.tapestry.IComponent;
021 import org.apache.tapestry.INamespace;
022 import org.apache.tapestry.IPage;
023 import org.apache.tapestry.IRequestCycle;
024
025 /**
026 * The ComponentAddress class contains the path to a component, allowing it to locate an instance of
027 * that component in a different {@link org.apache.tapestry.IRequestCycle}.
028 * <p>
029 * This class needs to be used mostly when working with components accessed via the
030 * {@link org.apache.tapestry.IRender}interface. It allows those components to serialize and pass
031 * as a service parameter information about what component they have to talk to if control returns
032 * back to them.
033 * <p>
034 * This situation often occurs when the component used via IRender contains Direct or Action links.
035 *
036 * @author mindbridge
037 * @since 2.2
038 */
039 public class ComponentAddress implements Serializable
040 {
041 private static final long serialVersionUID = 533068199722072804L;
042
043 private String _pageName;
044
045 private String _idPath;
046
047 /**
048 * Creates a new ComponentAddress object that carries the identification information of the
049 * given component (the page name and the ID path).
050 *
051 * @param component
052 * the component to get the address of
053 */
054 public ComponentAddress(IComponent component)
055 {
056 this(component.getPage().getPageName(), component.getIdPath());
057 }
058
059 /**
060 * Creates a new ComponentAddress using the given Page Name and ID Path.
061 *
062 * @param pageName
063 * the name of the page that contains the component
064 * @param idPath
065 * the ID Path of the component (which may be null)
066 */
067 public ComponentAddress(String pageName, String idPath)
068 {
069 Defense.notNull(pageName, "pageName");
070
071 _pageName = pageName;
072 _idPath = idPath;
073 }
074
075 /**
076 * Creates a new ComponentAddress using the given Page Name and ID Path relative on the provided
077 * Namespace.
078 *
079 * @param namespace
080 * the namespace of the page that contains the component
081 * @param pageName
082 * the name of the page that contains the component
083 * @param idPath
084 * the ID Path of the component
085 */
086 public ComponentAddress(INamespace namespace, String pageName, String idPath)
087 {
088 this(namespace.constructQualifiedName(pageName), idPath);
089 }
090
091 /**
092 * Finds a component with the current address using the given RequestCycle.
093 *
094 * @param cycle
095 * the RequestCycle to use to locate the component
096 * @return IComponent a component that has been initialized for the given RequestCycle
097 */
098 public IComponent findComponent(IRequestCycle cycle)
099 {
100 IPage objPage = cycle.getPage(_pageName);
101 return objPage.getNestedComponent(_idPath);
102 }
103
104 /**
105 * Returns the idPath of the component.
106 *
107 * @return String the ID path of the component, or null if the address references a page, not a
108 * component within a page.
109 */
110 public String getIdPath()
111 {
112 return _idPath;
113 }
114
115 /**
116 * Returns the Page Name of the component.
117 *
118 * @return String the Page Name of the component
119 */
120 public String getPageName()
121 {
122 return _pageName;
123 }
124
125 /**
126 * @see java.lang.Object#hashCode()
127 */
128 public int hashCode()
129 {
130 int hash = _pageName.hashCode() * 31;
131 if (_idPath != null)
132 hash += _idPath.hashCode();
133 return hash;
134 }
135
136 /**
137 * @see java.lang.Object#equals(Object)
138 */
139 public boolean equals(Object obj)
140 {
141 if (!(obj instanceof ComponentAddress))
142 return false;
143
144 if (obj == this)
145 return true;
146
147 ComponentAddress objAddress = (ComponentAddress) obj;
148 if (!getPageName().equals(objAddress.getPageName()))
149 return false;
150
151 String idPath1 = getIdPath();
152 String idPath2 = objAddress.getIdPath();
153 return (idPath1 == idPath2) || (idPath1 != null && idPath1.equals(idPath2));
154 }
155
156 }