/* Copyright (c) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gdata.data.youtube;
import com.google.gdata.data.BaseEntry;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.ExtensionDescription;
import com.google.gdata.data.ExtensionProfile;
import com.google.gdata.data.Kind;
import com.google.gdata.data.Link;
import com.google.gdata.data.PubControl;
import com.google.gdata.data.extensions.Comments;
import com.google.gdata.data.extensions.FeedLink;
import com.google.gdata.data.extensions.Rating;
import com.google.gdata.data.geo.impl.GeoRssWhere;
import com.google.gdata.data.geo.impl.GmlPoint;
import com.google.gdata.data.geo.impl.GmlPos;
import com.google.gdata.data.media.MediaEntry;
import com.google.gdata.data.media.mediarss.MediaRssNamespace;
import com.google.gdata.util.Namespaces;
import java.util.List;
/**
* Video entry for the youtube feeds.
*
*
*/
@ExtensionDescription.Default(
nsAlias = YouTubeNamespace.PREFIX,
nsUri = YouTubeNamespace.URI,
localName = "video"
)
@Kind.Term(YouTubeNamespace.KIND_VIDEO)
public class VideoEntry extends MediaEntry<VideoEntry> {
/**
* Nonstandard categories that might be found in this entry.
*/
public static final String[] CATEGORIES = {
YouTubeNamespace.CATEGORY_SCHEME,
YouTubeNamespace.KEYWORD_SCHEME,
YouTubeNamespace.DEVELOPER_TAG_SCHEME
};
/**
* Creates an empty video entry.
*/
public VideoEntry() {
EntryUtils.setKind(this, YouTubeNamespace.KIND_VIDEO);
}
/** Creates a copy of another entry. */
public VideoEntry(BaseEntry<?> original) {
super(original);
EntryUtils.setKind(this, YouTubeNamespace.KIND_VIDEO);
}
/**
* Creates a new video entry and initializes it.
*
` * @param id entry atom/rss id
*/
public VideoEntry(String id) {
this();
setId(id);
}
/** Sets yt:statistics tag. */
public void setStatistics(YtStatistics stats) {
if (stats == null) {
removeExtension(YtStatistics.class);
} else {
setExtension(stats);
}
}
/** Gets yt:statistics tag. */
public YtStatistics getStatistics() {
return getExtension(YtStatistics.class);
}
/** Gets whether external sites can embed and play this video. */
public boolean isEmbeddable() {
YtNoEmbed noEmbed =
getExtension(YtNoEmbed.class);
return noEmbed == null;
}
public void setEmbeddable(boolean embeddable) {
if (embeddable) {
removeExtension(YtNoEmbed.class);
} else {
setExtension(new YtNoEmbed());
}
}
/**
* Sets the yt:racy flag.
*
* @deprecated in favor of {@link MediaGroup#getRatings()} with scheme {@link
* YouTubeNamespace#MEDIA_RATING_SCHEME}. Removed in version 2.
*/
@Deprecated
public void setRacy(boolean racy) {
if (racy) {
setExtension(new YtRacy());
} else {
removeExtension(YtRacy.class);
}
}
/**
* Checks the yt:racy flag.
*
* @deprecated in favor of {@link MediaGroup#getRatings()} with scheme {@link
* YouTubeNamespace#MEDIA_RATING_SCHEME}. Removed in version 2
*/
@Deprecated
public boolean isRacy() {
YtRacy racy = getExtension(YtRacy.class);
return racy != null;
}
/** Sets the value of the yt:recorded tag. */
public void setRecorded(DateTime date) {
if (date == null) {
removeExtension(YtRecorded.class);
} else {
setExtension(new YtRecorded(date));
}
}
/** Gets the value of the yt:recorded tag. */
public DateTime getRecorded() {
YtRecorded recorded = getExtension(YtRecorded.class);
return recorded == null ? null : recorded.getDate();
}
/** Adds a georss:where tag. */
public void setGeoCoordinates(GeoRssWhere where) {
if (where == null) {
removeExtension(GeoRssWhere.class);
} else {
setExtension(where);
}
}
/** Gets the georss:where tag. */
public GeoRssWhere getGeoCoordinates() {
return getExtension(GeoRssWhere.class);
}
/** Gets the yt:location tag. */
public String getLocation() {
YtLocation tag = getExtension(YtLocation.class);
return tag == null ? null : tag.getContent();
}
/** Sets the yt:location tag. */
public void setLocation(String location) {
if (location == null) {
removeExtension(YtLocation.class);
} else {
setExtension(new YtLocation(location));
}
}
/** Gets all gd:feedLink tags. */
public List<FeedLink> getFeedLinks() {
return getRepeatingExtension(FeedLink.class);
}
/** Gets the comments tag or {@code null}. */
public Comments getComments() {
return getExtension(Comments.class);
}
/** Sets the comments tag. */
public void setComments(Comments comments) {
if (comments == null) {
removeExtension(Comments.class);
} else {
setExtension(comments);
}
}
/** Returns a link to the video responses feed. */
public Link getVideoResponsesLink() {
return getLink(YouTubeNamespace.RESPONSES_REL, Link.Type.ATOM);
}
/** Returns a link to the video rating feed. */
public Link getRatingLink() {
return getLink(YouTubeNamespace.RATINGS_REL, Link.Type.ATOM);
}
/** Returns a link to the video complaints feed. */
public Link getComplaintsLink() {
return getLink(YouTubeNamespace.COMPLAINTS_REL, Link.Type.ATOM);
}
/** Returns a link to the related videos feed. */
public Link getRelatedVideosLink() {
return getLink(YouTubeNamespace.RELATED_REL, Link.Type.ATOM);
}
/** Gets the gd:rating tag. */
public Rating getRating() {
return getExtension(Rating.class);
}
/** Sets the gd:rating tag. */
public void setRating(Rating rating) {
if (rating == null) {
removeExtension(Rating.class);
} else {
setExtension(rating);
}
}
/** Gets the yt:rating tag. */
public YtRating getYtRating() {
return getExtension(YtRating.class);
}
/** Sets the yt:rating. */
public void setYtRating(YtRating rating) {
if (rating == null) {
removeExtension(YtRating.class);
} else {
setExtension(rating);
}
}
/**
* Sets the publication state of this entry, using the tag
* app:control/yt:status.
*
* @param state publication state or {@code null}
*/
public void setPublicationState(YtPublicationState state) {
PubControl control = getPubControl();
if (state == null) {
if (control != null) {
control.removeExtension(YtPublicationState.class);
// check if we can remove app. control
if (control.isDraft() == false && control.getExtensions().isEmpty()) {
setPubControl(null);
}
}
} else {
if (control == null) {
control = new PubControl();
setPubControl(control);
}
control.setExtension(state);
}
}
/**
* Gets the publication state of this entry from the tag
* app:control/yt:status.
*
* @return publication state or {@code null}, in which case
* the video is live
*/
public YtPublicationState getPublicationState() {
PubControl control = getPubControl();
return control == null ? null : control.getExtension(YtPublicationState.class);
}
public YouTubeMediaGroup getMediaGroup() {
return getExtension(YouTubeMediaGroup.class);
}
public YouTubeMediaGroup getOrCreateMediaGroup() {
YouTubeMediaGroup group = getMediaGroup();
if (group == null) {
group = new YouTubeMediaGroup();
setExtension(group);
}
return group;
}
/**
* Sets the completion state of this entry, using the tag
* app:control/yt:incomplete.
*/
public void setYtIncomplete(boolean ytIncomplete) {
PubControl control = getPubControl();
if (!ytIncomplete) {
if (control != null) {
control.removeExtension(YtIncomplete.class);
// check if we can remove app. control
if (control.getExtensions().isEmpty()) {
setPubControl(null);
}
}
} else {
if (control == null) {
control = new PubControl();
setPubControl(control);
}
control.setExtension(new YtIncomplete());
control.setDraft(true);
}
}
/**
* Gets the completion state of this entry from the tag
* app:control/yt:incomplete.
*
* @return {@code true} if the entry is marked incomplete
* {@code false} otherwise.
*/
public boolean isYtIncomplete() {
PubControl control = getPubControl();
return control != null && control.getExtension(YtIncomplete.class) != null;
}
@Override
public void declareExtensions(ExtensionProfile extProfile) {
extProfile.declare(PubControl.class, YtPublicationState.class);
extProfile.declare(VideoEntry.class, Comments.getDefaultDescription());
extProfile.declare(VideoEntry.class, Rating.getDefaultDescription(false));
extProfile.declareAdditionalNamespace(Namespaces.gNs);
extProfile.declareAdditionalNamespace(YouTubeNamespace.NS);
extProfile.declare(VideoEntry.class, YtRacy.class);
extProfile.declare(VideoEntry.class, YtRecorded.class);
extProfile.declare(VideoEntry.class, YtStatistics.class);
extProfile.declare(VideoEntry.class, YtNoEmbed.class);
extProfile.declare(VideoEntry.class, YtLocation.class);
extProfile.declare(VideoEntry.class, YtRating.class);
extProfile.declare(VideoEntry.class, YouTubeMediaGroup.class);
new YouTubeMediaGroup().declareExtensions(extProfile);
extProfile.declareAdditionalNamespace(MediaRssNamespace.NS);
extProfile.declare(VideoEntry.class, GeoRssWhere.getDefaultDescription(false));
extProfile.declareAdditionalNamespace(
com.google.gdata.data.geo.Namespaces.GEO_RSS_NAMESPACE);
extProfile.declare(GeoRssWhere.class, GmlPoint.getDefaultDescription(false));
extProfile.declare(GmlPoint.class, GmlPos.getDefaultDescription(false));
extProfile.declareAdditionalNamespace(
com.google.gdata.data.geo.Namespaces.GML_NAMESPACE);
extProfile.declare(Link.class, YtToken.class);
// Ignore unsupported XML tags instead of rejecting them.
// Very useful in a client.
extProfile.declareArbitraryXmlExtension(VideoEntry.class);
}
}