package mentata.ldaphttp.forum; // import necessary classes import java.io.IOException; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.XMLReaderFactory; import org.xml.sax.helpers.DefaultHandler; import mentata.ldaphttp.LDAPHttpException; /** * A directory entry that represents a comment in reference to an item in an RSS feed. */ public class rep extends solicitation { // URI for RSS feed private String feed = null; // java class for xml parser private final String PARSER_CLASS = "org.apache.xerces.parsers.SAXParser"; /** * Instantiates an empty template for a rep. */ public rep() throws LDAPHttpException { // set default values for this object setDirectoryLocation("ou=Reps, ou=Comments, ou=Expressions, o=mentata.com", ONE); setLabel("RSS Extracted Posting"); setComment("rep"); // make this an incremental object setIncremental("CRA", "c=CRAcounter, ou=Reps, ou=Comments, ou=Expressions, o=mentata.com", "description"); // relabel some attributes relabelAttribute("description", ""); relabelAttribute("dnqualifier", "Written"); relabelAttribute("content", "I say..."); relabelAttribute("commentform", "You say..."); relabelAttribute("commenthr", ""); // set attribute lists to support retrievability addAttributeList("retrieve_html", new String[] {"description", "link", "commenthr", "dnqualifier", "content", "parent", "commenthr", "child", "commentform"} ); // set attribute lists to support creatability addAttributeList("create_initialize", new String[] {"content"} ); } /** * Retrieves and extracts information from an RSS 1.0 feed. */ public void preCreate() throws LDAPHttpException { // perform standard comment precreation super.preCreate(); // retrieve and parse the RSS feed String uri = getFeed(); RSS1Handler rss_handler = new RSS1Handler(); rss_handler.setItemSubstring( getItemSubstring() ); try { XMLReader reader = XMLReaderFactory.createXMLReader(PARSER_CLASS); reader.setContentHandler(rss_handler); reader.setErrorHandler(rss_handler); InputSource input_source = new InputSource(uri); reader.parse(input_source); // handle feed retrieval exceptions } catch(IOException e) { throw new LDAPHttpException("Unable to fetch the RSS feed: " + e.getMessage() ); // handle feed parsing exceptions } catch(SAXException e) { throw new LDAPHttpException("Unable to parse the RSS feed: " + e.getMessage() ); } // update attribute values with those found in the feed if ( rss_handler.itemFound() ) { resetAttribute("cn", new String[] {rss_handler.getTitle()} ); resetAttribute("description", new String[] {rss_handler.getDescription()} ); resetAttribute("link", new String[] {rss_handler.getLink()} ); // handle the case where the item wasn't found in the feed } else { throw new LDAPHttpException("An item matching " + getItemSubstring() + " was not found in the current feed: " + getFeed() ); } } /** * Sets the URI for the RSS feed. * * @param feed the URI for the RSS feed */ protected final void setFeed(String feed) { this.feed = feed; } /** * Returns the URI for the RSS feed. * * @return the URI for the feed * @throws LDAPHttpException if no feed is specified */ public final String getFeed() throws LDAPHttpException { if (this.feed == null) { throw new LDAPHttpException("No RSS feed is specified for " + getLabel() + " objects."); } else { return this.feed; } } /** * Constructs and returns the substring to match in an RSS item. * * @return the item substring */ public String getItemSubstring() throws LDAPHttpException { String current_id = getIdentifier(); if (current_id == null) { throw new LDAPHttpException("No identifier was submitted to determine the appropriate RSS item."); } else { return current_id; } } // handler used for parsing RSS 1.0 feed class RSS1Handler extends DefaultHandler { // item number to record private String item_substring = "somebodyforgottosetme"; // indicator for if the item was found private boolean item_found = false; // the name of the current element in parsing private String current_element = null; // structures for storing the text of relevant elements private StringBuffer title_buffer = new StringBuffer(); private StringBuffer link_buffer = new StringBuffer(); private StringBuffer description_buffer = new StringBuffer(); private StringBuffer creator_buffer = new StringBuffer(); // indicator for relevant portion of feed private boolean in_item; public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { // store the current element name this.current_element = localName; // indicate if within a relevant parent tag if ( localName.equalsIgnoreCase("item") ) { if (atts.getValue("rdf:about").indexOf(this.item_substring) > 0) { this.item_found = true; this.in_item = true; } } } public void endElement(String namespaceURI, String localName, String qName) throws SAXException { if ( localName.equalsIgnoreCase("item") ) this.in_item = false; } public void characters(char[] ch, int start, int length) throws SAXException { // store information from the relevant item if (in_item) { if ( this.current_element.equalsIgnoreCase("title") ) { this.title_buffer.append( new String(ch, start, length) ); } else { if ( this.current_element.equalsIgnoreCase("link") ) { this.link_buffer.append( new String(ch, start, length) ); } else { if ( this.current_element.equalsIgnoreCase("description") ) { this.description_buffer.append( new String(ch, start, length) ); } else { if ( this.current_element.equalsIgnoreCase("creator") ) { this.creator_buffer.append( new String(ch, start, length) ); }}}} } } // method to set the item number void setItemSubstring(String item_substring) { this.item_substring = item_substring; } // method to return article title boolean itemFound() { return this.item_found; } // method to return article title String getTitle() { return this.title_buffer.toString().trim(); } // method to return article link String getLink() { return this.link_buffer.toString().trim(); } // method to return article description String getDescription() { return this.description_buffer.toString().trim() + " " + this.creator_buffer.toString().trim() + ""; } // method for handling warnings public void warning(SAXParseException exception) throws SAXException { throw new SAXException("warning at line " + exception.getLineNumber() + "... " + exception.getMessage() ); } // method for handling nonfatal errors public void error(SAXParseException exception) throws SAXException { throw new SAXException("nonfatal error at line " + exception.getLineNumber() + "... " + exception.getMessage() ); } // method for handling fatal errors public void fatalError(SAXParseException exception) throws SAXException { throw new SAXException("fatal error at line " + exception.getLineNumber() + "... " + exception.getMessage() ); } } }