...
 
Commits (2)
buildscript {
ext.kotlin_version = '1.1.61'
ext.kotlin_version = '1.2.10'
ext.dokka_version = '0.9.15'
repositories {
......
......@@ -92,8 +92,8 @@ public class DavResourceTest {
.setBody(sampleText));
ResponseBody body = dav.get("*/*");
assertEquals(sampleText, body.string());
assertEquals("My Weak ETag", ((GetETag)dav.getProperties().get(GetETag.NAME)).getETag());
assertEquals("application/x-test-result", ((GetContentType) dav.getProperties().get(GetContentType.NAME)).getType());
assertEquals("My Weak ETag", dav.getProperties().get(GetETag.class).getETag());
assertEquals("application/x-test-result", dav.getProperties().get(GetContentType.class).getType());
RecordedRequest rq = mockServer.takeRequest();
assertEquals("GET", rq.getMethod());
......@@ -111,9 +111,9 @@ public class DavResourceTest {
.setBody(sampleText));
body = dav.get("*/*");
assertEquals(sampleText, body.string());
assertEquals("StrongETag", ((GetETag) dav.getProperties().get(GetETag.NAME)).getETag());
assertEquals("StrongETag", dav.getProperties().get(GetETag.class).getETag());
rq = mockServer.takeRequest();
mockServer.takeRequest();
rq = mockServer.takeRequest();
assertEquals("GET", rq.getMethod());
assertEquals("/target", rq.getPath());
......@@ -124,7 +124,7 @@ public class DavResourceTest {
.setResponseCode(HttpURLConnection.HTTP_OK)
.setBody(sampleText));
dav.get("*/*");
assertNull(dav.getProperties().get(GetETag.NAME));
assertNull(dav.getProperties().get(GetETag.class));
}
@Test
......@@ -139,7 +139,7 @@ public class DavResourceTest {
.setResponseCode(HttpURLConnection.HTTP_CREATED)
.setHeader("ETag", "W/\"Weak PUT ETag\""));
assertFalse(dav.put(RequestBody.create(MediaType.parse("text/plain"), sampleText), null, false));
assertEquals("Weak PUT ETag", ((GetETag)dav.getProperties().get(GetETag.NAME)).getETag());
assertEquals("Weak PUT ETag", dav.getProperties().get(GetETag.class).getETag());
RecordedRequest rq = mockServer.takeRequest();
assertEquals("PUT", rq.getMethod());
......@@ -155,9 +155,9 @@ public class DavResourceTest {
.setResponseCode(HttpURLConnection.HTTP_NO_CONTENT));
assertTrue(dav.put(RequestBody.create(MediaType.parse("text/plain"), sampleText), null, true));
assertEquals(url.resolve("/target"), dav.getLocation());
assertNull(dav.getProperties().get(GetETag.NAME));
assertNull(dav.getProperties().get(GetETag.class));
rq = mockServer.takeRequest();
mockServer.takeRequest();
rq = mockServer.takeRequest();
assertEquals("PUT", rq.getMethod());
assertEquals("*", rq.getHeader("If-None-Match"));
......@@ -328,7 +328,7 @@ public class DavResourceTest {
" </response>" +
"</multistatus>"));
dav.propfind(0, ResourceType.NAME);
assertNull(dav.getProperties().get(ResourceType.NAME));
assertNull(dav.getProperties().get(ResourceType.class));
/*** POSITIVE TESTS ***/
......@@ -374,7 +374,7 @@ public class DavResourceTest {
" </response>" +
"</multistatus>"));
dav.propfind(0, ResourceType.NAME, DisplayName.NAME);
assertEquals("My DAV Collection", ((DisplayName)dav.getProperties().get(DisplayName.NAME)).getDisplayName());
assertEquals("My DAV Collection", dav.getProperties().get(DisplayName.class).getDisplayName());
assertEquals(0, dav.getMembers().size());
// multi-status response for collection with several members; incomplete (not all <resourcetype>s listed)
......@@ -444,17 +444,17 @@ public class DavResourceTest {
boolean ok[] = new boolean[4];
for (DavResource member : dav.getMembers()) {
if (url.resolve("/dav/subcollection/").equals(member.getLocation())) {
assertTrue(((ResourceType) member.getProperties().get(ResourceType.NAME)).getTypes().contains(ResourceType.COLLECTION));
assertEquals("A Subfolder", ((DisplayName) member.getProperties().get(DisplayName.NAME)).getDisplayName());
assertTrue(member.getProperties().get(ResourceType.class).getTypes().contains(ResourceType.COLLECTION));
assertEquals("A Subfolder", member.getProperties().get(DisplayName.class).getDisplayName());
ok[0] = true;
} else if (url.resolve("/dav/uid@host:file").equals(member.getLocation())) {
assertEquals("Absolute path with @ and :", ((DisplayName)member.getProperties().get(DisplayName.NAME)).getDisplayName());
assertEquals("Absolute path with @ and :", member.getProperties().get(DisplayName.class).getDisplayName());
ok[1] = true;
} else if (url.resolve("/dav/relative-uid@host.file").equals(member.getLocation())) {
assertEquals("Relative path with @", ((DisplayName)member.getProperties().get(DisplayName.NAME)).getDisplayName());
assertEquals("Relative path with @", member.getProperties().get(DisplayName.class).getDisplayName());
ok[2] = true;
} else if (url.resolve("/dav/relative:colon.vcf").equals(member.getLocation())) {
assertEquals("Relative path with colon", ((DisplayName)member.getProperties().get(DisplayName.NAME)).getDisplayName());
assertEquals("Relative path with colon", member.getProperties().get(DisplayName.class).getDisplayName());
ok[3] = true;
}
}
......@@ -487,8 +487,8 @@ public class DavResourceTest {
" </response>" +
"</multistatus>"));
dav.propfind(0, ResourceType.NAME, DisplayName.NAME);
assertTrue(((ResourceType) dav.getProperties().get(ResourceType.NAME)).getTypes().contains(ResourceType.COLLECTION));
assertEquals("My DAV Collection", ((DisplayName) dav.getProperties().get(DisplayName.NAME)).getDisplayName());
assertTrue(dav.getProperties().get(ResourceType.class).getTypes().contains(ResourceType.COLLECTION));
assertEquals("My DAV Collection", dav.getProperties().get(DisplayName.class).getDisplayName());
// multi-status response with <propstat> that doesn't contain <status> (=> assume 200 OK)
mockServer.enqueue(new MockResponse()
......@@ -505,7 +505,7 @@ public class DavResourceTest {
" </response>" +
"</multistatus>"));
dav.propfind(0, DisplayName.NAME);
assertEquals("Without Status", ((DisplayName) dav.getProperties().get(DisplayName.NAME)).getDisplayName());
assertEquals("Without Status", dav.getProperties().get(DisplayName.class).getDisplayName());
}
@Test
......@@ -530,9 +530,9 @@ public class DavResourceTest {
" </response>" +
"</multistatus>"));
dav.propfind(0, DisplayName.NAME, GetETag.NAME, GetCTag.NAME);
assertEquals("DisplayName 1", ((DisplayName) dav.getProperties().get(DisplayName.NAME)).getDisplayName());
assertEquals("ETag 1", ((GetETag)dav.getProperties().get(GetETag.NAME)).getETag());
assertEquals("CTag 1", ((GetCTag) dav.getProperties().get(GetCTag.NAME)).getCTag());
assertEquals("DisplayName 1", dav.getProperties().get(DisplayName.class).getDisplayName());
assertEquals("ETag 1", dav.getProperties().get(GetETag.class).getETag());
assertEquals("CTag 1", dav.getProperties().get(GetCTag.class).getCTag());
mockServer.enqueue(new MockResponse()
.setResponseCode(207)
......@@ -555,9 +555,9 @@ public class DavResourceTest {
" </response>" +
"</multistatus>"));
dav.propfind(0, ResourceType.NAME, DisplayName.NAME);
assertEquals("DisplayName 2", ((DisplayName)dav.getProperties().get(DisplayName.NAME)).getDisplayName());
assertNull(dav.getProperties().get(GetETag.NAME));
assertEquals("CTag 1", ((GetCTag)dav.getProperties().get(GetCTag.NAME)).getCTag());
assertEquals("DisplayName 2", dav.getProperties().get(DisplayName.class).getDisplayName());
assertNull(dav.getProperties().get(GetETag.class));
assertEquals("CTag 1", dav.getProperties().get(GetCTag.class).getCTag());
}
}
......@@ -6,7 +6,7 @@
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.dav4android;
package at.bitfire.dav4android
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
......
......@@ -524,7 +524,7 @@ open class DavResource @JvmOverloads constructor(
hrefSegments = [ "davCollection", "aMember" ]
*/
if (hrefSegments.size > nBasePathSegments) {
val sameBasePath = (0..nBasePathSegments-1).none { locationSegments[it] != hrefSegments[it] }
val sameBasePath = (0 until nBasePathSegments).none { locationSegments[it] != hrefSegments[it] }
if (sameBasePath) {
target = DavResource(httpClient, href, log)
members.add(target)
......@@ -582,39 +582,39 @@ open class DavResource @JvmOverloads constructor(
// helpers
/** Finds first property within all responses (including unasked responses) */
fun findProperty(name: Property.Name): Pair<DavResource, Property>? {
fun<T: Property> findProperty(clazz: Class<T>): Pair<DavResource, T>? {
// check resource itself
val property = properties[name]
val property = properties[clazz]
if (property != null)
return Pair<DavResource, Property>(this, property)
return Pair(this, property)
// check members
for (member in members)
member.findProperty(name)?.let { return it }
member.findProperty(clazz)?.let { return it }
// check unrequested responses
for (resource in related)
resource.findProperty(name)?.let { return it }
resource.findProperty(clazz)?.let { return it }
return null
}
/** Finds properties within all responses (including unasked responses) */
fun findProperties(name: Property.Name): List<Pair<DavResource, Property>> {
val result = LinkedList<Pair<DavResource, Property>>()
fun<T: Property> findProperties(clazz: Class<T>): List<Pair<DavResource, T>> {
val result = LinkedList<Pair<DavResource, T>>()
// check resource itself
val property = properties[name]
val property = properties[clazz]
if (property != null)
result.add(Pair<DavResource, Property>(this, property))
result.add(Pair(this, property))
// check members
for (member in members)
result.addAll(member.findProperties(name))
result.addAll(member.findProperties(clazz))
// check unrequested responses
for (rel in related)
result.addAll(rel.findProperties(name))
result.addAll(rel.findProperties(clazz))
return Collections.unmodifiableList(result)
}
......
......@@ -8,6 +8,12 @@
package at.bitfire.dav4android
/**
* A WebDAV property.
*
* Every [Property] must define a static field called NAME of type Property.Name,
* which will be accessed by reflection.
*/
interface Property {
class Name(
......@@ -23,7 +29,7 @@ interface Property {
override fun hashCode() = namespace.hashCode() xor name.hashCode()
override fun toString() = "$name($namespace)"
override fun toString() = "$namespace$name"
}
}
......@@ -13,56 +13,50 @@ import java.util.Collections.unmodifiableMap
class PropertyCollection {
val properties = lazy { mutableMapOf<String, MutableMap<String, Property?>>() }
val properties = lazy { mutableMapOf<Property.Name, Property?>() }
operator fun get(name: Property.Name): Property? {
if (!properties.isInitialized())
return null
val nsProperties = properties.value[name.namespace] ?: return null
return nsProperties[name.name]
}
@Deprecated("Use get(Class<Property>) instead")
operator fun get(name: Property.Name): Property? =
if (!properties.isInitialized())
null
else
properties.value[name]
fun getMap(): Map<Property.Name, Property?> {
operator fun<T: Property> get(clazz: Class<T>): T? {
if (!properties.isInitialized())
return mapOf()
return null
val map = HashMap<Property.Name, Property?>()
for ((namespace, nsProperties) in properties.value) {
for ((name, property) in nsProperties)
map[Property.Name(namespace, name)] = property
try {
val name = clazz.getDeclaredField("NAME").get(null) as Property.Name
return properties.value[name] as? T
} catch (e: NoSuchFieldException) {
Constants.log.severe("$clazz does not have a static NAME field")
return null
}
return unmodifiableMap(map)
}
operator fun set(name: Property.Name, property: Property?) {
var nsProperties = properties.value[name.namespace]
if (nsProperties == null) {
nsProperties = mutableMapOf<String, Property?>()
properties.value[name.namespace] = nsProperties
}
fun getMap(): Map<Property.Name, Property?> =
if (!properties.isInitialized())
mapOf()
else
unmodifiableMap(properties.value)
nsProperties[name.name] = property
operator fun set(name: Property.Name, property: Property?) {
properties.value[name] = property
}
operator fun minusAssign(name: Property.Name) {
if (!properties.isInitialized())
return
val nsProperties = properties.value[name.namespace]
nsProperties?.remove(name.name)
properties.value.remove(name)
}
fun size(): Int {
if (!properties.isInitialized())
return 0
var size = 0
for (nsProperties in properties.value.values)
size += nsProperties.size
return size
}
fun size() =
if (!properties.isInitialized())
0
else
properties.value.size
/**
......@@ -95,17 +89,16 @@ class PropertyCollection {
if (!properties.isInitialized())
return
for ((_, nsProperties) in properties.value) {
for (name in nsProperties.keys)
nsProperties.put(name, null)
}
val props = properties.value
for (name in props.keys)
props[name] = null
}
override fun toString(): String {
val s = LinkedList<String>()
for ((name, value) in getMap())
s.add("$name: $value")
s.add("$name = $value")
return "[${s.joinToString(", ")}]"
}
......
......@@ -6,9 +6,11 @@
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.dav4android;
package at.bitfire.dav4android
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.io.IOException
interface PropertyFactory {
......@@ -18,6 +20,7 @@ interface PropertyFactory {
*/
fun getName(): Property.Name
@Throws(IOException::class, XmlPullParserException::class)
fun create(parser: XmlPullParser): Property?
}
......@@ -6,17 +6,19 @@
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.dav4android;
package at.bitfire.dav4android
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.*
import java.util.logging.Level
object PropertyRegistry {
val factories = mutableMapOf<String /*namespace*/, MutableMap<String /*name*/, PropertyFactory>>()
init {
Constants.log.info("Registering DAV property factories");
Constants.log.info("Registering DAV property factories")
for (factory in ServiceLoader.load(PropertyFactory::class.java)) {
Constants.log.fine("Registering ${factory::class.java.name} for ${factory.getName()}")
register(factory)
......@@ -24,7 +26,7 @@ object PropertyRegistry {
}
fun register(factory: PropertyFactory) {
private fun register(factory: PropertyFactory) {
val name = factory.getName()
var nsFactories = factories[name.namespace]
if (nsFactories == null) {
......@@ -35,8 +37,12 @@ object PropertyRegistry {
}
fun create(name: Property.Name, parser: XmlPullParser): Property? {
factories[name.namespace]?.let { nsFactories ->
nsFactories[name.name]?.let { factory -> return factory.create(parser) }
try {
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
}
......
......@@ -6,7 +6,7 @@
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.dav4android;
package at.bitfire.dav4android
object QuotedStringUtils {
......
......@@ -6,7 +6,7 @@
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.dav4android;
package at.bitfire.dav4android
import okhttp3.HttpUrl
import java.net.URI
......
......@@ -6,13 +6,12 @@
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.dav4android;
package at.bitfire.dav4android
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import org.xmlpull.v1.XmlPullParserFactory
import java.io.IOException
import java.util.logging.Level
object XmlUtils {
......@@ -39,40 +38,45 @@ object XmlUtils {
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? {
var text: String? = null
try {
val depth = parser.depth
val depth = parser.depth
var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.TEXT && parser.depth == depth)
text = parser.text
eventType = parser.next()
}
} catch(e: XmlPullParserException) {
Constants.log.log(Level.SEVERE, "Couldn't parse text property", e);
var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.TEXT && parser.depth == depth)
text = parser.text
eventType = parser.next()
}
return text
}
@Throws(IOException::class)
fun readTextPropertyList(parser: XmlPullParser, name: Property.Name, list: MutableList<String>) {
try {
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 &&
Property.Name(parser.namespace, parser.name) == name)
list.add(parser.nextText())
eventType = parser.next()
}
} catch(e: XmlPullParserException) {
Constants.log.log(Level.SEVERE, "Couldn't parse text property list", e)
@Throws(IOException::class, XmlPullParserException::class)
fun readTextPropertyList(parser: XmlPullParser, name: Property.Name, list: MutableCollection<String>) {
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 &&
Property.Name(parser.namespace, parser.name) == name)
list.add(parser.nextText())
eventType = parser.next()
}
}
......
......@@ -6,6 +6,6 @@
* http://www.gnu.org/licenses/gpl.html
*/
package at.bitfire.dav4android.exception;
package at.bitfire.dav4android.exception
open class DavException @JvmOverloads constructor(message: String, ex: Throwable? = null): Exception(message, ex)
\ No newline at end of file
......@@ -8,7 +8,7 @@
package at.bitfire.dav4android.exception
import okhttp3.Response;
import okhttp3.Response
import java.net.HttpURLConnection
class UnauthorizedException: HttpException {
......
......@@ -8,11 +8,10 @@
package at.bitfire.dav4android.property
import org.xmlpull.v1.XmlPullParser;
import at.bitfire.dav4android.Property;
import at.bitfire.dav4android.PropertyFactory;
import at.bitfire.dav4android.XmlUtils;
import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser
data class AddressbookDescription(
var description: String? = null
......
......@@ -9,7 +9,6 @@
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
......@@ -21,7 +20,7 @@ class AddressbookHomeSet: HrefListProperty() {
}
class Factory(): HrefListProperty.Factory() {
class Factory : HrefListProperty.Factory() {
override fun getName() = NAME
......
......@@ -20,7 +20,7 @@ class CalendarHomeSet: HrefListProperty() {
}
class Factory(): HrefListProperty.Factory() {
class Factory : HrefListProperty.Factory() {
override fun getName() = NAME
......
......@@ -20,7 +20,7 @@ class CalendarProxyReadFor: HrefListProperty() {
}
class Factory(): HrefListProperty.Factory() {
class Factory : HrefListProperty.Factory() {
override fun getName() = NAME
......
......@@ -20,7 +20,7 @@ class CalendarProxyWriteFor: HrefListProperty() {
}
class Factory(): HrefListProperty.Factory() {
class Factory : HrefListProperty.Factory() {
override fun getName() = NAME
......
......@@ -20,7 +20,7 @@ class CalendarUserAddressSet: HrefListProperty() {
}
class Factory(): HrefListProperty.Factory() {
class Factory : HrefListProperty.Factory() {
override fun getName() = NAME
......
......@@ -8,13 +8,10 @@
package at.bitfire.dav4android.property
import at.bitfire.dav4android.Constants
import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.logging.Level
// see RFC 5397: WebDAV Current Principal Extension
......@@ -33,23 +30,11 @@ data class CurrentUserPrincipal(
override fun getName() = NAME
override fun create(parser: XmlPullParser): CurrentUserPrincipal {
// <!ELEMENT current-user-principal (unauthenticated | href)>
var href: String? = null
try {
// <!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);
}
XmlUtils.processTag(parser, XmlUtils.NS_WEBDAV, "href", {
href = XmlUtils.readText(parser)
})
return CurrentUserPrincipal(href)
}
......
......@@ -8,13 +8,10 @@
package at.bitfire.dav4android.property
import at.bitfire.dav4android.Constants
import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.logging.Level
data class CurrentUserPrivilegeSet(
// only those privileges which are required for DAVdroid are implemented
......@@ -33,15 +30,15 @@ data class CurrentUserPrivilegeSet(
override fun getName() = NAME
override fun create(parser: XmlPullParser): CurrentUserPrivilegeSet? {
// <!ELEMENT current-user-privilege-set (privilege*)>
// <!ELEMENT privilege ANY>
val privs = CurrentUserPrivilegeSet(false, false)
fun parsePrivilege() {
XmlUtils.processTag(parser, XmlUtils.NS_WEBDAV, "privilege", {
val depth = parser.depth
// <!ELEMENT privilege ANY>
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)
if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1 && parser.namespace == XmlUtils.NS_WEBDAV)
when (parser.name) {
"read" ->
privs.mayRead = true
......@@ -51,26 +48,10 @@ data class CurrentUserPrivilegeSet(
privs.mayRead = 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()
}
} catch(e: XmlPullParserException) {
Constants.log.log(Level.SEVERE, "Couldn't parse <current-user-privilege-set>", e)
return null
}
})
return privs
}
......
......@@ -23,7 +23,7 @@ data class DisplayName(
}
class Factory(): PropertyFactory {
class Factory : PropertyFactory {
override fun getName() = NAME
......
......@@ -23,7 +23,7 @@ data class GetCTag(
}
class Factory(): PropertyFactory {
class Factory : PropertyFactory {
override fun getName() = NAME
......
......@@ -26,7 +26,7 @@ data class GetContentType(
constructor(mediaType: MediaType): this(mediaType.toString())
class Factory(): PropertyFactory {
class Factory : PropertyFactory {
override fun getName() = NAME
......
......@@ -14,7 +14,9 @@ import at.bitfire.dav4android.QuotedStringUtils
import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser
class GetETag: Property {
class GetETag(
rawETag: String?
): Property {
companion object {
@JvmField
......@@ -23,7 +25,7 @@ class GetETag: Property {
var eTag: String?
constructor(rawETag: String?) {
init {
/* entity-tag = [ weak ] opaque-tag
weak = "W/"
opaque-tag = quoted-string
......@@ -44,7 +46,7 @@ class GetETag: Property {
override fun toString() = eTag ?: "(null)"
class Factory(): PropertyFactory {
class Factory : PropertyFactory {
override fun getName() = NAME
......
......@@ -20,7 +20,7 @@ class GroupMembership: HrefListProperty() {
}
class Factory(): HrefListProperty.Factory() {
class Factory: HrefListProperty.Factory() {
override fun getName() = NAME
......
......@@ -8,13 +8,10 @@
package at.bitfire.dav4android.property
import at.bitfire.dav4android.Constants
import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.logging.Level
class ResourceType: Property {
......@@ -41,28 +38,22 @@ class ResourceType: Property {
override fun create(parser: XmlPullParser): ResourceType? {
val type = ResourceType()
try {
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) {
// use static objects to allow types.contains()
var typeName = Property.Name(parser.namespace, parser.name)
when (typeName) {
COLLECTION -> typeName = COLLECTION
PRINCIPAL -> typeName = PRINCIPAL
ADDRESSBOOK -> typeName = ADDRESSBOOK
CALENDAR -> typeName = CALENDAR
SUBSCRIBED -> typeName = SUBSCRIBED
}
type.types.add(typeName)
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) {
// use static objects to allow types.contains()
var typeName = Property.Name(parser.namespace, parser.name)
when (typeName) {
COLLECTION -> typeName = COLLECTION
PRINCIPAL -> typeName = PRINCIPAL
ADDRESSBOOK -> typeName = ADDRESSBOOK
CALENDAR -> typeName = CALENDAR
SUBSCRIBED -> typeName = SUBSCRIBED
}
eventType = parser.next()
type.types.add(typeName)
}
} catch(e: XmlPullParserException) {
Constants.log.log(Level.SEVERE, "Couldn't parse <resourcetype>", e);
return null
eventType = parser.next()
}
return type
......
......@@ -20,7 +20,7 @@ class Source: HrefListProperty() {
}
class Factory(): HrefListProperty.Factory() {
class Factory : HrefListProperty.Factory() {
override fun getName() = NAME
......
......@@ -14,6 +14,7 @@ import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils
import okhttp3.MediaType
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.logging.Level
class SupportedAddressData: Property {
......@@ -37,21 +38,14 @@ class SupportedAddressData: Property {
val supported = SupportedAddressData()
try {
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_CARDDAV && parser.name == "address-data-type")
parser.getAttributeValue(null, "content-type")?.let { contentType ->
@Suppress("NAME_SHADOWING")
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) {
XmlUtils.processTag(parser, XmlUtils.NS_CARDDAV, "address-data-type", {
parser.getAttributeValue(null, "content-type")?.let { contentType ->
var type = contentType
parser.getAttributeValue(null, "version")?.let { version -> type += "; version=$version" }
MediaType.parse(type)?.let { supported.types.add(it) }
}
})
} catch(e: XmlPullParserException) {
Constants.log.log(Level.SEVERE, "Couldn't parse <resourcetype>", e)
return null
}
......
......@@ -8,17 +8,10 @@
package at.bitfire.dav4android.property
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
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;
import at.bitfire.dav4android.Property
import at.bitfire.dav4android.PropertyFactory
import at.bitfire.dav4android.XmlUtils
import org.xmlpull.v1.XmlPullParser
data class SupportedCalendarComponentSet(
var supportsEvents: Boolean,
......@@ -36,35 +29,29 @@ data class SupportedCalendarComponentSet(
override fun getName() = NAME
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)
try {
/* <!ELEMENT supported-calendar-component-set (comp+)>
<!ELEMENT comp ((allprop | prop*), (allcomp | comp*))>
<!ATTLIST comp name CDATA #REQUIRED>
*/
val depth = parser.depth
var eventType = parser.eventType
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
}
val depth = parser.depth
var eventType = parser.eventType
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
}
}
eventType = parser.next()
}
} catch(e: XmlPullParserException) {
Constants.log.log(Level.SEVERE, "Couldn't parse <supported-calendar-component-set>", e)
return null
eventType = parser.next()
}
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
at.bitfire.dav4android.property.Source$Factory
at.bitfire.dav4android.property.SupportedAddressData$Factory
at.bitfire.dav4android.property.SupportedCalendarComponentSet$Factory
at.bitfire.dav4android.property.SupportedReportSet$Factory
at.bitfire.dav4android.property.SyncToken$Factory
......@@ -16,7 +16,6 @@ import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
@SuppressWarnings("ThrowableInstanceNeverThrown")
......