Package churchillobjects.rss4j.parser

Source Code of churchillobjects.rss4j.parser.RssParserImpl100

/*
*  Copyright (c) 1999-2002 ChurchillObjects.com  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions are
*  met: Redistributions of source code must retain the above copyright notice,
*  this list of conditions and the following disclaimer. Redistributions in
*  binary form must reproduce the above copyright notice, this list of
*  conditions and the following disclaimer in the documentation and/or other
*  materials provided with the distribution. Neither the name of the copyright
*  holder nor the names of its contributors may be used to endorse or promote
*  products derived from this software without specific prior written
*  permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
*  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
*  ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
*  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
*  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
*  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT, INCLUDING NEGLIGENCE OR OTHERWISE, ARISING IN ANY WAY
*  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
*  DAMAGE.
*
*/

package churchillobjects.rss4j.parser;

import java.text.ParseException;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import churchillobjects.rss4j.model.IUsesDublinCore;
import churchillobjects.rss4j.model.IUsesSyndication;
import churchillobjects.rss4j.model.RssNamespace;
import churchillobjects.rss4j.model.IUsesJbnPatch;
import churchillobjects.rss4j.RssDocument;
import churchillobjects.rss4j.RssJbnDependency;
import churchillobjects.rss4j.RssJbnPatch;
import churchillobjects.rss4j.RssChannel;
import churchillobjects.rss4j.RssChannelItem;
import churchillobjects.rss4j.RssChannelTextInput;
import churchillobjects.rss4j.RssChannelImage;
import churchillobjects.rss4j.RssSyndication;
import churchillobjects.rss4j.RssDublinCore;

/**
* Class to parse an RSS document according to the specifications of the RSS
* 1.0 standard. This object is created when the base parser already started
* parsing the document (and knows what the version number is), so it is given
* the document object and the known namespaces up to that point.
*/
class RssParserImpl100 extends RssParserImpl090{

    /**
     * Constructor for this RSS verion's parser. Provided with an already
     * set-up document and namespace.
     * @param document
     * @param namespaces
     */
    RssParserImpl100( RssDocument document, Vector namespaces){
        super(document, namespaces);
    }

    /**
     * Canonical version number that is handled by this parser.
     */
    private static final String VERSION = "1.0";

    /**
     * Maps resource strings to item objects.
     */
    private Hashtable itemMappings = new Hashtable();

    /**
     * Maps resource strings to image objects.
     */
    private Hashtable imageMappings = new Hashtable();

    /**
     * Maps resource strings to text input objects.
     */
    private Hashtable textInputMappings = new Hashtable();

    /**
     * A list of item resource strings that have not yet been found in the
     * document. In a correct RSS 1.0 document, this list will be emptied before
     * the document ends.
     */
    private Vector unmappedItems = new Vector();

    /**
     * A list of image resource strings that have not yet been found in the
     * document. In a correct RSS 1.0 document, this list will be emptied before
     * the document ends.
     */
    private Vector unmappedImages = new Vector();

    /**
     * A list of text input resource strings that have not yet been found in the
     * document. In a correct RSS 1.0 document, this list will be emptied before
     * the document ends.
     */
    private Vector unmappedTextInputs = new Vector();

    /**
     * Flag to indicate that channel items are being parsed.
     */
    private boolean inChannelItems = false;

    /**
     * Flag to indicate that we are within the item sequence.
     */
    private boolean inChannelItemsSeq = false;

    private boolean inJbnProducts = false;
    private RssJbnDependency currentJbnDependency = null;

    private boolean inJbnRequires = false;
    private boolean inJbnReplaces = false;
    private boolean inJbnIsReplacedBy = false;
    private boolean inJbnCompatibleWith = false;
    private boolean inJbnAutomatedInstallation = false;

