summaryrefslogtreecommitdiff
path: root/src/plugins/videos/src/com/motorola/studio/android/videos/model/VideoManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/videos/src/com/motorola/studio/android/videos/model/VideoManager.java')
-rw-r--r--src/plugins/videos/src/com/motorola/studio/android/videos/model/VideoManager.java431
1 files changed, 431 insertions, 0 deletions
diff --git a/src/plugins/videos/src/com/motorola/studio/android/videos/model/VideoManager.java b/src/plugins/videos/src/com/motorola/studio/android/videos/model/VideoManager.java
new file mode 100644
index 0000000..4e87470
--- /dev/null
+++ b/src/plugins/videos/src/com/motorola/studio/android/videos/model/VideoManager.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.motorola.studio.android.videos.model;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.motorola.studio.android.common.log.StudioLogger;
+import com.motorola.studio.android.common.utilities.HttpUtils;
+import com.motorola.studio.android.videos.Activator;
+import com.motorola.studio.android.videos.implementation.youtube.YoutubeVideoServiceProvider;
+import com.motorola.studio.android.videos.model.extension.VideoServiceProvider;
+
+/**
+ * Manage the actions related to videos, including loading them and
+ * providing any related information to other classes.
+ */
+public class VideoManager
+{
+
+ /*
+ * Sort options
+ */
+ public static final int SORT_MOST_RECENT = 0;
+
+ public static final int SORT_MOST_VIEWED = 1;
+
+ public static final int SORT_TOP_RATED = 2;
+
+ /*
+ * Video channels and source definitions (XML)
+ */
+ public static final String VIDEOS_DEFINITIONS = "resources/motodev_videos.xml";
+
+ public static final String TAG_USER = "user";
+
+ public static final String TAG_USER_ATT_NAME = "name";
+
+ public static final String TAG_CHANNEL = "channel";
+
+ public static final String TAG_CHANNEL_ATT_NAME = "name";
+
+ public static final String TAG_CHANNEL_ATT_DISPLAY_NAME = "display_name";
+
+ // "fixed" or "variable"
+ public static final String TAG_CHANNEL_ATT_ORDER = "order";
+
+ public static final String TAG_CHANNEL_ATT_ORDER_FIXED = "fixed";
+
+ // "true" or "false"
+ public static final String TAG_CHANNEL_ATT_DEFAULT = "default";
+
+ /*
+ * Singleton
+ */
+ private static VideoManager instance;
+
+ /*
+ * The selected video service provider
+ */
+ private VideoServiceProvider videoServiceProvider = null;
+
+ /*
+ * Credentials information to be passed to the video service provider
+ */
+ private String userName = null;
+
+ /*
+ * The video channel objects (the videos themselves are attributes of these objects)
+ */
+ private String defaultVideoChannel = null;
+
+ // Map "channel name" -> object that represent the video channel
+ private final Map<String, VideoChannel> channelsMap = new HashMap<String, VideoChannel>();
+
+ private final List<VideoChannel> channelsList = new ArrayList<VideoChannel>();
+
+ /**
+ * Singleton
+ *
+ * @return a unique VideoManager instance
+ * @throws Exception
+ */
+ public static synchronized VideoManager getInstance() throws Exception
+ {
+ if (instance == null)
+ {
+ instance = new VideoManager();
+ }
+ return instance;
+ }
+
+ /**
+ * Load all channels and videos
+ */
+ public void load() throws Exception
+ {
+ channelsMap.clear();
+ channelsList.clear();
+
+ File file =
+ new File(FileLocator.toFileURL(
+ Activator.getDefault().getBundle().getEntry(VIDEOS_DEFINITIONS)).getPath());
+
+ DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document doc = documentBuilder.parse(file);
+
+ /*
+ * Get service username
+ */
+ NodeList user = doc.getElementsByTagName(TAG_USER);
+ Node userNameNode = user.item(0).getAttributes().getNamedItem(TAG_USER_ATT_NAME);
+ userName = userNameNode.getNodeValue();
+
+ /*
+ * Initialize video service provider
+ */
+ videoServiceProvider = new YoutubeVideoServiceProvider(userName);
+
+ /*
+ * Get all channels
+ */
+ NodeList channels = doc.getElementsByTagName(TAG_CHANNEL);
+
+ for (int i = 0; i < channels.getLength(); i++)
+ {
+
+ Node channel = channels.item(i);
+ String displayName =
+ channel.getAttributes().getNamedItem(TAG_CHANNEL_ATT_DISPLAY_NAME)
+ .getTextContent();
+ String name =
+ channel.getAttributes().getNamedItem(TAG_CHANNEL_ATT_NAME).getTextContent();
+ boolean order = false;
+ boolean defaultChannel = false;
+ if (channel.getAttributes().getNamedItem(TAG_CHANNEL_ATT_ORDER) != null)
+ {
+ order =
+ channel.getAttributes().getNamedItem(TAG_CHANNEL_ATT_ORDER)
+ .getTextContent().equals(TAG_CHANNEL_ATT_ORDER_FIXED) ? true
+ : false;
+ }
+ if (channel.getAttributes().getNamedItem(TAG_CHANNEL_ATT_DEFAULT) != null)
+ {
+ defaultChannel =
+ channel.getAttributes().getNamedItem(TAG_CHANNEL_ATT_DEFAULT)
+ .getTextContent().equals(new Boolean(true).toString()) ? true
+ : false;
+ }
+
+ /*
+ * Create and populate the channels
+ */
+ VideoChannel videoChannel = new VideoChannel(name);
+ videoChannel.setDisplayName(displayName);
+ videoChannel.setOrdered(order);
+ videoChannel.setDefaultChannel(defaultChannel);
+ if (defaultChannel)
+ {
+ defaultVideoChannel = name;
+ }
+ List<Video> videos = videoServiceProvider.loadVideos(videoChannel);
+ if (videos != null)
+ {
+ videoChannel.setVideos(videos);
+ }
+ else
+ {
+ videoChannel.setActive(false);
+ }
+ channelsMap.put(name, videoChannel);
+ channelsList.add(videoChannel);
+
+ }
+
+ }
+
+ /**
+ * Sort all videos from all channels
+ *
+ * @param criteria
+ */
+ public void sort(final int criteria)
+ {
+ for (VideoChannel channel : channelsList)
+ {
+ if (!channel.isOrdered())
+ {
+ List<Video> videos = channel.getVideos();
+ Collections.sort(videos, new Comparator<Video>()
+ {
+
+ public int compare(Video arg0, Video arg1)
+ {
+ int result = 0;
+
+ switch (criteria)
+ {
+ case VideoManager.SORT_MOST_RECENT:
+ result = arg0.getDate().compareTo(arg1.getDate());
+ break;
+ case VideoManager.SORT_MOST_VIEWED:
+ result = arg0.getViews() >= arg1.getViews() ? 1 : -1;
+ break;
+ case VideoManager.SORT_TOP_RATED:
+ result = arg0.getRating() >= arg1.getRating() ? 1 : -1;
+ break;
+
+ }
+ return result;
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Get videos from a channel
+ *
+ * @param channel channel to retrieve the videos
+ */
+ public List<Video> getVideos(VideoChannel channel)
+ {
+ List<Video> videos = null;
+ if (channelsMap.get(channel.getName()) != null)
+ {
+ videos = channelsMap.get(channel.getName()).getVideos();
+ }
+ return videos;
+ }
+
+ /**
+ * Get all channels
+ *
+ * @return all channels
+ */
+ public List<VideoChannel> getChannels()
+ {
+ return channelsList;
+ }
+
+ /**
+ * Get only the active channels
+ *
+ * @return the active channels, which were found by the video service provider
+ */
+ public List<VideoChannel> getActiveChannels()
+ {
+ List<VideoChannel> activeVideoChannels = new ArrayList<VideoChannel>();
+ for (VideoChannel channel : channelsList)
+ {
+ if (channel.isActive())
+ {
+ activeVideoChannels.add(channel);
+ }
+ }
+ return activeVideoChannels;
+ }
+
+ /**
+ * Get the default channel, to be selected in the UI by default
+ *
+ * @return the default channel
+ */
+ public VideoChannel getDefaultChannel()
+ {
+ return channelsMap.get(defaultVideoChannel);
+ }
+
+ /**
+ * Rate a video
+ *
+ * @param video video to be rated
+ * @param rate video rate
+ */
+ public void rate(Video video, int rate) throws Exception
+ {
+ // delegate to the video service provider
+ videoServiceProvider.rate(video, rate);
+ }
+
+ /**
+ * Search all videos from all channels
+ *
+ * @param keyword search keyword
+ * @return only the videos that match the keyword
+ */
+ public List<Video> search(String keyword)
+ {
+
+ List<Video> selectedVideos = new ArrayList<Video>();
+
+ // split the keyword into tokens
+ String[] tokens = keyword.split("\\s");
+ int numberOfTokens = tokens.length;
+
+ /*
+ * For each channel, search the videos and try to find all
+ * tokens on each video
+ */
+ int visibleVideosInChannel;
+ for (VideoChannel channel : channelsList)
+ {
+ visibleVideosInChannel = 0;
+ for (Video video : channel.getVideos())
+ {
+
+ int tokensFound = 0;
+
+ if (numberOfTokens > 0)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(video.getTitle());
+ sb.append(" ");
+ sb.append(video.getDescription());
+ sb.append(" ");
+ sb.append(video.getKeywords());
+
+ for (int i = 0; i < tokens.length; i++)
+ {
+ String token = tokens[i];
+ if (sb.toString().toUpperCase().contains(token.toUpperCase()))
+ {
+ tokensFound++;
+ }
+ }
+ }
+
+ // if all tokens were found, mark the video as visible ...
+ if (tokensFound == numberOfTokens)
+ {
+ video.setVisible(true);
+ visibleVideosInChannel++;
+ selectedVideos.add(video);
+ }
+ // ... otherwise, mark the video as not visible
+ else
+ {
+ video.setVisible(false);
+ }
+ }
+ channel.setVisibleVideos(visibleVideosInChannel);
+ }
+
+ return selectedVideos;
+
+ }
+
+ /**
+ * Get the video thumbnail from the internet, given its URL
+ *
+ * @param url video URL
+ * @return the file representing the downloaded thumbnail
+ */
+ public File getThumbnail(URL url)
+ {
+
+ File cacheIconFile = null;
+ HttpUtils httpUtils = new HttpUtils();
+ InputStream inStream = null;
+ FileOutputStream outStream = null;
+ try
+ {
+ inStream = httpUtils.getInputStreamForUrl(url.toString(), new NullProgressMonitor());
+
+ File remoteFile = new File(url.toString());
+ String[] remoteFileName = remoteFile.getName().split("\\.");
+ cacheIconFile = File.createTempFile(remoteFileName[0], "." + remoteFileName[1]);
+ cacheIconFile.deleteOnExit();
+
+ outStream = new FileOutputStream(cacheIconFile);
+
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = inStream.read(buf)) > 0)
+ {
+ outStream.write(buf, 0, len);
+ }
+
+ }
+ catch (Exception e)
+ {
+ StudioLogger.error(this.getClass(), "Error while retrieving video thumbnail", e);
+ }
+ finally
+ {
+ try
+ {
+ inStream.close();
+ outStream.close();
+ }
+ catch (Exception e)
+ {
+ StudioLogger.error(e.getMessage());
+ }
+ }
+
+ return cacheIconFile;
+ }
+
+}