Implementing the collaborative search

Now we can do the actual implementation for the search. First we want to add a list of feeds to the Searcher class, and also a dispatcher and a document factory to retrieve the articles:

class Searcher() {

val dispatcher = newFixedThreadPoolContext(3, "IO-Search")
val factory = DocumentBuilderFactory.newInstance()

val feeds = listOf(
Feed("npr", "https://www.npr.org/rss/rss.php?id=1001"),
Feed("cnn", "http://rss.cnn.com/rss/cnn_topstories.rss"),
Feed("fox", "http://feeds.foxnews.com/foxnews/latest?format=xml")
)
...
}

Now we can add a search() function that will retrieve a feed, filter the articles containing the given query on the title or the description, and send them through a SendChannel received as a parameter. The initial implementation will be quite similar to the one we have used in the producer before:

private suspend fun search(
feed: Feed,
channel: SendChannel<Article>,
query: String
) {
val builder = factory.newDocumentBuilder()
val xml = builder.parse(feed.url)
val news = xml.getElementsByTagName("channel").item(0)

(0 until news.childNodes.length)
.map { news.childNodes.item(it) }
.filter { Node.ELEMENT_NODE == it.nodeType }
.map { it as Element }
.filter { "item" == it.tagName }
.forEach {
// TODO: Parse and filter
}

}

But instead of mapping the content, we want to send it through a channel after filtering:

val title = it.getElementsByTagName("title")
.item(0)
.textContent
var summary = it.getElementsByTagName("description")
.item(0)
.textContent

if (title.contains(query) || summary.contains(query)) {
if (summary.contains("<div")) {
summary = summary.substring(0, summary.indexOf("<div"))
}

val article = Article(feed.name, title, summary)
channel.send(article)
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.165.115