Commit 14611de4 authored by Ricki Hirner's avatar Ricki Hirner

Multi-status: process members and member properties

parent fb5f118c
......@@ -23,6 +23,7 @@ dependencies {
compile 'com.squareup.okhttp:okhttp:2.6.0-SNAPSHOT'
compile 'com.squareup.okhttp:logging-interceptor:2.6.0-SNAPSHOT'
provided 'org.projectlombok:lombok:1.16.6'
compile 'org.slf4j:slf4j-android:1.7.12'
androidTestCompile 'com.squareup.okhttp:mockwebserver:2.6.0-SNAPSHOT'
}
package at.bitfire.dav4android;
import com.squareup.okhttp.HttpUrl;
import junit.framework.TestCase;
public class UrlUtilsTest extends TestCase {
public void testOmitTrailingSlash() {
assertEquals(HttpUrl.parse("http://host/resource"), UrlUtils.omitTrailingSlash(HttpUrl.parse("http://host/resource")));
assertEquals(HttpUrl.parse("http://host/resource"), UrlUtils.omitTrailingSlash(HttpUrl.parse("http://host/resource/")));
}
}
package at.bitfire.dav4android;
import android.util.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Constants {
public static final String LOG_TAG = "dav4android";
public static final Logger log = LoggerFactory.getLogger("dav4android");
}
......@@ -20,7 +20,12 @@ public class HttpClient extends OkHttpClient {
public HttpClient() {
super();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Constants.log.trace(message);
}
});
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
networkInterceptors().add(logging);
}
......
......@@ -8,6 +8,9 @@
package at.bitfire.dav4android;
import android.provider.UserDictionary;
import android.text.TextUtils;
import lombok.RequiredArgsConstructor;
public interface Property {
......@@ -17,6 +20,16 @@ public interface Property {
public final String namespace;
public final String name;
@Override
public boolean equals(Object o) {
if (o instanceof Name) {
Name n = (Name)o;
return TextUtils.equals(namespace, n.namespace) &&
TextUtils.equals(name, n.name);
} else
return super.equals(o);
}
@Override
public String toString() {
return name + "(" + namespace + ")";
......
......@@ -25,7 +25,7 @@ public class PropertyCollection {
protected Map<String, Map<String, Property>> properties = null;
Property get(@NonNull Property.Name name) {
public Property get(@NonNull Property.Name name) {
if (properties == null)
return null;
......@@ -36,7 +36,7 @@ public class PropertyCollection {
return nsProperties.get(name.name);
}
Map<Property.Name, Property> getMap() {
public Map<Property.Name, Property> getMap() {
HashMap<Property.Name, Property> map = new HashMap<>();
if (properties != null) {
for (String namespace : properties.keySet()) {
......@@ -48,7 +48,7 @@ public class PropertyCollection {
return Collections.unmodifiableMap(map);
}
void put(Property.Name name, Property property) {
public void put(Property.Name name, Property property) {
if (properties == null)
properties = new HashMap<>();
......@@ -59,6 +59,23 @@ public class PropertyCollection {
nsProperties.put(name.name, property);
}
public int size() {
if (properties == null)
return 0;
int size = 0;
for (Map<String, Property> nsProperties : properties.values())
size += nsProperties.size();
return size;
}
public void merge(PropertyCollection another) {
Map<Property.Name, Property> properties = another.getMap();
for (Property.Name name : properties.keySet())
put(name, properties.get(name));
}
@Override
public String toString() {
if (properties == null)
......
......@@ -7,6 +7,8 @@ import java.util.Map;
import at.bitfire.dav4android.property.CalendarColor;
import at.bitfire.dav4android.property.DisplayName;
import at.bitfire.dav4android.property.ResourceType;
import at.bitfire.dav4android.property.SupportedAddressData;
public class PropertyRegistry {
......@@ -14,7 +16,13 @@ public class PropertyRegistry {
static final PropertyRegistry DEFAULT = new PropertyRegistry();
static {
DEFAULT.register(new ResourceType.Factory());
DEFAULT.register(new DisplayName.Factory());
// CardDAV
DEFAULT.register(new SupportedAddressData.Factory());
// CalDAV
DEFAULT.register(new CalendarColor.Factory());
}
......
package at.bitfire.dav4android;
import com.squareup.okhttp.HttpUrl;
public class UrlUtils {
static public HttpUrl omitTrailingSlash(HttpUrl url) {
int idxLast = url.pathSize() - 1;
boolean hasTrailingSlash = "".equals(url.pathSegments().get(idxLast));
if (hasTrailingSlash)
return url.newBuilder().removePathSegment(idxLast).build();
else
return url;
}
static public HttpUrl withTrailingSlash(HttpUrl url) {
int idxLast = url.pathSize() - 1;
boolean hasTrailingSlash = "".equals(url.pathSegments().get(idxLast));
if (hasTrailingSlash)
return url;
else
return url.newBuilder().addPathSegment("").build();
}
}
......@@ -3,6 +3,7 @@ package at.bitfire.dav4android;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;
import lombok.SneakyThrows;
......@@ -10,6 +11,7 @@ public class XmlUtils {
public static final String
NS_WEBDAV = "DAV:",
NS_CARDDAV = "urn:ietf:params:xml:ns:carddav",
NS_APPLE_ICAL = "http://apple.com/ns/ical/";
private static final XmlPullParserFactory factory;
......@@ -27,4 +29,9 @@ public class XmlUtils {
return factory.newPullParser();
}
@SneakyThrows(XmlPullParserException.class)
public static XmlSerializer newSerializer() {
return factory.newSerializer();
}
}
......@@ -34,11 +34,9 @@ public class CalendarColor implements Property {
final int depth = parser.getDepth();
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.TEXT && parser.getDepth() == depth) {
while (eventType != XmlPullParser.END_DOCUMENT && !(eventType == XmlPullParser.END_TAG && parser.getDepth() == depth)) {
if (eventType == XmlPullParser.TEXT && parser.getDepth() == depth)
calendarColor.color = parser.getText();
} else if (eventType == XmlPullParser.END_TAG && parser.getDepth() == depth)
break;
eventType = parser.next();
}
} catch(XmlPullParserException |IOException e) {
......@@ -49,5 +47,4 @@ public class CalendarColor implements Property {
return calendarColor;
}
}
}
......@@ -44,11 +44,9 @@ public class DisplayName implements Property {
final int depth = parser.getDepth();
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.TEXT && parser.getDepth() == depth) {
while (eventType != XmlPullParser.END_DOCUMENT && !(eventType == XmlPullParser.END_TAG && parser.getDepth() == depth)) {
if (eventType == XmlPullParser.TEXT && parser.getDepth() == depth)
displayName.displayName = parser.getText();
} else if (eventType == XmlPullParser.END_TAG && parser.getDepth() == depth)
break;
eventType = parser.next();
}
} catch(XmlPullParserException|IOException e) {
......@@ -59,5 +57,4 @@ public class DisplayName implements Property {
return displayName;
}
}
}
package at.bitfire.dav4android.property;
import android.util.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import at.bitfire.dav4android.Constants;
import at.bitfire.dav4android.Property;
import at.bitfire.dav4android.PropertyFactory;
import at.bitfire.dav4android.XmlUtils;
import lombok.ToString;
@ToString
public class ResourceType implements Property {
public static final Name NAME = new Name(XmlUtils.NS_WEBDAV, "resourcetype");
public static final Name WEBDAV_COLLECTION = new Name(XmlUtils.NS_WEBDAV, "collection");
public final Set<Property.Name> types = new HashSet<>();
public static class Factory implements PropertyFactory {
@Override
public Name getName() {
return NAME;
}
@Override
public ResourceType create(XmlPullParser parser) {
ResourceType type = new ResourceType();
try {
final int depth = parser.getDepth();
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT && !(eventType == XmlPullParser.END_TAG && parser.getDepth() == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.getDepth() == depth + 1) {
String namespace = parser.getNamespace(), name = parser.getName();
// use pre-defined objects to allow types.contains()
Name typeName = new Name(parser.getNamespace(), parser.getName());
if (WEBDAV_COLLECTION.equals(typeName))
typeName = WEBDAV_COLLECTION;
type.types.add(typeName);
}
eventType = parser.next();
}
} catch(XmlPullParserException |IOException e) {
Log.e(Constants.LOG_TAG, "Couldn't parse <resourcetype>", e);
return null;
}
return type;
}
}
}
package at.bitfire.dav4android.property;
import android.util.Log;
import com.squareup.okhttp.MediaType;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import at.bitfire.dav4android.Constants;
import at.bitfire.dav4android.Property;
import at.bitfire.dav4android.PropertyFactory;
import at.bitfire.dav4android.XmlUtils;
public class SupportedAddressData implements Property {
public static final Property.Name NAME = new Property.Name(XmlUtils.NS_CARDDAV, "supported-address-data");
public final Set<MediaType> types = new HashSet<>();
public static class Factory implements PropertyFactory {
@Override
public Property.Name getName() {
return NAME;
}
@Override
public SupportedAddressData create(XmlPullParser parser) {
SupportedAddressData supported = new SupportedAddressData();
try {
final int depth = parser.getDepth();
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT && !(eventType == XmlPullParser.END_TAG && parser.getDepth() == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.getDepth() == depth+1 &&
XmlUtils.NS_CARDDAV.equals(parser.getNamespace()) && "address-data-type".equals(parser.getName())) {
String contentType = parser.getAttributeValue(XmlUtils.NS_CARDDAV, "content-type"),
version = parser.getAttributeValue(XmlUtils.NS_CARDDAV, "version");
if (contentType != null) {
if (version != null)
contentType += "; version=" + version;
supported.types.add(MediaType.parse(contentType));
}
}
eventType = parser.next();
}
} catch(XmlPullParserException |IOException e) {
Log.e(Constants.LOG_TAG, "Couldn't parse <resourcetype>", e);
return null;
}
return supported;
}
}
}
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