    /**
     * SAX event. Used to set flags for where the parser is in the document
     * and to handle major parts of the RSS document object model.
     * @param uri
     * @param name
     * @param qName
     * @param attrs
     */
    public void startElement(String uri, String name, String qName, Attributes attrs) throws SAXException{
        try{
            if("channel".equals(name)){
                handleChannel(uri, name, qName, attrs);
            }
            if("item".equals(name) || "rdf:li".equals(qName)){
                handleItem(uri, name, qName, attrs);
            }
            if("textinput".equals(name)){
                handleTextInput(uri, name, qName, attrs);
            }
            if("image".equals(name)){
                handleImage(uri, name, qName, attrs);
            }
            if("items".equals(qName) && inChannel){
                inChannelItems = true;
            }
            if("rdf:Seq".equals(qName) && inChannel && inChannelItems){
                inChannelItemsSeq = true;
            }
            if( (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PRODUCTS).equals( qName) ||
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PRODUCT).equals( qName) ||
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_REQUIRES).equals( qName) ||
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_REPLACES).equals( qName) ||
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_IS_REPLACED_BY).equals( qName) ||
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PATCH).equals( qName) ||
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_AUTOMATED_INSTALL).equals( qName) ||
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_INSTRUCTION_SET).equals( qName))
            {
                handleEmbeddedElement(uri, name, qName, attrs);
            }
        }
        catch(RssParseException e){
            throw new SAXException(e);
        }
    }

    /**
     * SAX event. Used to set flags for where the parser is in the document,
     * and to pick up characters and set them to their elements in the RSS
     * object hierarchy.
     * @param uri
     * @param name
     * @param qName
     * @throws SAXException
     */
    public void endElement(String uri, String name, String qName) throws SAXException{
        try{
            if("channel".equals(qName)){
                currentChannel = null;
                inChannel = false;
            }
            if("item".equals(qName) && !inChannel){
                currentItem = null;
                inItem = false;
            }
            if("textinput".equals(qName) && !inChannel){
                currentTextInput = null;
                inTextInput = false;
            }
            if("image".equals(qName) && !inChannel){
                currentImage = null;
                inImage = false;
            }
            if("items".equals(qName) && inChannel){
                inChannelItems = false;
            }
            if("rdf:Seq".equals(qName) && inChannel && inChannelItems){
                inChannelItemsSeq = false;
            }
            if( inItem && inJbnProducts && (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PRODUCTS).equals( qName ) )
            {
                inJbnProducts = false;
                currentJbnDependency = null;
            }

            if( inItem && inJbnReplaces && (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_REPLACES).equals( qName ) )
            {
                inJbnReplaces = false;
                currentJbnDependency = null;
            }
            if( inItem && inJbnRequires && ( RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_REQUIRES).equals( qName ) )
            {
                inJbnRequires = false;
                currentJbnDependency = null;
            }
            if( inItem && inJbnIsReplacedBy && (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_IS_REPLACED_BY).equals( qName ) )
            {
                inJbnIsReplacedBy = false;
                currentJbnDependency = null;
            }
            if( inItem && inJbnCompatibleWith && (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_COMPATIBLE_WITH).equals( qName ) )
            {
                inJbnCompatibleWith = false;
                currentJbnDependency = null;
            }
            if( inItem && inJbnAutomatedInstallation && (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_AUTOMATED_INSTALL).equals( qName ) )
            {
                inJbnAutomatedInstallation = false;
                currentJbnDependency = null;
            }

            // all others are fields within others,
            // if no chars then no sense in continuing
            if(!hasChars()){
                return;
            }

            if(inChannel && !(inImage || inItem || inTextInput)){
                addChannelAttribute(name, qName);
            }
            if(inImage){
                addImageAttribute(name, qName);
            }
            if(inItem){
                addItemAttribute(name, qName);
            }
            if(inTextInput){
                addTextInputAttribute(name, qName);
            }
            if( inItem &&
                    ( inJbnProducts &&
                        ( RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PRODUCT).equals( qName ) ||
                    ( inJbnReplaces || inJbnRequires || inJbnIsReplacedBy  || inJbnCompatibleWith) &&
                        ( RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PATCH).equals( qName ) ) ||
                    inJbnAutomatedInstallation &&
                        ( RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_INSTRUCTION_SET).equals( qName ))
            {
                currentJbnDependency = null;
            }


            resetChars();
        }
        catch(RssParseException e){
            throw new SAXException(e);
        }
    }

    /**
     * Adds a text input attribute value from the characters buffer.
     * @param name
     * @param qName
     */
    private void addTextInputAttribute(String name, String qName) throws RssParseException{
        String value = getChars();
        if("title".equals(qName)){
            currentTextInput.setInputTitle(value);
        }
        if("description".equals(qName)){
            currentTextInput.setInputDescription(value);
        }
        if("name".equals(qName)){
            currentTextInput.setInputName(value);
        }
        if("link".equals(qName)){
            currentTextInput.setInputLink(value);
        }
        if(qName.startsWith("dc:")){
            handleDublinCore(currentTextInput, name, value);
        }
        if(qName.startsWith( RssJbnPatch.PREFIX + ":" ) ){
            handleJbnPatch(currentTextInput, name, value);
        }
    }

    /**
     * Adds an item attribute value from the characters buffer.
     * @param name
     * @param qName
     */
    private void addItemAttribute(String name, String qName) throws RssParseException{
        String value = getChars();
        if("title".equals(qName)){
            currentItem.setItemTitle(value);
        }
        if("link".equals(qName)){
            currentItem.setItemLink(value);
        }
        if("description".equals(qName)){
            currentItem.setItemDescription(value);
        }
        if(qName.startsWith("dc:")){
            handleDublinCore(currentItem, name, value);
        }
        if(qName.startsWith( RssJbnPatch.PREFIX + ":" )){
            handleJbnPatch(currentItem, name, value);
        }
    }

    /**
     * Adds an image attribute value from the characters buffer.
     * @param name
     * @param qName
     */
    private void addImageAttribute(String name, String qName) throws RssParseException{
        String value = getChars();
        if("title".equals(name)){
            currentImage.setImageTitle(value);
        }
        if("url".equals(name)){
            currentImage.setImageUrl(value);
        }
        if("link".equals(name)){
            currentImage.setImageLink(value);
        }
        if(qName.startsWith("dc:")){
            handleDublinCore(currentImage, name, value);
        }
        if(qName.startsWith( RssJbnPatch.PREFIX + ":" )){
            handleJbnPatch(currentItem, name, value);
        }
    }

    /**
     * Adds a channel attribute value from the characters buffer.
     * @param name
     * @param qName
     */
    private void addChannelAttribute(String name, String qName) throws RssParseException{
        String value = getChars();
        if("title".equals(qName)){
            currentChannel.setChannelTitle(value);
        }
        if("link".equals(qName)){
            currentChannel.setChannelLink(value);
        }
        if("description".equals(qName)){
            currentChannel.setChannelDescription(value);
        }
        if(qName.startsWith("sy:")){
            handleSyndication(currentChannel, name, value);
        }
        if(qName.startsWith("dc:")){
            handleDublinCore(currentChannel, name, value);
        }
        if(qName.startsWith( RssJbnPatch.PREFIX + ":" )){
            handleJbnPatch(currentItem, name, value);
        }
    }

    /**
     * SAX event. Performs a check for leftover images, items and textinputs
     * that would indicate an incomplete RSS 1.0 document.
     */
    public void endDocument() throws SAXException{
        try{
            checkForLeftovers();
        }
        catch(RssParseException e){
            throw new SAXException(e);
        }
    }

    /**
     * Handles a channel element. Sets the current channel to a new instance and
     * sets its uri from the about attribute.
     * @param uri
     * @param name
     * @param qName
     * @param attrs
     */
    protected void handleChannel(String uri, String name, String qName, Attributes attrs) throws RssParseException{
        currentChannel = new RssChannel();
        String about = getAttributeUnqualified(name, "about", "rdf", attrs);
        currentChannel.setChannelUri(about);
        document.addChannel(currentChannel);
        inChannel = true;
    }

    /**
     * Handles an item and rdf:li element. Matches them together based on their
     * about/resource attributes.
     * @param uri
     * @param name
     * @param qName
     * @param attrs
     */
    protected void handleItem(String uri, String name, String qName, Attributes attrs) throws RssParseException{
        if("item".equals(name) && !inChannel){
            String about = getAttributeUnqualified(name, "about", "rdf", attrs);
            currentItem = (RssChannelItem)itemMappings.get(about);
            if(currentItem==null){
                document.addWarning("Encountered an <item> element under <rdf:RDF> that was not used in a preceding channel: "+about);
            }
            else{
                unmappedItems.removeElement(about);
                inItem = true;
            }
        }
        else if("rdf:li".equals(qName) && inChannel && inChannelItems && inChannelItemsSeq){
            String resource = getAttributeUnqualified(qName, "resource", "rdf", attrs);
            RssChannelItem item = new RssChannelItem();
            currentChannel.addItem(item);
            itemMappings.put(resource, item);
            unmappedItems.addElement(resource);
        }
    }

    protected void handleEmbeddedElement( String uri, String name, String qName, Attributes attrs ) throws RssParseException
    {
        if( (inJbnProducts &&
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PRODUCT).equals( qName ) ) ||
            (inJbnReplaces || inJbnRequires || inJbnIsReplacedBy || inJbnCompatibleWith ) &&
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PATCH).equals( qName ) ||
             inJbnAutomatedInstallation &&
                (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_INSTRUCTION_SET).equals( qName ))
        {
            currentJbnDependency = new RssJbnDependency();
            currentJbnDependency.setUrl( getAttributeUnqualified( qName, "about", "rdf", attrs ) );
            if( (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PRODUCT).equals( qName ) )
            {
                currentJbnDependency.setProductName( getAttributeUnqualified( qName, RssJbnDependency.ATTR_PRODUCT_NAME,
                        RssJbnPatch.PREFIX, attrs ) );
                currentJbnDependency.setProductVersion( getAttributeUnqualified( qName, RssJbnDependency.ATTR_PRODUCT_VERSION,
                        RssJbnPatch.PREFIX, attrs ) );
                currentJbnDependency.setJonResourceType( getAttributeUnqualified( qName, RssJbnDependency.ATTR_JON_RESOURCE_TYPE,
                        RssJbnPatch.PREFIX, attrs ) );
                currentJbnDependency.setJonResourceVersion( getAttributeUnqualified( qName, RssJbnDependency.ATTR_JON_RESOURCE_VERSION,
                        RssJbnPatch.PREFIX, attrs ) );
            }
        }
        else if( (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_PRODUCTS).equals( qName ) )
        {
            inJbnProducts = true;
        }
        else if( (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_REPLACES).equals( qName ) )
        {
            inJbnReplaces = true;
        }
        else if( (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_REQUIRES).equals( qName ) )
        {
            inJbnRequires = true;
        }
        else if( (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_IS_REPLACED_BY).equals( qName ) )
        {
            inJbnIsReplacedBy = true;
        }
        else if( (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_COMPATIBLE_WITH).equals( qName ) )
        {
            inJbnCompatibleWith = true;
        }
        else if( (RssJbnPatch.PREFIX + ":" + RssJbnPatch.ATTR_AUTOMATED_INSTALL).equals( qName ) )
        {
            inJbnAutomatedInstallation = true;
        }


    }

    /**
     * Handles a new textinput element. Distinguishes between a textinput that
     * occurs within a channel and one that does not. Matches them together based on their
     * about/resource attributes.
     * @param uri
     * @param name
     * @param qName
     * @param attrs
     */
    protected void handleTextInput(String uri, String name, String qName, Attributes attrs) throws RssParseException{
        if(inChannel){
            RssChannelTextInput textInput = new RssChannelTextInput();
            String resource = getAttributeUnqualified(name, "resource", "rdf", attrs);
            textInputMappings.put(resource, textInput);
            unmappedTextInputs.addElement(resource);
            currentChannel.setChannelTextInput(textInput);
        }
        else{
            String about = getAttributeUnqualified(name, "about", "rdf", attrs);
            currentTextInput = (RssChannelTextInput)textInputMappings.get(about);
            if(currentTextInput==null){
                document.addWarning("Encountered a <textinput> element under <rdf:RDF> that was not used in a preceding channel: "+about);
            }
            else{
                unmappedTextInputs.removeElement(about);
                inTextInput = true;
            }
        }
    }

    /**
     * Handles a new image element. Distinguishes between an image that occurs
     * within a channel and one that does not.
     * @param uri
     * @param name
     * @param qName
     * @param attrs
     */
    protected void handleImage(String uri, String name, String qName, Attributes attrs) throws RssParseException{
        if(inChannel){
            // image tag within channel
            RssChannelImage image = new RssChannelImage();
            String resource = getAttributeUnqualified(name, "resource", "rdf", attrs);
            imageMappings.put(resource, image);
            unmappedImages.addElement(resource);
            currentChannel.setChannelImage(image);
        }
        else{
            // image tag outside channel
            String about = getAttributeUnqualified(name, "about", "rdf", attrs);
            currentImage = (RssChannelImage)imageMappings.get(about);
            if(currentImage==null){
                document.addWarning("Encountered an <image> element under <rdf:RDF> that was not used in a preceding channel: "+about);
            }
            else{
                unmappedImages.removeElement(about);
                inImage = true;
            }
        }
    }

    /**
     * Handle items that appear to be under syndication (qualified names sstart with "sy:").
     * The syndication namespace must be present or an RssParseException will be thrown.
     * @param synobj The element that uses syndication.
     * @param name
     * @param value
     */
    protected void handleSyndication(IUsesSyndication synobj, String name, String value) throws RssParseException{
        checkSyndication();
        RssSyndication syn = synobj.getChannelSyndication();
        if(syn==null){
            syn = new RssSyndication();
            synobj.setChannelSyndication(syn);
        }
        if("updatePeriod".equals(name)){
            syn.setUpdatePeriod(value);
        }
        if("updateFrequency".equals(name)){
            syn.setUpdateFrequency(Integer.parseInt(value));
        }
        if("updateBase".equals(name)){
            try{
                syn.setUpdateBase(value);
            }
            catch(ParseException e){
                throw new RssParseException("Syndication update base date value not convertible from ISO8601: '"+value+"'");
            }
        }
    }

    /**
     * Handle items that appear to be under dublin core (qualified names sstart with "dc:").
     * The dublin core namespace must be present or an RssParseException will be thrown.
     * @param dcobj The element that uses dublin core.
     * @param name
     * @param value
     */
    protected void handleDublinCore(IUsesDublinCore dcobj, String name, String value) throws RssParseException{
        checkDublinCore();
        RssDublinCore dc = dcobj.getDublinCore();
        if(dc==null){
            dc = new RssDublinCore();
            dcobj.setDublinCore(dc);
        }
        if("title".equals(name)){
            dc.setTitle(value);
        }
        if("creator".equals(name)){
            dc.setCreator(value);
        }
        if("subject".equals(name)){
            dc.setSubject(value);
        }
        if("description".equals(name)){
            dc.setDescription(value);
        }
        if("publisher".equals(name)){
            dc.setPublisher(value);
        }
        if("contributor".equals(name)){
            dc.setContributor(value);
        }
        if("date".equals(name)){
            try{
                dc.setDate(value);
            }
            catch(ParseException e){
                throw new RssParseException( e );
//                throw new RssParseException("Dublin Core date value not convertible from ISO8601: '"+value+"'");
            }
        }
        if("type".equals(name)){
            dc.setType(value);
        }
        if("format".equals(name)){
            dc.setFormat(value);
        }
        if("identifier".equals(name)){
            dc.setIdentifier(value);
        }
        if("source".equals(name)){
            dc.setSource(value);
        }
        if("language".equals(name)){
            dc.setLanguage(value);
        }
        if("relation".equals(name)){
            dc.setRelation(value);
        }
        if("coverage".equals(name)){
            dc.setCoverage(value);
        }
        if("rights".equals(name)){
            dc.setRights(value);
        }
    }

    /**
     * Handle items that appear to be under dublin core (qualified names sstart with "dc:").
     * The dublin core namespace must be present or an RssParseException will be thrown.
     * @param dcobj The element that uses dublin core.
     * @param name
     * @param value
     */
    protected void handleJbnPatch( IUsesJbnPatch dcobj, String name, String value) throws RssParseException{
        checkJbnPatch();
        RssJbnPatch jbn = dcobj.getJbnPatch();
        if(jbn == null){
            jbn = new RssJbnPatch();
            dcobj.setJbnPatch(jbn);
        }

        if( RssJbnPatch.ATTR_TYPE.equals(name)){
            jbn.setType( value);
        }
        else if( RssJbnPatch.ATTR_CREATOR.equals( name ) )
        {
            jbn.setCreator( value );
        }
        else if( RssJbnPatch.ATTR_JIRA.equals( name ))
        {
            jbn.setJira( value );
        }
        else if( RssJbnPatch.ATTR_MD5.equals( name ) )
        {
            jbn.setMd5( value );
        }
        else if( RssJbnPatch.ATTR_SHA256.equals( name ) )
        {
            jbn.setSha256( value );
        }
        else if( RssJbnPatch.ATTR_FILE_NAME.equals( name ) )
        {
            jbn.setFileName( value );
        }
        else if( RssJbnPatch.ATTR_FILE_SIZE.equals( name ) )
        {
            jbn.setFileSize( value );
        }
        else if( RssJbnPatch.ATTR_DOWNLOAD_URL.equals( name ) )
        {
            jbn.setDownloadUrl( value );
        }
        else if( RssJbnPatch.ATTR_AUTOMATED_DOWNLOAD_URL.equals( name ) )
        {
            jbn.setAutomatedDownloadUrl( value );
        }
        else if( RssJbnPatch.ATTR_INSTRUCTION_VERSION.equals( name ) )
        {
            jbn.setInstructionCompatibilityVersion( value );
        }
        else if( RssJbnPatch.ATTR_LONG_DESC.equals( name ) )
        {
            jbn.setLongDescription( value );
        }
        else if( RssJbnPatch.ATTR_SHORT_DESC.equals( name ) )
        {
            jbn.setShortDescription( value );
        }
        else if( RssJbnPatch.ATTR_MANUAL_INSTALL.equals( name ) )
        {
            jbn.setManualInstallation( value );
        }
        else if( RssJbnPatch.ATTR_AUTOMATED_INSTALL.equals( name ) )
        {
            jbn.setAutomatedInstallation( value );
        }
        else if( RssJbnPatch.ATTR_CASE_ID.equals( name ) )
        {
            jbn.setCaseId( value );
        }
        else if( RssJbnPatch.ATTR_LICENSE_NAME.equals( name ) )
        {
            jbn.setLicenseName( value );
        }
        else if( RssJbnPatch.ATTR_LICENSE_VERSION.equals( name ) )
        {
            jbn.setLicenseVersion( value );
        }
        else if( RssJbnPatch.ATTR_DISTRIBUTION_STATUS.equals( name ) )
        {
            jbn.setDistributionStatus( value );
        }
        else if( RssJbnPatch.ATTR_LAST_UPDATED.equals( name ) )
        {
            try
            {
                jbn.setLastUpdated( value );
            }
            catch ( ParseException e )
            {
                e.printStackTrace();
            }
        }
        else if( inJbnProducts && RssJbnPatch.ATTR_PRODUCT.equals( name ) )
        {
            currentJbnDependency.setName( value );
            jbn.addProduct( currentJbnDependency );
        }
        else if( inJbnRequires && RssJbnPatch.ATTR_PATCH.equals( name ) )
        {
            currentJbnDependency.setName( value );
            jbn.addRequires( currentJbnDependency );
        }
        else if( inJbnReplaces && RssJbnPatch.ATTR_PATCH.equals( name ) )
        {
            currentJbnDependency.setName( value );
            jbn.addReplaces( currentJbnDependency );
        }
        else if( inJbnIsReplacedBy && RssJbnPatch.ATTR_PATCH.equals( name ) )
        {
            currentJbnDependency.setName( value );
            jbn.addReplacedBy( currentJbnDependency );
        }
        else if( inJbnCompatibleWith && RssJbnPatch.ATTR_PATCH.equals( name ) )
        {
            currentJbnDependency.setName( value );
            jbn.addReplacedBy( currentJbnDependency );
        }
        else if( inJbnAutomatedInstallation && RssJbnPatch.ATTR_INSTRUCTION_SET.equals( name ) )
        {
           currentJbnDependency.setName( value );
           jbn.addAutomatedInstallationSet( currentJbnDependency );
        }
    }

    /**
     * Obtains the named attribute, whether qualified or not. If the fully qualified attribute is
     * not found but the unqualified is, then a warning is added to the document. If it is not
     * found at all, then an RssParseException is thrown since this does not adhere to the 1.0 standard.
     * @param element
     * @param attName
     * @param prefix
     * @param attrs
     * @return the attribute
     */
    protected String getAttributeUnqualified(String element, String attName, String prefix, Attributes attrs) throws RssParseException{
        String attrValue = getAttribute(attrs, prefix+":"+attName);
        if(attrValue==null){
            attrValue = getAttribute(attrs, attName);
            if(attrValue!=null){
                document.addWarning(element+": The use of unqualified attributes (such as '"+attName+"' vs. '"+prefix+":"+attName+"') is deprecated.");
            }
            else{
                throw new RssParseException(prefix+":"+attName+" attribute not present on the <"+element+"> element");
            }
        }
        return attrValue;
    }

    /**
     * Validates that this document has specified Dublin Core in its header
     * by examining the namespaces. If it is there, then the method returns
     * normally. Otherwise, throws an RssParseException which halts processing.
     */
    protected void checkDublinCore() throws RssParseException{
        Enumeration enumeration = namespaces.elements();
        while(enumeration.hasMoreElements()){
            RssNamespace ns = (RssNamespace)enumeration.nextElement();
            if(ns!=null){
                if(RssDublinCore.PREFIX.equals(ns.getPrefix()) && RssDublinCore.XMLNS_VALUE.equals(ns.getUri())){
                    return;
                }
            }
        }
        throw new RssParseException("Elements were found using Dublin Core but its namespace ("+RssDublinCore.XMLNS+"=\""+RssDublinCore.XMLNS_VALUE+"\") was not specified in the document header");
    }

    /**
     * Validates that this document has specified JBN patch in its header
     * by examining the namespaces. If it is there, then the method returns
     * normally. Otherwise, throws an RssParseException which halts processing.
     */
    protected void checkJbnPatch() throws RssParseException{
        Enumeration enumeration = namespaces.elements();
        while(enumeration.hasMoreElements()){
            RssNamespace ns = (RssNamespace)enumeration.nextElement();
            if(ns!=null){
                if( RssJbnPatch.PREFIX.equals(ns.getPrefix()) && RssJbnPatch.XMLNS_VALUE.equals(ns.getUri())){
                    return;
                }
            }
        }
        throw new RssParseException("Elements were found using JBN Patch but its namespace ("+RssJbnPatch.XMLNS+"=\""+RssJbnPatch.XMLNS_VALUE+"\") was not specified in the document header");
    }

    /**
     * Validates that this document has specified Syndication in its header
     * by examining the namespaces. If it is there, then the method returns
     * normally. Otherwise, throws an RssParseException which halts processing.
     */
    protected void checkSyndication() throws RssParseException{
        Enumeration enumeration = namespaces.elements();
        while(enumeration.hasMoreElements()){
            RssNamespace ns = (RssNamespace)enumeration.nextElement();
            if(ns!=null){
                if(RssSyndication.PREFIX.equals(ns.getPrefix()) && RssSyndication.XMLNS_VALUE.equals(ns.getUri())){
                    return;
                }
            }
        }
        throw new RssParseException("Elements were found using Syndication but its namespace ("+RssSyndication.XMLNS+"=\""+RssSyndication.XMLNS_VALUE+"\") was not specified in the document header");
    }

    /**
     * Looks for any leftover items, images or textinputs from within channels that
     * have not been 'matched' to items, images and textinputs outside the channels.
     * If any are found, then a RssParseException is thrown with its resource
     * attribute.
     */
    private void checkForLeftovers() throws RssParseException{
        if(unmappedItems.size()>0){
            String resource = (String)unmappedItems.elements().nextElement();
            throw new RssParseException("Item was found in channel but had no corresponding resource: '"+resource+"'");
        }
        if(unmappedImages.size()>0){
            String resource = (String)unmappedImages.elements().nextElement();
            throw new RssParseException("Image was found in channel but had no corresponding resource: '"+resource+"'");
        }
        if(unmappedTextInputs.size()>0){
            String resource = (String)unmappedTextInputs.elements().nextElement();
            throw new RssParseException("TextInput was found in channel but had no corresponding resource: '"+resource+"'");
        }
    }
}
TOP

Related Classes of churchillobjects.rss4j.parser.RssParserImpl100

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.