/* * Copyright 2012 Eric F. Savage, code@efsavage.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ajah.syndicate.rome; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import lombok.extern.java.Log; import org.jdom.Document; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import com.ajah.syndicate.FeedSource; import com.ajah.syndicate.FeedSourceStatus; import com.ajah.syndicate.FeedSourceType; import com.ajah.syndicate.PollStatus; import com.ajah.syndicate.SyndicationException; import com.ajah.syndicate.opml.Opml; import com.ajah.syndicate.opml.Outline; import com.ajah.util.CollectionUtils; import com.ajah.util.StringUtils; import com.sun.syndication.io.FeedException; import com.sun.syndication.io.impl.OPML10Parser; /** * Utilities for dealing with OPML files. * * @author <a href="http://efsavage.com">Eric F. Savage</a>, <a * href="mailto:code@efsavage.com">code@efsavage.com</a>. * */ @Log public class OpmlUtils { private static Outline createOutline(final com.sun.syndication.feed.opml.Outline syndOutline, final Outline parent) { final Outline outline = new Outline(); @SuppressWarnings("unchecked") final List<com.sun.syndication.feed.opml.Outline> children = syndOutline.getChildren(); outline.setOutlines(createOutlines(children, outline)); outline.setText(syndOutline.getText()); outline.setTitle(syndOutline.getTitle()); outline.setHtmlUrl(syndOutline.getHtmlUrl()); outline.setXmlUrl(syndOutline.getXmlUrl()); outline.setType(syndOutline.getType()); outline.setParent(parent); return outline; } private static List<Outline> createOutlines(final com.sun.syndication.feed.opml.Opml syndOpml) { @SuppressWarnings("unchecked") final List<com.sun.syndication.feed.opml.Outline> syndOutlines = syndOpml.getOutlines(); return createOutlines(syndOutlines, null); } private static List<Outline> createOutlines(final List<com.sun.syndication.feed.opml.Outline> syndOutlines, final Outline parent) { final List<Outline> outlines = new ArrayList<>(syndOutlines.size()); for (final com.sun.syndication.feed.opml.Outline syndOutline : syndOutlines) { outlines.add(createOutline(syndOutline, parent)); } return outlines; } private static FeedSource extractFeedSource(final Outline outline) { final FeedSource feedSource = new FeedSource(); feedSource.setTitle(outline.getTitle()); feedSource.setHtmlUrl(outline.getHtmlUrl()); feedSource.setFeedUrl(outline.getXmlUrl()); if (!outline.getTitle().equals(outline.getText())) { feedSource.setDescription(outline.getText()); } if ("rss".equals(outline.getType())) { feedSource.setType(FeedSourceType.RSS); } else { log.warning("Unknown type " + outline.getType()); feedSource.setType(FeedSourceType.UNKNOWN); } feedSource.setStatus(FeedSourceStatus.ACTIVE); feedSource.setPollStatus(PollStatus.ACTIVE); return feedSource; } private static void extractFeedSources(final List<Outline> outlines, final List<FeedSource> feedSources) { for (final Outline outline : outlines) { if (!CollectionUtils.isEmpty(outline.getOutlines())) { extractFeedSources(outline.getOutlines(), feedSources); } if (!StringUtils.isBlank(outline.getXmlUrl())) { feedSources.add(extractFeedSource(outline)); } } } /** * Extracts a list of FeedSources from an {@link Opml} instance. * * @param opml * The opml to investigate. * @return The list of feedSources, may be empty but will not be null. */ public static List<FeedSource> extractFeedSources(final Opml opml) { final List<FeedSource> feedSources = new ArrayList<>(); extractFeedSources(opml.getOutlines(), feedSources); return feedSources; } /** * Parses a JDOM document into an Ajah {@link Opml}. * * @param doc * The document to parse. * @return The constructed Opml instance. * @throws SyndicationException * if the document could not be parsed. */ public static Opml parse(final Document doc) throws SyndicationException { com.sun.syndication.feed.opml.Opml syndOpml; try { syndOpml = (com.sun.syndication.feed.opml.Opml) new OPML10Parser().parse(doc, false); } catch (IllegalArgumentException | FeedException e) { throw new SyndicationException(e); } final Opml opml = new Opml(); opml.setOutlines(createOutlines(syndOpml)); return opml; } /** * Parses a JDOM document into an Ajah {@link Opml} via * {@link #parse(Document)}. * * @see #parse(Document) * @param file * The file to parse. * @return The constructed Opml instance. * @throws IOException * If the file could not be read. * @throws SyndicationException */ public static Opml parse(final File file) throws IOException, SyndicationException { Document doc; try { doc = new SAXBuilder(false).build(file); } catch (final JDOMException e) { throw new SyndicationException(e); } return parse(doc); } }