package net.x4a42.volksempfaenger.feedparser; import java.io.IOException; import java.io.Reader; import java.util.Stack; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class OpmlParser { public static SubscriptionTree parse(Reader reader) { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser; OpmlHandler handler = new OpmlHandler(); try { parser = factory.newSAXParser(); parser.parse(new InputSource(reader), handler); return removeEmptyFolders(handler.getTree()); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } private static SubscriptionTree removeEmptyFolders(SubscriptionTree tree) { return tree; // TODO } private static class OpmlHandler extends DefaultHandler { private SubscriptionTree tree = new SubscriptionTree("root"); private Stack<SubscriptionTree> path = new Stack<SubscriptionTree>(); private Stack<Integer> depthStack = new Stack<Integer>(); private Integer depth = 0; public OpmlHandler() { super(); path.push(tree); } private final static String OPML_OUTLINE = "outline"; private final static String OPML_XML_URL = "xmlUrl"; private final static String OPML_TITLE = "title"; private static final String OPML_TEXT = "text"; public SubscriptionTree getTree() { return tree; } @Override public void startElement(String uri, String localName, String qName, Attributes atts) { if (!uri.isEmpty()) { // opml does not have a namespace // ignore all elements which have one return; } if (localName.equals(OPML_OUTLINE)) { final String url = atts.getValue(OPML_XML_URL); String title = atts.getValue(OPML_TITLE); final String text = atts.getValue(OPML_TEXT); SubscriptionTree newChild; if (url != null) { if (title == null) { if (text != null) { title = text; } else { title = url; } } newChild = new SubscriptionTree(title, url); path.peek().addChild(newChild); } else if (title != null) { newChild = new SubscriptionTree(title); path.peek().addChild(newChild); path.push(newChild); depthStack.push(depth); } } depth++; } @Override public void endElement(String uri, String localName, String qName) { depth--; if (!depthStack.isEmpty() && depthStack.peek().equals(depth)) { depthStack.pop(); path.pop(); } } } }