Skip Headers

Oracle® Application Server Syndication Services Developer’s and Administrator’s Guide
10g (9.0.4)
Part No. B10667-01
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous Next

D RSS Content Connector (CPAdaptor)

This appendix provides a listing of the RSSCPAdaptor.java program in Section D.1.

D.1 Listing of the RSSCPAdaptor.java Program

A listing of the RSSCPAdaptor.java program follows:

import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;

import org.w3c.dom.*;
import javax.xml.parsers.*;
import oracle.xml.parser.v2.*;

import oracle.syndicate.message.pkg.*;
import oracle.syndicate.server.cp.*;
import oracle.syndicate.server.cp.message.*;
import oracle.syndicate.server.cp.impl.exmsgs.*;

import oracle.syndicate.util.date.*;

// For testing only.
import oracle.syndicate.util.io.*;
import oracle.syndicate.server.cp.impl.message.*;

/**
 * Content provider adaptor (content connector) creates a
 * CPOffer for each channel defined in a given RSS feed. CPOffers will be 
 * shown to Syndication Services administrators as resources, for which they can create offers. 
 * RSS (Really Simple Syndication) is a mechanism for enabling 
 * lightweight syndication of content.
 * More details on RSS can be found at: http://backend.userland.com/rss.
 * The adaptor exposes only one property:
 * the url of the RSS feed for which the offer has to be created.
 * Custom exception messages can be supplied by subclassing the CPException
 * class.
 * The adaptor code can be compiled as follows:
 *   javac -d demo/cp/rss/classes -classpath lib/syndserver.jar:../../xdk/lib/xmlparserv2.jar demo/cp/rss/src/RSSCPAdaptor.java
 * Standalone unit tests can be run by:
 *   java -Dhttp.proxyHost=www-proxy.us.oracle.com -Dhttp.proxyPort=80 -classpath lib/syndserver.jar:../../xdk/lib/xmlparserv2.jar:lib/redist/jazn/jazn.jar:demo/cp/rss/classes/ RSSCPAdaptor http://static.userland.com/gems/backend/rssTwoExample2.xml "Scripting News" *
 * To install:
 *   java -DORACLE_HOME=$OH -jar lib/syndserver.jar -installConnector -name "RSS Content Connector" -description "Allows to create offers based on RSS feeds" -className RSSCPAdaptor  *
 *  @version $Header: RSSCPAdaptor.java 03-apr-2003.13:23:05 mcarrer Exp $
 *  @author  mcarrer 
 *  @since   release specific (what release of product did this appear in)
 */
