Commit ae82dfe9 authored by Ricki Hirner's avatar Ricki Hirner

Add supported-report-set and sync-token; refactoring

parent b4b0e6bb
buildscript { buildscript {
ext.kotlin_version = '1.1.61' ext.kotlin_version = '1.2.10'
ext.dokka_version = '0.9.15' ext.dokka_version = '0.9.15'
repositories { repositories {
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
package at.bitfire.dav4android; package at.bitfire.dav4android;
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.io.IOException
interface PropertyFactory { interface PropertyFactory {
...@@ -18,6 +20,7 @@ interface PropertyFactory { ...@@ -18,6 +20,7 @@ interface PropertyFactory {
*/ */
fun getName(): Property.Name fun getName(): Property.Name
@Throws(IOException::class, XmlPullParserException::class)
fun create(parser: XmlPullParser): Property? fun create(parser: XmlPullParser): Property?
} }
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
package at.bitfire.dav4android; package at.bitfire.dav4android;
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.* import java.util.*
import java.util.logging.Level
object PropertyRegistry { object PropertyRegistry {
...@@ -24,7 +26,7 @@ object PropertyRegistry { ...@@ -24,7 +26,7 @@ object PropertyRegistry {
} }
fun register(factory: PropertyFactory) { private fun register(factory: PropertyFactory) {
val name = factory.getName() val name = factory.getName()
var nsFactories = factories[name.namespace] var nsFactories = factories[name.namespace]
if (nsFactories == null) { if (nsFactories == null) {
...@@ -35,8 +37,12 @@ object PropertyRegistry { ...@@ -35,8 +37,12 @@ object PropertyRegistry {
} }
fun create(name: Property.Name, parser: XmlPullParser): Property? { fun create(name: Property.Name, parser: XmlPullParser): Property? {
factories[name.namespace]?.let { nsFactories -> try {
nsFactories[name.name]?.let { factory -> return factory.create(parser) } factories[name.namespace]?.let { nsFactories ->
nsFactories[name.name]?.let { factory -> return factory.create(parser) }
}
} catch (e: XmlPullParserException) {
Constants.log.log(Level.WARNING, "Couldn't parse $name", e)
} }
return null return null
} }
......
...@@ -12,7 +12,6 @@ import org.xmlpull.v1.XmlPullParser ...@@ -12,7 +12,6 @@ import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException import org.xmlpull.v1.XmlPullParserException
import org.xmlpull.v1.XmlPullParserFactory import org.xmlpull.v1.XmlPullParserFactory
import java.io.IOException import java.io.IOException
import java.util.logging.Level
object XmlUtils { object XmlUtils {
...@@ -39,40 +38,45 @@ object XmlUtils { ...@@ -39,40 +38,45 @@ object XmlUtils {
fun newSerializer() = factory.newSerializer()!! fun newSerializer() = factory.newSerializer()!!
@Throws(IOException::class) @Throws(IOException::class, XmlPullParserException::class)
fun processTag(parser: XmlPullParser, namespace: String, name: String, lambda: () -> Unit) {
val depth = parser.depth
var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1 &&
parser.namespace == namespace && parser.name == name) {
lambda()
}
eventType = parser.next()
}
}
@Throws(IOException::class, XmlPullParserException::class)
fun readText(parser: XmlPullParser): String? { fun readText(parser: XmlPullParser): String? {
var text: String? = null var text: String? = null
try { val depth = parser.depth
val depth = parser.depth
var eventType = parser.eventType var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) { while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.TEXT && parser.depth == depth) if (eventType == XmlPullParser.TEXT && parser.depth == depth)
text = parser.text text = parser.text
eventType = parser.next() eventType = parser.next()
}
} catch(e: XmlPullParserException) {
Constants.log.log(Level.SEVERE, "Couldn't parse text property", e);
} }
return text return text
} }
@Throws(IOException::class) @Throws(IOException::class, XmlPullParserException::class)
fun readTextPropertyList(parser: XmlPullParser, name: Property.Name, list: MutableList<String>) { fun readTextPropertyList(parser: XmlPullParser, name: Property.Name, list: MutableCollection<String>) {
try { val depth = parser.depth
val depth = parser.depth
var eventType = parser.eventType
var eventType = parser.eventType while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) { if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1 &&
if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1 && Property.Name(parser.namespace, parser.name) == name)
Property.Name(parser.namespace, parser.name) == name) list.add(parser.nextText())
list.add(parser.nextText()) eventType = parser.next()
eventType = parser.next()
}
} catch(e: XmlPullParserException) {
Constants.log.log(Level.SEVERE, "Couldn't parse text property list", e)
} }
} }
......
...@@ -8,13 +8,10 @@ ...@@ -8,13 +8,10 @@
package at.bitfire.dav4android.property package at.bitfire.dav4android.property
import at.bitfire.dav4android.Constants
import at.bitfire.dav4android.Property import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.logging.Level
// see RFC 5397: WebDAV Current Principal Extension // see RFC 5397: WebDAV Current Principal Extension
...@@ -33,23 +30,11 @@ data class CurrentUserPrincipal( ...@@ -33,23 +30,11 @@ data class CurrentUserPrincipal(
override fun getName() = NAME override fun getName() = NAME
override fun create(parser: XmlPullParser): CurrentUserPrincipal { override fun create(parser: XmlPullParser): CurrentUserPrincipal {
// <!ELEMENT current-user-principal (unauthenticated | href)>
var href: String? = null var href: String? = null
XmlUtils.processTag(parser, XmlUtils.NS_WEBDAV, "href", {
try { href = XmlUtils.readText(parser)
// <!ELEMENT current-user-principal (unauthenticated | href)> })
val depth = parser.depth
var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.depth == depth+1 &&
parser.namespace == XmlUtils.NS_WEBDAV && parser.name == "href")
href = parser.nextText()
eventType = parser.next()
}
} catch(e: XmlPullParserException) {
Constants.log.log(Level.SEVERE, "Couldn't parse <current-user-principal>", e);
}
return CurrentUserPrincipal(href) return CurrentUserPrincipal(href)
} }
......
...@@ -8,13 +8,10 @@ ...@@ -8,13 +8,10 @@
package at.bitfire.dav4android.property package at.bitfire.dav4android.property
import at.bitfire.dav4android.Constants
import at.bitfire.dav4android.Property import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.logging.Level
data class CurrentUserPrivilegeSet( data class CurrentUserPrivilegeSet(
// only those privileges which are required for DAVdroid are implemented // only those privileges which are required for DAVdroid are implemented
...@@ -33,15 +30,15 @@ data class CurrentUserPrivilegeSet( ...@@ -33,15 +30,15 @@ data class CurrentUserPrivilegeSet(
override fun getName() = NAME override fun getName() = NAME
override fun create(parser: XmlPullParser): CurrentUserPrivilegeSet? { override fun create(parser: XmlPullParser): CurrentUserPrivilegeSet? {
// <!ELEMENT current-user-privilege-set (privilege*)>
// <!ELEMENT privilege ANY>
val privs = CurrentUserPrivilegeSet(false, false) val privs = CurrentUserPrivilegeSet(false, false)
fun parsePrivilege() { XmlUtils.processTag(parser, XmlUtils.NS_WEBDAV, "privilege", {
val depth = parser.depth val depth = parser.depth
// <!ELEMENT privilege ANY>
var eventType = parser.eventType var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) { while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.depth == depth+1 && parser.namespace == XmlUtils.NS_WEBDAV) if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1 && parser.namespace == XmlUtils.NS_WEBDAV)
when (parser.name) { when (parser.name) {
"read" -> "read" ->
privs.mayRead = true privs.mayRead = true
...@@ -51,26 +48,10 @@ data class CurrentUserPrivilegeSet( ...@@ -51,26 +48,10 @@ data class CurrentUserPrivilegeSet(
privs.mayRead = true privs.mayRead = true
privs.mayWriteContent = true privs.mayWriteContent = true
} }
} }
eventType = parser.next()
}
}
try {
// <!ELEMENT current-user-privilege-set (privilege*)>
val depth = parser.depth
var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.depth == depth+1 &&
parser.namespace == XmlUtils.NS_WEBDAV && parser.name == "privilege")
parsePrivilege()
eventType = parser.next() eventType = parser.next()
} }
} catch(e: XmlPullParserException) { })
Constants.log.log(Level.SEVERE, "Couldn't parse <current-user-privilege-set>", e)
return null
}
return privs return privs
} }
......
...@@ -14,7 +14,9 @@ import at.bitfire.dav4android.QuotedStringUtils ...@@ -14,7 +14,9 @@ import at.bitfire.dav4android.QuotedStringUtils
import at.bitfire.dav4android.XmlUtils import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
class GetETag: Property { class GetETag(
rawETag: String?
): Property {
companion object { companion object {
@JvmField @JvmField
...@@ -23,7 +25,7 @@ class GetETag: Property { ...@@ -23,7 +25,7 @@ class GetETag: Property {
var eTag: String? var eTag: String?
constructor(rawETag: String?) { init {
/* entity-tag = [ weak ] opaque-tag /* entity-tag = [ weak ] opaque-tag
weak = "W/" weak = "W/"
opaque-tag = quoted-string opaque-tag = quoted-string
......
...@@ -20,7 +20,7 @@ class GroupMembership: HrefListProperty() { ...@@ -20,7 +20,7 @@ class GroupMembership: HrefListProperty() {
} }
class Factory(): HrefListProperty.Factory() { class Factory: HrefListProperty.Factory() {
override fun getName() = NAME override fun getName() = NAME
......
...@@ -8,13 +8,10 @@ ...@@ -8,13 +8,10 @@
package at.bitfire.dav4android.property package at.bitfire.dav4android.property
import at.bitfire.dav4android.Constants
import at.bitfire.dav4android.Property import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.logging.Level
class ResourceType: Property { class ResourceType: Property {
...@@ -41,28 +38,22 @@ class ResourceType: Property { ...@@ -41,28 +38,22 @@ class ResourceType: Property {
override fun create(parser: XmlPullParser): ResourceType? { override fun create(parser: XmlPullParser): ResourceType? {
val type = ResourceType() val type = ResourceType()
try { val depth = parser.depth
val depth = parser.depth var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
var eventType = parser.eventType if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1) {
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) { // use static objects to allow types.contains()
if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1) { var typeName = Property.Name(parser.namespace, parser.name)
// use static objects to allow types.contains() when (typeName) {
var typeName = Property.Name(parser.namespace, parser.name) COLLECTION -> typeName = COLLECTION
when (typeName) { PRINCIPAL -> typeName = PRINCIPAL
COLLECTION -> typeName = COLLECTION ADDRESSBOOK -> typeName = ADDRESSBOOK
PRINCIPAL -> typeName = PRINCIPAL CALENDAR -> typeName = CALENDAR
ADDRESSBOOK -> typeName = ADDRESSBOOK SUBSCRIBED -> typeName = SUBSCRIBED
CALENDAR -> typeName = CALENDAR
SUBSCRIBED -> typeName = SUBSCRIBED
}
type.types.add(typeName)
} }
eventType = parser.next() type.types.add(typeName)
} }
} catch(e: XmlPullParserException) { eventType = parser.next()
Constants.log.log(Level.SEVERE, "Couldn't parse <resourcetype>", e);
return null
} }
return type return type
......
...@@ -14,6 +14,7 @@ import at.bitfire.dav4android.PropertyFactory ...@@ -14,6 +14,7 @@ import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils import at.bitfire.dav4android.XmlUtils
import okhttp3.MediaType import okhttp3.MediaType
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.logging.Level import java.util.logging.Level
class SupportedAddressData: Property { class SupportedAddressData: Property {
...@@ -37,21 +38,14 @@ class SupportedAddressData: Property { ...@@ -37,21 +38,14 @@ class SupportedAddressData: Property {
val supported = SupportedAddressData() val supported = SupportedAddressData()
try { try {
val depth = parser.depth XmlUtils.processTag(parser, XmlUtils.NS_CARDDAV, "address-data-type", {
parser.getAttributeValue(null, "content-type")?.let { contentType ->
var eventType = parser.eventType var type = contentType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) { parser.getAttributeValue(null, "version")?.let { version -> type += "; version=$version" }
if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1 && MediaType.parse(type)?.let { supported.types.add(it) }
parser.namespace == XmlUtils.NS_CARDDAV && parser.name == "address-data-type") }
parser.getAttributeValue(null, "content-type")?.let { contentType -> })
@Suppress("NAME_SHADOWING") } catch(e: XmlPullParserException) {
var contentType = contentType
parser.getAttributeValue(null, "version")?.let { version -> contentType += "; version=$version" }
MediaType.parse(contentType)?.let { supported.types.add(it) }
}
eventType = parser.next()
}
} catch(e: Exception) {
Constants.log.log(Level.SEVERE, "Couldn't parse <resourcetype>", e) Constants.log.log(Level.SEVERE, "Couldn't parse <resourcetype>", e)
return null return null
} }
......
...@@ -8,17 +8,10 @@ ...@@ -8,17 +8,10 @@
package at.bitfire.dav4android.property package at.bitfire.dav4android.property
import org.xmlpull.v1.XmlPullParser; import at.bitfire.dav4android.Property
import org.xmlpull.v1.XmlPullParserException; import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils
import java.io.IOException; import org.xmlpull.v1.XmlPullParser
import java.util.Locale;
import java.util.logging.Level;
import at.bitfire.dav4android.Constants;
import at.bitfire.dav4android.Property;
import at.bitfire.dav4android.PropertyFactory;
import at.bitfire.dav4android.XmlUtils;
data class SupportedCalendarComponentSet( data class SupportedCalendarComponentSet(
var supportsEvents: Boolean, var supportsEvents: Boolean,
...@@ -36,35 +29,29 @@ data class SupportedCalendarComponentSet( ...@@ -36,35 +29,29 @@ data class SupportedCalendarComponentSet(
override fun getName() = NAME override fun getName() = NAME
override fun create(parser: XmlPullParser): SupportedCalendarComponentSet? { override fun create(parser: XmlPullParser): SupportedCalendarComponentSet? {
/* <!ELEMENT supported-calendar-component-set (comp+)>
<!ELEMENT comp ((allprop | prop*), (allcomp | comp*))>
<!ATTLIST comp name CDATA #REQUIRED>
*/
val components = SupportedCalendarComponentSet(false, false) val components = SupportedCalendarComponentSet(false, false)
try { val depth = parser.depth
/* <!ELEMENT supported-calendar-component-set (comp+)> var eventType = parser.eventType
<!ELEMENT comp ((allprop | prop*), (allcomp | comp*))> while (!(eventType == XmlPullParser.END_TAG && parser.getDepth() == depth)) {
<!ATTLIST comp name CDATA #REQUIRED> if (eventType == XmlPullParser.START_TAG && parser.getDepth() == depth + 1 && parser.namespace == XmlUtils.NS_CALDAV) {
*/ when (parser.name) {
val depth = parser.depth "allcomp" -> {
components.supportsEvents = true
var eventType = parser.eventType components.supportsTasks = true
while (!(eventType == XmlPullParser.END_TAG && parser.getDepth() == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.getDepth() == depth + 1 && parser.namespace == XmlUtils.NS_CALDAV) {
when (parser.name) {
"allcomp" -> {
components.supportsEvents = true
components.supportsTasks = true
}
"comp" ->
when (parser.getAttributeValue(null, "name")?.toUpperCase()) {
"VEVENT" -> components.supportsEvents = true
"VTODO" -> components.supportsTasks = true
}
} }
"comp" ->
when (parser.getAttributeValue(null, "name")?.toUpperCase()) {
"VEVENT" -> components.supportsEvents = true
"VTODO" -> components.supportsTasks = true
}
} }
eventType = parser.next()
} }
} catch(e: XmlPullParserException) { eventType = parser.next()
Constants.log.log(Level.SEVERE, "Couldn't parse <supported-calendar-component-set>", e)
return null
} }
return components return components
......
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.dav4android.property
import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser
class SupportedReportSet: Property {
companion object {
@JvmField val NAME = Property.Name(XmlUtils.NS_WEBDAV, "supported-report-set")
@JvmField val SYNC_COLLECTION = "DAV:sync-collection" // collection synchronization (RFC 6578)
}
val reports = mutableSetOf<String>()
override fun toString() = "[${reports.joinToString(", ")}]"
class Factory: PropertyFactory {
override fun getName() = NAME
override fun create(parser: XmlPullParser): SupportedReportSet? {
/* <!ELEMENT supported-report-set (supported-report*)>
<!ELEMENT supported-report report>
<!ELEMENT report ANY>
*/
val supported = SupportedReportSet()
XmlUtils.processTag(parser, XmlUtils.NS_WEBDAV, "supported-report", {
XmlUtils.processTag(parser, XmlUtils.NS_WEBDAV, "report") {
parser.nextTag()
if (parser.eventType == XmlPullParser.TEXT)
supported.reports += parser.text
else if (parser.eventType == XmlPullParser.START_TAG)
supported.reports += "${parser.namespace}${parser.name}"
}
})
return supported
}
}
}
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.dav4android.property
import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser
data class SyncToken(
val token: String?
): Property {
companion object {
@JvmField
val NAME = Property.Name(XmlUtils.NS_WEBDAV, "sync-token")
}
class Factory(): PropertyFactory {
override fun getName() = NAME
override fun create(parser: XmlPullParser) =
// <!ELEMENT sync-token #PCDATA>
SyncToken(XmlUtils.readText(parser))
}
}
...@@ -21,3 +21,5 @@ at.bitfire.dav4android.property.ResourceType$Factory ...@@ -21,3 +21,5 @@ at.bitfire.dav4android.property.ResourceType$Factory
at.bitfire.dav4android.property.Source$Factory at.bitfire.dav4android.property.Source$Factory
at.bitfire.dav4android.property.SupportedAddressData$Factory at.bitfire.dav4android.property.SupportedAddressData$Factory
at.bitfire.dav4android.property.SupportedCalendarComponentSet$Factory at.bitfire.dav4android.property.SupportedCalendarComponentSet$Factory
at.bitfire.dav4android.property.SupportedReportSet$Factory
at.bitfire.dav4android.property.SyncToken$Factory
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment