Package org.jampa.model.podcasts

Source Code of org.jampa.model.podcasts.Podcast

/*
* Jampa
* Copyright (C) 2008-2009 J. Devauchelle and contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 3 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

package org.jampa.model.podcasts;

import java.io.File;
import java.io.FileWriter;
import java.io.StringReader;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.jampa.logging.Log;
import org.jampa.model.IAudioItem;
import org.jampa.model.IPlaylist;
import org.jampa.net.podcast.PodcastUpdater;
import org.jampa.utils.SystemUtils;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class Podcast implements IPlaylist {
 
  private static final String PODCAST_TAG = "podcast";
  private static final String NAME_TAG = "name";
  private static final String TITLE_TAG = "title";
  private static final String DESCRIPTION_TAG = "description";
  private static final String URL_TAG = "url";
  private static final String POSITION_TAG = "position";
  private static final String DATA_TAG = "data";
  private static final String ITEMS_TAG = "items";
  private static final String PODCAST_ITEM_TAG = "podcastItem";
  private static final String PODCAST_ITEM_TITLE_ATTR = "title";
  private static final String PODCAST_ITEM_DATE_ATTR = "date";
  private static final String PODCAST_ITEM_URL_ATTR = "url";
  private static final String PODCAST_ITEM_DURATION_ATTR = "duration";
  private static final String PODCAST_ITEM_READ_ATTR = "read";
 
  private static final String VERSION_ATTRIBUTE = "version";
  private static final String XMLNS_ATTRIBUTE = "xmlns";
  private static final String XMLNS_ATTRIBUTE_VALUE = "http://jampa.sourceforge.net/podcast/";
 
  private static final String CDATA_OPEN_TAG = "<![CDATA[";
  private static final String CDATA_CLOSE_TAG = "]]>";
 
  private String _fileName;
 
  private String _name; 
  private String _title;
  private String _description;
  private String _url;
  private int _position;
  private String _data;
 
  private List<PodcastItem> _items;
 
  public Podcast() {
    _name = "";
    _title = "";
    _url = "";
    _description = "";
    _data = "";
   
    _items = new ArrayList<PodcastItem>();
  }
 
  public Podcast(Podcast oldPodcast) {
    _name = oldPodcast._name;
    _title = oldPodcast._title;
    _url = oldPodcast._url;
    _description = oldPodcast._description;
    _data = oldPodcast._data;
    _position = oldPodcast._position;
   
    _items = oldPodcast._items;
  }
 
  public Podcast(String name, String title, String url, String description) {
    this();
    setName(name);
    _title = title;
    _url = url;
    _description = description;       
  }
 
  public void download() {
    PodcastUpdater downloader = new PodcastUpdater(_url);
   
    if (downloader.download()) {
      _data = downloader.getData();
    } else {
      _data = "";
    }
  }
 
  public void loadFromDisk() {       
   
    Document document = null;   
   
    try {
     
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     
      DocumentBuilder builder = factory.newDocumentBuilder();

      File file = new File(_fileName);     
      document = builder.parse(file);

      Element podcast = document.getDocumentElement();
     
      if ((podcast == null) ||
          (!podcast.getNodeName().equals(PODCAST_TAG))) {
        Log.getInstance(Podcast.class).info("Empty podcast: " + _fileName); //$NON-NLS-1$
        return;
      }
     
      if ((podcast.hasAttribute(XMLNS_ATTRIBUTE)) &&
          (podcast.getAttribute(XMLNS_ATTRIBUTE).equals(XMLNS_ATTRIBUTE_VALUE))) {
       
        NodeList nameList = document.getElementsByTagName(NAME_TAG);
        if ((nameList != null) &&
            (nameList.getLength() > 0)) {
          _name = URLDecoder.decode(nameList.item(0).getTextContent(), "UTF-8");
          //_name = nameList.item(0).getTextContent();
        }
       
        NodeList titleList = document.getElementsByTagName(TITLE_TAG);
        if ((titleList != null) &&
            (titleList.getLength() > 0)) {
          _title = URLDecoder.decode(titleList.item(0).getTextContent(), "UTF-8");
          //_title = titleList.item(0).getTextContent();
        }
       
        NodeList descList = document.getElementsByTagName(DESCRIPTION_TAG);
        if ((descList != null) &&
            (descList.getLength() > 0)) {
          _description = URLDecoder.decode(descList.item(0).getTextContent(), "UTF-8");
          //_description = descList.item(0).getTextContent();
        }
       
        NodeList positionList = document.getElementsByTagName(POSITION_TAG);
        if ((positionList != null) &&
            (positionList.getLength() > 0)) {
          try {
            _position = Integer.parseInt(positionList.item(0).getTextContent());
          } catch (NumberFormatException e) {
            _position = Integer.MAX_VALUE;
          }
        }
       
        NodeList urlList = document.getElementsByTagName(URL_TAG);
        if ((urlList != null) &&
            (urlList.getLength() > 0)) {
          _url = URLDecoder.decode(urlList.item(0).getTextContent(), "UTF-8");
          //_url = urlList.item(0).getTextContent();
        }
       
        NodeList dataList = document.getElementsByTagName(DATA_TAG);
        if ((dataList != null) &&
            (dataList.getLength() > 0)) {
          _data = URLDecoder.decode(dataList.item(0).getTextContent().replace(CDATA_OPEN_TAG, "").replace(CDATA_CLOSE_TAG, ""), "UTF-8");
          //_data = dataList.item(0).getTextContent().replace(CDATA_OPEN_TAG, "").replace(CDATA_CLOSE_TAG, "");
        }
       
        NodeList podcastItemsList = document.getElementsByTagName(ITEMS_TAG);
        if ((podcastItemsList != null) &&
            (podcastItemsList.getLength() > 0)) {
          Node item;
          PodcastItem podcastItem;
          NodeList podcastItems = podcastItemsList.item(0).getChildNodes();
          for (int i = 0; i < podcastItems.getLength(); i++) {
            String title = "";
            String date = "";
            String url = "";
            int duration = 0;
            boolean read = false;
            Node tmpNode;
            item = podcastItems.item(i);
           
            if (item.getNodeName().equals(PODCAST_ITEM_TAG)) {
              NamedNodeMap itemMap = item.getAttributes();
              title = URLDecoder.decode(itemMap.getNamedItem(PODCAST_ITEM_TITLE_ATTR).getTextContent(), "UTF-8");
              date = URLDecoder.decode(itemMap.getNamedItem(PODCAST_ITEM_DATE_ATTR).getTextContent(), "UTF-8");
              url = URLDecoder.decode(itemMap.getNamedItem(PODCAST_ITEM_URL_ATTR).getTextContent(), "UTF-8");
              try {
                duration = Integer.parseInt(itemMap.getNamedItem(PODCAST_ITEM_DURATION_ATTR).getTextContent());
              } catch (Exception e) {
                duration = 0;
              }
              tmpNode = itemMap.getNamedItem(PODCAST_ITEM_READ_ATTR);
              if (tmpNode != null) {
                read = Boolean.parseBoolean(tmpNode.getTextContent());
              } else {
                read = false;
              }
              podcastItem = new PodcastItem(this, title, date, url, duration, read);
              _items.add(podcastItem);
            }
          }
        }

      } else {
        Log.getInstance(Podcast.class).info("Invalid podcast (xmlns missmatch): " + _fileName); //$NON-NLS-1$
      }
     
     
    } catch (Exception e) {
      Log.getInstance(Podcast.class).error("Error while reading podcast: " + _fileName + " (" + e.getMessage() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$   
    }
  }
 
  public void writeToDisk() {       
   
    Document document = null;
   
    try {     
      DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = builderFactory.newDocumentBuilder();

      document = builder.newDocument();

      document.setXmlVersion("1.0"); //$NON-NLS-1$
      document.setXmlStandalone(true);     
     
      Element podcastElement = document.createElement(PODCAST_TAG);
      podcastElement.setAttribute(XMLNS_ATTRIBUTE, XMLNS_ATTRIBUTE_VALUE);
      podcastElement.setAttribute(VERSION_ATTRIBUTE, "1");
     
      Element nameElement = document.createElement(NAME_TAG);
      nameElement.setTextContent(URLEncoder.encode(_name, "UTF-8"));
      //nameElement.setTextContent(_name);
      podcastElement.appendChild(nameElement);
     
      Element titleElement = document.createElement(TITLE_TAG);   
      titleElement.setTextContent(URLEncoder.encode(_title, "UTF-8"));
      //titleElement.setTextContent(_title);
      podcastElement.appendChild(titleElement);
     
      Element descElement = document.createElement(DESCRIPTION_TAG);
      descElement.setTextContent(URLEncoder.encode(_description, "UTF-8"));
      //descElement.setTextContent(_description);
      podcastElement.appendChild(descElement);
     
      Element positionElement = document.createElement(POSITION_TAG);
      positionElement.setTextContent(URLEncoder.encode(Integer.toString(_position), "UTF-8"));
      podcastElement.appendChild(positionElement);
     
      Element urlElement = document.createElement(URL_TAG);
      urlElement.setTextContent(URLEncoder.encode(_url, "UTF-8"));
      //urlElement.setTextContent(_url);
      podcastElement.appendChild(urlElement);
     
      Element dataElement = document.createElement(DATA_TAG);
      CDATASection dataSection = document.createCDATASection(DATA_TAG);
      dataSection.setData(URLEncoder.encode(_data, "UTF-8"));
      //dataSection.setData(_data);
      dataElement.appendChild(dataSection);
      podcastElement.appendChild(dataElement);
     
      Element podcastItems = document.createElement(ITEMS_TAG);
     
      Element podcastItem;
      PodcastItem item;
      Iterator<PodcastItem> iter = _items.iterator();
      while (iter.hasNext()) {
        item = iter.next();
        podcastItem = document.createElement(PODCAST_ITEM_TAG);
        podcastItem.setAttribute(PODCAST_ITEM_TITLE_ATTR, URLEncoder.encode(item.getTitle(), "UTF-8"));
        podcastItem.setAttribute(PODCAST_ITEM_DATE_ATTR, URLEncoder.encode(item.getDate(), "UTF-8"));
        podcastItem.setAttribute(PODCAST_ITEM_DURATION_ATTR, URLEncoder.encode(Integer.toString(item.getDuration()), "UTF-8"));
        podcastItem.setAttribute(PODCAST_ITEM_URL_ATTR, URLEncoder.encode(item.getUrl(), "UTF-8"));
        podcastItem.setAttribute(PODCAST_ITEM_READ_ATTR, Boolean.toString(item.isRead()));
       
        podcastItems.appendChild(podcastItem);
      }
      podcastElement.appendChild(podcastItems);
     
      document.appendChild(podcastElement);
     
      DOMSource domSource = new DOMSource(document);
      FileWriter writer = new FileWriter(new File(_fileName));
      StreamResult result = new StreamResult(writer);
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer transformer = tf.newTransformer();
      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
      //transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
      transformer.transform(domSource, result);    
     
      writer.flush();
      writer.close();
     
    } catch (Exception e) {
      Log.getInstance(Podcast.class).error("Error while writting file: " + _fileName + " (" + e.getMessage() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    }
  }
 
  private PodcastItem getOldPodcastItem(List<PodcastItem> list, String url) {
    PodcastItem result = null;
   
    PodcastItem item = null;
    boolean stop = false;
    Iterator<PodcastItem> iter = list.iterator();
    while ((!stop) &&
        (iter.hasNext())) {
      item = iter.next();
      if (item.getUrl().equals(url)) {
        stop = true;
      }
    }
   
    if (stop) {
      result = item;
    }
   
    return result;
  }
 
  private boolean doesItemExistsInList(List<PodcastItem> list, PodcastItem item) {
    boolean result = false;
   
    PodcastItem iterItem;
    Iterator<PodcastItem> iter = list.iterator();
    while ((iter.hasNext()) &&
        (!result)) {
      iterItem = iter.next();
      if (iterItem.getUrl().equals(item.getUrl())) {
        result = true;
      }
    }
   
    return result;
  }
 
  private int countNewItems(List<PodcastItem> oldList) {
    int result = 0;
   
    PodcastItem item;
    Iterator<PodcastItem> iter = _items.iterator();
    while (iter.hasNext()) {
      item = iter.next();
      if (!doesItemExistsInList(oldList, item)) {
        result++;
      }
    }
   
    return result;
  }
 
  public int parseData() {
   
    List<PodcastItem> oldList = _items;
    _items = new ArrayList<PodcastItem>();
   
    try {
      if ((_data != null) &&
          (!_data.isEmpty())) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        DocumentBuilder builder = factory.newDocumentBuilder();     

        Document document = builder.parse(new InputSource(new StringReader(_data)));

        Element rss = document.getDocumentElement();

        if ((rss == null) ||
            (!rss.getNodeName().equals(PodcastRssConstants.RSS_TAG))) {
          return 0;
        }

        NodeList channelNodeList = rss.getElementsByTagName(PodcastRssConstants.CHANNEL_TAG);
        if ((channelNodeList != null) &&
            (channelNodeList.getLength() > 0)) {
          Node channelNode = channelNodeList.item(0);

          NodeList channelItems = channelNode.getChildNodes();
          for (int i = 0; i < channelItems.getLength(); i++) {
            if (channelItems.item(i).getNodeName().equals(PodcastRssConstants.CHANNEL_TITLE_TAG)) {
              _title = channelItems.item(i).getTextContent();
            }
           
            if (channelItems.item(i).getNodeName().equals(PodcastRssConstants.CHANNEL_DESC_TAG)) {
              _description = channelItems.item(i).getTextContent();
            }

            // TODO: read all

            if (channelItems.item(i).getNodeName().equals(PodcastRssConstants.ITEM_TAG)) {
              NodeList itemsList = channelItems.item(i).getChildNodes();

              String title = "";
              String date = "";
              String url = "";
              String type = "";
              PodcastItem oldItem = null;
              int duration = 0;

              for (int j = 0; j < itemsList.getLength(); j++) {
                if (itemsList.item(j).getNodeName().equals(PodcastRssConstants.ITEM_TITLE_TAG)) {
                  title = itemsList.item(j).getTextContent();
                } else if (itemsList.item(j).getNodeName().equals(PodcastRssConstants.ITEM_DATE_TAG)) {
                  date = itemsList.item(j).getTextContent();
                } else if (itemsList.item(j).getNodeName().equals(PodcastRssConstants.ITEM_ENCLOSURE_TAG)) {
                  NamedNodeMap enclosureMap = itemsList.item(j).getAttributes();
                  type = enclosureMap.getNamedItem(PodcastRssConstants.ITEM_ENCLOSURE_TYPE).getTextContent();
                  if ((type != null) &&
                      (!type.isEmpty()) &&
                      (type.equals(PodcastRssConstants.ITEM_ENCLOSURE_TYPE_VALUE))) {
                    url = enclosureMap.getNamedItem(PodcastRssConstants.ITEM_ENCLOSURE_URL).getTextContent();
                    duration = Integer.parseInt(enclosureMap.getNamedItem(PodcastRssConstants.ITEM_ENCLOSURE_LENGTH).getTextContent());
                  }
                }
              }         

              if ((url != null) &&
                  (!url.isEmpty())) {
                PodcastItem newItem;
                oldItem = getOldPodcastItem(oldList, url);
               
                if (oldItem != null) {
                  newItem = oldItem;                 
                  newItem.setParent(this);
                  newItem.setTitle(title);
                  newItem.setDate(date);
                  newItem.setUrl(url);
                  newItem.setDuration(duration);
                } else {
                  newItem = new PodcastItem(this, title, date, url, duration, false);
                }
                               
                _items.add(newItem);
              }
            }
          }       
        }
      }     
    } catch (Exception e) {
      Log.getInstance(Podcast.class).error("Error while reading data: (" + e.getMessage() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
      return 0;
    }
   
    return countNewItems(oldList);
  }
 
  public void deletePodcast() {
    File file = new File(_fileName);
    if (file.exists())
      file.delete();
  }
 
  public void setName(String value) {
    _name = value;
    _fileName = SystemUtils.podcastDirectory + _name + ".xml";
  }
 
  public String getName() {
    return _name;
  }
 
  public String getTitle() {
    return _title;
  }
 
  public String getDescription() {
    return _description;
  }
 
  public String getUrl() {
    return _url;
  }
 
  public void setUrl(String value) {
    _url = value;
  }
 
  public int getPosition() {
    return _position;
  }
 
  public void setPosition(int value) {
    _position = value;
  }
 
  public void setData(String value) {
    _data = value;
  }
 
  public List<PodcastItem> getPodcastList() {
    return _items;
  }

  @Override
  public IAudioItem getAudioItemByIndex(int index) {   
    return _items.get(index);
  }

  @Override
  public int getAudioItemIndex(IAudioItem item) {
    return _items.indexOf(item);
  }

  @Override
  public int getPlaylistMaxIndex() {   
    return _items.size() - 1;
  }
 
  public int getItemsCount() {
    return _items.size();
  }
 
  public int getUnreadItemsCount() {
    int result = 0;
   
    Iterator<PodcastItem> iter = _items.iterator();
    while (iter.hasNext()) {
      if (!iter.next().isRead()) {
        result++;
      }
    }
   
    return result;
  }
 
  public boolean hasAudioItemPlaying() {
    boolean result = false;
    for (int i = 0; i < _items.size(); i++) {
      if (_items.get(i).isBoPlaying()) {
        result = true;
        break;
      }
    }
   
    return result;
  }
 
  public void setReadStatus(boolean newStatus) {
    Iterator<PodcastItem> iter = _items.iterator();
    while (iter.hasNext()) {
      iter.next().setRead(newStatus);
    }     
  }

}
TOP

Related Classes of org.jampa.model.podcasts.Podcast

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.