import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.rss.Guid;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
import com.sun.syndication.io.FeedException;

import java.net.URL;
import java.io.InputStream;
import java.io.IOException;
import java.util.List;
import java.util.Date;
import java.util.Iterator;


public class RssFeed
{
	public  SyndFeed feedData;

	private RssFeed()
	{
	}

	public static RssFeed parse(InputStream strIn) throws FeedException, IOException
	{
		RssFeed feed = new RssFeed();

		SyndFeedInput synIn = new SyndFeedInput();
		synIn.setPreserveWireFeed(true);

		feed.feedData = synIn.build( new XmlReader(strIn) );
		return feed;
	}

	public String getTitle()
	{
		return CleanTitle( feedData.getTitle() );
	}

	public Date getDate()
	{
		Date[] dates = new Date[]{ feedData.getPublishedDate() };
		return CleanDate(dates);
	}

	public RssItem[] getItems()
	{
		List entries = feedData.getEntries();

		RssItem[] items = new RssItem[entries.size()];

		SyndEntry entry;
		Date[] dates;
		for(int i=0;i<entries.size();i++)
		{
			entry = (SyndEntry) entries.get(i);
			dates = new Date[]{ entry.getPublishedDate() , entry.getUpdatedDate() };

			items[i] = new RssItem();
			items[i].content = entry.getDescription().getValue();
			items[i].title = CleanTitle(entry.getTitle());
			items[i].link = CleanLink(entry.getLink());
			items[i].date = CleanDate(dates);
			items[i].guid = GetGuid(entry, GetGuid(entry,items[i].link));	//See GetGuid
		}
		return items;
	}

	private static String CleanTitle(String str)
	{
		if( str == null || str.trim().equals("") )
			return "UNKOWEN TITLE";
		else
			return str;
	}

	private static Date CleanDate(Date[] dates)
	{
		Date max = null;
		for(int i=0;i<dates.length;i++)
			if( ( dates[i] != null ) && ( max == null || dates[i].after(max) ) )
				max = dates[i];

		if( max == null )
			max = new Date();

		return max;
	}

	private static String GetGuid(SyndEntry se,String def)
	{
		Object wireEntry = se.getWireEntry();

		if( wireEntry !=null )
		{
			String guid = null;

			if( wireEntry instanceof Entry )	//atom
			{
				guid = ( (Entry) wireEntry ).getId();
			}else if( wireEntry instanceof Item)	//rss
			{
				Guid guidObj = ( (Item) wireEntry ).getGuid();

				if( guidObj != null )
					guid = guidObj.getValue();
			}

			if( guid != null)
				return guid;
		}

		return def;
	}

	private static String CleanLink(String link)
	{
		if( link != null && IsURI(link))
		{
			return link.replaceAll("&amp;","&").replaceAll("&#38;","&");
		}

		return "UNKOWEN LINK";
	}

	private static boolean IsURI(String link)
	{
		try
		{
			new java.net.URI(link);
		}catch(Exception e)
		{
			return false;
		}

		return true;
	}
}