package com.rssuper.parsing import com.rssuper.models.Feed import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserFactory import java.io.StringReader import java.util.Date object FeedParser { fun parse(xml: String, feedUrl: String): ParseResult { val feedType = detectFeedType(xml) return when (feedType) { FeedType.RSS -> { val feed = RSSParser.parse(xml, feedUrl) ParseResult(FeedType.RSS, feed) } FeedType.Atom -> { val feed = AtomParser.parse(xml, feedUrl) ParseResult(FeedType.Atom, feed) } } } fun parseAsync(xml: String, feedUrl: String, callback: (Result) -> Unit) { try { val result = parse(xml, feedUrl) callback(Result.success(result)) } catch (e: Exception) { callback(Result.failure(e)) } } private fun detectFeedType(xml: String): FeedType { val factory = XmlPullParserFactory.newInstance() factory.isNamespaceAware = true val parser = factory.newPullParser() parser.setInput(StringReader(xml)) var eventType = parser.eventType while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG) { val tagName = parser.name return when { tagName.equals("rss", ignoreCase = true) -> FeedType.RSS tagName.equals("feed", ignoreCase = true) -> FeedType.Atom tagName.equals("RDF", ignoreCase = true) -> FeedType.RSS else -> { val namespace = parser.namespace if (namespace != null && namespace.isNotEmpty()) { when { tagName.equals("rss", ignoreCase = true) -> FeedType.RSS tagName.equals("feed", ignoreCase = true) -> FeedType.Atom else -> throw FeedParsingError.UnsupportedFeedType } } else { throw FeedParsingError.UnsupportedFeedType } } } } eventType = parser.next() } throw FeedParsingError.UnsupportedFeedType } }