001    /*
002     * Copyright 1999,2004 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.apache.commons.feedparser;
018    
019    import java.util.Locale;
020    
021    import org.apache.commons.feedparser.tools.RFC3066LocaleParser;
022    import org.jaxen.jdom.JDOMXPath;
023    import org.jdom.Attribute;
024    import org.jdom.Element;
025    
026    /**
027     * Basic parser support common between RSS, Atom, and FOAF feed impls.
028     * 
029     * @author <a href="mailto:burton@apache.org">Kevin A. Burton (burtonator)</a>
030     * @version $Id: BaseParser.java 373614 2006-01-30 22:31:21Z mvdb $
031     */
032    public class BaseParser {
033    
034        protected static void doLocale( FeedParserState state,
035                                        FeedParserListener listener,
036                                        Element element ) throws Exception {
037    
038            if ( element == null )
039                return;
040    
041            if ( state.metaFeedParserlistener == null )
042                return;
043    
044            String l = getLocaleString( element );
045            
046            if ( l != null ) {
047    
048                Locale locale = RFC3066LocaleParser.parse( l );
049    
050                if ( locale != null )
051                    state.metaFeedParserlistener.onLocale( state, locale );
052    
053            }
054    
055        }
056    
057        protected static void doLocaleEnd( FeedParserState state,
058                                           FeedParserListener listener,
059                                           Element element )
060            throws Exception {
061    
062            if ( element == null )
063                return;
064    
065            if ( state.metaFeedParserlistener == null )
066                return;
067    
068            String l = getLocaleString( element );
069    
070            if ( l != null ) 
071                state.metaFeedParserlistener.onLocaleEnd();
072    
073        }
074    
075        protected static String getLocaleString( Element element ) {
076    
077            //hm.. crap. how do we get the 'xml' namespace here?
078            Attribute attr = element.getAttribute( "lang" );
079    
080            if ( attr != null )
081                return attr.getValue();
082            
083            //when stil null see that we have dc:language
084    
085            Element lang = element.getChild( "language", NS.DC );
086    
087            if ( lang != null )
088                return lang.getText();
089    
090            //fall over to just using "language" and if it isn't a local string we
091            //won't parse it.  This is for RSS 0.91 and RSS 2.0 content.
092            lang = element.getChild( "language" );
093    
094            if ( lang != null )
095                return lang.getText();
096    
097            return null;
098    
099        }
100    
101        // **** shared code for all parsers *****************************************
102    
103        //FIXME: unify this with RSSFeedParser.getChildElementTextByName
104        protected static String selectText( String query, Element element ) throws Exception {
105    
106            JDOMXPath xpath = new JDOMXPath( query );
107            xpath.setNamespaceContext( NS.context );
108            
109            //perform onChannel method...  (title, link, description)
110            Element e = (Element)xpath.selectSingleNode( element );
111    
112            if ( e == null )
113                return null;
114    
115            String result = e.getText();
116    
117            //The normalize method of XML SHOULD take care of this but for some
118            //reason it doesnt.
119            if ( result != null )
120                result = result.trim();
121    
122            return result;
123    
124        }
125    
126        /**
127         * Regardless of namespace, get the child node text by name or null if it is not found.
128         *
129         * 
130         */
131        protected static String getChildElementTextByName( FeedParserState state,
132                                                        String name ) throws Exception {
133    
134            //FIXME: this can be rewritten to use getChild()
135            
136            JDOMXPath xpath = new JDOMXPath( "descendant::*[local-name() = '" + name + "']" );
137            Object resultNode = xpath.selectSingleNode( state.current );
138    
139            String resultText = null;
140    
141            if ( resultNode != null )
142                resultText = ((Element)resultNode).getText();
143    
144            //The normalize method of XML SHOULD take care of this but for some
145            //reason it doesnt.
146            if ( resultText != null )
147                resultText = resultText.trim();
148    
149            return resultText;
150            
151        }
152    
153    }