Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ test {

publishing {
publications {
myPublication(MavenPublication) {
kotlinSimpleXmlRss(MavenPublication) {
from components.java
//noinspection GroovyAssignabilityCheck
artifact sourcesJar
Expand Down
2 changes: 1 addition & 1 deletion gradle/shipkit.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ allprojects {
user = 'magneticflux'
key = System.getenv("BINTRAY_API_KEY")

publications = ['myPublication']
publications = ['kotlinSimpleXmlRss']

pkg {
repo = 'kotlin-simplexml-rss'
Expand Down
35 changes: 31 additions & 4 deletions src/main/kotlin/com/github/magneticflux/rss/Converters.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.github.magneticflux.rss

import com.github.magneticflux.rss.namespaces.Namespace
import com.github.magneticflux.rss.namespaces.Namespace.ATOM
import com.github.magneticflux.rss.namespaces.Namespace.DEFAULT
import com.github.magneticflux.rss.namespaces.Namespace.ITUNES
import com.github.magneticflux.rss.namespaces.Namespace.XML
import org.simpleframework.xml.convert.Converter
import org.simpleframework.xml.stream.InputNode
import org.simpleframework.xml.stream.OutputNode
Expand All @@ -15,10 +19,11 @@ internal val fallbackPersister = createRssPersister()
*/
internal val InputNode.namespace: Namespace?
get() {
return when (reference.toLowerCase()) {
Namespace.DEFAULT.reference -> Namespace.DEFAULT
Namespace.ITUNES.reference -> Namespace.ITUNES
Namespace.ATOM.reference -> Namespace.ATOM
return when {
reference.equals(DEFAULT.reference, true) -> DEFAULT
reference.equals(ITUNES.reference, true) -> ITUNES
reference.equals(ATOM.reference, true) -> ATOM
reference.equals(XML.reference, true) -> XML
else -> null
}
}
Expand All @@ -30,6 +35,13 @@ internal val InputNode.children: Iterator<InputNode>
get() {
return InputNodeChildIterator(this)
}
/**
* Creates an iterator over an InputNode's attributes.
*/
internal val InputNode.allAttributes: Iterator<InputNode>
get() {
return this.attributes.asSequence().map { this.attributes[it] }.iterator()
}

/**
* Create a child node containing only the given String with the specified namespace.
Expand All @@ -40,6 +52,21 @@ internal fun OutputNode.createChild(reference: String = "", name: String, value:
child.reference = reference
}

/**
* Create a child node containing only the given String with the specified namespace.
*/
internal fun OutputNode.createAttribute(
reference: String = "",
name: String,
value: String,
prefix: String? = null
) {
val child = this.setAttribute(name, value)
child.reference = reference
if (prefix != null)
child.namespaces.setReference(reference, prefix)
}

/**
* An iterator that iterates over children of an [InputNode].
*/
Expand Down
13 changes: 12 additions & 1 deletion src/main/kotlin/com/github/magneticflux/rss/Persisters.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package com.github.magneticflux.rss

import com.github.magneticflux.rss.namespaces.atom.converters.AtomAuthorConverter
import com.github.magneticflux.rss.namespaces.atom.converters.AtomContributorConverter
import com.github.magneticflux.rss.namespaces.atom.converters.AtomFeedConverter
import com.github.magneticflux.rss.namespaces.atom.elements.AtomAuthor
import com.github.magneticflux.rss.namespaces.atom.elements.AtomContributor
import com.github.magneticflux.rss.namespaces.atom.elements.AtomFeed
import com.github.magneticflux.rss.namespaces.itunes.converters.ITunesImageConverter
import com.github.magneticflux.rss.namespaces.itunes.converters.ITunesSubCategoryConverter
import com.github.magneticflux.rss.namespaces.itunes.converters.ITunesTopLevelCategoryConverter
Expand Down Expand Up @@ -62,9 +68,14 @@ fun createRssStrategy(): Strategy {
this.bind(Enclosure::class.java, EnclosureConverter)
this.bind(Guid::class.java, GuidConverter)
this.bind(Source::class.java, SourceConverter)

this.bind(ITunesTopLevelCategory::class.java, ITunesTopLevelCategoryConverter)
this.bind(ITunesSubCategory::class.java, ITunesSubCategoryConverter)
this.bind(ITunesImage::class.java, ITunesImageConverter)

this.bind(AtomFeed::class.java, AtomFeedConverter)
this.bind(AtomAuthor::class.java, AtomAuthorConverter)
this.bind(AtomContributor::class.java, AtomContributorConverter)
})
}

Expand All @@ -80,4 +91,4 @@ fun createRssMatcher(): Matcher {
this.bind(Locale::class.java, LocaleLanguageTransform)
this.bind(URL::class.java, URLTransform)
}
}
}
15 changes: 15 additions & 0 deletions src/main/kotlin/com/github/magneticflux/rss/Transforms.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.github.magneticflux.rss

import org.simpleframework.xml.transform.Transform
import org.threeten.bp.DayOfWeek
import org.threeten.bp.Instant
import org.threeten.bp.ZonedDateTime
import org.threeten.bp.format.DateTimeFormatter
import org.threeten.bp.format.DateTimeFormatterBuilder
Expand Down Expand Up @@ -52,6 +53,20 @@ object ZonedDateTimeTransform : Transform<ZonedDateTime> {
}
}

/**
* @author Mitchell Skaggs
* @since 1.2.0
*/
object ISODateTimeTransform : Transform<Instant> {
override fun write(value: Instant): String {
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value)
}

override fun read(value: String): Instant {
return Instant.FROM.queryFrom(DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(value))
}
}

/**
* @author Mitchell Skaggs
* @since 1.0.1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,11 @@ sealed class Namespace {
object ATOM : Namespace() {
const val reference: String = "http://www.w3.org/2005/Atom"
}

/**
* "Note that unlike all other XML namespaces, both the name and the prefix are specified; i.e., if you want XML 1.0 processors to recognize this namespace, you must use the reserved prefix `xml:`."
*/
object XML : Namespace() {
const val reference: String = "http://www.w3.org/XML/1998/namespace"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.github.magneticflux.rss.namespaces.atom.converters

import com.github.magneticflux.rss.allAttributes
import com.github.magneticflux.rss.children
import com.github.magneticflux.rss.createChild
import com.github.magneticflux.rss.namespace
import com.github.magneticflux.rss.namespaces.Namespace
import com.github.magneticflux.rss.namespaces.atom.elements.AtomAuthor
import org.simpleframework.xml.convert.Converter
import org.simpleframework.xml.stream.InputNode
import org.simpleframework.xml.stream.OutputNode

/**
* @author Mitchell Skaggs
* @since 1.2.0
*/
object AtomAuthorConverter : Converter<AtomAuthor> {
override fun read(node: InputNode): AtomAuthor {
var base: String? = null
var lang: String? = null

lateinit var name: String
var uri: String? = null
var email: String? = null

node.allAttributes.forEach {
when (it.namespace) {
Namespace.XML -> {
when (it.name) {
"base" -> base = it.value
"lang" -> lang = it.value
}
}
}
}

node.children.forEach {
when (it.namespace) {
Namespace.ATOM -> {
when (it.name) {
"name" -> name = it.value
"uri" -> uri = it.value
"email" -> email = it.value
}
}
}
}

return AtomAuthor(base, lang, name, uri, email)
}

override fun write(node: OutputNode, value: AtomAuthor) {
val writable = value.toWritable()

node.createChild(Namespace.ATOM.reference, "name", writable.name)
writable.uri?.let { node.createChild(Namespace.ATOM.reference, "uri", it) }
writable.email?.let { node.createChild(Namespace.ATOM.reference, "email", it) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.github.magneticflux.rss.namespaces.atom.converters

import com.github.magneticflux.rss.allAttributes
import com.github.magneticflux.rss.children
import com.github.magneticflux.rss.createChild
import com.github.magneticflux.rss.namespace
import com.github.magneticflux.rss.namespaces.Namespace
import com.github.magneticflux.rss.namespaces.atom.elements.AtomContributor
import org.simpleframework.xml.convert.Converter
import org.simpleframework.xml.stream.InputNode
import org.simpleframework.xml.stream.OutputNode

/**
* @author Mitchell Skaggs
* @since 1.2.0
*/
object AtomContributorConverter : Converter<AtomContributor> {
override fun read(node: InputNode): AtomContributor {
var base: String? = null
var lang: String? = null

lateinit var name: String
var uri: String? = null
var email: String? = null

node.allAttributes.forEach {
when (it.namespace) {
Namespace.XML -> {
when (it.name) {
"base" -> base = it.value
"lang" -> lang = it.value
}
}
}
}

node.children.forEach {
when (it.namespace) {
Namespace.ATOM -> {
when (it.name) {
"name" -> name = it.value
"uri" -> uri = it.value
"email" -> email = it.value
}
}
}
}

return AtomContributor(base, lang, name, uri, email)
}

override fun write(node: OutputNode, value: AtomContributor) {
val writable = value.toWritable()

node.createChild(Namespace.ATOM.reference, "name", writable.name)
writable.uri?.let { node.createChild(Namespace.ATOM.reference, "uri", it) }
writable.email?.let { node.createChild(Namespace.ATOM.reference, "email", it) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.github.magneticflux.rss.namespaces.atom.converters

import com.github.magneticflux.rss.allAttributes
import com.github.magneticflux.rss.children
import com.github.magneticflux.rss.createAttribute
import com.github.magneticflux.rss.fallbackPersister
import com.github.magneticflux.rss.namespace
import com.github.magneticflux.rss.namespaces.Namespace
import com.github.magneticflux.rss.namespaces.atom.elements.AtomAuthor
import com.github.magneticflux.rss.namespaces.atom.elements.AtomContributor
import com.github.magneticflux.rss.namespaces.atom.elements.AtomFeed
import org.simpleframework.xml.convert.Converter
import org.simpleframework.xml.stream.InputNode
import org.simpleframework.xml.stream.OutputNode

/**
* @author Mitchell Skaggs
* @since 1.2.0
*/
object AtomFeedConverter : Converter<AtomFeed> {
override fun read(node: InputNode): AtomFeed {
var xmlBase: String? = null
var xmlLang: String? = null

val authors: MutableList<AtomAuthor> = mutableListOf()
val contributors: MutableList<AtomContributor> = mutableListOf()

node.allAttributes.forEach {
when (it.namespace) {
Namespace.XML -> {
when (it.name) {
"base" -> xmlBase = it.value
"lang" -> xmlLang = it.value
}
}
}
}

node.children.forEach {
when (it.namespace) {
Namespace.ATOM -> {
when (it.name) {
"author" -> authors += fallbackPersister.read(AtomAuthor::class.java, it)
"contributor" -> contributors += fallbackPersister.read(
AtomContributor::class.java,
it
)
}
}
}
}

return AtomFeed(xmlBase, xmlLang, authors)
}

override fun write(node: OutputNode, value: AtomFeed) {
val writable = value.toWritable()

writable.base?.let { node.createAttribute(Namespace.XML.reference, "base", it, "xml") }
writable.lang?.let { node.createAttribute(Namespace.XML.reference, "lang", it, "xml") }

writable.author.forEach { fallbackPersister.write(it, node) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.github.magneticflux.rss.namespaces.atom.elements

import com.github.magneticflux.rss.namespaces.Namespace.ATOM
import com.github.magneticflux.rss.namespaces.atom.converters.AtomAuthorConverter
import com.github.magneticflux.rss.namespaces.standard.elements.HasReadWrite
import org.simpleframework.xml.Namespace
import org.simpleframework.xml.Root

/**
* Properties common to all representations of an `<author>` element.
*
* @since 1.2.0
*/
interface ICommonAtomAuthor : HasReadWrite<IAtomAuthor, IWritableAtomAuthor>, AtomPersonConstruct

/**
* The final RSS view of an `<author>` element. Defaults are used if applicable.
*
* @since 1.2.0
*/
interface IAtomAuthor : ICommonAtomAuthor {
override fun toReadOnly(): IAtomAuthor = this
}

/**
* The literal contents of an `<author>` element. Elements with defaults may be omitted or invalid.
*
* @since 1.2.0
*/
interface IWritableAtomAuthor : ICommonAtomAuthor {
override fun toWritable(): IWritableAtomAuthor = this
}

/**
* This class represents an Author object in a [AtomFeed].
*
* @author Mitchell Skaggs
* @since 1.2.0
* @see AtomAuthorConverter
*/
@Root(name = "author")
@Namespace(reference = ATOM.reference)
data class AtomAuthor(
override val base: String?,
override val lang: String?,
override val name: String,
override val uri: String?,
override val email: String?
) : IAtomAuthor, IWritableAtomAuthor
Loading