Skip to content
This repository was archived by the owner on Sep 4, 2020. It is now read-only.

Commit 19240bd

Browse files
author
Peter Nied
committed
Merge pull request #13 from iambmelt/recurrence
Fix processing of RecurrenceRange
2 parents 2eba044 + ae6f96f commit 19240bd

5 files changed

Lines changed: 223 additions & 16 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.microsoft.graph.serializer;
2+
3+
import android.test.AndroidTestCase;
4+
5+
import com.microsoft.graph.model.DateOnly;
6+
7+
public class DateOnlyTests extends AndroidTestCase {
8+
9+
public void testDateSerializer() throws Exception {
10+
String strDate = DateOnly.parse("2016-04-27").toString();
11+
assertEquals("2016-04-27", strDate);
12+
}
13+
14+
public void testDateSerializerIndefinite() throws Exception {
15+
String strDate = DateOnly.parse("0001-01-01").toString();
16+
assertEquals("0001-01-01", strDate);
17+
}
18+
19+
public void testDateDeserializer() throws Exception {
20+
DateOnly date = DateOnly.parse("2016-04-27");
21+
assertEquals(2016, date.getYear());
22+
assertEquals(4, date.getMonth());
23+
assertEquals(27, date.getDay());
24+
}
25+
26+
public void testDateDeserializerIndefinite() throws Exception{
27+
DateOnly date = DateOnly.parse("0001-01-01");
28+
assertEquals(1, date.getYear());
29+
assertEquals(1, date.getMonth());
30+
assertEquals(1, date.getDay());
31+
}
32+
}

graphsdk/src/androidTest/java/com/microsoft/graph/serializer/DefaultSerializerTests.java

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,22 @@
2222

2323
package com.microsoft.graph.serializer;
2424

25+
import android.test.AndroidTestCase;
26+
2527
import com.microsoft.graph.extensions.Drive;
28+
import com.microsoft.graph.extensions.RecurrenceRangeType;
29+
import com.microsoft.graph.generated.BaseRecurrenceRange;
2630
import com.microsoft.graph.logger.DefaultLogger;
27-
28-
import android.test.AndroidTestCase;
31+
import com.microsoft.graph.model.DateOnly;
2932

