/* 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.DateTime;
import com.google.gdata.data.ExtensionDescription;
import com.google.gdata.data.ExtensionProfile;
import com.google.gdata.data.media.mediarss.MediaCategory;
import com.google.gdata.data.media.mediarss.MediaContent;
import com.google.gdata.data.media.mediarss.MediaCredit;
import com.google.gdata.data.media.mediarss.MediaDescription;
import com.google.gdata.data.media.mediarss.MediaGroup;
import com.google.gdata.data.media.mediarss.MediaKeywords;
import com.google.gdata.data.media.mediarss.MediaPlayer;
import com.google.gdata.data.media.mediarss.MediaRating;
import com.google.gdata.data.media.mediarss.MediaRestriction;
import com.google.gdata.data.media.mediarss.MediaRssNamespace;
import com.google.gdata.data.media.mediarss.MediaThumbnail;
import com.google.gdata.data.media.mediarss.MediaTitle;
import java.util.AbstractList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* Subset of {@code <media:group>}.
*
* See description on
* <a href="http://search.yahoo.com/mrss">http://search.yahoo.com/mrss</a>.
*
*
*/
@ExtensionDescription.Default(
nsAlias = MediaRssNamespace.PREFIX,
nsUri = MediaRssNamespace.URI,
localName = "group"
)
public class YouTubeMediaGroup extends MediaGroup {
private static final String UPLOADER_ROLE = "uploader";
/**
* Gets the YouTube ID of the video.
*
* @since 2.0
*/
public String getVideoId() {
YtVideoId videoId = getExtension(YtVideoId.class);
return videoId == null ? null : videoId.getVideoId();
}
/**
* Sets the YouTube video ID of the video.
*
* @since 2.0
*/
public void setVideoId(String videoId) {
if (videoId == null) {
removeExtension(YtVideoId.class);
} else {
setExtension(new YtVideoId(videoId));
}
}
/** Gets the duration, in seconds, of the youtube video. */
public Long getDuration() {
YtDuration duration = getExtension(YtDuration.class);
return duration == null ? null : duration.getSeconds();
}
/** Sets the duration, in seconds, of the youtube video. */
public void setDuration(Long seconds) {
if (seconds == null) {
removeExtension(YtDuration.class);
} else {
YtDuration duration = new YtDuration();
duration.setSeconds(seconds);
setExtension(duration);
}
}
/**
* Returns the time the video was uploaded at.
*
* @since 2.0
*/
public DateTime getUploaded() {
YtUploaded uploadTime = getExtension(YtUploaded.class);
return uploadTime != null ? uploadTime.getDateTime() : null;
}
/**
* Sets or unsets the time the video was uploaded at.
*
* @since 2.0
*/
public void setUploaded(DateTime dateTime) {
if (dateTime == null) {
removeExtension(YtUploaded.class);
} else {
setExtension(new YtUploaded(dateTime));
}
}
/**
* Sets the YouTube user who uploaded the video.
*
* @param uploader YouTube user name or {@code null}
* @since 2.0
*/
public void setUploader(String uploader) {
for (Iterator<YouTubeMediaCredit> iterator = getYouTubeCredits().iterator();
iterator.hasNext(); ) {
MediaCredit credit = iterator.next();
if (UPLOADER_ROLE.equals(credit.getRole())
&& YouTubeNamespace.CREDIT_SCHEME.equals(credit.getScheme())) {
iterator.remove();
}
}
if (uploader != null) {
YouTubeMediaCredit credit = new YouTubeMediaCredit();
credit.setScheme(YouTubeNamespace.CREDIT_SCHEME);
credit.setRole(UPLOADER_ROLE);
credit.setContent(uploader);
addCredit(credit);
}
}
/**
* Gets the YouTube user who uploaded the video.
*
* @return YouTube user name or {@code null}
* @since 2.0
*/
public String getUploader() {
YouTubeMediaCredit uploader = getUploaderTag();
return uploader == null ? null : uploader.getContent();
}
/**
* Checks whether the uploader is a partner.
*
* @return uploader type
*/
public YouTubeMediaCredit.Type getUploaderType() {
YouTubeMediaCredit uploader = getUploaderTag();
return uploader == null ? null : uploader.getType();
}
/**
* Returns a {@code media:credit} with role {@code uploader}.
*
* @return a {@code media:credit} tag or {@code null}
*/
private YouTubeMediaCredit getUploaderTag() {
for (YouTubeMediaCredit credit : getYouTubeCredits()) {
if (UPLOADER_ROLE.equals(credit.getRole())
&& YouTubeNamespace.CREDIT_SCHEME.equals(credit.getScheme())) {
return credit;
}
}
return null;
}
/**
* Gets a modifiable list of {@link YouTubeMediaContent}.
*
* @return list of {@code MediaContent}.
*/
public List<YouTubeMediaContent> getYouTubeContents() {
return getRepeatingExtension(YouTubeMediaContent.class);
}
/**
* Adds a new {@link MediaContent}.
*
* YouTube entries can only contain {@link YouTubeMediaContent} and this
* method checks that at runtime. Please use
* {@link #addContent(YouTubeMediaContent)} instead.
*
* @param content
* @throws IllegalArgumentException if {@code content} is not a
* {@link YouTubeMediaContent}
*/
@Override
public void addContent(MediaContent content) {
if (!(content instanceof YouTubeMediaContent)) {
throw new IllegalArgumentException("YouTube entries requires "
+ "YouTubeMediaContent");
}
super.addContent(content);
}
/**
* Gets a read-only list of {@link MediaContent}.
*
* YouTube entries only contain {@link YouTubeMediaContent}. Please use
* {@link #getYouTubeContents()} instead to make sure you have access to
* a modifiable lis.
*
* This collection has been made read-only to make sure only
* {@link YouTubeMediaContent} are ever added. Please use
* {@link #getYouTubeContents()}/{@link #addContent(YouTubeMediaContent)} to
* modify the list of media:content tags..
*
* @return a read-only collection of {@code MediaContent}
*/
@Override
public List<MediaContent> getContents() {
final List<YouTubeMediaContent> contents = getYouTubeContents();
return new AbstractList<MediaContent>() {
@Override
public MediaContent get(int index) {
return contents.get(index);
}
@Override
public int size() {
return contents.size();
}
};
}
/**
* Clears the list of {@code media:content} tags.
*/
@Override
public void clearContents() {
getYouTubeContents().clear();
}
/**
* Adds a {@code media:content} tag.
*
* @param content
*/
public void addContent(YouTubeMediaContent content) {
addRepeatingExtension(content);
}
/**
* Gets a modifiable list of {@link YouTubeMediaRating}.
*
* @return list of {@code MediaRating}.
*/
public List<YouTubeMediaRating> getYouTubeRatings() {
return getRepeatingExtension(YouTubeMediaRating.class);
}
/**
* Adds a new {@link MediaRating}.
*
* YouTube entries can only contain {@link YouTubeMediaRating} and this
* method checks that at runtime. Please use
* {@link #addRating(YouTubeMediaRating)} instead.
*
* @param rating
* @throws IllegalArgumentException if {@code rating} is not a
* {@link YouTubeMediaRating}
*/
@Override
public void addRating(MediaRating rating) {
if (!(rating instanceof YouTubeMediaRating)) {
throw new IllegalArgumentException("YouTube entries requires "
+ "YouTubeMediaRating");
}
super.addRating(rating);
}
/**
* Gets a read-only list of {@link MediaRating}.
*
* YouTube entries only contain {@link YouTubeMediaRating}. Please use
* {@link #getYouTubeRatings()} instead to make sure you have access to
* a modifiable lis.
*
* This collection has been made read-only to make sure only
* {@link YouTubeMediaRating} are ever added. Please use
* {@link #getYouTubeRatings()}/{@link #addRating(YouTubeMediaRating)} to
* modify the list of media:rating tags..
*
* @return a read-only collection of {@code MediaRating}
*/
@Override
public List<MediaRating> getRatings() {
final List<YouTubeMediaRating> ratings = getYouTubeRatings();
return new AbstractList<MediaRating>() {
@Override
public MediaRating get(int index) {
return ratings.get(index);
}
@Override
public int size() {
return ratings.size();
}
};
}
/**
* Clears the list of {@code media:rating} tags.
*/
@Override
public void clearRatings() {
getYouTubeRatings().clear();
}
/**
* Adds a {@code media:rating} tag.
*
* @param rating
*/
public void addRating(YouTubeMediaRating rating) {
addRepeatingExtension(rating);
}
/**
* Gets a modifiable list of {@link YouTubeMediaCredit}.
*
* @return list of {@code MediaCredit}.
*/
public List<YouTubeMediaCredit> getYouTubeCredits() {
return getRepeatingExtension(YouTubeMediaCredit.class);
}
/**
* Adds a new {@link MediaCredit}.
*
* YouTube entries can only contain {@link YouTubeMediaCredit} and this
* method checks that at runtime. Please use
* {@link #addCredit(YouTubeMediaCredit)} instead.
*
* @param credit
* @throws IllegalArgumentException if {@code credit} is not a
* {@link YouTubeMediaCredit}
*/
@Override
public void addCredit(MediaCredit credit) {
if (!(credit instanceof YouTubeMediaCredit)) {
throw new IllegalArgumentException("YouTube entries requires "
+ "YouTubeMediaCredit");
}
super.addCredit(credit);
}
/**
* Gets a read-only list of {@link MediaCredit}.
*
* YouTube entries only contain {@link YouTubeMediaCredit}. Please use
* {@link #getYouTubeCredits()} instead to make sure you have access to
* a modifiable lis.
*
* This collection has been made read-only to make sure only
* {@link YouTubeMediaCredit} are ever added. Please use
* {@link #getYouTubeCredits()}/{@link #addCredit(YouTubeMediaCredit)} to
* modify the list of media:credit tags..
*
* @return a read-only collection of {@code MediaCredit}
*/
@Override
public List<MediaCredit> getCredits() {
final List<YouTubeMediaCredit> credits = getYouTubeCredits();
return new AbstractList<MediaCredit>() {
@Override
public MediaCredit get(int index) {
return credits.get(index);
}
@Override
public int size() {
return credits.size();
}
};
}
/**
* Clears the list of {@code media:credit} tags.
*/
@Override
public void clearCredits() {
getYouTubeCredits().clear();
}
/**
* Adds a {@code media:credit} tag.
*
* @param credit
*/
public void addCredit(YouTubeMediaCredit credit) {
addRepeatingExtension(credit);
}
public void setAspectRatio(YtAspectRatio aspectRatio) {
if (aspectRatio == null) {
removeExtension(YtAspectRatio.class);
} else {
setExtension(aspectRatio);
}
}
public YtAspectRatio getAspectRatio() {
return getExtension(YtAspectRatio.class);
}
/** Checks the yt:private flag. */
public boolean isPrivate() {
YtPrivate privacyLevel = getExtension(YtPrivate.class);
return privacyLevel != null;
}
/** Sets the yt:private flag. */
public void setPrivate(boolean makePrivate) {
if (makePrivate) {
setExtension(new YtPrivate());
} else {
removeExtension(YtPrivate.class);
}
}
/**
* A YouTube media group can have only one YouTube category defined by this
* scheme: {@link YouTubeNamespace#CATEGORY_SCHEME} and this method is a
* helper for retrieving it. See also: {@link #getCategories()}.
* <p>
* If two or more such categories are specified it cannot be determined which
* is the right one so this method will return null.
*
* @return the YouTube category of this video, if such a category cannot be
* found or determined it returns null.
*/
public MediaCategory getYouTubeCategory() {
Set<MediaCategory> found = getCategoriesWithScheme(YouTubeNamespace.CATEGORY_SCHEME);
if (found.size() == 1) {
return found.iterator().next();
} else if (found.size() > 1) {
// could not determine the YouTube video category.
return null;
} else {
// the default scheme is the YouTube category scheme,
// so search for a category with no scheme (=default scheme) next.
Set<MediaCategory> withNoScheme = getCategoriesWithScheme(null);
if (withNoScheme.size() == 1) {
return withNoScheme.iterator().next();
} else {
// could not determine the YouTube video category.
return null;
}
}
}
/**
* Sets or changes the previously set YouTube category.
*
* @param name the new category name to set.
*/
public void setYouTubeCategory(String name) {
for (Iterator<MediaCategory> iterator = getCategories().iterator(); iterator.hasNext();) {
MediaCategory category = iterator.next();
if (YouTubeNamespace.CATEGORY_SCHEME.equals(category.getScheme())) {
iterator.remove();
}
}
addCategory(new MediaCategory(YouTubeNamespace.CATEGORY_SCHEME, name));
}
/**
* Declare extensions available in media:group on youtube feeds.
*/
@Override
public void declareExtensions(ExtensionProfile extProfile) {
extProfile.declare(YouTubeMediaGroup.class, YtAspectRatio.class);
extProfile.declare(YouTubeMediaGroup.class, YtVideoId.class);
extProfile.declare(YouTubeMediaGroup.class, YtDuration.class);
extProfile.declare(YouTubeMediaGroup.class, YtPrivate.class);
extProfile.declare(YouTubeMediaGroup.class, YtUploaded.class);
extProfile.declare(YouTubeMediaGroup.class, YouTubeMediaContent.class);
extProfile.declare(YouTubeMediaGroup.class, MediaPlayer.class);
extProfile.declare(YouTubeMediaGroup.class, MediaKeywords.class);
extProfile.declare(YouTubeMediaGroup.class, MediaTitle.class);
extProfile.declare(YouTubeMediaGroup.class, MediaDescription.class);
extProfile.declare(YouTubeMediaGroup.class, MediaRestriction.class);
extProfile.declare(YouTubeMediaGroup.class, MediaCategory.class);
extProfile.declare(YouTubeMediaGroup.class, MediaThumbnail.class);
extProfile.declare(YouTubeMediaGroup.class, YouTubeMediaRating.class);
extProfile.declare(YouTubeMediaGroup.class, YouTubeMediaCredit.class);
extProfile.declareArbitraryXmlExtension(YouTubeMediaGroup.class);
}
}