All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sakaiproject.news.impl.BasicNewsChannel Maven / Gradle / Ivy

/**********************************************************************************
 * $URL: https://source.sakaiproject.org/svn/web/tags/sakai-10.7/news-impl/impl/src/java/org/sakaiproject/news/impl/BasicNewsChannel.java $
 * $Id: BasicNewsChannel.java 115829 2012-11-07 13:07:22Z [email protected] $
 ***********************************************************************************
 *
 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 The Sakai Foundation
 *
 * Licensed under the Educational Community 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.opensource.org/licenses/ECL-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 org.sakaiproject.news.impl;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.javax.Filter;
import org.sakaiproject.news.api.NewsChannel;
import org.sakaiproject.news.api.NewsConnectionException;
import org.sakaiproject.news.api.NewsFormatException;
import org.sakaiproject.news.api.NewsItem;
import org.sakaiproject.news.api.NewsItemEnclosure;
import org.sakaiproject.util.FormattedText;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.util.Validator;
import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.tool.cover.SessionManager;

import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndImage;
import com.sun.syndication.fetcher.FeedFetcher;
import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
import com.sun.syndication.io.ParsingFeedException;

/***********************************************************************************
 * NewsChannel implementation
 **********************************************************************************/

public class BasicNewsChannel implements NewsChannel
{
	protected String m_source = null;
	
	protected String m_userAgent = null;
	
	protected String m_link = null;

	protected String m_title = null;

	protected String m_description = null;

	protected String m_language = null;

	protected String m_copyright = null;

	protected String m_pubdate = null;

	protected String m_lastbuilddate = null;

	protected String m_imageLink = null;

	protected String m_imageTitle = null;

	protected String m_imageUrl = null;

	protected String m_imageHeight = "31";

	protected String m_imageWidth = "88";

	protected String m_imageDescription = null;

	protected List m_items = null;

	/** Our log (commons). */
	private static Log M_log = LogFactory.getLog(BasicNewsService.class);
	
	private ResourceLoader rl = new ResourceLoader("news-impl");

	
	/**
	 * Construct.
	 * 
	 * @param source
	 *        The URL from which the feed can be obtained
	 * @param userAgent
	 *        The user agent to make the request as.
	 * @exception NewsConnectionException,
	 *            for errors making the connection.
	 * @exception NewsFormatException,
	 *            for errors in the URL or errors parsing the feed.
	 */
	public BasicNewsChannel(String source, String userAgent) throws NewsConnectionException, NewsFormatException
	{
		if (m_items == null)
		{
			m_items = new Vector();
		}

		// get the file, parse it and cache it
		// throw NewsConnectionException if unable to get file
		// throw NewsFormatException if file is in wrong format
		m_userAgent = userAgent;
		initChannel(source);
	}


