/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2003-2006 RSSOwl Development Team                                  **
 **   http://www.rssowl.org/                                                 **
 **                                                                          **
 **   All rights reserved                                                    **
 **                                                                          **
 **   This program and the accompanying materials are made available under   **
 **   the terms of the Eclipse Public License 1.0 which accompanies this     **
 **   distribution, and is available at:                                     **
 **   http://www.rssowl.org/legal/epl-v10.html                               **
 **                                                                          **
 **   A copy is found in the file epl-v10.html and important notices to the  **
 **   license from the team is found in the textfile LICENSE.txt distributed **
 **   in this package.                                                       **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Contributors:                                                          **
 **     RSSOwl - initial API and implementation (bpasero@rssowl.org)         **
 **                                                                          **
 **  **********************************************************************  */

package net.sourceforge.rssowl.dao.feedparser;

import net.sourceforge.rssowl.dao.NewsfeedFactoryException;
import net.sourceforge.rssowl.model.Channel;
import net.sourceforge.rssowl.model.ChannelImage;
import net.sourceforge.rssowl.util.shop.StringShop;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.Text;

/**
 * Basic RSS Parser used by RSS versions 0.91, 0.92 and 2.0 to parse Elements
 * that all three have in common. These Elements are all sub-elements of the
 * Channel-Tag and do therefor not belong to the item-element.
 * 
 * @author <a href="mailto:bpasero@rssowl.org">Benjamin Pasero </a>
 * @version 1.2.3
 */
public class BaseRSSParser extends AbstractFeedParser {

  /**
   * Instantiate a new Parser for this format.
   * 
   * @param document The document containing the data to parse
   * @param rssChannel The Channel to fill with data from the document
   * @param url The URL of the Newsfeed that is parsed
   * @param nameSpaces Possible Namespaces of the XML document
   * @throws NewsfeedFactoryException If any error occurs
   */
  protected BaseRSSParser(Document document, Channel rssChannel, String url, Namespace nameSpaces[]) throws NewsfeedFactoryException {
    super(document, rssChannel, url, nameSpaces);
  }

  /**
   * @see net.sourceforge.rssowl.dao.feedparser.AbstractFeedParser#parse()
   */
  protected void parse() throws NewsfeedFactoryException {

    /** Temp String */
    String str;

    /** Get Channel Element */
    Element channel = getChildElement(root, "channel");

    if (channel == null)
      throw new NewsfeedFactoryException(url, null, null, NewsfeedFactoryException.ERROR_INVALID_NEWSFEED);

    /** Title of channel */
    str = getChildValue("title", channel);
    if (StringShop.isset(str))
      rssChannel.setTitle(Text.normalizeString(str));

    /** Link of feed homepage */
    str = getChildValue("link", channel);
    if (StringShop.isset(str))
      rssChannel.setHomepage(str);

    /** Description of channel */
    str = getChildValue("description", channel);
    if (StringShop.isset(str))
      rssChannel.setDescription(Text.normalizeString(str));

    /** Language of channel */
    str = getChildValue("language", channel);
    if (StringShop.isset(str))
      rssChannel.setLanguage(str);

    /** Image of channel */
    Element image = getChildElement(channel, "image");

    if (image != null) {
      ChannelImage rssChannelImage = new ChannelImage();

      /** URL to the Image */
      str = getChildValue("url", image);
      if (StringShop.isset(str))
        rssChannelImage.setImgUrl(str);

      /** Link to the Homepage */
      str = getChildValue("link", image);
      if (StringShop.isset(str))
        rssChannelImage.setLink(str);

      /** Only add Image if a URL is provided */
      if (StringShop.isset(rssChannelImage.getImgUrl()))
        rssChannel.setImage(rssChannelImage);
    }

    /** Copyright of channel */
    str = getChildValue("copyright", channel);
    if (StringShop.isset(str))
      rssChannel.setCopyright(str);

    /** pubDate of channel */
    str = getChildValue("pubDate", channel);
    if (StringShop.isset(str))
      rssChannel.setPubDate(str);

    /** lastBuildDate of channel */
    str = getChildValue("lastBuildDate", channel);
    if (StringShop.isset(str))
      rssChannel.setLastBuildDate(str);

    /** Docs of channel */
    str = getChildValue("docs", channel);
    if (StringShop.isset(str))
      rssChannel.setDocs(str);

    /** Managing Editor of channel */
    str = getChildValue("managingEditor", channel);
    if (StringShop.isset(str))
      rssChannel.setManagingEditor(str);

    /** Webmaster of channel */
    str = getChildValue("webMaster", channel);
    if (StringShop.isset(str))
      rssChannel.setWebmaster(str);

    /** Parse Elements with Dublin Core Module namespace */
    if (dc != null) {

      /** Title of the channel */
      str = getChildValue("title", channel, dc);
      if (StringShop.isset(str))
        rssChannel.setTitle(Text.normalizeString(str));

      /** Description of the channel */
      str = getChildValue("description", channel, dc);
      if (StringShop.isset(str))
        rssChannel.setDescription(Text.normalizeString(str));

      /** Language of channel */
      str = getChildValue("language", channel, dc);
      if (StringShop.isset(str)) {
        rssChannel.setLanguage(str);
      } else {

        /** Check for language declaration in the first NewsItem */
        Element firstNewsItem = getChildElement(channel, "item");

        if (firstNewsItem != null) {
          Element language = firstNewsItem.getChild("language", dc);

          if (language != null)
            rssChannel.setLanguage(language.getTextTrim());
        }
      }

      /** Publisher of the channel */
      str = getChildValue("publisher", channel, dc);
      if (StringShop.isset(str))
        rssChannel.setPublisher(str);

      /** Copyrights of the channel */
      str = getChildValue("rights", channel, dc);
      if (StringShop.isset(str))
        rssChannel.setCopyright(str);

      /** Date of the channel */
      str = getChildValue("date", channel, dc);
      if (StringShop.isset(str))
        rssChannel.setLastBuildDate(str);

      /** Creator of the channel */
      str = getChildValue("creator", channel, dc);
      if (StringShop.isset(str))
        rssChannel.setCreator(str);

      /** Category of the channel */
      str = getChildValue("subject", channel, dc);
      if (StringShop.isset(str))
        rssChannel.setCategory(str);
    }

    /** Parse Elements with Syndication Module namespace */
    if (sy != null) {

      /** updatePeriod of the channel */
      str = getChildValue("updatePeriod", channel, sy);
      if (StringShop.isset(str))
        rssChannel.setUpdatePeriod(str);

      /** updateFrequency of the channel */
      str = getChildValue("updateFrequency", channel, sy);
      if (StringShop.isset(str))
        rssChannel.setUpdateFrequency(str);
    }

    /** Parse Elements with RDF Module namespace */
    if (rdf != null) {

      image = getChildElement(channel, "image");

      /** Image of the channel */
      if (image != null) {
        ChannelImage rssChannelImage = new ChannelImage();

        if (image.getAttributeValue("resource", rdf) != null)
          rssChannelImage.setImgUrl(image.getAttributeValue("resource", rdf));
        else if (getChildElement(image, "url") != null)
          rssChannelImage.setImgUrl(getChildValue("url", image));

        /** Only add Image if an URL is given */
        if (StringShop.isset(rssChannelImage.getImgUrl()))
          rssChannel.setImage(rssChannelImage);
      }
    }
  }
}