package uk.ac.ebi.ep.sitemap.advanced; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; /** One configurable Google Video Search URL. To configure, use {@link Options} * * @author Dan Fabulich * @see Options * @see <a href="http://www.google.com/support/webmasters/bin/answer.py?answer=80472">Creating Video Sitemaps</a> */ public class GoogleVideoSitemapUrl extends WebSitemapUrl { private final URL playerUrl; private final URL contentUrl; private final URL thumbnailUrl; private final String title; private final String description; private final Double rating; private final Integer viewCount; private final Date publicationDate; private final ArrayList<String> tags; private final String category; // TODO can there be multiple categories? // "Usually a video will belong to a single category." // http://www.google.com/support/webmasters/bin/answer.py?answer=80472 private final String familyFriendly; private final Integer durationInSeconds; private final String allowEmbed; /** Options to configure Google Video URLs */ public static class Options extends AbstractSitemapUrlOptions<GoogleVideoSitemapUrl, Options> { private URL playerUrl; private URL contentUrl; private URL thumbnailUrl; private String title; private String description; private Double rating; private Integer viewCount; private Date publicationDate; private ArrayList<String> tags; private String category; // TODO can there be multiple categories? // "Usually a video will belong to a single category." // http://www.google.com/support/webmasters/bin/answer.py?answer=80472 private Boolean familyFriendly; private Integer durationInSeconds; private Boolean allowEmbed; /** Specifies a landing page URL, together with a "player" (e.g. SWF) * * @param url the landing page URL * @param playerUrl the URL of the "player" (e.g. SWF file) * @param allowEmbed when specifying a player, you must specify whether embedding is allowed */ public Options(URL url, URL playerUrl, boolean allowEmbed) { super(url, GoogleVideoSitemapUrl.class); this.playerUrl = playerUrl; this.allowEmbed = allowEmbed; } /** Specifies a landing page URL, together with the URL of the underlying video (e.g. FLV) * * @param url the landing page URL * @param contentUrl the URL of the underlying video (e.g. FLV) */ public Options(URL url, URL contentUrl) { super(url, GoogleVideoSitemapUrl.class); this.contentUrl = contentUrl; } /** Specifies a player URL (e.g. SWF) * * @param playerUrl the URL of the "player" (e.g. SWF file) * @param allowEmbed when specifying a player, you must specify whether embedding is allowed */ public Options playerUrl(URL playerUrl, boolean allowEmbed) { this.playerUrl = playerUrl; this.allowEmbed = allowEmbed; return this; } /** Specifies the URL of the underlying video (e.g FLV) */ public Options contentUrl(URL contentUrl) { this.contentUrl = contentUrl; return this; } /** * A URL pointing to the URL for the video thumbnail image file. This * allows you to suggest the thumbnail you want displayed in search * results. If you provide a {@link #contentUrl(URL)}, Google will attempt * to generate a set of representative thumbnail images from your actual * video content. However, we strongly recommended that you provide a * thumbnail URL to increase the likelihood of your video being included * in the video index. */ public Options thumbnailUrl(URL thumbnailUrl) { this.thumbnailUrl = thumbnailUrl; return this; } /** The title of the video. Limited to 100 characters. */ public Options title(String title) { if (title != null) { if (title.length() > 100) { throw new RuntimeException("Video title is limited to 100 characters: " + title); } } this.title = title; return this; } /** The description of the video. Descriptions longer than 2048 characters will be truncated. */ public Options description(String description) { if (description != null) { if (description.length() > 2048) { throw new RuntimeException("Truncate video descriptions to 2048 characters: " + description); } } this.description = description; return this; } /** The rating of the video. The value must be number in the range 0.0-5.0. */ public Options rating(Double rating) { if (rating != null) { if (rating < 0 || rating > 5.0) { throw new RuntimeException("Rating must be between 0.0 and 5.0:" + rating); } } this.rating = rating; return this; } /** The number of times the video has been viewed */ public Options viewCount(int viewCount) { this.viewCount = viewCount; return this; } /** The date the video was first published, in {@link W3CDateFormat}. */ public Options publicationDate(Date publicationDate) { this.publicationDate = publicationDate; return this; } /** * Tag associated with the video; tags are generally very short * descriptions of key concepts associated with a video or piece of * content. A single video could have several tags, although it might * belong to only one category. For example, a video about grilling food * may belong in the Grilling category, but could be tagged "steak", * "meat", "summer", and "outdoor". Create a new <video:tag> element for * each tag associated with a video. A maximum of 32 tags is permitted. */ public Options tags(ArrayList<String> tags) { this.tags = tags; return this; } /** * Tag associated with the video; tags are generally very short * descriptions of key concepts associated with a video or piece of * content. A single video could have several tags, although it might * belong to only one category. For example, a video about grilling food * may belong in the Grilling category, but could be tagged "steak", * "meat", "summer", and "outdoor". Create a new <video:tag> element for * each tag associated with a video. A maximum of 32 tags is permitted. */ public Options tags(Iterable<String> tags) { this.tags = new ArrayList<String>(); for (String tag : tags) { this.tags.add(tag); } return this; } /** * Tag associated with the video; tags are generally very short * descriptions of key concepts associated with a video or piece of * content. A single video could have several tags, although it might * belong to only one category. For example, a video about grilling food * may belong in the Grilling category, but could be tagged "steak", * "meat", "summer", and "outdoor". Create a new <video:tag> element for * each tag associated with a video. A maximum of 32 tags is permitted. */ public Options tags(String... tags) { return tags(Arrays.asList(tags)); } /** * The video's category; for example, <code>cooking</code>. The value * should be a string no longer than 256 characters. In general, * categories are broad groupings of content by subject. Usually a video * will belong to a single category. For example, a site about cooking * could have categories for Broiling, Baking, and Grilling */ public Options category(String category) { if (category != null) { if (category.length() > 256) { throw new RuntimeException("Video category is limited to 256 characters: " + title); } } this.category = category; return this; } /** Whether the video is suitable for viewing by children */ public Options familyFriendly(boolean familyFriendly) { this.familyFriendly = familyFriendly; return this; } /** The duration of the video in seconds; value must be between 0 and 28800 (8 hours). */ public Options durationInSeconds(int durationInSeconds) { if (durationInSeconds < 0 || durationInSeconds > 28800) { throw new RuntimeException("Duration must be between 0 and 28800 (8 hours):" + durationInSeconds); } this.durationInSeconds = durationInSeconds; return this; } } /** Specifies a landing page URL, together with a "player" (e.g. SWF) * * @param url the landing page URL * @param playerUrl the URL of the "player" (e.g. SWF file) * @param allowEmbed when specifying a player, you must specify whether embedding is allowed */ public GoogleVideoSitemapUrl(URL url, URL playerUrl, boolean allowEmbed) { this(new Options(url, playerUrl, allowEmbed)); } /** Specifies a landing page URL, together with the URL of the underlying video (e.g. FLV) * * @param url the landing page URL * @param contentUrl the URL of the underlying video (e.g. FLV) */ public GoogleVideoSitemapUrl(URL url, URL contentUrl) { this(new Options(url, contentUrl)); } /** Configures the url with options */ public GoogleVideoSitemapUrl(Options options) { super(options); contentUrl = options.contentUrl; playerUrl = options.playerUrl; if (playerUrl == null && contentUrl == null) { throw new RuntimeException("You must specify either contentUrl or playerUrl or both; neither were specified"); } allowEmbed = convertBooleanToYesOrNo(options.allowEmbed); if (playerUrl != null && allowEmbed == null) { throw new RuntimeException("allowEmbed must be specified if playerUrl is specified"); } category = options.category; description = options.description; durationInSeconds = options.durationInSeconds; familyFriendly = convertBooleanToYesOrNo(options.familyFriendly); publicationDate = options.publicationDate; rating = options.rating; tags = options.tags; if (tags != null && tags.size() > 32) { throw new RuntimeException("A maximum of 32 tags is permitted"); } thumbnailUrl = options.thumbnailUrl; title = options.title; viewCount = options.viewCount; } private static String convertBooleanToYesOrNo(Boolean value) { if (value == null) return null; return value ? "Yes" : "No"; } /** Retrieves the {@link Options#playerUrl}*/ public URL getPlayerUrl() { return playerUrl; } /** Retrieves the {@link Options#contentUrl}*/ public URL getContentUrl() { return contentUrl; } /** Retrieves the {@link Options#thumbnailUrl}*/ public URL getThumbnailUrl() { return thumbnailUrl; } /** Retrieves the {@link Options#title}*/ public String getTitle() { return title; } /** Retrieves the {@link Options#description}*/ public String getDescription() { return description; } /** Retrieves the {@link Options#rating}*/ public Double getRating() { return rating; } /** Retrieves the {@link Options#viewCount}*/ public Integer getViewCount() { return viewCount; } /** Retrieves the {@link Options#publicationDate}*/ public Date getPublicationDate() { return publicationDate; } /** Retrieves the {@link Options#tags}*/ public ArrayList<String> getTags() { return tags; } /** Retrieves the {@link Options#category}*/ public String getCategory() { return category; } /** Retrieves whether the video is {@link Options#familyFriendly}*/ public String getFamilyFriendly() { return familyFriendly; } /** Retrieves the {@link Options#durationInSeconds}*/ public Integer getDurationInSeconds() { return durationInSeconds; } /** Retrieves whether embedding is allowed */ public String getAllowEmbed() { return allowEmbed; } }