	// get the file, parse it and cache it
	// throw NewsConnectionException if unable to get file
	// throw NewsFormatException if file is in wrong format
	// updated to use ROME syndication api
	private void initChannel(String source) throws NewsConnectionException, NewsFormatException
	{
		SyndFeed feed = null;

		try
		{
			// if feedUrl is on this sakai server, add session parameter
			if ( source.startsWith( ServerConfigurationService.getServerUrl() ) )
			{
				String sessionId = SessionManager.getCurrentSession().getId();
				if ( source.indexOf("?")!= -1 )
					source = source+"&session="+sessionId;
				else
					source = source+"?session="+sessionId;
			}
			
			URL feedUrl = new URL(source);
			FeedFetcher feedFetcher = new HttpURLFeedFetcher();
			feedFetcher.setUserAgent(m_userAgent);
			feed = feedFetcher.retrieveFeed(feedUrl);
		}
		catch (MalformedURLException e)
		{
			if (M_log.isDebugEnabled()) M_log.debug("initChannel(" + source + ") bad url: " + e.getMessage());
			throw new NewsFormatException("\"" + source + "\" " + rl.getString("is_not_a_valid_url"));
		}
		catch (IOException e)
		{
			if (M_log.isDebugEnabled())
				M_log.debug("initChannel(" + source + ") constructor: couldn't connect: " + e.getMessage());
			throw new NewsConnectionException( rl.getString("unable_to_obtain_news_feed") + " " + source);
		}
		catch (ParsingFeedException pfe)
		{
			M_log.info("initChannel(" + source + ") constructor: couldn't parse: "+ source, pfe);
			throw new NewsConnectionException(rl.getString("unable_to_interpret") +" " + source);
		}
		catch (Exception e)
		{
			M_log.info("initChannel(" + source + ") constructor: couldn't parse: " + e.getMessage());
			throw new NewsConnectionException(rl.getString("unable_to_interpret") +" " + source);
		}

		m_title = FormattedText.processEscapedHtml(feed.getTitle());
		m_source = source;
		m_description = FormattedText.processEscapedHtml(feed.getDescription());
		m_description = Validator.stripAllNewlines(m_description);

		m_lastbuilddate = "";
		m_pubdate = "";
		Date pubdate = feed.getPublishedDate();
		if (pubdate != null)
		{
			m_pubdate = FormattedText.processEscapedHtml(DateFormat.getDateInstance().format(pubdate));
			m_lastbuilddate = m_pubdate;
		}
		m_pubdate = Validator.stripAllNewlines(m_pubdate);
		m_lastbuilddate = Validator.stripAllNewlines(m_lastbuilddate);

		m_copyright = FormattedText.processEscapedHtml(feed.getCopyright());
		m_copyright = Validator.stripAllNewlines(m_copyright);

		m_language = FormattedText.processEscapedHtml(feed.getLanguage());
		m_language = Validator.stripAllNewlines(m_language);

		m_link = FormattedText.processEscapedHtml(feed.getLink());
		m_link = Validator.stripAllNewlines(m_link);

		SyndImage image = feed.getImage();
		if (image != null)
		{
			m_imageLink = FormattedText.processEscapedHtml(image.getLink());
			m_imageLink = Validator.stripAllNewlines(m_imageLink);

			m_imageTitle = FormattedText.processEscapedHtml(image.getTitle());
			m_imageTitle = Validator.stripAllNewlines(m_imageTitle);

			m_imageUrl = FormattedText.processEscapedHtml(image.getUrl());
			m_imageUrl = Validator.stripAllNewlines(m_imageUrl);

			m_imageHeight = "";

			m_imageWidth = "";

			m_imageDescription = FormattedText.processEscapedHtml(image.getDescription());
			m_imageDescription = Validator.stripAllNewlines(m_imageDescription);

		}
		// others??
		m_items = new Vector();

		List items = feed.getEntries();

		for (int i = 0; i < items.size(); ++i)
		{
			SyndEntry entry = (SyndEntry) items.get(i);

			String iTitle = FormattedText.processEscapedHtml(entry.getTitle());
			iTitle = Validator.stripAllNewlines(iTitle);

			String iDescription = null;
			try
			{
				if (entry.getDescription() != null)
				{
					iDescription = FormattedText.processEscapedHtml(
						entry.getDescription().getValue());
					iDescription = Validator.stripAllNewlines(iDescription);
				}
			}
			catch (Exception e)
			{
				M_log.warn(e);
			}

			String iLink = FormattedText.processEscapedHtml(entry.getLink());
			iLink = Validator.stripAllNewlines(iLink);
			String iPubDate = "";
			Date entrydate = entry.getPublishedDate();
			if (entrydate != null)
			{
				iPubDate = FormattedText.processEscapedHtml(
				             DateFormat.getDateInstance().format(entrydate));
			}
			
			List enclosures = new Vector();
			List syndEnclosures = entry.getEnclosures();

			for (int j = 0; j < syndEnclosures.size(); j++)
			{
				SyndEnclosure syndEnclosure = (SyndEnclosure) syndEnclosures.get(j);

				enclosures.add(new BasicNewsItemEnclosure(
								FormattedText.processEscapedHtml(syndEnclosure.getUrl()), 
								syndEnclosure.getType(), syndEnclosure.getLength()));

			}
			iPubDate = Validator.stripAllNewlines(iPubDate);
			m_items.add(new BasicNewsItem(iTitle, iDescription, iLink, iPubDate, enclosures));
		}
	} // initChannel

	/**
	 * A .
	 * 
	 * @return the NewsItem that has the specified id.
	 */
	public List getNewsitems()
	{
		List rv = new Vector();
		rv.addAll(m_items);

		return rv;

	} // getNewsitems

	/**
	 * A .
	 * 
	 * @param filter
	 *        A filtering object to accept messages, or null if no filtering is desired.
	 * @return a list of NewsItems objects (may be empty).
	 */
	public List getNewsitems(Filter filter)
	{
		List items = new Vector(m_items);
		if (filter != null)
		{
			List accepted = new Vector();
			Iterator it = items.iterator();
			while (it.hasNext())
			{
				NewsItem item = (NewsItem) it.next();
				if (filter.accept(item))
				{
					accepted.add(item);
				}
			}
			items = accepted;
		}
		return items;
	}

	public String getSource()
	{
		return m_source;
	}

	public String getLink()
	{
		return m_link;
	}

	public String getTitle()
	{
		return m_title;
	}