3033
/**
3134
* Test cases for the {@see DefaultSerializer}
3235
*/
33-
public class DefaultSerializerTests extends AndroidTestCase {
36+
public class DefaultSerializerTests extends AndroidTestCase {
3437

3538
/**
3639
* Make sure that deserializing a Drive also returns members from BaseDrive
40+
*
3741
* @throws Exception If there is an exception during the test
3842
*/
3943
public void testDriveDeserialization() throws Exception {
@@ -46,4 +50,36 @@ public void testDriveDeserialization() throws Exception {
4650
assertEquals("8bf6ae90006c4a4c", result.id);
4751

4852
}
53+
54+
public void testRecurrenceRangeDeserialization() throws Exception {
55+
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
56+
String source = "{\n" +
57+
" \"type\": \"noEnd\",\n" +
58+
" \"startDate\": \"2016-04-27\",\n" +
59+
" \"endDate\": \"0001-01-01\",\n" +
60+
" \"recurrenceTimeZone\": \"China Standard Time\",\n" +
61+
" \"numberOfOccurrences\": 0\n" +
62+
"}";
63+
BaseRecurrenceRange baseRecurrenceRange = serializer.deserializeObject(source, BaseRecurrenceRange.class);
64+
assertNotNull(source);
65+
assertEquals(baseRecurrenceRange.type, RecurrenceRangeType.noEnd);
66+
assertEquals("2016-04-27", baseRecurrenceRange.startDate.toString());
67+
assertEquals("0001-01-01", baseRecurrenceRange.endDate.toString());
68+
assertEquals("China Standard Time", baseRecurrenceRange.recurrenceTimeZone);
69+
assertEquals(Integer.valueOf(0), baseRecurrenceRange.numberOfOccurrences);
70+
}
71+
72+
public void testRecurrenceRangeSerialization() throws Exception {
73+
final String expected = "{\"endDate\":\"2016-05-25\",\"numberOfOccurrences\":4,\"@odata.type\":\"microsoft.graph.recurrenceRange\",\"recurrenceTimeZone\":\"PST\",\"startDate\":\"2016-04-25\",\"type\":\"endDate\"}";
74+
final DefaultSerializer serializer = new DefaultSerializer(new DefaultLogger());
75+
BaseRecurrenceRange brr = new BaseRecurrenceRange();
76+
brr.type = RecurrenceRangeType.endDate;
77+
brr.startDate = new DateOnly(2016, 4, 25);
78+
brr.endDate = new DateOnly(2016, 5, 25);
79+
brr.recurrenceTimeZone = "PST";
80+
brr.numberOfOccurrences = 4;
81+
String jsonOut = serializer.serializeObject(brr);
82+
assertNotNull(jsonOut);
83+
assertEquals(jsonOut, expected);
84+
}
4985
}

graphsdk/src/main/java/com/microsoft/graph/generated/BaseRecurrenceRange.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ public BaseRecurrenceRange(){
4242
* The Start Date.
4343
*/
4444
@SerializedName("startDate")
45-
public java.util.Calendar startDate;
45+
public com.microsoft.graph.model.DateOnly startDate;
4646

4747
/**
4848
* The End Date.
4949
*/
5050
@SerializedName("endDate")
51-
public java.util.Calendar endDate;
51+
public com.microsoft.graph.model.DateOnly endDate;
5252

5353
/**
5454
* The Recurrence Time Zone.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.microsoft.graph.model;
2+
3+
4+
import java.text.ParseException;
5+
import java.util.Locale;
6+
7+
/**
8+
* A timezone-nonspecific date
9+
*/
10+
public class DateOnly {
11+
12+
/**
13+
* The year
14+
*/
15+
private final int mYear;
16+
17+
/**
18+
* The month
19+
*/
20+
private final int mMonth;
21+
22+
/**
23+
* The day
24+
*/
25+
private final int mDay;
26+
27+
/**
28+
* Constructs a timezone-nonspecific DateOnly
29+
*
30+
* @param dateStr date string of the form <code>yyyy-mm-dd</code>
31+
* @return the parsed DateOnly instance
32+
* @exception ParseException If there was a failure parsing the dateStr
33+
*/
34+
public static DateOnly parse(final String dateStr) throws ParseException {
35+
// break the date up into its constituent parts
36+
String[] dateInfo = dateStr.split("-");
37+
38+
// validate the split date string
39+
final int expectedLength = 3;
40+
if (dateInfo.length != expectedLength) {
41+
throw new ParseException(
42+
"Expected datestring format 'yyyy-mm-dd' but found: " + dateStr, 0
43+
);
44+
}
45+
46+
// array indices for date parsing
47+
final int indYear = 0;
48+
final int indMonth = 1;
49+
final int indDay = 2;
50+
51+
// unpack this array
52+
int year = Integer.parseInt(dateInfo[indYear]);
53+
int month = Integer.parseInt(dateInfo[indMonth]);
54+
int day = Integer.parseInt(dateInfo[indDay]);
55+
56+
return new DateOnly(year, month, day);
57+
}
58+
59+
/**
60+
* Constructs a timezone-nonspecific DateOnly
61+
*
62+
* @param year the year
63+
* @param month 1-indexed month value (Jan == 1)
64+
* @param day day of the month
65+
*/
66+
public DateOnly(final int year, final int month, final int day) {
67+
mYear = year;
68+
mMonth = month;
69+
mDay = day;
70+
}
71+
72+
/**
73+
* Gets the year
74+
*
75+
* @return the year
76+
*/
77+
public int getYear() {
78+
return mYear;
79+
}
80+
81+
/**
82+
* Gets the month
83+
*
84+
* @return the month
85+
*/
86+
public int getMonth() {
87+
return mMonth;
88+
}
89+
90+
/**
91+
* Gets the day
92+
*
93+
* @return the day
94+
*/
95+
public int getDay() {
96+
return mDay;
97+
}
98+
99+
@Override
100+
public String toString() {
101+
return String.format(
102+
Locale.ROOT,
103+
"%04d-%02d-%02d", mYear, mMonth, mDay
104+
);
105+
}
106+
}

graphsdk/src/main/java/com/microsoft/graph/serializer/GsonFactory.java

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// ------------------------------------------------------------------------------
22
// Copyright (c) 2015 Microsoft Corporation
3-
//
3+
//
44
// Permission is hereby granted, free of charge, to any person obtaining a copy
55
// of this software and associated documentation files (the "Software"), to deal
66
// in the Software without restriction, including without limitation the rights
77
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
88
// copies of the Software, and to permit persons to whom the Software is
99
// furnished to do so, subject to the following conditions:
10-
//
10+
//
1111
// The above copyright notice and this permission notice shall be included in
1212
// all copies or substantial portions of the Software.
13-
//
13+
//
1414
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1515
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1616
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -31,8 +31,8 @@
3131
import com.google.gson.JsonPrimitive;
3232
import com.google.gson.JsonSerializationContext;
3333
import com.google.gson.JsonSerializer;
34-
3534
import com.microsoft.graph.logger.ILogger;
35+
import com.microsoft.graph.model.DateOnly;
3636

3737
import java.lang.reflect.Type;
3838
import java.text.ParseException;
@@ -52,12 +52,13 @@ private GsonFactory() {
5252

5353
/**
5454
* Creates an instance of Gson.
55+
*
5556
* @param logger The logger.
5657
* @return The new instance.
5758
*/
5859
public static Gson getGsonInstance(final ILogger logger) {
5960

60-
final JsonSerializer<Calendar> dateJsonSerializer = new JsonSerializer<Calendar>() {
61+
final JsonSerializer<Calendar> calendarJsonSerializer = new JsonSerializer<Calendar>() {
6162
@Override
6263
public JsonElement serialize(final Calendar src,
6364
final Type typeOfSrc,
@@ -74,7 +75,7 @@ public JsonElement serialize(final Calendar src,
7475
}
7576
};
7677

77-
final JsonDeserializer<Calendar> dateJsonDeserializer = new JsonDeserializer<Calendar>() {
78+
final JsonDeserializer<Calendar> calendarJsonDeserializer = new JsonDeserializer<Calendar>() {
7879
@Override
7980
public Calendar deserialize(final JsonElement json,
8081
final Type typeOfT,
@@ -111,13 +112,43 @@ public JsonElement serialize(final byte[] src,
111112
final JsonDeserializer<byte[]> byteArrayJsonDeserializer = new JsonDeserializer<byte[]>() {
112113
@Override
113114
public byte[] deserialize(final JsonElement json,
115+
final Type typeOfT,
116+
final JsonDeserializationContext context) throws JsonParseException {
117+
if (json == null) {
118+
return null;
119+
}
120+
try {
121+
return ByteArraySerializer.deserialize(json.getAsString());
122+
} catch (final ParseException e) {
123+
logger.logError("Parsing issue on " + json.getAsString(), e);
124+
return null;
125+
}
126+
}
127+
};
128+
129+
final JsonSerializer<DateOnly> dateJsonSerializer = new JsonSerializer<DateOnly>() {
130+
@Override
131+
public JsonElement serialize(final DateOnly src,
132+
final Type typeOfSrc,
133+
final JsonSerializationContext context) {
134+
if (src == null) {
135+
return null;
136+
}
137+
return new JsonPrimitive(src.toString());
138+
}
139+
};
140+
141+
final JsonDeserializer<DateOnly> dateJsonDeserializer = new JsonDeserializer<DateOnly>() {
142+
@Override
143+
public DateOnly deserialize(final JsonElement json,
114144
final Type typeOfT,
115145
final JsonDeserializationContext context) throws JsonParseException {
116146
if (json == null) {
117147
return null;
118148
}
149+
119150
try {
120-
return ByteArraySerializer.deserialize(json.getAsString());
151+
return DateOnly.parse(json.getAsString());
121152
} catch (final ParseException e) {
122153
logger.logError("Parsing issue on " + json.getAsString(), e);
123154
return null;
@@ -126,12 +157,14 @@ public byte[] deserialize(final JsonElement json,
126157
};
127158

128159
return new GsonBuilder()
129-
.registerTypeAdapter(Calendar.class, dateJsonSerializer)
130-
.registerTypeAdapter(Calendar.class, dateJsonDeserializer)
131-
.registerTypeAdapter(GregorianCalendar.class, dateJsonSerializer)
132-
.registerTypeAdapter(GregorianCalendar.class, dateJsonDeserializer)
160+
.registerTypeAdapter(Calendar.class, calendarJsonSerializer)
161+
.registerTypeAdapter(Calendar.class, calendarJsonDeserializer)
162+
.registerTypeAdapter(GregorianCalendar.class, calendarJsonSerializer)
163+
.registerTypeAdapter(GregorianCalendar.class, calendarJsonDeserializer)
133164
.registerTypeAdapter(byte[].class, byteArrayJsonDeserializer)
134165
.registerTypeAdapter(byte[].class, byteArrayJsonSerializer)
166+
.registerTypeAdapter(DateOnly.class, dateJsonSerializer)
167+
.registerTypeAdapter(DateOnly.class, dateJsonDeserializer)
135168
.registerTypeAdapterFactory(new FallBackEnumTypeAdapter())
136169
.create();
137170
}

0 commit comments

Comments
 (0)