`
ttitfly
  • 浏览: 616018 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Rome使用简单说明二(部分关键源码分析)

SUN 
阅读更多

Parser部分(解析)

com.sun.syndication.io.SyndFeedInput input = new com.sun.syndication.io.SyndFeedInput();
调用
public SyndFeedInput() {
        this(false);
}
public SyndFeedInput(boolean validate) {
        _feedInput = new WireFeedInput(validate);
}
直接就构造了对象WireFeedInput _feedInput.

com.sun.syndication.feed.synd.SyndFeed feed = input.build(new

com.sun.syndication.io.XmlReader(feedUrl));

实际上调用的是WireFeedInput对象的build方法

WireFeedInput里有个对象FeedParsers,构造WireFeedInput时,也会实例化FeedParsers,实例化

FeedParsers时,由于FeedParsers extends PluginManager,所以会通过PluginManager去加载

rome.properties文件,(因为FeedParsers 里FEED_PARSERS_KEY = "WireFeedParser.classes"所以会去

rome.properties里加载key为WireFeedParser.classes的值)。并实例化所有的parser对象。

所以当在WireFeedInput里调用FeedParsers的getParserFor(document)方法时,会自动匹配该document需

要用哪个解析器来进行解析

FeedParsers.getParserFor(document)方法返回的是个interface WireFeedParser.
在WireFeedInput里调用
public WireFeed build(Document document) throws IllegalArgumentException,FeedException {
        WireFeedParser parser = FEED_PARSERS.getParserFor(document);//确定使用哪个解析器
        if (parser==null) {
            throw new IllegalArgumentException("Invalid document");
        }
        return parser.parse(document, _validate);//最终调用的parser方法,返回的是一个

WireFeed对象。

 

    }

 

 


SyndFeedImpl构造函数接受到WireFeed参数以后,直接通过feedType获取需要哪种转换器(Converter)
因为CONVERTERS是Converters对象,Converters是extends PluginManager的。所以可以通过Converters

来加载rome.properties,并读取key为Converter.classes的value;
 public SyndFeedImpl(WireFeed feed) {
        this(SyndFeed.class,IGNORE_PROPERTIES);
        if (feed!=null) {
            _feedType = feed.getFeedType();
            Converter converter = CONVERTERS.getConverter(_feedType);//获取需要哪种转换器
            if (converter==null) {
                throw new IllegalArgumentException("Invalid feed type ["+_feedType+"]");
            }
            converter.copyInto(feed,this);//将WireFeed对象里的各个属性值,转换为SyndFeed对应

的值
        }
    }

//将WireFeed对象里的各个属性值,转换为SyndFeed对应的值
public void copyInto(WireFeed feed,SyndFeed syndFeed) {
        syndFeed.setModules(ModuleUtils.cloneModules(feed.getModules()));
        if (((List)feed.getForeignMarkup()).size() > 0) {
            syndFeed.setForeignMarkup(feed.getForeignMarkup());
        }
        syndFeed.setEncoding(feed.getEncoding());
        Channel channel = (Channel) feed;
        syndFeed.setTitle(channel.getTitle());
        syndFeed.setLink(channel.getLink());
        syndFeed.setDescription(channel.getDescription());

        Image image = channel.getImage();
        if (image!=null) {
            syndFeed.setImage(createSyndImage(image));
        }

        List items = channel.getItems();
        if (items!=null) {
            syndFeed.setEntries(createSyndEntries(items));
        }
    }

Channel extends WireFeed(是个abstaract)


输出部分:

//写入到另一个文件里
SyndFeedOutput output = new SyndFeedOutput();
feed.setFeedType(feedType);//以哪种格式输出feed,如果这里不设置以哪种格式输出,会以它原来的格

式输出
output.output(feed, new File("c:/pic/2.xml"));

直接调用的是SyndFeedOutput对象里的方法:
public void output(SyndFeed feed,File file) throws IOException, FeedException {
        _feedOutput.output(feed.createWireFeed(),file);//先获得真正的WireFeed后,再让

WireFeedOutput去处理
    }
WireFeedOutput对象里的output方法:
public void output(WireFeed feed,File file) throws

IllegalArgumentException,IOException,FeedException {
        Writer writer = new FileWriter(file);
        output(feed,writer);
        writer.close();
    }


Convert里:又把SyndFeed的Entries格式转换为WireFeed的Item形式

可以把WireFeed看成是一种中间格式,是document和SyndFeed之间的一种中间格式(只是可以这样看作)
public WireFeed createRealFeed(SyndFeed syndFeed) {
        return createRealFeed(getType(),syndFeed);
    }

    protected WireFeed createRealFeed(String type,SyndFeed syndFeed) {
        Channel channel = new Channel(type);
        channel.setModules(ModuleUtils.cloneModules(syndFeed.getModules()));

        channel.setEncoding(syndFeed.getEncoding());

        channel.setTitle(syndFeed.getTitle());
        channel.setLink(syndFeed.getLink());
        channel.setDescription(syndFeed.getDescription());
        SyndImage sImage = syndFeed.getImage();
        if (sImage!=null) {
            channel.setImage(createRSSImage(sImage));
        }

        List sEntries = syndFeed.getEntries();
        if (sEntries!=null) {
            channel.setItems(createRSSItems(sEntries));
        }
        return channel;
    }

 

总结:
1。WireFeedOutput和WireFeedInput只是对WireFeed的一种操作(也就是需要SyndOutput传递给它的参数

是个WireFeed对象,WireFeedInput返回的也是个WireFeed对象)。(Document<==>WireFeed之间转换)
例如:WireFeedInput是接收到一个Document对象,然后将其转换为WireFeed对象,同理 WireFeedOutput

也是接收到WireFeed对象后,将其转换为Document对象。
2。SyndFeedOutput和SyndFeedInput是操纵SyndFeedImpl对象的。例如:
SyndFeedInput build方法,创建SyndFeed对象
public SyndFeed build(Document document) throws IllegalArgumentException,FeedException {
        return new SyndFeedImpl(_feedInput.build(document));
    }
SyndFeedOut output方法 
public void output(SyndFeed feed,File file) throws IOException, FeedException {
        _feedOutput.output(feed.createWireFeed(),file);
    }
3。SyndFeedImpl对象:(SyndFeed<==>WireFeed):
A.public SyndFeedImpl(WireFeed feed)构造函数中代码converter.copyInto(feed,this);,将WireFeed

转换为SyndFeed格式
B.public WireFeed createWireFeed(String feedType),将SyndFeed格式转换为WireFeed

4.Convert 体现的是WireFeed和SyndFeed之间的转换


  
  • rome.rar (9 KB)
  • 描述: rome io包下的类之间的关系
  • 下载次数: 74
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics