001: package com.meterware.httpunit;
002:
003: /********************************************************************************************************************
004: * $Id: WebLink.java,v 1.47 2004/09/29 17:15:25 russgold Exp $
005: *
006: * Copyright (c) 2000-2004, Russell Gold
007: *
008: * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
009: * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
010: * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
011: * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
012: *
013: * The above copyright notice and this permission notice shall be included in all copies or substantial portions
014: * of the Software.
015: *
016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
017: * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
018: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
019: * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
020: * DEALINGS IN THE SOFTWARE.
021: *
022: *******************************************************************************************************************/
023: import com.meterware.httpunit.scripting.ScriptableDelegate;
024: import com.meterware.httpunit.scripting.NamedDelegate;
025:
026: import java.io.IOException;
027: import java.net.MalformedURLException;
028: import java.net.URL;
029:
030: import org.w3c.dom.Node;
031: import org.xml.sax.SAXException;
032:
033: /**
034: * This class represents a link in an HTML page. Users of this class may examine the
035: * structure of the link (as a DOM), or create a {@link WebRequest} to simulate clicking
036: * on the link.
037: *
038: * @author <a href="mailto:russgold@httpunit.org">Russell Gold</a>
039: * @author <a href="mailto:benoit.xhenseval@avondi.com>Benoit Xhenseval</a>
040: **/
041: public class WebLink extends FixedURLWebRequestSource {
042:
043: /** Predicate to match part or all of a link's URL string. **/
044: public final static HTMLElementPredicate MATCH_URL_STRING;
045:
046: /** Predicate to match a link's text exactly. **/
047: public final static HTMLElementPredicate MATCH_TEXT;
048:
049: /** Predicate to match part or all of a link's contained text. **/
050: public final static HTMLElementPredicate MATCH_CONTAINED_TEXT;
051:
052: /** Predicate to match a link's ID. **/
053: public final static HTMLElementPredicate MATCH_ID;
054:
055: /** Predicate to match a link's name. **/
056: public final static HTMLElementPredicate MATCH_NAME;
057:
058: private Scriptable _scriptable;
059:
060: /**
061: * Returns the URL referenced by this link. This may be a relative URL. It will not include any fragment identifier.
062: **/
063: public String getURLString() {
064: return getRelativeURL();
065: }
066:
067: /**
068: * Returns the text value of this link.
069: * @since 1.6
070: **/
071: public String getText() {
072: if (getNode().getNodeName().equalsIgnoreCase("area")) {
073: return getAttribute("alt");
074: } else {
075: return super .getText();
076: }
077: }
078:
079: /**
080: * Returns the text value of this link.
081: * @deprecated as of 1.6, use #getText instead
082: **/
083: public String asText() {
084: return getText();
085: }
086:
087: /**
088: * Submits a request as though the user had clicked on this link. Will also fire the 'onClick' event if defined.
089: * If clicking results in submitting a request (that is, there is no 'onClick' event or it returns true,
090: * this method will return the result of that submission; otherwise, it will
091: * return the updated contents of the frame containing this link. Note that if an event updates a different frame
092: * that frame will not be returned by this method.
093: **/
094: public WebResponse click() throws IOException, SAXException {
095: return submitRequest(getAttribute("onclick"), getRequest());
096: }
097:
098: /**
099: * Simulates moving the mouse over the link. Will fire the 'onMouseOver' event if defined.
100: **/
101: public void mouseOver() {
102: String event = getAttribute("onmouseover");
103: if (event.length() > 0)
104: getScriptableObject().doEvent(event);
105: }
106:
107: public class Scriptable extends HTMLElementScriptable implements
108: NamedDelegate {
109:
110: public Scriptable() {
111: super (WebLink.this );
112: }
113:
114: public String getName() {
115: return WebLink.this .getID().length() != 0 ? WebLink.this
116: .getID() : WebLink.this .getName();
117: }
118:
119: public Object get(String propertyName) {
120: if (propertyName.equalsIgnoreCase("href")) {
121: return getReference().toExternalForm();
122: } else {
123: return super .get(propertyName);
124: }
125: }
126:
127: public void set(String propertyName, Object value) {
128: if (propertyName.equals("href")) {
129: setDestination((String) value);
130: } else {
131: super .set(propertyName, value);
132: }
133: }
134:
135: private URL getReference() {
136: try {
137: return getRequest().getURL();
138: } catch (MalformedURLException e) {
139: return WebLink.this .getBaseURL();
140: }
141: }
142: }
143:
144: //----------------------------------------- WebRequestSource methods ---------------------------------------------------
145:
146: /**
147: * Returns the scriptable delegate.
148: */
149: public ScriptableDelegate getScriptableDelegate() {
150: return getScriptableObject();
151: }
152:
153: //--------------------------------------------------- package members --------------------------------------------------
154:
155: /**
156: * Contructs a web link given the URL of its source page and the DOM extracted
157: * from that page.
158: **/
159: WebLink(WebResponse response, URL baseURL, Node node,
160: FrameSelector sourceFrame, String defaultTarget,
161: String characterSet) {
162: super (response, node, baseURL, NodeUtils.getNodeAttribute(node,
163: "href"), sourceFrame, defaultTarget, characterSet);
164: }
165:
166: /**
167: * Returns an object which provides scripting access to this link.
168: **/
169: Scriptable getScriptableObject() {
170: if (_scriptable == null) {
171: _scriptable = new Scriptable();
172: _scriptable.setScriptEngine(getBaseResponse()
173: .getScriptableObject().getDocument()
174: .getScriptEngine(_scriptable));
175: }
176: return _scriptable;
177: }
178:
179: static {
180: MATCH_URL_STRING = new HTMLElementPredicate() {
181: public boolean matchesCriteria(Object htmlElement,
182: Object criteria) {
183: return HttpUnitUtils.contains(((WebLink) htmlElement)
184: .getURLString(), (String) criteria);
185: };
186: };
187:
188: MATCH_TEXT = new HTMLElementPredicate() {
189: public boolean matchesCriteria(Object htmlElement,
190: Object criteria) {
191: return HttpUnitUtils.matches(((WebLink) htmlElement)
192: .getText(), (String) criteria);
193: };
194: };
195:
196: MATCH_CONTAINED_TEXT = new HTMLElementPredicate() {
197: public boolean matchesCriteria(Object htmlElement,
198: Object criteria) {
199: return HttpUnitUtils.contains(((WebLink) htmlElement)
200: .getText(), (String) criteria);
201: };
202: };
203:
204: MATCH_ID = new HTMLElementPredicate() {
205: public boolean matchesCriteria(Object htmlElement,
206: Object criteria) {
207: return HttpUnitUtils.matches(((WebLink) htmlElement)
208: .getID(), (String) criteria);
209: };
210: };
211:
212: MATCH_NAME = new HTMLElementPredicate() {
213: public boolean matchesCriteria(Object htmlElement,
214: Object criteria) {
215: return HttpUnitUtils.matches(((WebLink) htmlElement)
216: .getName(), (String) criteria);
217: };
218: };
219:
220: }
221:
222: }
|