package webGrude.elements;
import org.jsoup.nodes.Element;
import webGrude.Browser;
/**
* A Link for a Page that can be visited.
* <p>
* This class is supposed to be a type of a field on a class anottated with
* {@literal @}Page. The field must be annotated with {@literal @}Selector ,
* and the selector must resolve to a link.
* <p>
* A link is supposed to be a Link of a Page. For example a page is being mapped
* and it has a link for www.example.com, wich is mapped by a ExamplePage class,
* the field should look like this:<br>
* <p>
* <i>{@literal @}Selector("a.linksToExample") Link{@literal <}ExamplePage{@literal ></}ExamplePage{@literal >} linkToExample; </i>
* </p>
* After the webgrude Browser opens the page, the field linkToExample will
* contain a link that can be visited:
* <p>
* <i> ExamplePage examplePage = linkToExample.visit(); </i>
* </p>
*
* @author beothorn
* @see webGrude.Browser
* @see webGrude.annotations.Page
* @see webGrude.annotations.Selector
*/
public class Link<T> {
private final Class<T> type;
private final Element hrefElement;
private final String currentPageUrl;
/***
* A link uses maps a page from an url to an instance of a class annotated with <i>{@literal @}Page</i>.
* when the method {@link #visit() visit} is called
*
* @param hrefElement A Jsoup Element with a href attribute
* @param visitingType The type that will be mapped from the page when the method {@link #visit() visit} is called
* @param baseUrl The base url, it is used to resolve relative links
*/
public Link(final Element hrefElement, final Class<T> visitingType, final String baseUrl) {
this.hrefElement = hrefElement;
this.type = visitingType;
this.currentPageUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 2) : baseUrl;
}
public String getLinkUrl() {
final String href = this.hrefElement.attr("href");
String urlToVisit = href;
if (href.startsWith("/")) {
final String rootPage = this.currentPageUrl.replaceAll("(.*://.*?/).*", "$1");
urlToVisit = rootPage.substring(0, rootPage.length() - 1) + href;
}
if (href.startsWith(".")) {
urlToVisit = this.currentPageUrl + "/" + href;
}
return urlToVisit;
}
/***
* Visit a page link and map its values to an instance of the visitingType.
*
* @return an instance of visitingType
*/
public T visit() {
return Browser.get(this.getLinkUrl(), this.type);
}
}