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.HashSet; 020 021 import org.apache.commons.feedparser.impl.DebugFeedParserListener; 022 import org.apache.commons.feedparser.locate.AnchorParser; 023 import org.apache.commons.feedparser.locate.AnchorParserException; 024 import org.apache.commons.feedparser.locate.AnchorParserListener; 025 026 /** 027 * 028 * Experimental class to play with supporting XFN. HTML parsing in general is 029 * interesting because I could start with the AnchorParser and move to an HTML 030 * parser but that might be too generic. 031 * 032 * @author <a href="mailto:burton@apache.org">Kevin A. Burton (burtonator)</a> 033 * @version $Id: HTMLFeedParser.java 373614 2006-01-30 22:31:21Z mvdb $ 034 */ 035 public class HTMLFeedParser extends BaseParser { 036 037 public static final HashSet XFN_RELATIONS = new HashSet(); 038 039 public static void parse( String content, final FeedParserListener listener ) throws Exception { 040 041 if ( listener instanceof FeedDirectoryParserListener == false ) 042 return; 043 044 //FIXME: only convert to using XFN if these types of links are detected. 045 //If its just a plain XHTML file then we shouldn't use this interface. 046 //Also FeedVersion needs to be called. 047 048 final FeedDirectoryParserListener directoryParserLisener = 049 (FeedDirectoryParserListener)listener; 050 051 directoryParserLisener.init(); 052 053 final FeedParserState state = new FeedParserState(); 054 055 AnchorParserListener alistener = new AnchorParserListener() { 056 057 public void setContext( Object context ) {} 058 059 public Object getResult() { return null; } 060 061 public boolean onAnchor( String href, String rel, String title ) 062 throws AnchorParserException { 063 064 try { 065 066 if ( rel == null || "".equals( rel ) ) 067 return true; 068 069 //right now these aren't valid here 070 String description = null; 071 String feed = null; 072 073 //FIXME: only include onItem when we have at least ONE XFN 074 //relations that valid. 075 076 directoryParserLisener.onItem( state, title, href, description, feed ); 077 078 String[] rels = rel.split( " " ); 079 080 for ( int i = 0; i < rels.length; ++i ) { 081 082 String current = rels[i]; 083 084 //FIXME: when this current rel is NOT part of any XFN 085 //spec we should not be using the feed parser listener 086 //because it might just be a nofollow link or such. 087 088 boolean isXFriendRel = XFN_RELATIONS.contains( current ); 089 090 if ( isXFriendRel ) { 091 092 directoryParserLisener.onRelation( state, 093 current ); 094 095 directoryParserLisener.onRelationEnd(); 096 097 } 098 099 } 100 101 directoryParserLisener.onItemEnd(); 102 103 //split this into individual rels... then call them. 104 105 return true; 106 107 } catch ( Exception e ) { 108 throw new AnchorParserException( e ); 109 } 110 111 } 112 113 }; 114 115 AnchorParser.parse( content, alistener ); 116 117 directoryParserLisener.finished(); 118 119 } 120 121 public static void main( String[] args ) throws Exception { 122 123 FeedParserListener listener = new DebugFeedParserListener(); 124 125 parse( "<a href='http://jane-blog.example.org/' rel='sweetheart date met'>Jane</a> ", 126 listener ); 127 128 } 129 130 static { 131 132 XFN_RELATIONS.add( "contact" ); 133 XFN_RELATIONS.add( "acquaintance" ); 134 XFN_RELATIONS.add( "friend" ); 135 XFN_RELATIONS.add( "met" ); 136 XFN_RELATIONS.add( "co-worker" ); 137 XFN_RELATIONS.add( "colleague" ); 138 XFN_RELATIONS.add( "co-resident" ); 139 XFN_RELATIONS.add( "neighbor" ); 140 XFN_RELATIONS.add( "child" ); 141 XFN_RELATIONS.add( "parent" ); 142 XFN_RELATIONS.add( "sibling" ); 143 XFN_RELATIONS.add( "spouse" ); 144 XFN_RELATIONS.add( "kin" ); 145 XFN_RELATIONS.add( "muse" ); 146 XFN_RELATIONS.add( "crush" ); 147 XFN_RELATIONS.add( "date" ); 148 XFN_RELATIONS.add( "sweetheart" ); 149 XFN_RELATIONS.add( "me" ); 150 151 } 152 153 } 154