fr.faylixe.googlecodejam.client.Round Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of googlecodejam-client Show documentation
Show all versions of googlecodejam-client Show documentation
Java client API for Google Code Jam contest
package fr.faylixe.googlecodejam.client;
import fr.faylixe.googlecodejam.client.common.HTMLConstant;
import fr.faylixe.googlecodejam.client.common.NamedObject;
import fr.faylixe.googlecodejam.client.executor.HttpRequestExecutor;
import fr.faylixe.googlecodejam.client.executor.Request;
import fr.faylixe.googlecodejam.client.webservice.InitialValues;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
/**
* POJO class that represents a Google Jam {@link Round}.
* A {@link Round} is defined by a name, and a dashboard
* URL.
*
* @author fv
*/
public final class Round extends NamedObject {
/** Serialization index.
**/
private static final long serialVersionUID = 1L;
/** URL path of a contest. **/
private static final String CODEJAM_PATH = "/codejam/contest/";
/** Prefix for built round URL. **/
private static final String ROUND_PREFIX = "/dashboard";
/** Label used for parent contest when parent could not be retrieved. **/
private static final String UNKNOWN_PARENT = "unkwown-contest";
/** Class name of the HTML description node.
**/
public static final String DESCRIPTION_CLASS_NAME = "desc";
/** Name of the parent contest.
**/
private final String parent;
/** URL of this round dashboard.
**/
private final String url;
/**
* Default constructor.
*
* @param parent Name of the parent contest of this round.
* @param name Name of this round.
* @param url URL of this round dashboard.
*/
private Round(final String parent, final String name, final String url) {
super(name);
this.parent = parent;
this.url = url;
}
/**
* Getter for the parent contest name.
*
* @return Name of the parent contest.
*/
public String getContestName() {
return parent;
}
/**
* Getter for round dashboard URL.
*
* @return URL of this round dashboard.
*/
public String getURL() {
return url;
}
/** {@inheritDoc} **/
@Override
public int hashCode() {
return url.hashCode();
}
/** {@inheritDoc} **/
@Override
public boolean equals(final Object object) {
if (object == this) {
return true;
}
if (object == null || object.getClass() != getClass()) {
return false;
}
final Round other = (Round) object;
return url.equals(other.getURL());
}
/**
* Static factory method that builds a {@link Round} instance
* from the given HTML element.
*
* @param element Element that contains our round description.
* @return Built {@link Round} instance.
*/
private static Optional buildRound(final Element element, final String parent) {
final Elements links = element.getElementsByTag(HTMLConstant.ANCHOR);
Round round = null;
if (!links.isEmpty()) {
final Element link = links.first();
final String name = link.text();
final String url = link.attr(HTMLConstant.HREF);
round = new Round(parent, name, url);
}
return Optional.ofNullable(round);
}
/**
* Static factory method that retrieves a list of round
* from the given JSoup contest node.
*
* @param contest Root element of the contest in the contest index page.
* @param parent Parent contest name.
* @return List of retrieved round.
*/
public static List get(final Element contest, final String parent) {
final Elements rows = contest.getElementsByTag(HTMLConstant.TR);
final List rounds = new ArrayList(rows.size());
for (final Element row : rows) {
final Elements cells = row.getElementsByClass(DESCRIPTION_CLASS_NAME);
if (!cells.isEmpty()) {
final Element cell = cells.first();
buildRound(cell, parent).ifPresent(rounds::add);
}
}
return rounds;
}
/**
* Static factory method that creates a round from the
* given identifier.
*
* @param identifier Round id to use.
* @param cookie Cookie value to use for retrieving contest.
* @return Created round.
* @throws IOException If any error occurs while retrieving round information.
* @throws GeneralSecurityException If any error occurs while creating {@link HttpRequestExecutor} instance.
*/
public static Round fromIdentifier(final String identifier, final String cookie) throws GeneralSecurityException, IOException {
final StringBuilder builder = new StringBuilder();
builder
.append(CODEJAM_PATH)
.append(identifier)
.append(ROUND_PREFIX);
return fromURL(builder.toString(), cookie);
}
/**
* Static factory method that creates a round from the
* given url.
*
* @param url Round url.
* @param cookie Cookie value to use for retrieving contest.
* @return Created round.
* @throws IOException If any error occurs while retrieving round information.
* @throws GeneralSecurityException If any error occurs while creating {@link HttpRequestExecutor} instance.
*/
public static Round fromURL(final String url, final String cookie) throws GeneralSecurityException, IOException {
final HttpRequestExecutor executor = HttpRequestExecutor.create(Request.getHostname(), cookie);
final InitialValues values = InitialValues.get(executor, new Round("", "", url));
return new Round(UNKNOWN_PARENT, values.getName(), url);
}
}