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 }