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