	public String getDescription()
	{
		return m_description;
	}

	public String getLanguage()
	{
		return m_language;
	}

	public String getCopyright()
	{
		return m_copyright;
	}

	public String getPubdate()
	{
		return m_pubdate;
	}
	public Date getPubdateInDateFormat(){
		if (m_pubdate!=null) {
			try {
				return DateFormat.getInstance().parse(m_pubdate);
			} catch (ParseException e) {}
		}
		return new Date();
	}

	public String getLastbuilddate()
	{
		return m_lastbuilddate;
	}
	public Date getLastbuilddateInDateFormat(){
		if (m_lastbuilddate!=null) {
			try {
				return DateFormat.getInstance().parse(m_lastbuilddate);
			} catch (ParseException e) {}
		}
		return new Date();
	}

	public String getImageUrl()
	{
		return m_imageUrl;
	}

	public String getImageTitle()
	{
		return m_imageTitle;
	}

	public String getImageLink()
	{
		return m_imageLink;
	}

	public String getImageWidth()
	{
		return m_imageWidth;
	}

	public String getImageHeight()
	{
		return m_imageHeight;
	}

	public String getImageDescription()
	{
		return m_imageDescription;
	}

	public void setNewsitems(List items)
	{
		m_items = new Vector(items);
	}

	public void addNewsitem(NewsItem item)
	{
		m_items.add(item);
	}

	public void setSource(String source) throws NewsConnectionException, NewsFormatException
	{
		m_source = source;
		initChannel(source);
	}

	public void setLink(String link)
	{
		m_link = link;
	}

	public void setTitle(String title)
	{
		m_title = title;
	}

	public void setDescription(String description)
	{
		m_description = description;
	}

	public void setLanguage(String language)
	{
		m_language = language;
	}

	public void setCopyright(String copyright)
	{
		m_copyright = copyright;
	}

	public void setPubdate(String pubdate)
	{
		m_pubdate = pubdate;
	}

	public void setLastbuilddate(String builddate)
	{
		m_lastbuilddate = builddate;
	}

	public void setImageUrl(String imageUrl)
	{
		m_imageUrl = imageUrl;
	}

	public void setImageTitle(String imageTitle)
	{
		m_imageTitle = imageTitle;
	}

	public void setImageLink(String imageLink)
	{
		m_imageLink = imageLink;
	}

	public void setImageWidth(String imageWidth)
	{
		m_imageWidth = imageWidth;
	}

	public void setImageHeight(String imageHeight)
	{
		m_imageHeight = imageHeight;
	}

	public void setImageDescription(String imageDescription)
	{
		m_imageDescription = imageDescription;
	}

	/**
	 * Checks whether an update is available for the rss news feed.
	 * 
	 * @return true if update is available, false otherwise
	 */
	public boolean isUpdateAvailable()
	{
		// %%%%%%%%
		return true;
	}

	/**
	 * Checks the relative ordering of the String url's of two Channels. Same 
	 * response pattern as compareTo method for Strings--negative if "this" 
	 * object is greater than parameter, zero if the objects are equal, and 
	 * positive if "this" object is less than the parameter. The parameter 
	 * can be a String reference or a NewsChannel object (otherwise method 
	 * throws ClassCastException).
	 * 
	 * @return A negative integer if "this" object is greater than parameter, 
	 * zero if the objects are equal, and a positive integer if "this" object 
	 * is less than the parameter
	 */
	public int compareTo(Object obj) throws ClassCastException
	{
		int rv = 0;
		if (m_source == null)
		{
			if (obj != null)
			{
				rv = -1;
			}
		}
		else if (obj == null)
		{
			rv = 1;
		}
		else if (obj instanceof String)
		{
			rv = m_source.compareTo((String) obj);
		}
		else
		{
			NewsChannel other = (NewsChannel) obj;
			rv = m_source.compareTo(other.getLink());
		}
		return rv;
	}

	/**
	 * Checks whether the parameter obj refers to the same channel as "this" channel.
	 *  The parameter can be a String URL or a NewsChannel object (otherwise method 
	 *  throws ClassCastException).
	 * 
	 * @return true if the channels are the same, false otherwise
	 */
	public boolean equals(Object obj) throws ClassCastException
	{
		return (compareTo(obj) == 0);
	}

	/**
	 * Calculates a hash code for the channel object's URL.
	 * 
	 * @return The hash-code for the String URL to the channel.
	 */
	public int hashCode()
	{
		String hval = "";
		if (m_source != null)
		{
			hval = m_source;
		}

		return hval.hashCode();
	}

} // BasicNewsChannel




© 2015 - 2025 Weber Informatics LLC | Privacy Policy