public class RSSCPAdaptor 
  implements CPAdaptor, OSSExceptionConstants
{
  private static final String LAST_BUILD_DATE_FORMAT = "EEE, dd MMM yyyy H:mm:ss z";

  private String    _rssurl;
  private CPContext _cpctx;

  public RSSCPAdaptor()
  {}

  /**
   * Returns the URL of the RSS feed.
   */
  public String getRSSURL()
  {
    return _rssurl;
  }

  /**
   * Sets the URL of the RSS feed.
   */
  public void setRSSURL(String rssurl)
  {
    _rssurl = rssurl;
  }

  /**
   * Receives and stores the CPContext from which 
   * you can access the CPMessageFactory object.
   */

  public void init(CPContext cpctx)
    throws CPException
  {
    _cpctx = cpctx;
  }

  public boolean ping()
    throws CPException
  {
    // TODO
    return true;
  }

  /**
   * Returns only one offer corresponding to the RSS content feed.
   */
  public Iterator buildCatalog()
    throws CPException
  {
    Document docrss = parseRSS();
    Element   elrss = docrss.getDocumentElement();
    NodeList  nlchs = elrss.getElementsByTagName("channel");
    
    // Loop over the channels defined in this RSS
    // and for each one, create an offer.
    CPMessageFactory cpmf = _cpctx.getCPMessageFactory();
    ArrayList      alOffs = new ArrayList();
    for (int i=0; i<nlchs.getLength(); i++) {

      // For each channel, you will create 
      // a CPOffer. CPOffers are shown to 
      // Syndication administrators as content
      // provider resources from which you can build offers.
      Element  elCh = (Element) nlchs.item(i);
      CPOffer cpoff = cpmf.createCPOffer();
      
      // Each offer must have a unique ID for its content provider.
      // Set the mandatory ID attribute and any other
      // optional attributes.
      String title = getChildElementValue(elCh, "title");
      if ((title == null) || (title.trim().length() == 0)) {
        title = "unknown";
      }

      // Set the offer properties.
      cpoff.setCPOfferID(title);
      cpoff.setName(title);
      cpoff.setDescription(getChildElementValue(elCh,  "description"));
      cpoff.setRightsHolder(getChildElementValue(elCh, "copyright"));
      cpoff.setProductName("OracleAS Syndication Services RSS Feed Import");
      cpoff.setAtomicUse(false);
      cpoff.setEditable(true);
      cpoff.setShowCredit(false);
      cpoff.setUsageRequired(false);
      
      alOffs.add(cpoff);
    }

    return alOffs.iterator();  }

  public CPPackage buildPackage(CPPackageRequest req,
                                CPRequestContext ctx)
    throws CPException
  {
    // Parse the RSS document.
    Document docrss = parseRSS();
    Element   elrss = docrss.getDocumentElement();
    Element    elCh = getChannelElement(elrss, req.getOfferID());

    // Create a new content package and initialize
    // its properties by using RSS feed values.
    CPMessageFactory cpmf = _cpctx.getCPMessageFactory();
    CPPackage  pkg = cpmf.createCPPackage();

    // Check if the RSS feed has been modified since the
    // the last content package request.
    String oldState = req.getState();
    String newState = getChildElementValue(elCh, "lastBuildDate");

    Date dNewState = getDate(newState);
    Date dOldState = null;
    if (!oldState.equals(INITIAL_STATE)) {

      dOldState = getDate(oldState);
      if ((dOldState != null) && 
          (dNewState != null) && 
          dOldState.equals(dNewState)) {
          
        // The RSS feed has not been updated
        // since the last visit. Throw an exception
        // notifying that the content package sequence is
        // up-to-date and no update needs to be reported.
        throw new CPException(CPExceptionConstants.CP_PACKAGE_UP_TO_DATE);
      }
      // This is an incremental update over
      // the previous update that was sent.
      // Set the full update flag accordingly.
      pkg.setFullUpdate(false);
    }
    else {

      // This is a request for a full new update.
      // Set the full update flag accordingly.
      pkg.setFullUpdate(true);
    }
    pkg.setOldState(oldState);
    pkg.setNewState(newState);
    
    // Scan through the RSS items, building 
    // corresponding CPItem objects.    
    NodeList nlItems = elCh.getElementsByTagName("item");
    for (int i=0; i<nlItems.getLength(); i++) {

      Element elItem = (Element) nlItems.item(i);
      CPItem cpi = cpmf.createCPItem();

      // Sets item file name and content type.
      // Each RSS news item will have a dummy file name
      // and an XML code excerpt for the associated news.
      String itemFilename = "item"+i+".xml";
      cpi.setContentFilename(itemFilename);
      cpi.setContentType("text/xml");

      // Sets the item ID.
      String guid = getChildElementValue(elItem, "guid");
      if (guid != null) {
        cpi.setID(guid);
      }

      // Sets the item name.
      String title = getChildElementValue(elItem, "title");
      if (title != null) {
        cpi.setName(title);
      }
      else {
        // Item name is mandatory,
        // so you need to set it
        // to a value.
        cpi.setName(itemFilename);
      }

      // Sets the item activation date, if any.
      String pubDate = getChildElementValue(elItem, "pubDate");
      if (pubDate != null) {
        Date dPubDate = getDate(pubDate);        
        cpi.setActivation( new ISODateTime(dPubDate));
      }

      // Set the item content to the RSS item XML element.
      try {
        StringWriter sw = new StringWriter();
        ((XMLElement) elItem).print( new PrintWriter(sw));
        ContentAccessor ca = cpmf.createContentAccessor(sw.toString());
        cpi.setContent(ca);
      }
      catch(Exception e) {
        throw new CPException(CPExceptionConstants.CP_GENERIC_ERROR, e, e);
      }

      // Add the item to the content package.
      pkg.addPackageItem(cpi);
    }

    return pkg;
  }

  public void closePackage(CPRequestContext ctx)
    throws CPException
  {
  }

  private Document parseRSS()
    throws CPException
  {
    Document doc = null;
    InputStream is = null;
    try {

      URL url = new URL(_rssurl);
      URLConnection urlc = url.openConnection();
      is = urlc.getInputStream();

      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
      doc = db.parse(is);
    }
    catch (Exception e) {
      throw new CPException(CPExceptionConstants.CP_GENERIC_ERROR, e, e);
    }
    finally {
      if (is != null) {
        try { is.close(); }
        catch (Exception e) {
          throw new CPException(CPExceptionConstants.CP_GENERIC_ERROR, e, e);
        }        
      }
    }

    return doc;
  }


  private String getChildElementValue(Element el,
                                      String tagName)
    throws CPException
  {
    String value = null;
    try {

      NodeList  nl = el.getElementsByTagName(tagName);
      if (nl.getLength() > 0) {
        
        Element elChild = (Element) nl.item(0);
        NodeList nl1 = elChild.getChildNodes();
        for(int i=0; i<nl1.getLength(); i++) {
          
          Node nChild = nl1.item(i);
          int  iNodeType = nChild.getNodeType();
          if (iNodeType == Node.TEXT_NODE) {
            value = nChild.getNodeValue();
            break;
          }
        }        
      }
    }
    catch (Exception e) {
      throw new CPException(CPExceptionConstants.CP_GENERIC_ERROR, e, e);
    }

    return value;
  }

  private Element getChannelElement(Element el,
                                    String chName)
    throws CPException
  {
    Element elch = null;
    try {

      NodeList nl = el.getElementsByTagName("channel");
      for (int i=0; i<nl.getLength(); i++) {
        
        Element elTemp = (Element) nl.item(i);
        String  chTitle = getChildElementValue(elTemp, "title");
        if (chTitle.equals(chName)) {
          elch = el;
          break;
        }
      }
    }
    catch (Exception e) {
      throw new CPException(CPExceptionConstants.CP_GENERIC_ERROR, e, e);
    }

    return elch;
  }

  private Date getDate(String sd)
    throws CPException
  { 
    Date d = null;
    try {

      if ((sd != null) && (sd.trim().length() != 0)) {
        SimpleDateFormat sdf = new SimpleDateFormat(LAST_BUILD_DATE_FORMAT);
        d = sdf.parse(sd);
      }
    }
    catch (Exception e) {
      throw new CPException(CPExceptionConstants.CP_GENERIC_ERROR, e, e);
    }

    return d;  }

  public static void main(String argv[])    throws Exception
  {
    String rssurl = argv[0];
    String  offid = argv[1];
    
    RSSCPAdaptor rsscp = new RSSCPAdaptor();
    rsscp.init( new oracle.syndicate.server.cp.impl.CPContextImpl());
    rsscp.setRSSURL(rssurl);

    Iterator itOffs = rsscp.buildCatalog();
    while (itOffs.hasNext()) {

      CPOffer cpoff = (CPOffer) itOffs.next();
      System.out.println("id: "+cpoff.getCPOfferID());
      System.out.println("name: "+cpoff.getName());
      System.out.println("desc: "+cpoff.getDescription());
      System.out.println("rh: "+cpoff.getRightsHolder());
      System.out.println("pn: "+cpoff.getProductName());
    }

    CPPackage pkg = rsscp.buildPackage( new CPPackageRequestImpl(null, null, 
                                                                 offid, null,
                                                                 null),
                                        null);
    Iterator itItems = pkg.getPackageItems();
    while (itItems.hasNext()) {

      CPItem cpi = (CPItem) itItems.next();
      System.out.println("id: "+cpi.getID());
      System.out.println("title: "+cpi.getName());
      System.out.println("actv: "+cpi.getActivation());

      ContentAccessor ca = cpi.getContent();
      InputStream cais = ca.openStream();
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      IOUtils.pipe(cais, baos);
      System.out.println(baos.toString());

      System.out.println("");
    }
  }
}