├── .idea ├── .name ├── copyright │ ├── profiles_settings.xml │ └── Citrix.xml ├── scopes │ └── scope_settings.xml ├── encodings.xml ├── vcs.xml ├── modules.xml ├── misc.xml ├── gradle.xml └── compiler.xml ├── sdk ├── .gitignore ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── podio │ │ │ │ └── sdk │ │ │ │ ├── domain │ │ │ │ ├── data │ │ │ │ │ ├── UnknownData.java │ │ │ │ │ └── Data.java │ │ │ │ ├── reference │ │ │ │ │ ├── UnknownReferenceGroup.java │ │ │ │ │ ├── OrganisationTagReferenceGroup.java │ │ │ │ │ ├── TasksReferenceGroup.java │ │ │ │ │ ├── SpacesReferenceGroup.java │ │ │ │ │ ├── AppsReferenceGroup.java │ │ │ │ │ ├── ProfilesReferenceGroup.java │ │ │ │ │ ├── AppReferenceGroup.java │ │ │ │ │ └── SpaceContactsSpaceMembersReferenceGroup.java │ │ │ │ ├── ItemReferenceCount.java │ │ │ │ ├── TextTaskAction.java │ │ │ │ ├── AssignTaskAction.java │ │ │ │ ├── stream │ │ │ │ │ ├── FileEventActivity.java │ │ │ │ │ ├── FileEventContext.java │ │ │ │ │ ├── ItemEventActivity.java │ │ │ │ │ ├── TaskEventActivity.java │ │ │ │ │ ├── UnknownEventContext.java │ │ │ │ │ ├── GrantEventActivity.java │ │ │ │ │ ├── StatusEventContext.java │ │ │ │ │ ├── UnknownEventActivity.java │ │ │ │ │ ├── VoteEventActivity.java │ │ │ │ │ ├── RatingEventActivity.java │ │ │ │ │ ├── TaskActionEventActivity.java │ │ │ │ │ ├── QuestionAnswerEventActivity.java │ │ │ │ │ ├── ItemParticipationEventActivity.java │ │ │ │ │ └── EventActivity.java │ │ │ │ ├── notification │ │ │ │ │ ├── VoteNotification.java │ │ │ │ │ ├── GrantNotification.java │ │ │ │ │ ├── RatingNotification.java │ │ │ │ │ ├── CommentNotification.java │ │ │ │ │ ├── UnknownNotification.java │ │ │ │ │ ├── ItemNotificationContext.java │ │ │ │ │ ├── AppNotificationContext.java │ │ │ │ │ ├── UnknownNotificationContext.java │ │ │ │ │ ├── BatchNotificationContext.java │ │ │ │ │ ├── ParticipationNotification.java │ │ │ │ │ ├── NotificationInboxCount.java │ │ │ │ │ ├── NotificationContext.java │ │ │ │ │ └── Notification.java │ │ │ │ ├── Label.java │ │ │ │ ├── Answer.java │ │ │ │ ├── QuestionOption.java │ │ │ │ ├── PushEventViewing.java │ │ │ │ ├── QuestionAnswer.java │ │ │ │ ├── PushEventTyping.java │ │ │ │ ├── LinkedAccountData.java │ │ │ │ ├── Vote.java │ │ │ │ ├── Reminder.java │ │ │ │ ├── Push.java │ │ │ │ ├── NotificationGroup.java │ │ │ │ ├── Reference.java │ │ │ │ ├── Right.java │ │ │ │ ├── ItemParticipation.java │ │ │ │ ├── Presence.java │ │ │ │ ├── Voting.java │ │ │ │ ├── field │ │ │ │ │ ├── UndefinedField.java │ │ │ │ │ ├── LinkedAccountDataField.java │ │ │ │ │ └── ProgressField.java │ │ │ │ ├── Rating.java │ │ │ │ ├── Batch.java │ │ │ │ ├── TaskAction.java │ │ │ │ ├── UserStatus.java │ │ │ │ ├── Address.java │ │ │ │ ├── ReferenceType.java │ │ │ │ ├── DataReference.java │ │ │ │ ├── LinkedAccount.java │ │ │ │ ├── Recurrence.java │ │ │ │ ├── Byline.java │ │ │ │ ├── Embed.java │ │ │ │ ├── File.java │ │ │ │ ├── View.java │ │ │ │ ├── PushEvent.java │ │ │ │ ├── User.java │ │ │ │ ├── Status.java │ │ │ │ └── Grant.java │ │ │ │ ├── NetworkError.java │ │ │ │ ├── NoResponseError.java │ │ │ │ ├── ConnectionError.java │ │ │ │ ├── Client.java │ │ │ │ ├── internal │ │ │ │ └── DefaultHashMap.java │ │ │ │ ├── provider │ │ │ │ ├── FileProvider.java │ │ │ │ ├── EmbedProvider.java │ │ │ │ ├── OrganizationProvider.java │ │ │ │ ├── SpacesProvider.java │ │ │ │ ├── ViewProvider.java │ │ │ │ ├── LocationProvider.java │ │ │ │ ├── GrantProvider.java │ │ │ │ ├── ReminderProvider.java │ │ │ │ ├── RecurrenceProvider.java │ │ │ │ ├── StatusProvider.java │ │ │ │ ├── ReferenceProvider.java │ │ │ │ ├── LinkedAccountProvider.java │ │ │ │ ├── UserProvider.java │ │ │ │ ├── CommentProvider.java │ │ │ │ ├── StreamProvider.java │ │ │ │ ├── RatingProvider.java │ │ │ │ └── ClientProvider.java │ │ │ │ ├── QueueClient.java │ │ │ │ ├── Filter.java │ │ │ │ ├── Provider.java │ │ │ │ ├── localstore │ │ │ │ ├── FreeRequest.java │ │ │ │ ├── RemoveRequest.java │ │ │ │ ├── EraseRequest.java │ │ │ │ └── SetRequest.java │ │ │ │ ├── PodioError.java │ │ │ │ ├── Store.java │ │ │ │ ├── json │ │ │ │ ├── TaskActionDeserializerSerializer.java │ │ │ │ ├── JsonParser.java │ │ │ │ ├── EventContextDeserializerSerializer.java │ │ │ │ ├── DataReferenceDeserializer.java │ │ │ │ ├── NotificationContextDeserializerSerializer.java │ │ │ │ ├── NotificationDeserializerSerializer.java │ │ │ │ ├── EventActivityDeserializerSerializer.java │ │ │ │ └── ReferenceGroupDeserializerSerializer.java │ │ │ │ ├── Session.java │ │ │ │ ├── androidasynchttp │ │ │ │ └── AndroidAsyncHttpClient.java │ │ │ │ ├── Request.java │ │ │ │ └── volley │ │ │ │ └── VolleyCallbackManager.java │ │ └── AndroidManifest.xml │ └── androidTest │ │ └── java │ │ └── com │ │ └── podio │ │ └── sdk │ │ ├── ThreadCaptureResultListener.java │ │ ├── provider │ │ ├── OrganizationFilterTest.java │ │ ├── OrganizationProviderTest.java │ │ ├── ItemFilterTest.java │ │ ├── CalendarProviderTest.java │ │ ├── ApplicationFilterTest.java │ │ ├── ClientProviderTest.java │ │ └── UserProviderTest.java │ │ ├── domain │ │ ├── UserEmailTest.java │ │ ├── field │ │ │ └── FieldTest.java │ │ ├── ItemPushTest.java │ │ ├── FileTests.java │ │ ├── CalendarEventTest.java │ │ ├── EmbedTest.java │ │ └── UserProfileTest.java │ │ └── volley │ │ ├── MockRestClient.java │ │ └── MockWebServer.java └── sdk.pom ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitmodules ├── .gitignore ├── README.md ├── android-sdk.iml ├── gradle.properties ├── LICENSE └── gradlew.bat /.idea/.name: -------------------------------------------------------------------------------- 1 | Android SDK -------------------------------------------------------------------------------- /sdk/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':sdk' 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/podio/podio-android/master/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "test-runner"] 2 | path = test-runner 3 | url = git@github.com:podio/mixed-android-instrumentation-test-runner.git 4 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/data/UnknownData.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.data; 2 | 3 | /** 4 | */ 5 | public class UnknownData implements Data { 6 | } 7 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sdk/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 10 15:27:10 PDT 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip 7 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/reference/UnknownReferenceGroup.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.reference; 3 | 4 | /** 5 | * Fallback reference group when there are unknown reference groups. 6 | * 7 | */ 8 | public class UnknownReferenceGroup extends ReferenceGroup{ 9 | } 10 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/ItemReferenceCount.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | public class ItemReferenceCount { 5 | 6 | private int count; 7 | private Application app; 8 | 9 | //following attributes are not supported yet 10 | //private Object field 11 | } 12 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/data/Data.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.data; 3 | 4 | /** 5 | * Interface that defines the static inheritance structure of the supported types of reference data 6 | * objects that our custom reference data JSON deserializer can parse. 7 | * 8 | */ 9 | public interface Data { 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # IDE generated files 12 | /local.properties 13 | /.idea/workspace.xml 14 | /.idea/libraries 15 | *.iml 16 | 17 | # Gradle files 18 | .gradle 19 | .DS_Store 20 | /build 21 | 22 | # Local configuration file (sdk path, etc) 23 | local.properties 24 | 25 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/TextTaskAction.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | /** 5 | * A Java representation of the TaskActionDTO API domain object when the action type is of any type 6 | * but "assign". 7 | * 8 | */ 9 | public class TextTaskAction extends TaskAction{ 10 | 11 | String changed = null; 12 | 13 | public String getText() { 14 | return changed; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/AssignTaskAction.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | /** 5 | * A Java representation of the TaskActionDTO API domain object when the action type is of type 6 | * "assign". 7 | * 8 | */ 9 | public class AssignTaskAction extends TaskAction { 10 | 11 | Profile changed = null; 12 | 13 | public Profile getProfile() { 14 | return changed; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/FileEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.File; 4 | 5 | /** 6 | * This class is used when the activity is of type "file". 7 | * 8 | */ 9 | public class FileEventActivity extends EventActivity { 10 | 11 | private final File data = null; 12 | 13 | public File getFile() { 14 | return data; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/FileEventContext.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.File; 4 | 5 | /** 6 | * This class is used when the stream object is of type "file". 7 | * 8 | */ 9 | public class FileEventContext extends EventContext { 10 | 11 | private final File data = null; 12 | 13 | public File getFile() { 14 | return data; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/ItemEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.Item; 4 | 5 | /** 6 | * This class is used when the activity is of type "item". 7 | * 8 | */ 9 | public class ItemEventActivity extends EventActivity { 10 | 11 | private final Item data = null; 12 | 13 | public Item getItem() { 14 | return data; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/TaskEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.Task; 4 | 5 | /** 6 | * This class is used when the activity is of type "task". 7 | * 8 | */ 9 | public class TaskEventActivity extends EventActivity { 10 | 11 | private final Task data = null; 12 | 13 | public Task getTask() { 14 | return data; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/UnknownEventContext.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | /** 4 | * This class is used for all stream objects that we are yet to define in the SDK. In most cases the 5 | * attributes in the super class EventContext} is sufficient so stream objects of this type are 6 | * still useful to handle. 7 | * 8 | */ 9 | public class UnknownEventContext extends EventContext { 10 | } 11 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/GrantEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.Grant; 4 | 5 | /** 6 | * This class is used when the activity is of type "grant". 7 | * 8 | */ 9 | public class GrantEventActivity extends EventActivity { 10 | 11 | private final Grant data = null; 12 | 13 | public Grant getGrant() { 14 | return data; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/StatusEventContext.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.Status; 4 | 5 | /** 6 | * This class is used when the stream object is of type "status". 7 | * 8 | */ 9 | public class StatusEventContext extends EventContext { 10 | 11 | private final Status data = null; 12 | 13 | public Status getStatus() { 14 | return data; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/UnknownEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | /** 4 | * This class is used for all activities that we are yet to define in the SDK. In most cases the 5 | * attributes in the super class {@link EventActivity} is sufficient so activities of this type are 6 | * still useful to handle. 7 | * 8 | */ 9 | public class UnknownEventActivity extends EventActivity { 10 | } 11 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/VoteEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.Vote; 4 | 5 | /** 6 | * This class is used when the activity is of type "vote". 7 | * 8 | */ 9 | public class VoteEventActivity extends EventActivity { 10 | 11 | private final Vote data = null; 12 | 13 | 14 | public Vote getVote() { 15 | return data; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/VoteNotification.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.Vote; 5 | 6 | /** 7 | * This class is used when the notification is of type "vote". 8 | * 9 | */ 10 | public class VoteNotification extends Notification { 11 | 12 | private final Vote data = null; 13 | 14 | public Vote getVote() { 15 | return data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/RatingEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.Rating; 4 | 5 | /** 6 | * This class is used when the activity is of type "rating". 7 | * 8 | */ 9 | public class RatingEventActivity extends EventActivity { 10 | 11 | private final Rating data = null; 12 | 13 | 14 | public Rating getRating() { 15 | return data; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/GrantNotification.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.Grant; 5 | 6 | /** 7 | * This class is used when the notification is of type "grant_create". 8 | * 9 | */ 10 | public class GrantNotification extends Notification { 11 | 12 | private final Grant data = null; 13 | 14 | public Grant getGrant() { 15 | return data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/RatingNotification.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.Rating; 5 | 6 | /** 7 | * This class is used when the notification is of type "rating". 8 | * 9 | */ 10 | public class RatingNotification extends Notification { 11 | 12 | private final Rating data = null; 13 | 14 | public Rating getRating() { 15 | return data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/CommentNotification.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.Comment; 5 | 6 | /** 7 | * This class is used when the notification is of type "comment". 8 | * 9 | */ 10 | public class CommentNotification extends Notification { 11 | 12 | private final Comment data = null; 13 | 14 | public Comment getComment() { 15 | return data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/UnknownNotification.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | /** 5 | * This class is used for all notifications that we are yet to define in the SDK. In most cases the 6 | * attributes in the super class {@link Notification} is sufficient so notifications of this type 7 | * are still useful to handle. 8 | * 9 | */ 10 | public class UnknownNotification extends Notification { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/TaskActionEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.TaskAction; 4 | 5 | /** 6 | * This class is used when the activity is of type "task_action". 7 | * 8 | */ 9 | public class TaskActionEventActivity extends EventActivity { 10 | 11 | private final TaskAction data = null; 12 | 13 | public TaskAction getTaskAction() { 14 | return data; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/ItemNotificationContext.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.Item; 5 | 6 | /** 7 | * This class is used when the notification context object is of type "item". 8 | * 9 | */ 10 | public class ItemNotificationContext extends NotificationContext { 11 | 12 | private final Item data = null; 13 | 14 | public Item getItem() { 15 | return data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/reference/OrganisationTagReferenceGroup.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.reference; 3 | 4 | import java.util.List; 5 | 6 | /** 7 | * When the reference search group name is "tag_field" you will get this object. 8 | * 9 | */ 10 | public class OrganisationTagReferenceGroup extends ReferenceGroup { 11 | private final List contents = null; 12 | 13 | public List getContents() { 14 | return contents; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) 2 | 3 | # Podio SDK for Android # 4 | You can find an introduction to the Podio Android SDK [here](http://podio.github.io/podio-android/) and an example implementation, using the Podio SDK [here](http://engineering.podio.com/2014/07/07/build-time-tracker-app-podio-sdk-android-time/). 5 | 6 | You should also check out our [engineering blog](http://engineering.podio.com/) for any news and other cool examples. 7 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/AppNotificationContext.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.Application; 5 | 6 | /** 7 | * This class is used when the notification context object is of type "app". 8 | * 9 | */ 10 | public class AppNotificationContext extends NotificationContext { 11 | 12 | private final Application data = null; 13 | 14 | public Application getApp() { 15 | return data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/UnknownNotificationContext.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | /** 5 | * This class is used for all notification contexts that we are yet to define in the SDK. In most 6 | * cases the attributes in the super class {@link NotificationContext} is sufficient so 7 | * notifications of this type are still useful to handle. 8 | * 9 | */ 10 | public class UnknownNotificationContext extends NotificationContext { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/QuestionAnswerEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.QuestionAnswer; 4 | 5 | /** 6 | * This class is used when the activity is of type "question_answer". 7 | * 8 | */ 9 | public class QuestionAnswerEventActivity extends EventActivity { 10 | 11 | private final QuestionAnswer data = null; 12 | 13 | public QuestionAnswer getQuestionAnswer() { 14 | return data; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/ThreadCaptureResultListener.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk; 2 | 3 | public class ThreadCaptureResultListener implements Request.ResultListener { 4 | 5 | private String threadName; 6 | 7 | public String getThreadName() { 8 | return threadName; 9 | } 10 | 11 | @Override 12 | public boolean onRequestPerformed(Object content) { 13 | this.threadName = Thread.currentThread().getName(); 14 | return false; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/reference/TasksReferenceGroup.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.reference; 3 | 4 | import com.podio.sdk.domain.Task; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * When the reference search group name is "tasks" you will get this object. 10 | * 11 | */ 12 | public class TasksReferenceGroup extends ReferenceGroup{ 13 | private final List contents = null; 14 | 15 | public List getContents() { 16 | return contents; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/BatchNotificationContext.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.Batch; 5 | 6 | /** 7 | * This class is used when the notification context object is of type "batch_process" or "batch_complete". 8 | * 9 | */ 10 | public class BatchNotificationContext extends NotificationContext { 11 | 12 | private final Batch data = null; 13 | 14 | public Batch getBatch() { 15 | return data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/reference/SpacesReferenceGroup.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.reference; 3 | 4 | import com.podio.sdk.domain.Space; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * When the reference search group name is "spaces" you will get this object. 10 | * 11 | */ 12 | public class SpacesReferenceGroup extends ReferenceGroup{ 13 | private final List contents = null; 14 | 15 | public List getContents() { 16 | return contents; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/ParticipationNotification.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.ItemParticipation; 5 | 6 | /** 7 | * This class is used when the notification was of type "participation". 8 | * 9 | */ 10 | public class ParticipationNotification extends Notification { 11 | 12 | private final ItemParticipation data = null; 13 | 14 | public ItemParticipation getItemParticipation() { 15 | return data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/ItemParticipationEventActivity.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.stream; 2 | 3 | import com.podio.sdk.domain.ItemParticipation; 4 | 5 | /** 6 | * This class is used when the activity is of type "item_participation". 7 | * 8 | */ 9 | public class ItemParticipationEventActivity extends EventActivity { 10 | 11 | private final ItemParticipation data = null; 12 | 13 | public ItemParticipation getItemParticipation() { 14 | return data; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/reference/AppsReferenceGroup.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.reference; 3 | 4 | import com.podio.sdk.domain.Application; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * When the reference search group name is "apps" you will get this object. 10 | * 11 | */ 12 | public class AppsReferenceGroup extends ReferenceGroup { 13 | private final List contents = null; 14 | 15 | public List getContents() { 16 | return contents; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/reference/ProfilesReferenceGroup.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.reference; 3 | 4 | import com.podio.sdk.domain.Profile; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * When the reference search group name is "profiles" you will get this object. 10 | * 11 | */ 12 | public class ProfilesReferenceGroup extends ReferenceGroup { 13 | private final List contents = null; 14 | 15 | public List getContents() { 16 | return contents; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Label.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain; 2 | 3 | /** 4 | * Created by ianhenry on 6/28/16. 5 | */ 6 | public class Label { 7 | private final Long label_id = null; 8 | private final String text = null; 9 | private final String color = null; 10 | 11 | public Long getLabelId() { 12 | return label_id; 13 | } 14 | 15 | public String getText() { 16 | return text; 17 | } 18 | 19 | public String getColor() { 20 | return color; 21 | } 22 | } -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Answer.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * A Java representation of the AnswerDTO API domain object. 8 | * 9 | */ 10 | public class Answer { 11 | 12 | 13 | private final String text = null; 14 | private final Long answer_id = null; 15 | 16 | public String getText() { 17 | return text; 18 | } 19 | 20 | public long getAnswerId() { 21 | return Utils.getNative(answer_id,-1L); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/NetworkError.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | /** 5 | * This class represents a network error when trying to perform the request. 6 | * 7 | */ 8 | public class NetworkError extends PodioError { 9 | 10 | public NetworkError(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | 14 | public NetworkError(String message) { 15 | super(message); 16 | } 17 | 18 | public NetworkError(Throwable cause) { 19 | super(cause); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/NotificationInboxCount.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.notification; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | /** 6 | * Simple class that enables a client to get hold of the number of unread notifications in the 7 | * inbox. 8 | * 9 | */ 10 | public class NotificationInboxCount { 11 | 12 | @SerializedName("new") 13 | private int newUnreadNotificationsCount = 0; 14 | 15 | public int getCount() { 16 | return newUnreadNotificationsCount; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/provider/OrganizationFilterTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import android.net.Uri; 4 | import android.test.AndroidTestCase; 5 | 6 | public class OrganizationFilterTest extends AndroidTestCase { 7 | 8 | public void testOrganizationPathIsIncludedInResultUri() { 9 | Uri reference = Uri.parse("content://test.uri/org"); 10 | 11 | Uri result = new OrganizationProvider.Path() 12 | .buildUri("content", "test.uri"); 13 | 14 | assertEquals(reference, result); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/QuestionOption.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * A Java representation of the QuestionOptionDTO API domain object. 8 | * 9 | */ 10 | public class QuestionOption { 11 | 12 | private final Long question_option_id = null; 13 | 14 | private final String text = null; 15 | 16 | public long getQuestionOptionId() { 17 | return Utils.getNative(question_option_id, -1L); 18 | } 19 | 20 | public String getText() { 21 | return text; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/NoResponseError.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | /** 5 | * This class represents a client side error caused by a request not delivering a response in a 6 | * timely manner. 7 | * 8 | */ 9 | public class NoResponseError extends PodioError { 10 | 11 | public NoResponseError(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public NoResponseError(String message) { 16 | super(message); 17 | } 18 | 19 | public NoResponseError(Throwable cause) { 20 | super(cause); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/PushEventViewing.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * This class describes a push event sent by the API when someone is viewing a target object. 8 | * 9 | */ 10 | public class PushEventViewing extends PushEvent { 11 | 12 | private final Long[] data = null; 13 | 14 | public long get(int index) throws IndexOutOfBoundsException { 15 | return Utils.getNative(data[index], -1); 16 | } 17 | 18 | public int size() { 19 | return Utils.notEmpty(data) ? data.length : 0; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/ConnectionError.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | /** 5 | * This class represents a client side error caused by an invalid connection state (typically 6 | * DISCONNECTED, CONNECTING or DISCONNECTING). 7 | * 8 | */ 9 | public class ConnectionError extends PodioError { 10 | 11 | public ConnectionError(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public ConnectionError(String message) { 16 | super(message); 17 | } 18 | 19 | public ConnectionError(Throwable cause) { 20 | super(cause); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/QuestionAnswer.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * A Java representation of the QuestionAnswerDTO API domain object. 8 | * 9 | */ 10 | public class QuestionAnswer { 11 | 12 | private final Long question_option_id = null; 13 | 14 | private final QuestionOption question_option = null; 15 | 16 | public long getQuestionOptionId() { 17 | return Utils.getNative(question_option_id, -1L); 18 | } 19 | 20 | public QuestionOption getQuestionOption() { 21 | return question_option; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/PushEventTyping.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * This class describes a push event sent by the API when someone is typing text on a target 8 | * object. 9 | * 10 | */ 11 | public class PushEventTyping extends PushEvent { 12 | 13 | private final Long[] data = null; 14 | 15 | public long get(int index) throws IndexOutOfBoundsException { 16 | return Utils.getNative(data[index], -1); 17 | } 18 | 19 | public int size() { 20 | return Utils.notEmpty(data) ? data.length : 0; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/LinkedAccountData.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain; 2 | 3 | /** 4 | * Created by sai on 8/31/16. 5 | */ 6 | public class LinkedAccountData { 7 | private final String url = null; 8 | private final String info = null; 9 | private final String type = null; 10 | private final String id = null; 11 | 12 | public String getUrl() { 13 | return url; 14 | } 15 | 16 | public String getInfo() { 17 | return info; 18 | } 19 | 20 | public String getType() { 21 | return type; 22 | } 23 | 24 | public String getId() { 25 | return id; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Vote.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * A Java representation of the VoteDTO API domain object. 8 | * 9 | */ 10 | public class Vote { 11 | 12 | private final Integer rating = null; 13 | 14 | private final Answer answer = null; 15 | 16 | private final Voting voting = null; 17 | 18 | public Integer getRating() { 19 | return Utils.getNative(rating, -1); 20 | } 21 | 22 | public Answer getAnswer(){ 23 | return answer; 24 | } 25 | 26 | public Voting getVoting() { 27 | return voting; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Reminder.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain; 2 | 3 | import com.podio.sdk.internal.Utils; 4 | 5 | public class Reminder { 6 | 7 | public static class CreateData { 8 | private final int remind_delta; 9 | 10 | public CreateData(int remind_delta) { 11 | this.remind_delta = remind_delta; 12 | } 13 | } 14 | private final Integer remind_delta = null; 15 | 16 | /** 17 | * @return returns minutes to remind before the due_date or -1 if no such value exists 18 | */ 19 | public int getReminderDelta() { 20 | return Utils.getNative(remind_delta, -1); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/Client.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | public interface Client { 5 | public static final int CLIENT_DEFAULT_TIMEOUT_MS = 30000; 6 | 7 | public Request authenticateWithUserCredentials(String username, String password); 8 | 9 | public Request authenticateWithAppCredentials(String appId, String appToken); 10 | 11 | public Request authenticateWithTransferToken(String transferToken); 12 | 13 | @Deprecated 14 | public Request forceRefreshTokens(); 15 | 16 | public Request request(Request.Method method, Filter filter, Object requestData, Class classOfExpectedResult); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/reference/AppReferenceGroup.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.reference; 3 | 4 | import com.podio.sdk.domain.Application; 5 | import com.podio.sdk.domain.Item; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * When the reference search group name is "app" you will get this object. 11 | * 12 | */ 13 | public class AppReferenceGroup extends ReferenceGroup { 14 | private final Application data = null; 15 | private final List contents = null; 16 | 17 | public Application getData() { 18 | return data; 19 | } 20 | 21 | public List getContents() { 22 | return contents; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/internal/DefaultHashMap.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.internal; 3 | 4 | import java.util.HashMap; 5 | 6 | /** 7 | * The purpose of this map is to be able to define a default value when there is no corresponding 8 | * key. 9 | * 10 | */ 11 | public class DefaultHashMap extends HashMap { 12 | 13 | protected V mDefaultValue; 14 | 15 | public DefaultHashMap(V defaultValue) { 16 | super(); 17 | mDefaultValue = defaultValue; 18 | } 19 | 20 | @Override 21 | public V get(Object k) { 22 | V v = super.get(k); 23 | return ((v == null) && !this.containsKey(k)) ? mDefaultValue : v; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Push.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | public class Push { 7 | 8 | private final Long timestamp = null; 9 | private final Integer expires_in = null; 10 | private final String channel = null; 11 | private final String signature = null; 12 | 13 | public long getTimestamp() { 14 | return Utils.getNative(timestamp, -1L); 15 | } 16 | 17 | public int getExpiresIn() { 18 | return Utils.getNative(expires_in, -1); 19 | } 20 | 21 | public String getChannel() { 22 | return channel; 23 | } 24 | 25 | public String getSignature() { 26 | return signature; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/reference/SpaceContactsSpaceMembersReferenceGroup.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.reference; 3 | 4 | import com.podio.sdk.domain.Profile; 5 | import com.podio.sdk.domain.Space; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * When the reference search group name is "space_contacts" or "space_members" you will get this 11 | * object. 12 | * 13 | */ 14 | public class SpaceContactsSpaceMembersReferenceGroup extends ReferenceGroup { 15 | private final Space data = null; 16 | private final List contents = null; 17 | 18 | public Space getData() { 19 | return data; 20 | } 21 | 22 | public List getContents() { 23 | return contents; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/NotificationGroup.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.domain.notification.Notification; 5 | import com.podio.sdk.domain.notification.NotificationContext; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * A Java representation of the NotificationContextDTO and NotificationContentDTO API domain 11 | * object. 12 | * 13 | */ 14 | public class NotificationGroup { 15 | 16 | private final NotificationContext context = null; 17 | private final List notifications = null; 18 | 19 | public List getNotifications() { 20 | return notifications; 21 | } 22 | 23 | public NotificationContext getNotificationContext() { 24 | return context; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Reference.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | public class Reference { 7 | private final String title = null; 8 | private final String type = null; 9 | private final Long id = null; 10 | private final String link = null; 11 | 12 | public ReferenceType getType() { 13 | return ReferenceType.getType(type); 14 | } 15 | 16 | /** 17 | * @return returns the id of the reference or -1 if for some reason there is no id 18 | */ 19 | public long getId() { 20 | return Utils.getNative(id, -1); 21 | } 22 | 23 | public String getTitle() { 24 | return title; 25 | } 26 | 27 | public String getLink() { 28 | return link; 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/FileProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.File; 8 | 9 | /** 10 | * This class provides methods to access Files API area. 11 | * 12 | */ 13 | public class FileProvider extends Provider { 14 | 15 | public static class FileFilter extends Filter { 16 | 17 | protected FileFilter() { 18 | super("file"); 19 | } 20 | 21 | } 22 | 23 | /** 24 | * Uploads a new file 25 | * 26 | * @return A ticket which the caller can use to identify this request with. 27 | */ 28 | public Request uploadFile(java.io.File file) { 29 | FileFilter filter = new FileFilter(); 30 | return post(filter, file, File.class); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /android-sdk.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/QueueClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | import java.util.concurrent.ExecutorService; 5 | import java.util.concurrent.FutureTask; 6 | import java.util.concurrent.LinkedBlockingQueue; 7 | import java.util.concurrent.ThreadPoolExecutor; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public abstract class QueueClient { 11 | 12 | /** 13 | * The queue executor service that manages the request queue. 14 | */ 15 | private ExecutorService executorService; 16 | 17 | protected QueueClient(int corePoolSize, int maxPoolSize, long waitTimeSeconds) { 18 | executorService = new ThreadPoolExecutor(corePoolSize, maxPoolSize, waitTimeSeconds, TimeUnit.SECONDS, new LinkedBlockingQueue(Integer.MAX_VALUE)); 19 | } 20 | 21 | protected void execute(FutureTask request) { 22 | executorService.execute(request); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/EmbedProvider.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import com.podio.sdk.Filter; 4 | import com.podio.sdk.Provider; 5 | import com.podio.sdk.Request; 6 | import com.podio.sdk.domain.Embed; 7 | 8 | /** 9 | * * This class provides methods to access {@link com.podio.sdk.domain.Embed} objects from the API. 10 | * 11 | */ 12 | public class EmbedProvider extends Provider { 13 | 14 | static class Path extends Filter { 15 | 16 | protected Path() { 17 | super("embed"); 18 | } 19 | 20 | } 21 | 22 | /** 23 | * Fetches the currently logged in user data. 24 | * 25 | * @return A ticket which the caller can use to identify this request with. 26 | */ 27 | public Request addEmbed(Embed.Create create) { 28 | Path filter = new Path(); 29 | return post(filter, create, Embed.class); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Right.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | /** 5 | */ 6 | public enum Right { 7 | add_advanced_flow, 8 | add_answer, 9 | add_app, 10 | add_contact, 11 | add_contract, 12 | add_conversation, 13 | add_file, 14 | add_flow, 15 | add_hook, 16 | add_item, 17 | add_question, 18 | add_space, 19 | add_status, 20 | add_task, 21 | add_user, 22 | add_user_light, 23 | add_widget, 24 | auto_join, 25 | comment, 26 | delete, 27 | download, 28 | export, 29 | grant, 30 | install, 31 | manage_public_views, 32 | move, 33 | rate, 34 | reference, 35 | reply, 36 | request_membership, 37 | send_push, 38 | share, 39 | statistics, 40 | subscribe, 41 | update, 42 | view, 43 | view_admins, 44 | view_members, 45 | view_structure, 46 | undefined 47 | } 48 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/domain/UserEmailTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain; 2 | 3 | import android.test.AndroidTestCase; 4 | 5 | import com.google.gson.Gson; 6 | 7 | public class UserEmailTest extends AndroidTestCase { 8 | 9 | public void testUserEmailCanBeCreatedFromJson() { 10 | String json = new StringBuilder("{") 11 | .append("disabled:true,") 12 | .append("primary:true,") 13 | .append("verified:true,") 14 | .append("mail:'MAIL'") 15 | .append("}").toString(); 16 | 17 | Gson gson = new Gson(); 18 | User.Email email = gson.fromJson(json, User.Email.class); 19 | 20 | assertNotNull(email); 21 | assertEquals(true, email.isDisabled()); 22 | assertEquals(true, email.isPrimary()); 23 | assertEquals(true, email.isVerified()); 24 | assertEquals("MAIL", email.getAddress()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /.idea/copyright/Citrix.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/ItemParticipation.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | /** 5 | * A Java representation of the ItemParticipationDTO API domain object. 6 | * 7 | */ 8 | public class ItemParticipation { 9 | 10 | public enum MeetingParticipantStatus { 11 | invited, 12 | accepted, 13 | declined, 14 | tentative 15 | } 16 | 17 | private final String status; 18 | 19 | public ItemParticipation(MeetingParticipantStatus meetingParticipantStatus) { 20 | this.status = meetingParticipantStatus.name(); 21 | } 22 | 23 | public MeetingParticipantStatus getStatus() { 24 | try { 25 | return MeetingParticipantStatus.valueOf(status); 26 | } catch (NullPointerException e) { 27 | return MeetingParticipantStatus.invited; 28 | } catch (IllegalArgumentException e) { 29 | return MeetingParticipantStatus.invited; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Presence.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | public class Presence { 7 | private final Long ref_id = null; 8 | private final Long user_id = null; 9 | private final String ref_type = null; 10 | private final String signature = null; 11 | 12 | public ReferenceType getRefType() { 13 | try { 14 | return ReferenceType.valueOf(ref_type); 15 | } catch (NullPointerException e) { 16 | return ReferenceType.unknown; 17 | } catch (IllegalArgumentException e) { 18 | return ReferenceType.unknown; 19 | } 20 | } 21 | 22 | public long getRefId() { 23 | return Utils.getNative(ref_id, -1L); 24 | } 25 | 26 | public long getUserId() { 27 | return Utils.getNative(user_id, -1L); 28 | } 29 | 30 | public String getSignature() { 31 | return signature; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/OrganizationProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.Organization; 8 | 9 | /** 10 | * Enables access to the organization API end point. 11 | * 12 | */ 13 | public class OrganizationProvider extends Provider { 14 | 15 | static class Path extends Filter { 16 | 17 | Path() { 18 | super("org"); 19 | } 20 | 21 | } 22 | 23 | /** 24 | * Fetches all organizations - including a minimal set of information on the contained 25 | * workspaces - that are available to the user. 26 | * 27 | * @return A ticket which the caller can use to identify this request with. 28 | */ 29 | public Request getAll() { 30 | Path filter = new Path(); 31 | 32 | return get(filter, Organization[].class); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/volley/MockRestClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.volley; 3 | 4 | import android.content.Context; 5 | import android.net.Uri; 6 | 7 | import com.podio.sdk.Filter; 8 | import com.podio.sdk.Request; 9 | import com.podio.sdk.json.JsonParser; 10 | 11 | public class MockRestClient extends VolleyClient { 12 | public String data; 13 | public Uri uri; 14 | 15 | public MockRestClient(Context context) { 16 | super(); 17 | super.setup(context, "https", "test", clientId, clientSecret, null, null); 18 | } 19 | 20 | @Override 21 | public Request request(Request.Method method, Filter filter, Object requestData, Class classOfExpectedResult) { 22 | this.uri = filter.buildUri(scheme, authority); 23 | this.data = requestData != null ? JsonParser.toJson(requestData) : null; 24 | return VolleyRequest.newRequest(userAgent, method, this.uri.toString(), this.data, classOfExpectedResult); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/SpacesProvider.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import com.podio.sdk.Filter; 4 | import com.podio.sdk.Provider; 5 | import com.podio.sdk.Request; 6 | import com.podio.sdk.domain.Space; 7 | 8 | /** 9 | * Enables access to the Status API end point. 10 | */ 11 | public class SpacesProvider extends Provider { 12 | 13 | protected static class Path extends Filter { 14 | 15 | public Path() { 16 | super("space"); 17 | } 18 | 19 | public Path withId(long spaceId) { 20 | addPathSegment(Long.toString(spaceId)); 21 | return this; 22 | } 23 | } 24 | 25 | /** 26 | * Fetches a space domain object based on the given space id 27 | * 28 | * @param spaceId 29 | * ID of the space 30 | * 31 | * @return 32 | */ 33 | public Request getSpace(long spaceId) { 34 | return get(new Path().withId(spaceId), Space.class); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/Filter.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | import android.net.Uri; 5 | 6 | import com.podio.sdk.internal.Utils; 7 | 8 | public class Filter { 9 | private final Uri.Builder uriBuilder; 10 | 11 | protected Filter() { 12 | this(null); 13 | } 14 | 15 | protected Filter(String path) { 16 | uriBuilder = new Uri.Builder(); 17 | 18 | if (Utils.notEmpty(path)) { 19 | uriBuilder.appendEncodedPath(path); 20 | } 21 | } 22 | 23 | protected Filter addQueryParameter(String key, String value) { 24 | uriBuilder.appendQueryParameter(key, value); 25 | return this; 26 | } 27 | 28 | protected Filter addPathSegment(String segment) { 29 | uriBuilder.appendPath(segment); 30 | return this; 31 | } 32 | 33 | public Uri buildUri(String scheme, String authority) { 34 | return uriBuilder 35 | .scheme(scheme) 36 | .authority(authority) 37 | .build(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Voting.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * A Java representation of the VotingDTO API domain object. 8 | * 9 | */ 10 | public class Voting { 11 | 12 | public static enum VotingKind { 13 | answer, 14 | fivestar, 15 | unknown // Custom value to handle errors. 16 | } 17 | private final String kind = null; 18 | 19 | private final String question = null; 20 | 21 | private final Long voting_id = null; 22 | 23 | public long getVotingId() { 24 | return Utils.getNative(voting_id, -1L); 25 | } 26 | 27 | public VotingKind getKind() { 28 | try { 29 | return VotingKind.valueOf(kind); 30 | } catch (NullPointerException e) { 31 | return VotingKind.unknown; 32 | } catch (IllegalArgumentException e) { 33 | return VotingKind.unknown; 34 | } 35 | } 36 | 37 | public String getQuestion() { 38 | return question; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Podio 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/field/UndefinedField.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.field; 3 | 4 | import java.util.List; 5 | 6 | /** 7 | * Fall back Podio field when new fields are introduced and we want to not get a null pointer 8 | * exception in the parsing. 9 | * 10 | */ 11 | public class UndefinedField extends Field { 12 | 13 | public UndefinedField(String externalId) { 14 | super(externalId); 15 | } 16 | 17 | @Override 18 | public void setValues(List values) { 19 | } 20 | 21 | @Override 22 | public void addValue(Value value) { 23 | } 24 | 25 | @Override 26 | public Value getValue(int index) { 27 | return null; 28 | } 29 | 30 | @Override 31 | public List getValues() { 32 | return null; 33 | } 34 | 35 | @Override 36 | public void removeValue(Value value) { 37 | } 38 | 39 | @Override 40 | public void clearValues() { 41 | 42 | } 43 | 44 | @Override 45 | public int valuesCount() { 46 | return 0; 47 | } 48 | 49 | public Configuration getConfiguration() { 50 | return null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/ViewProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.View; 8 | 9 | /** 10 | * Enables access to the view API end point. 11 | * 12 | */ 13 | public class ViewProvider extends Provider { 14 | 15 | static class Path extends Filter { 16 | 17 | Path() { 18 | super("view"); 19 | } 20 | 21 | Path withApplicationId(long applicationId) { 22 | addPathSegment("app"); 23 | addPathSegment(Long.toString(applicationId, 10)); 24 | 25 | return this; 26 | } 27 | 28 | } 29 | 30 | /** 31 | * Fetches views for a given application that can be used to filter items for that application. 32 | * 33 | * @param applicationId 34 | * The id of the parent application. 35 | * 36 | * @return A ticket which the caller can use to identify this request with. 37 | */ 38 | public Request getAllViews(long applicationId) { 39 | Path filter = new Path().withApplicationId(applicationId); 40 | return get(filter, View[].class); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/provider/OrganizationProviderTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import org.mockito.Mock; 4 | import org.mockito.Mockito; 5 | import org.mockito.MockitoAnnotations; 6 | 7 | import android.net.Uri; 8 | import android.test.InstrumentationTestCase; 9 | 10 | import com.podio.sdk.Request; 11 | import com.podio.sdk.domain.Organization; 12 | import com.podio.sdk.volley.MockRestClient; 13 | 14 | public class OrganizationProviderTest extends InstrumentationTestCase { 15 | 16 | @Mock 17 | Request.ResultListener resultListener; 18 | 19 | @Override 20 | protected void setUp() throws Exception { 21 | super.setUp(); 22 | MockitoAnnotations.initMocks(this); 23 | } 24 | 25 | public void testGetAllOrganizations() { 26 | MockRestClient mockClient = new MockRestClient(getInstrumentation().getTargetContext()); 27 | OrganizationProvider provider = new OrganizationProvider(); 28 | provider.setClient(mockClient); 29 | 30 | provider.getAll().withResultListener(resultListener); 31 | 32 | Mockito.verify(resultListener, Mockito.timeout(100).times(0)).onRequestPerformed(null); 33 | assertEquals(Uri.parse("https://test/org"), mockClient.uri); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/provider/ItemFilterTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import android.net.Uri; 4 | import android.test.InstrumentationTestCase; 5 | 6 | public class ItemFilterTest extends InstrumentationTestCase { 7 | 8 | public void testApplicationIdIsIncludedInResultUri() { 9 | Uri reference = Uri.parse("content://test.uri/item/app/12"); 10 | 11 | Uri result = new ItemProvider.Path() 12 | .withApplicationId(12) 13 | .buildUri("content", "test.uri"); 14 | 15 | assertEquals(reference, result); 16 | } 17 | 18 | public void testFilterPropertyIsIncludedInResultUri() { 19 | Uri reference = Uri.parse("content://test.uri/item/app/12/filter"); 20 | 21 | Uri result = new ItemProvider.Path() 22 | .withApplicationIdFilter(12) 23 | .buildUri("content", "test.uri"); 24 | 25 | assertEquals(reference, result); 26 | } 27 | 28 | public void testItemIdIsIncludedInResultUri() { 29 | Uri reference = Uri.parse("content://test.uri/item/12"); 30 | 31 | Uri result = new ItemProvider.Path() 32 | .withItemId(12) 33 | .buildUri("content", "test.uri"); 34 | 35 | assertEquals(reference, result); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Rating.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * A Java representation of the RatingDTO API domain object. 8 | * 9 | */ 10 | public class Rating { 11 | 12 | public static enum RatingType { 13 | like, 14 | approved, 15 | rsvp, 16 | fivestar, 17 | yesno, 18 | thumbs, 19 | unknown // Custom value to handle errors. 20 | } 21 | 22 | public static class Create { 23 | int value; 24 | 25 | public Create(int value){ 26 | this.value = value; 27 | } 28 | } 29 | 30 | private final Long rating_id = null; 31 | 32 | private final String type = null; 33 | 34 | private final Integer value = null; 35 | 36 | public long getRatingId() { 37 | return Utils.getNative(rating_id, -1L); 38 | } 39 | 40 | public RatingType getType() { 41 | try { 42 | return RatingType.valueOf(type); 43 | } catch (NullPointerException e) { 44 | return RatingType.unknown; 45 | } catch (IllegalArgumentException e) { 46 | return RatingType.unknown; 47 | } 48 | } 49 | 50 | public Integer getValue() { 51 | return value; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/Provider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | public abstract class Provider { 5 | 6 | protected Client client; 7 | 8 | public void setClient(Client client) { 9 | this.client = client; 10 | } 11 | 12 | protected void validateClient() { 13 | if (this.client == null) { 14 | throw new NullPointerException("Your provider subclass MUST set a Client instance prior to a REST operation!"); 15 | } 16 | } 17 | 18 | protected Request delete(Filter filter) { 19 | validateClient(); 20 | return client.request(Request.Method.DELETE, filter, null, null); 21 | } 22 | 23 | protected Request get(Filter filter, Class classOfResult) { 24 | validateClient(); 25 | return client.request(Request.Method.GET, filter, null, classOfResult); 26 | } 27 | 28 | protected Request post(Filter filter, Object item, Class classOfItem) { 29 | validateClient(); 30 | return client.request(Request.Method.POST, filter, item, classOfItem); 31 | } 32 | 33 | protected Request put(Filter filter, Object item, Class classOfItem) { 34 | validateClient(); 35 | return client.request(Request.Method.PUT, filter, item, classOfItem); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Batch.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * A Java representation of the BatchDTO API domain object. 8 | * 9 | */ 10 | public class Batch { 11 | 12 | public static enum PluginTypes { 13 | app_import, 14 | app_export, 15 | connection_load, 16 | unknown // Custom value to handle errors. 17 | } 18 | 19 | private final String plugin = null; 20 | 21 | private final Integer completed = null; 22 | 23 | private final Integer skipped = null; 24 | 25 | private final Long batch_id = null; 26 | 27 | public long getBatchId() { 28 | return Utils.getNative(batch_id, -1L); 29 | } 30 | 31 | public PluginTypes getPluginType() { 32 | try { 33 | return PluginTypes.valueOf(plugin); 34 | } catch (NullPointerException e) { 35 | return PluginTypes.unknown; 36 | } catch (IllegalArgumentException e) { 37 | return PluginTypes.unknown; 38 | } 39 | } 40 | 41 | public int getSkipped() { 42 | return Utils.getNative(skipped, 0); 43 | } 44 | 45 | public int getCompleted() { 46 | return Utils.getNative(completed, 0); 47 | } 48 | 49 | // TODO Add missing attributes 50 | } 51 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/localstore/FreeRequest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.localstore; 3 | 4 | import android.util.LruCache; 5 | 6 | import java.util.concurrent.Callable; 7 | 8 | /** 9 | * A specific {@link com.podio.sdk.localstore.LocalStoreRequest LocalStoreRequest} implementation, 10 | * targeting the "close store" operation. This implementation simply clears the memory cache while 11 | * leaving the persistent disk store untouched. 12 | * 13 | */ 14 | final class FreeRequest extends LocalStoreRequest { 15 | 16 | /** 17 | * Creates a new Request for closing the local store, clearing the memory store. The disk store 18 | * is left intact. The request will not deliver anything. 19 | * 20 | * @param memoryStore 21 | * The reference to the memory cache object. 22 | */ 23 | FreeRequest(final LruCache memoryStore) { 24 | super(new Callable() { 25 | @Override 26 | public Void call() throws Exception { 27 | if (memoryStore == null) { 28 | throw new IllegalStateException("You're trying to free up a closed store."); 29 | } 30 | 31 | memoryStore.evictAll(); 32 | return null; 33 | } 34 | }); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/LocationProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.Address; 8 | 9 | /** 10 | * Enables access to the location API end point. 11 | * 12 | */ 13 | public class LocationProvider extends Provider { 14 | 15 | static class LocationFilter extends Filter { 16 | 17 | protected LocationFilter() { 18 | super("location"); 19 | } 20 | 21 | public LocationFilter withAddress(String address) { 22 | this.addPathSegment("lookup"); 23 | this.addQueryParameter("address", address); 24 | 25 | return this; 26 | } 27 | } 28 | 29 | /** 30 | * Lookup the address to get location information of the query longitude, latitude, city, post code, 31 | * etc. 32 | * 33 | * @param address 34 | * The address search query to lookup. 35 | * 36 | * @return A ticket which the caller can use to identify this request with. 37 | */ 38 | public Request lookupAddress(String address) { 39 | LocationFilter filter = new LocationFilter(); 40 | filter.withAddress(address); 41 | 42 | return get(filter, Address[].class); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/TaskAction.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | * A Java representation of the TaskActionDTO API domain object. 8 | * 9 | */ 10 | public abstract class TaskAction { 11 | 12 | public static enum TaskActionType { 13 | creation, 14 | start, 15 | stop, 16 | assign, 17 | complete, 18 | incomplete, 19 | update_text, 20 | update_description, 21 | update_due_date, 22 | update_private, 23 | delete, 24 | update_ref, 25 | unknown; // Custom value to handle errors. 26 | 27 | public static TaskActionType getType(String type) { 28 | try { 29 | return TaskActionType.valueOf(type); 30 | } catch (NullPointerException e) { 31 | return TaskActionType.unknown; 32 | } catch (IllegalArgumentException e) { 33 | return TaskActionType.unknown; 34 | } 35 | } 36 | } 37 | 38 | private final Long task_action_id = null; 39 | 40 | private final String type = null; 41 | 42 | public long getTaskActionId() { 43 | return Utils.getNative(task_action_id, -1L); 44 | } 45 | 46 | public TaskActionType getType() { 47 | return TaskActionType.getType(type); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/PodioError.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | import com.android.volley.VolleyError; 5 | 6 | /** 7 | * This class represents a generic client side error with an undefined or unknown cause. 8 | * 9 | */ 10 | public class PodioError extends RuntimeException { 11 | 12 | private int responseCode; 13 | 14 | public PodioError(String message, Throwable cause) { 15 | super(message, cause); 16 | responseCode = 0; 17 | } 18 | 19 | public PodioError(String message) { 20 | super(message); 21 | responseCode = 0; 22 | } 23 | 24 | public PodioError(Throwable cause) { 25 | super(cause); 26 | responseCode = 0; 27 | } 28 | 29 | public PodioError(VolleyError volleyError, int responseCode) { 30 | super(volleyError); 31 | this.responseCode = responseCode; 32 | } 33 | 34 | /** 35 | * In the scenario that our API does not return a json error we will fallback to using 36 | * PodioError rather than ApiError and in such scenario this method will return the response 37 | * code but PodioError is used in more scenarios than actual API responses and in such scenarios 38 | * the response code returned will be 0 and thus not valid. 39 | * 40 | * @return 41 | */ 42 | public int getResponseCode() { 43 | return responseCode; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/domain/field/FieldTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.field; 2 | 3 | import android.test.AndroidTestCase; 4 | 5 | import com.google.gson.Gson; 6 | 7 | public class FieldTest extends AndroidTestCase { 8 | 9 | public void testStatusEnumCanBeParsedFromJson() { 10 | Gson gson = new Gson(); 11 | TextField field; 12 | 13 | field = gson.fromJson("{status:'active'}", TextField.class); 14 | assertEquals(Field.Status.active, field.getStatus()); 15 | 16 | field = gson.fromJson("{}", TextField.class); 17 | assertEquals(Field.Status.undefined, field.getStatus()); 18 | 19 | field = gson.fromJson("{status:'fdafadsfads'}", TextField.class); 20 | assertEquals(Field.Status.undefined, field.getStatus()); 21 | } 22 | 23 | public void testValueOfStatus() { 24 | assertEquals(Field.Status.active, Field.Status.valueOf("active")); 25 | assertEquals(Field.Status.deleted, Field.Status.valueOf("deleted")); 26 | assertEquals(Field.Status.undefined, Field.Status.valueOf("undefined")); 27 | 28 | assertEquals(Field.Status.active, Enum.valueOf(Field.Status.class, "active")); 29 | assertEquals(Field.Status.deleted, Enum.valueOf(Field.Status.class, "deleted")); 30 | assertEquals(Field.Status.undefined, Enum.valueOf(Field.Status.class, "undefined")); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/domain/ItemPushTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain; 2 | 3 | import android.test.AndroidTestCase; 4 | 5 | import com.google.gson.Gson; 6 | import com.podio.sdk.domain.field.TextField; 7 | 8 | public class ItemPushTest extends AndroidTestCase { 9 | 10 | 11 | public void testItemPushDataIsProducedFromItem() { 12 | Gson gson = new Gson(); 13 | Item item = new Item(); 14 | item.addValue("FIELD-1", new TextField.Value("VALUE")); 15 | String pushJson = gson.toJson(item.getCreateData(false)); 16 | String reference = "{\"fields\":{\"FIELD-1\":[{\"value\":\"VALUE\"}]}"; 17 | assertTrue(pushJson.contains(reference)); 18 | } 19 | 20 | public void testItemPushResultCanBeInitializedFromJson() { 21 | String json = "{item_id:1, revision:1, title:'TITLE'}"; 22 | Gson gson = new Gson(); 23 | Item.CreateResult pushResult = gson.fromJson(json, Item.CreateResult.class); 24 | 25 | assertEquals(1L, pushResult.getItemId()); 26 | assertEquals(1L, pushResult.getRevisionId()); 27 | assertEquals("TITLE", pushResult.getTitle()); 28 | } 29 | 30 | 31 | public void testItemPushResultDefaults() { 32 | Item.CreateResult pushResult = new Item.CreateResult(); 33 | 34 | assertEquals(-1L, pushResult.getItemId()); 35 | assertEquals(-1L, pushResult.getRevisionId()); 36 | assertEquals(null, pushResult.getTitle()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/GrantProvider.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import com.podio.sdk.Filter; 4 | import com.podio.sdk.Provider; 5 | import com.podio.sdk.Request; 6 | import com.podio.sdk.domain.ReferenceType; 7 | 8 | /** 9 | * Enables access to the Grants API end point. 10 | * 11 | */ 12 | public class GrantProvider extends Provider { 13 | 14 | static class Path extends Filter { 15 | 16 | protected Path() { 17 | super("grant"); 18 | } 19 | 20 | public Path withReference(ReferenceType type, long id) { 21 | this.addPathSegment(type.name()); 22 | this.addPathSegment(Long.toString(id, 10)); 23 | 24 | return this; 25 | } 26 | 27 | public Path withUserId(long id) { 28 | addPathSegment(Long.toString(id, 10)); 29 | return this; 30 | } 31 | 32 | } 33 | 34 | /** 35 | * Removes the grant from the given user on the given object 36 | * 37 | * @param type 38 | * reference type of the object 39 | * @param referenceId 40 | * id of the object 41 | * @param userId 42 | * id of the user 43 | * 44 | * @return A ticket which the caller can use to identify this request with. 45 | */ 46 | public Request removeGrant(ReferenceType type, long referenceId, long userId) { 47 | Path path = new Path().withReference(type, referenceId).withUserId(userId); 48 | return delete(path); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/UserStatus.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | public class UserStatus { 7 | private final User user = null; 8 | private final Profile profile = null; 9 | private final Integer inbox_new = null; 10 | private final Integer message_unread_count = null; 11 | private final String calendar_code = null; 12 | private final String mailbox = null; 13 | private final Push push = null; 14 | private final Presence presence = null; 15 | 16 | // TODO: Add support for these? 17 | // private final Properties properties = null; 18 | // private final Referral referral = null; 19 | // private final Betas betas = null; 20 | // private final List flags = null; 21 | 22 | public User getUser() { 23 | return user; 24 | } 25 | 26 | public Profile getProfile() { 27 | return profile; 28 | } 29 | 30 | public int getUnreadNotificationsCount() { 31 | return Utils.getNative(inbox_new, -1); 32 | } 33 | 34 | public int getUnreadMessagesCount() { 35 | return Utils.getNative(message_unread_count, -1); 36 | } 37 | 38 | public String getCalendarCode() { 39 | return calendar_code; 40 | } 41 | 42 | public String getMailboxPrefix() { 43 | return mailbox; 44 | } 45 | 46 | public Push getPush() { 47 | return push; 48 | } 49 | 50 | public Presence getPresence() { 51 | return presence; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/ReminderProvider.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import com.podio.sdk.Filter; 4 | import com.podio.sdk.Provider; 5 | import com.podio.sdk.Request; 6 | import com.podio.sdk.domain.Reminder; 7 | 8 | /** 9 | * Created by sai on 9/30/16. 10 | */ 11 | 12 | public class ReminderProvider extends Provider { 13 | 14 | public static class ReminderFilter extends Filter { 15 | private static String itemRefType = "item"; 16 | private static String refType = "ref_type"; 17 | private static String refId = "ref_id"; 18 | 19 | public ReminderFilter() { 20 | super("reminder/"); 21 | } 22 | 23 | public ReminderFilter item(long itemId) { 24 | this.addPathSegment(itemRefType); 25 | this.addPathSegment(String.valueOf(itemId)); 26 | 27 | this.addQueryParameter(refType, itemRefType); 28 | this.addQueryParameter(refId, String.valueOf(itemId)); 29 | 30 | return this; 31 | } 32 | 33 | } 34 | 35 | public Request getReminder(long itemId) { 36 | return get(new ReminderFilter().item(itemId), Reminder.class); 37 | } 38 | 39 | public Request deleteReminder(long itemId) { 40 | return delete(new ReminderFilter().item(itemId)); 41 | } 42 | 43 | public Request createOrUpdateReminder(long itemId, Reminder.CreateData createData) { 44 | return put(new ReminderFilter().item(itemId), createData, Reminder.class); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/RecurrenceProvider.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import com.podio.sdk.Filter; 4 | import com.podio.sdk.Provider; 5 | import com.podio.sdk.Request; 6 | import com.podio.sdk.domain.Recurrence; 7 | 8 | /** 9 | * Created by sai on 9/30/16. 10 | */ 11 | 12 | public class RecurrenceProvider extends Provider { 13 | 14 | public static class RecurrenceFilter extends Filter { 15 | private static String itemRefType = "item"; 16 | private static String refType = "ref_type"; 17 | private static String refId = "ref_id"; 18 | 19 | public RecurrenceFilter() { 20 | super("recurrence/"); 21 | } 22 | 23 | public RecurrenceFilter item(long itemId) { 24 | this.addPathSegment(itemRefType); 25 | this.addPathSegment(String.valueOf(itemId)); 26 | 27 | this.addQueryParameter(refType, itemRefType); 28 | this.addQueryParameter(refId, String.valueOf(itemId)); 29 | 30 | return this; 31 | } 32 | } 33 | 34 | public Request getRecurrence(long itemId) { 35 | return get(new RecurrenceFilter().item(itemId), Recurrence.class); 36 | } 37 | 38 | public Request deleteRecurrence(long itemId) { 39 | return delete(new RecurrenceFilter().item(itemId)); 40 | } 41 | 42 | public Request updateRecurrence(long itemId, Recurrence.CreateData createData) { 43 | return put(new RecurrenceFilter().item(itemId), createData, Recurrence.class); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Address.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | public class Address { 7 | 8 | private final String formatted = null; 9 | private final String street_number = null; 10 | private final String street_name = null; 11 | private final String postal_code = null; 12 | private final String city = null; 13 | private final String state = null; 14 | private final String country = null; 15 | private final Double lat = null; 16 | private final Double lng = null; 17 | 18 | public String getCity() { 19 | return city; 20 | } 21 | 22 | public String getCountry() { 23 | return country; 24 | } 25 | 26 | public String getFormatted() { 27 | return formatted; 28 | } 29 | 30 | public String getStreetNumber() { 31 | return street_number; 32 | } 33 | 34 | public String getStreetName() { 35 | return street_name; 36 | } 37 | 38 | public String getPostalCode() { 39 | return postal_code; 40 | } 41 | 42 | public String getState() { 43 | return state; 44 | } 45 | 46 | /** 47 | * 48 | * @return The latitude or Double.MIN_VALUE if the value is not set. 49 | */ 50 | public double getLat() { 51 | return Utils.getNative(lat, Double.MIN_VALUE); 52 | } 53 | 54 | /** 55 | * 56 | * @return The longitude or Double.MIN_VALUE if the value is not set. 57 | */ 58 | public double getLng() { 59 | return Utils.getNative(lng, Double.MIN_VALUE); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/provider/CalendarProviderTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import java.text.ParseException; 4 | import java.util.Date; 5 | 6 | import org.mockito.Mock; 7 | import org.mockito.Mockito; 8 | import org.mockito.MockitoAnnotations; 9 | 10 | import android.net.Uri; 11 | import android.test.InstrumentationTestCase; 12 | 13 | import com.podio.sdk.Request; 14 | import com.podio.sdk.domain.CalendarEvent; 15 | import com.podio.sdk.internal.Utils; 16 | import com.podio.sdk.volley.MockRestClient; 17 | 18 | public class CalendarProviderTest extends InstrumentationTestCase { 19 | 20 | @Mock 21 | Request.ResultListener resultListener; 22 | 23 | @Override 24 | protected void setUp() throws Exception { 25 | super.setUp(); 26 | MockitoAnnotations.initMocks(this); 27 | } 28 | 29 | 30 | public void testGetGlobalCalendar() throws ParseException { 31 | MockRestClient mockClient = new MockRestClient(getInstrumentation().getTargetContext()); 32 | CalendarProvider provider = new CalendarProvider(); 33 | provider.setClient(mockClient); 34 | 35 | Date fromDate = Utils.parseDateDefault("1970-01-01"); 36 | Date toDate = Utils.parseDateDefault("1970-01-02"); 37 | 38 | provider.getGlobalCalendar(fromDate, toDate, 1, false).withResultListener(resultListener); 39 | 40 | Mockito.verify(resultListener, Mockito.timeout(100).times(0)).onRequestPerformed(null); 41 | 42 | assertEquals(Uri.parse("https://test/calendar?date_from=1970-01-01&date_to=1970-01-02&priority=1&tasks=false"), mockClient.uri); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/StatusProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.Status; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Enables access to the Status API end point. 13 | * 14 | */ 15 | public class StatusProvider extends Provider { 16 | 17 | static class Path extends Filter { 18 | 19 | protected Path() { 20 | super("status"); 21 | } 22 | 23 | Path withSpace() { 24 | addPathSegment("space"); 25 | return this; 26 | } 27 | 28 | Path withId(long id) { 29 | addPathSegment(Long.toString(id)); 30 | return this; 31 | } 32 | 33 | Path withAlertInvite(boolean alertInvite) { 34 | addQueryParameter("alert_invite", alertInvite ? "true" : "false"); 35 | return this; 36 | } 37 | 38 | } 39 | 40 | /** 41 | * @param spaceId 42 | * @param alertInvite 43 | * true if any mentioned user should be automatically invited to the workspace if the 44 | * user does not have access to the object and access cannot be granted to the object. 45 | * @param value 46 | * @param fileIds 47 | * 48 | * @return 49 | */ 50 | public Request addStatusMessage(long spaceId, boolean alertInvite, String value, List fileIds) { 51 | Path path = new Path().withSpace().withId(spaceId).withAlertInvite(alertInvite); 52 | return post(path, new Status.PushData(value, fileIds), Status.class); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/ReferenceProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.DataReference; 8 | import com.podio.sdk.domain.reference.ReferenceGroup; 9 | 10 | /** 11 | * Enables access to the Reference API end point. 12 | * 13 | */ 14 | public class ReferenceProvider extends Provider { 15 | 16 | static class Path extends Filter { 17 | 18 | protected Path() { 19 | super("reference"); 20 | } 21 | 22 | Path withSearch() { 23 | addPathSegment("search"); 24 | return this; 25 | } 26 | 27 | Path withResolve() { 28 | addPathSegment("resolve"); 29 | return this; 30 | } 31 | 32 | Path withUrl(String url) { 33 | addQueryParameter("url", url); 34 | return this; 35 | } 36 | } 37 | 38 | /** 39 | * Performs a reference search based on the @referenceTarget. 40 | * 41 | * @param referenceTarget 42 | * The reference search target. 43 | * 44 | * @return A ticket which the caller can use to identify this request with. 45 | */ 46 | public Request referenceSearch(ReferenceGroup.ReferenceTarget referenceTarget) { 47 | Path filter = new Path().withSearch(); 48 | return post(filter, referenceTarget, ReferenceGroup[].class); 49 | } 50 | 51 | public Request resolveURL(String url) { 52 | Path filter = new Path().withResolve().withUrl(url); 53 | return get(filter, DataReference.class); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/ReferenceType.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | public enum ReferenceType { 5 | action, 6 | alert, 7 | answer, 8 | app, 9 | app_field, 10 | app_revision, 11 | auth_client, 12 | batch, 13 | bulletin, 14 | comment, 15 | condition, 16 | condition_set, 17 | connection, 18 | contract, 19 | conversation, 20 | embed, 21 | extension, 22 | extension_installation, 23 | file, 24 | file_service, 25 | flow, 26 | flow_condition, 27 | flow_effect, 28 | form, 29 | grant, 30 | hook, 31 | icon, 32 | identity, 33 | integration, 34 | invoice, 35 | item, 36 | item_participation, 37 | item_revision, 38 | item_transaction, 39 | label, 40 | linked_account, 41 | live, 42 | location, 43 | message, 44 | notification, 45 | org, 46 | org_member, 47 | partner, 48 | payment, 49 | profile, 50 | promotion, 51 | question, 52 | question_answer, 53 | rating, 54 | share, 55 | share_install, 56 | space, 57 | space_member, 58 | space_member_request, 59 | status, 60 | subscription, 61 | system, 62 | tag, 63 | task, 64 | task_action, 65 | user, 66 | view, 67 | vote, 68 | voting, 69 | widget, 70 | unknown; // Custom value to handle errors. 71 | 72 | public static ReferenceType getType(String type) { 73 | try { 74 | return ReferenceType.valueOf(type); 75 | } catch (NullPointerException e) { 76 | return ReferenceType.unknown; 77 | } catch (IllegalArgumentException e) { 78 | return ReferenceType.unknown; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/LinkedAccountProvider.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import com.podio.sdk.Filter; 4 | import com.podio.sdk.Provider; 5 | import com.podio.sdk.Request; 6 | import com.podio.sdk.domain.LinkedAccount; 7 | 8 | /** 9 | * Created by sai on 9/26/16. 10 | */ 11 | 12 | public class LinkedAccountProvider extends Provider { 13 | public static class GetLinkedAccountFilter extends Filter { 14 | 15 | private static final String CAPABILITY = "capability"; 16 | private static final String PROVIDER ="provider"; 17 | 18 | public GetLinkedAccountFilter() { 19 | super("linked_account/"); 20 | } 21 | 22 | public GetLinkedAccountFilter capability(LinkedAccount.Capability capability) { 23 | this.addQueryParameter(CAPABILITY, capability.name()); 24 | return this; 25 | } 26 | 27 | public GetLinkedAccountFilter provider(LinkedAccount.Provider provider) { 28 | this.addQueryParameter(PROVIDER, provider.name()); 29 | return this; 30 | } 31 | } 32 | public Request getLinkedAccounts(LinkedAccount.Capability capability) { 33 | return get(new GetLinkedAccountFilter().capability(capability), LinkedAccount[].class); 34 | } 35 | 36 | public Request getLinkedAccounts(LinkedAccount.Provider provider) { 37 | return get(new GetLinkedAccountFilter().provider(provider), LinkedAccount[].class); 38 | } 39 | 40 | public Request getLinkedAccounts(LinkedAccount.Capability capability, LinkedAccount.Provider provider) { 41 | return get(new GetLinkedAccountFilter().capability(capability).provider(provider), LinkedAccount[].class); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/DataReference.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.domain.data.Data; 5 | import com.podio.sdk.internal.Utils; 6 | import com.podio.sdk.json.DataReferenceDeserializer; 7 | 8 | /** 9 | * Same as {@link Reference} but with the added data attribute. Ideally we shouldn't have this 10 | * duplicate class definition but since the URL resolver API call needs the data object for certain 11 | * cases and we risk breaking the app for new unsupported types of references we have this separate 12 | * class for our custom deserializer {@link DataReferenceDeserializer} to handle. 13 | * 14 | * This is of course not the ideal solution 15 | * 16 | */ 17 | public class DataReference { 18 | private final String title; 19 | private final Data data; 20 | private final String type; 21 | private final Long id; 22 | 23 | public DataReference(String title, Data data, String type, long id) { 24 | this.title = title; 25 | this.data = data; 26 | this.type = type; 27 | this.id = id; 28 | } 29 | 30 | public ReferenceType getType() { 31 | return ReferenceType.getType(type); 32 | } 33 | 34 | /** 35 | * @return returns the id of the reference or -1 if for some reason there is no id 36 | */ 37 | public long getId() { 38 | return Utils.getNative(id, -1); 39 | } 40 | 41 | public String getTitle() { 42 | return title; 43 | } 44 | 45 | /** 46 | * @return Returns the data object for this reference if the reference type is supported (see 47 | * {@link DataReferenceDeserializer}, otherwise {@link com.podio.sdk.domain.data.UnknownData} 48 | */ 49 | public Data getData() { 50 | return data; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/Store.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | /** 5 | * Definition of capabilities for a Store object. 6 | * 7 | */ 8 | public interface Store { 9 | 10 | /** 11 | * Enables means of freeing up memory without affecting the long term store. 12 | * 13 | * @return The future task which enables hooking in callback listeners. 14 | */ 15 | public Request free(); 16 | 17 | /** 18 | * Enables means of completely erasing the store from the system. 19 | * 20 | * @return The future task which enables hooking in callback listeners. 21 | */ 22 | public Request erase(); 23 | 24 | /** 25 | * Enables means of retrieving an object with the given key from the store. 26 | * 27 | * @param key 28 | * The key of the object to retrieve. 29 | * @param classOfValue 30 | * The Class definition of any disk persisted JSON. 31 | * @return The future task which enables hooking in callback listeners. 32 | */ 33 | public Request get(Object key, Class classOfValue); 34 | 35 | /** 36 | * Enables means of adding or replacing an item with the given key in the 37 | * store. 38 | * 39 | * @param key 40 | * The key associated with the object. 41 | * @param value 42 | * The object to cache. 43 | * @return The future task which enables hooking in callback listeners. 44 | */ 45 | public Request set(Object key, Object value); 46 | 47 | /** 48 | * Enables means of removing an object with the given key from the store. 49 | * 50 | * @param key 51 | * The key of the object to remove. 52 | * @return The future task which enables hooking in callback listeners. 53 | */ 54 | public Request remove(Object key); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/LinkedAccount.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Created by sai on 9/26/16. 7 | */ 8 | 9 | public class LinkedAccount { 10 | 11 | public enum Status { 12 | active, 13 | revoked 14 | } 15 | 16 | public enum Provider { 17 | google, 18 | legacy_google, 19 | google_apps, 20 | citrix, 21 | sharefile, 22 | appear_in 23 | } 24 | 25 | public enum Capability { 26 | contacts, 27 | files, 28 | meetings, 29 | calendar, 30 | profile, 31 | message, 32 | social, 33 | addressbook 34 | } 35 | 36 | public enum Option { 37 | action_install, 38 | action_share 39 | } 40 | 41 | private final Long linked_account_id = null; 42 | 43 | private final Status status = null; 44 | 45 | private final String label = null; 46 | 47 | private final Provider provider = null; 48 | 49 | private final String provider_humanized_name = null; 50 | 51 | private final Map capability_names = null; 52 | 53 | private final Map options = null; 54 | 55 | public Long getLinkedAccountId() { 56 | return linked_account_id; 57 | } 58 | 59 | public Status getStatus() { 60 | return status; 61 | } 62 | 63 | public String getLabel() { 64 | return label; 65 | } 66 | 67 | public Provider getProvider() { 68 | return provider; 69 | } 70 | 71 | public String getProviderHumanizedName() { 72 | return provider_humanized_name; 73 | } 74 | 75 | public Map getCapabilityNames() { 76 | return capability_names; 77 | } 78 | 79 | public Map getOptions() { 80 | return options; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/provider/ApplicationFilterTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.provider; 2 | 3 | import android.net.Uri; 4 | import android.test.AndroidTestCase; 5 | 6 | public class ApplicationFilterTest extends AndroidTestCase { 7 | 8 | public void testAllPropertiesIncludedInResultUri() { 9 | Uri reference = Uri.parse("content://test.uri/app/space/2" // 10 | + "?include_inactive=true"); 11 | 12 | Uri result = new ApplicationProvider.Path() // 13 | .withSpaceId(2L) // 14 | .withInactivesIncluded(true) // 15 | .buildUri("content", "test.uri"); 16 | 17 | assertEquals(reference, result); 18 | } 19 | 20 | 21 | public void testApplicationIdAddedAsPathSegment() { 22 | Uri reference = Uri.parse("content://test.uri/app/1"); 23 | Uri result = new ApplicationProvider.Path().withApplicationId(1L).buildUri("content", "test.uri"); 24 | 25 | assertEquals(reference, result); 26 | } 27 | 28 | 29 | public void testIncludeInactiveFlagAddedAsQueryParameter() { 30 | Uri reference = Uri.parse("content://test.uri/app?include_inactive=false"); 31 | Uri result = new ApplicationProvider.Path().withInactivesIncluded(false).buildUri("content", 32 | "test.uri"); 33 | 34 | assertEquals(reference, result); 35 | } 36 | 37 | 38 | public void testSpaceIdAddedAsPathSegment() { 39 | Uri reference = Uri.parse("content://test.uri/app/space/1"); 40 | Uri result = new ApplicationProvider.Path().withSpaceId(1L).buildUri("content", "test.uri"); 41 | 42 | assertEquals(reference, result); 43 | } 44 | 45 | 46 | public void testTypeFlagAddedAsQueryParameter() { 47 | Uri reference = Uri.parse("content://test.uri/app?type=test"); 48 | Uri result = new ApplicationProvider.Path().withType("test").buildUri("content", "test.uri"); 49 | 50 | assertEquals(reference, result); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/UserProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.Profile; 8 | import com.podio.sdk.domain.User; 9 | import com.podio.sdk.domain.UserStatus; 10 | 11 | /** 12 | * Enables access to the User API end point. 13 | * 14 | */ 15 | public class UserProvider extends Provider { 16 | 17 | static class Path extends Filter { 18 | 19 | protected Path() { 20 | super("user"); 21 | } 22 | 23 | Path withProfile() { 24 | addPathSegment("profile"); 25 | return this; 26 | } 27 | 28 | Path withStatus() { 29 | addPathSegment("status"); 30 | return this; 31 | } 32 | 33 | Path withProperty(String property) { 34 | addQueryParameter("name", property); 35 | return this; 36 | } 37 | 38 | } 39 | 40 | /** 41 | * Fetches the currently logged in user data. 42 | * 43 | * @return A ticket which the caller can use to identify this request with. 44 | */ 45 | public Request getUser() { 46 | Path filter = new Path(); 47 | return get(filter, User.class); 48 | } 49 | 50 | /** 51 | * Fetches the currently logged in user profile. 52 | * 53 | * @return A ticket which the caller can use to identify this request with. 54 | */ 55 | public Request getProfile() { 56 | Path filter = new Path().withProfile(); 57 | return get(filter, Profile.class); 58 | } 59 | 60 | /** 61 | * Fetches the currently logged in user status. 62 | * 63 | * @return A ticket which the caller can use to identify this request with. 64 | */ 65 | public Request getUserStatus() { 66 | Path filter = new Path().withStatus(); 67 | return get(filter, UserStatus.class); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/provider/ClientProviderTest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import org.mockito.Mock; 5 | import org.mockito.Mockito; 6 | import org.mockito.MockitoAnnotations; 7 | 8 | import android.net.Uri; 9 | import android.test.InstrumentationTestCase; 10 | import android.test.suitebuilder.annotation.Suppress; 11 | 12 | import com.podio.sdk.Request; 13 | import com.podio.sdk.volley.MockRestClient; 14 | 15 | public class ClientProviderTest extends InstrumentationTestCase { 16 | 17 | @Mock 18 | Request.ResultListener resultListener; 19 | 20 | @Override 21 | protected void setUp() throws Exception { 22 | super.setUp(); 23 | MockitoAnnotations.initMocks(this); 24 | } 25 | 26 | @Suppress 27 | public void testAuthenticateWithUserCredentials() { 28 | MockRestClient mockClient = new MockRestClient(getInstrumentation().getTargetContext()); 29 | ClientProvider provider = new ClientProvider(); 30 | provider.setClient(mockClient); 31 | 32 | provider.authenticateWithUserCredentials("USERNAME", "PASSWORD").withResultListener(resultListener); 33 | 34 | Mockito.verify(resultListener, Mockito.timeout(1000).times(0)).onRequestPerformed(null); 35 | 36 | assertEquals(Uri.parse("/oauth/token?grant_type=password&username=USERNAME&password=PASSWORD"), mockClient.uri); 37 | } 38 | 39 | 40 | @Suppress 41 | public void testAuthenticateWithAppCredentials() { 42 | MockRestClient mockClient = new MockRestClient(getInstrumentation().getTargetContext()); 43 | ClientProvider provider = new ClientProvider(); 44 | provider.setClient(mockClient); 45 | 46 | provider.authenticateWithAppCredentials("APPID", "APPTOKEN").withResultListener(resultListener); 47 | 48 | Mockito.verify(resultListener, Mockito.timeout(100).times(0)).onRequestPerformed(null); 49 | assertEquals(Uri.parse("/oauth/token?grant_type=app&app_id=APPID&app_token=APPTOKEN"), mockClient.uri); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/stream/EventActivity.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.stream; 3 | 4 | import com.podio.sdk.domain.Byline; 5 | import com.podio.sdk.domain.ReferenceType; 6 | import com.podio.sdk.internal.Utils; 7 | 8 | import java.util.Date; 9 | 10 | /** 11 | * This class is the base class for all activities. 12 | *

13 | * In most cases all information we are interested in is provided by this class so even if you are 14 | * getting activities of type {@link UnknownEventActivity} there is still plenty of information 15 | * available in that one. 16 | * 17 | */ 18 | public abstract class EventActivity { 19 | 20 | public static enum EventType { 21 | comment, 22 | file, 23 | rating, 24 | creation, 25 | update, 26 | task, 27 | answer, 28 | rsvp, 29 | grant, 30 | reference, 31 | like, 32 | vote, 33 | participation, 34 | file_delete, 35 | unknown; // Custom value to handle errors. 36 | 37 | public static EventType getActivityType(String activity_type) { 38 | try { 39 | return EventType.valueOf(activity_type); 40 | } catch (NullPointerException e) { 41 | return EventType.unknown; 42 | } catch (IllegalArgumentException e) { 43 | return EventType.unknown; 44 | } 45 | } 46 | } 47 | 48 | private final String type = null; 49 | private final String activity_type = null; 50 | private final Byline created_by = null; 51 | private final String created_on = null; 52 | 53 | public Date getCreatedOnDate() { 54 | return Utils.parseDateTimeUtc(created_on); 55 | } 56 | 57 | public String getCreatedOnString() { 58 | return created_on; 59 | } 60 | 61 | public Byline getCreatedBy() { 62 | return created_by; 63 | } 64 | 65 | public ReferenceType getType() { 66 | return ReferenceType.getType(type); 67 | } 68 | 69 | public EventType getActivityType() { 70 | return EventType.getActivityType(activity_type); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Recurrence.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | /** 8 | * Created by sai on 9/29/16. 9 | */ 10 | 11 | public class Recurrence { 12 | 13 | public static class CreateData { 14 | public static final String DAY_OF_WEEK = "day_of_week"; 15 | public static final String DAY_OF_MONTH = "day_of_month"; 16 | 17 | private static final String DAYS = "days"; 18 | private static final String REPEAT_ON = "repeat_on"; 19 | 20 | private final String name; 21 | private int step; 22 | private Map config; 23 | private String until = null; 24 | 25 | public CreateData(String name) { 26 | this.name = name; 27 | config = new HashMap<>(); 28 | } 29 | 30 | public void setStep(int step) { 31 | this.step = step; 32 | } 33 | 34 | public void setUntil(String until) { 35 | this.until = until; 36 | } 37 | 38 | public void setDays(List days) { 39 | config.put(DAYS, days); 40 | } 41 | 42 | public void setRepeatOn(String repeatOn) { 43 | config.put(REPEAT_ON, repeatOn); 44 | } 45 | } 46 | 47 | private final String name = null; 48 | 49 | private final Integer step = null; 50 | 51 | private final String until = null; 52 | 53 | private final Config config = null; 54 | 55 | public String getName() { 56 | return name; 57 | } 58 | 59 | public Integer getStep() { 60 | return step; 61 | } 62 | 63 | public String getUntil() { 64 | return until; 65 | } 66 | 67 | public Config getConfig() { 68 | return config; 69 | } 70 | 71 | public class Config { 72 | private final List days = null; 73 | 74 | private final String repeat_on = null; 75 | 76 | public List getDays() { 77 | return days; 78 | } 79 | 80 | public String getRepeatOn() { 81 | return repeat_on; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/CommentProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.Comment; 8 | import com.podio.sdk.domain.ReferenceType; 9 | 10 | /** 11 | * Enables access to the Comments API end point. 12 | * 13 | */ 14 | public class CommentProvider extends Provider { 15 | 16 | static class CommentsFilter extends Filter { 17 | 18 | protected CommentsFilter() { 19 | super("comment"); 20 | } 21 | 22 | public CommentsFilter withReference(ReferenceType type, long id) { 23 | this.addPathSegment(type.name()); 24 | this.addPathSegment(Long.toString(id, 10)); 25 | 26 | return this; 27 | } 28 | 29 | public CommentsFilter withCommentId(long commentId) { 30 | addPathSegment(Long.toString(commentId, 10)); 31 | return this; 32 | } 33 | 34 | } 35 | 36 | /** 37 | * 38 | * Create a comment on a reference type with the given id. The request result will deliver the 39 | * generated comment. 40 | * 41 | * @param type 42 | * The reference type of what you are commenting on. 43 | * @param id 44 | * The id of the reference type your are commenting on. 45 | * @param value 46 | * The comment body. 47 | * @param fileIds 48 | * The list of ids of any files attached to the comment. 49 | * 50 | * @return A ticket which the caller can use to identify this request with. 51 | */ 52 | public Request createComment(ReferenceType type, long id, String value, long[] fileIds) { 53 | CommentsFilter filter = new CommentsFilter(); 54 | filter.withReference(type,id); 55 | Comment.Create create = new Comment.Create(value, fileIds); 56 | return post(filter, create, Comment.class); 57 | } 58 | 59 | public Request getComment(long id) { 60 | CommentsFilter filter = new CommentsFilter(); 61 | filter.withCommentId(id); 62 | return get(filter, Comment.class); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/NotificationContext.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.Organization; 5 | import com.podio.sdk.domain.Reference; 6 | import com.podio.sdk.domain.Right; 7 | import com.podio.sdk.domain.Space; 8 | import com.podio.sdk.internal.Utils; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * This class is the base class of all notification contexts. 14 | *

15 | * In most cases all information we are interested in is provided by this class so even if you are 16 | * getting notification contexes of type {@link UnknownNotificationContext} there is still plenty of 17 | * information available in that one. 18 | * 19 | */ 20 | public abstract class NotificationContext { 21 | 22 | private final Reference ref = null; 23 | private final String title = null; 24 | private final List rights = null; 25 | private final Integer comment_count = null; 26 | private final Space space = null; 27 | private final Organization org = null; 28 | 29 | public Organization getOrganization() { 30 | return org; 31 | } 32 | 33 | public Space getSpace() { 34 | return space; 35 | } 36 | 37 | public int getCommentCount() { 38 | return Utils.getNative(comment_count, -1); 39 | } 40 | 41 | /** 42 | * Checks whether the list of rights the user has for this notification context contains 43 | * all the given permissions. 44 | * 45 | * @param permissions 46 | * The list of permissions to check for. 47 | * 48 | * @return Boolean true if all given permissions are found or no permissions are given. Boolean 49 | * false otherwise. 50 | */ 51 | public boolean hasRights(Right... permissions) { 52 | if (rights != null) { 53 | for (Right permission : permissions) { 54 | if (!rights.contains(permission)) { 55 | return false; 56 | } 57 | } 58 | 59 | return true; 60 | } 61 | 62 | return false; 63 | } 64 | 65 | public String getTitle() { 66 | return title; 67 | } 68 | 69 | public Reference getReference() { 70 | return ref; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Byline.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import java.util.Date; 5 | 6 | import com.podio.sdk.internal.Utils; 7 | 8 | public class Byline { 9 | private final Long id = null; 10 | private final Long user_id = null; 11 | private final Long avatar = null; 12 | private final Long avatar_id = null; 13 | private final String avatar_type = null; // See "Type" enum. 14 | private final String name = null; 15 | private final String last_seen_on = null; 16 | private final String type = null; // See "Type" enum. 17 | private final String url = null; 18 | private final File image = null; 19 | 20 | public long getId() { 21 | return Utils.getNative(id, -1L); 22 | } 23 | 24 | public long getUserId() { 25 | return Utils.getNative(user_id, -1L); 26 | } 27 | 28 | public long getAvatar() { 29 | return Utils.getNative(avatar, -1L); 30 | } 31 | 32 | public long getAvatarId() { 33 | return Utils.getNative(avatar_id, -1L); 34 | } 35 | 36 | public ReferenceType getAvatarType() { 37 | try { 38 | return ReferenceType.valueOf(avatar_type); 39 | } catch (NullPointerException e) { 40 | return ReferenceType.unknown; 41 | } catch (IllegalArgumentException e) { 42 | return ReferenceType.unknown; 43 | } 44 | } 45 | 46 | public String getName() { 47 | return name; 48 | } 49 | 50 | public Date getLastSeenDate() { 51 | return Utils.parseDateTimeUtc(last_seen_on); 52 | } 53 | 54 | public String getLastSeenDateString() { 55 | return last_seen_on; 56 | } 57 | 58 | public ReferenceType getType() { 59 | try { 60 | return ReferenceType.valueOf(type); 61 | } catch (NullPointerException e) { 62 | return ReferenceType.unknown; 63 | } catch (IllegalArgumentException e) { 64 | return ReferenceType.unknown; 65 | } 66 | } 67 | 68 | public String getUrl() { 69 | return url; 70 | } 71 | 72 | public String getImageUrl() { 73 | return image != null ? image.getLink() : null; 74 | } 75 | 76 | public File getImage() { 77 | return image; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/json/TaskActionDeserializerSerializer.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.json; 2 | 3 | 4 | import com.google.gson.JsonDeserializationContext; 5 | import com.google.gson.JsonDeserializer; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonParseException; 9 | import com.google.gson.JsonSerializationContext; 10 | import com.google.gson.JsonSerializer; 11 | import com.podio.sdk.domain.AssignTaskAction; 12 | import com.podio.sdk.domain.TaskAction; 13 | import com.podio.sdk.domain.TextTaskAction; 14 | import com.podio.sdk.internal.DefaultHashMap; 15 | 16 | import java.lang.reflect.Type; 17 | import java.util.Map; 18 | 19 | /** 20 | * Notifications contains a dynamic "data" part that can have different content depending on the 21 | * type of notifications so we need to have this deserializer/serializer to decide what kind of 22 | * notification we are handling. 23 | * 24 | */ 25 | class TaskActionDeserializerSerializer implements JsonDeserializer, JsonSerializer { 26 | 27 | private Map> mTaskActionClassesMap; 28 | 29 | public TaskActionDeserializerSerializer() { 30 | mTaskActionClassesMap = new DefaultHashMap>(TextTaskAction.class); 31 | mTaskActionClassesMap.put(TaskAction.TaskActionType.assign, AssignTaskAction.class); 32 | } 33 | 34 | @Override 35 | public TaskAction deserialize(JsonElement element, Type type, JsonDeserializationContext gsonContext) throws JsonParseException { 36 | if (element == null || element.isJsonNull()) { 37 | return null; 38 | } 39 | 40 | JsonObject jsonObject = element.getAsJsonObject(); 41 | 42 | TaskAction.TaskActionType taskActionType = TaskAction.TaskActionType.getType(jsonObject.get("type").getAsString()); 43 | 44 | return gsonContext.deserialize(jsonObject, mTaskActionClassesMap.get(taskActionType)); 45 | } 46 | 47 | @Override 48 | public JsonElement serialize(TaskAction taskAction, Type typeOfSrc, JsonSerializationContext gsonContext) { 49 | return gsonContext.serialize(taskAction, mTaskActionClassesMap.get(taskAction.getType())); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/json/JsonParser.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.json; 3 | 4 | import com.google.gson.FieldNamingPolicy; 5 | import com.google.gson.Gson; 6 | import com.google.gson.GsonBuilder; 7 | import com.google.gson.JsonSyntaxException; 8 | import com.podio.sdk.domain.DataReference; 9 | import com.podio.sdk.domain.TaskAction; 10 | import com.podio.sdk.domain.field.Field; 11 | import com.podio.sdk.domain.notification.Notification; 12 | import com.podio.sdk.domain.notification.NotificationContext; 13 | import com.podio.sdk.domain.reference.ReferenceGroup; 14 | import com.podio.sdk.domain.stream.EventActivity; 15 | import com.podio.sdk.domain.stream.EventContext; 16 | 17 | public class JsonParser { 18 | 19 | private static final Gson GSON = new GsonBuilder() 20 | .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) 21 | .setDateFormat("yyyy-MM-dd HH:mm:ss") 22 | .registerTypeAdapter(Field.class, new FieldDeserializerSerializer()) 23 | .registerTypeAdapter(Notification.class, new NotificationDeserializerSerializer()) 24 | .registerTypeAdapter(NotificationContext.class, new NotificationContextDeserializerSerializer()) 25 | .registerTypeAdapter(EventContext.class, new EventContextDeserializerSerializer()) 26 | .registerTypeAdapter(EventActivity.class, new EventActivityDeserializerSerializer()) 27 | .registerTypeAdapter(TaskAction.class, new TaskActionDeserializerSerializer()) 28 | .registerTypeAdapter(ReferenceGroup.class, new ReferenceGroupDeserializerSerializer()) 29 | .registerTypeAdapter(DataReference.class, new DataReferenceDeserializer()) 30 | .disableHtmlEscaping() 31 | .serializeNulls() 32 | .create(); 33 | 34 | public static T fromJson(String json, Class classOfResult) { 35 | try { 36 | return GSON.fromJson(json, classOfResult); 37 | } catch (JsonSyntaxException e) { 38 | throw new JsonSyntaxException("Couldn't parse API error json: " + json, e); 39 | } catch (IllegalStateException e) { 40 | throw new IllegalStateException("Couldn't parse API error json: " + json, e); 41 | } 42 | } 43 | 44 | public static String toJson(T item) { 45 | return GSON.toJson(item); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/Session.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | 9 | public class Session { 10 | 11 | private static String accessToken; 12 | private static String refreshToken; 13 | private static String transferToken; 14 | private static long expires; 15 | 16 | public static String accessToken() { 17 | return accessToken; 18 | } 19 | 20 | public static long expires() { 21 | return expires; 22 | } 23 | 24 | public static String refreshToken() { 25 | return refreshToken; 26 | } 27 | 28 | public static String transferToken() { 29 | return transferToken; 30 | } 31 | 32 | public static void set(String jsonString) { 33 | JSONObject jsonObject = null; 34 | 35 | try { 36 | jsonObject = new JSONObject(jsonString); 37 | accessToken = jsonObject.optString("access_token", null); 38 | refreshToken = jsonObject.optString("refresh_token", null); 39 | transferToken = jsonObject.optString("transfer_token", null); 40 | 41 | if (jsonObject.has("expires")) { 42 | expires = jsonObject.optLong("expires", 0L); 43 | } else if (jsonObject.has("expires_in")) { 44 | long expiresIn = jsonObject.optLong("expires_in", 0L); 45 | expires = Utils.currentTimeSeconds() + expiresIn; 46 | } 47 | } catch (JSONException e) { 48 | // Input JSON was most likely invalid. Fallback to defaults. 49 | accessToken = refreshToken = null; 50 | expires = 0; 51 | } catch (NullPointerException e) { 52 | // Input JSON was most likely a null pointer. Fallback to defaults. 53 | accessToken = refreshToken = null; 54 | expires = 0; 55 | } 56 | } 57 | 58 | public static void set(String accessToken, String refreshToken, long expires) { 59 | set(accessToken, refreshToken, null, expires); 60 | } 61 | 62 | public static void set(String accessToken, String refreshToken, String transferToken, long expires) { 63 | Session.accessToken = accessToken; 64 | Session.refreshToken = refreshToken; 65 | Session.transferToken = transferToken; 66 | Session.expires = expires; 67 | } 68 | 69 | private Session() { 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/json/EventContextDeserializerSerializer.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.json; 3 | 4 | import com.google.gson.JsonDeserializationContext; 5 | import com.google.gson.JsonDeserializer; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonParseException; 9 | import com.google.gson.JsonSerializationContext; 10 | import com.google.gson.JsonSerializer; 11 | import com.podio.sdk.domain.ReferenceType; 12 | import com.podio.sdk.domain.stream.EventContext; 13 | import com.podio.sdk.domain.stream.FileEventContext; 14 | import com.podio.sdk.domain.stream.StatusEventContext; 15 | import com.podio.sdk.domain.stream.UnknownEventContext; 16 | import com.podio.sdk.internal.DefaultHashMap; 17 | 18 | import java.lang.reflect.Type; 19 | import java.util.Map; 20 | 21 | /** 22 | * EventContext contains a dynamic "data" part that can have different content depending on the type 23 | * of context so we need to have this deserializer/serializer to decide what kind of context we are 24 | * handling. 25 | * 26 | */ 27 | class EventContextDeserializerSerializer implements JsonDeserializer, JsonSerializer { 28 | 29 | private Map> mEventContextClassesMap; 30 | 31 | public EventContextDeserializerSerializer() { 32 | mEventContextClassesMap = new DefaultHashMap>(UnknownEventContext.class); 33 | mEventContextClassesMap.put(ReferenceType.status, StatusEventContext.class); 34 | mEventContextClassesMap.put(ReferenceType.file, FileEventContext.class); 35 | } 36 | 37 | @Override 38 | public EventContext deserialize(JsonElement element, Type type, JsonDeserializationContext gsonContext) throws JsonParseException { 39 | if (element == null || element.isJsonNull()) { 40 | return null; 41 | } 42 | 43 | JsonObject jsonObject = element.getAsJsonObject(); 44 | ReferenceType referenceType = ReferenceType.getType(jsonObject.get("type").getAsString()); 45 | 46 | return gsonContext.deserialize(jsonObject, mEventContextClassesMap.get(referenceType)); 47 | } 48 | 49 | @Override 50 | public JsonElement serialize(EventContext eventContext, Type typeOfSrc, JsonSerializationContext gsonContext) { 51 | return gsonContext.serialize(eventContext, mEventContextClassesMap.get(eventContext.getType())); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/domain/FileTests.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import android.test.AndroidTestCase; 5 | 6 | import com.google.gson.Gson; 7 | 8 | public class FileTests extends AndroidTestCase { 9 | 10 | public void testEmbedCanBeCreatedFromJson() { 11 | String json = new StringBuilder("{") 12 | .append("file_id:1,") 13 | .append("size:1,") 14 | .append("description:'DESCRIPTION',") 15 | .append("hosted_by:'HOSTEDBY',") 16 | .append("hosted_by_humanized_name:'HOSTEDBYHUMANIZEDNAME',") 17 | .append("link:'LINK',") 18 | .append("link_target:'LINKTARGET',") 19 | .append("mimetype:'MIMETYPE',") 20 | .append("name:'NAME',") 21 | .append("perma_link:'PERMALINK',") 22 | .append("thumbnail_link:'THUMBNAILLINK'") 23 | .append("}").toString(); 24 | 25 | Gson gson = new Gson(); 26 | File file = gson.fromJson(json, File.class); 27 | 28 | assertNotNull(file); 29 | assertEquals(1, file.getId()); 30 | assertEquals(1, file.getSize()); 31 | assertEquals("DESCRIPTION", file.getDescription()); 32 | assertEquals("HOSTEDBY", file.getHostName()); 33 | assertEquals("HOSTEDBYHUMANIZEDNAME", file.getHumanizedHostName()); 34 | assertEquals("LINK", file.getLink()); 35 | assertEquals("LINKTARGET", file.getLinkTarget()); 36 | assertEquals("MIMETYPE", file.getMimeType()); 37 | assertEquals("NAME", file.getName()); 38 | assertEquals("PERMALINK", file.getPermaLink()); 39 | assertEquals("THUMBNAILLINK", file.getThumbnailLink()); 40 | } 41 | 42 | 43 | public void testEmbedCanBeCreatedFromInstantiation() { 44 | File file = new File(1); 45 | 46 | assertNotNull(file); 47 | assertEquals(1, file.getId()); 48 | assertEquals(0, file.getSize()); 49 | assertEquals(null, file.getDescription()); 50 | assertEquals(null, file.getHostName()); 51 | assertEquals(null, file.getHumanizedHostName()); 52 | assertEquals(null, file.getLink()); 53 | assertEquals(null, file.getLinkTarget()); 54 | assertEquals(null, file.getMimeType()); 55 | assertEquals(null, file.getName()); 56 | assertEquals(null, file.getPermaLink()); 57 | assertEquals(null, file.getThumbnailLink()); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Embed.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | /** 7 | */ 8 | public class Embed { 9 | 10 | @Override 11 | public boolean equals(Object o) { 12 | if (this == o) return true; 13 | if (o == null || getClass() != o.getClass()) return false; 14 | 15 | Embed embed = (Embed) o; 16 | 17 | return !(embed_id != null ? !embed_id.equals(embed.embed_id) : embed.embed_id != null); 18 | 19 | } 20 | 21 | @Override 22 | public int hashCode() { 23 | return embed_id != null ? embed_id.hashCode() : 0; 24 | } 25 | 26 | public static enum Type { 27 | link, undefined 28 | } 29 | 30 | public static class Create { 31 | private final String url; 32 | 33 | public Create(String url) { 34 | this.url = url; 35 | } 36 | } 37 | 38 | private final Integer embed_height = null; 39 | private final Integer embed_width = null; 40 | private final Long embed_id = null; 41 | private final String description = null; 42 | private final String embed_html = null; 43 | private final String hostname = null; 44 | private final String original_url = null; 45 | private final String resolved_url = null; 46 | private final String title = null; 47 | private final String url; 48 | private final Type type = null; 49 | 50 | public Embed(String url) { 51 | this.url = url; 52 | } 53 | 54 | public String getDescription() { 55 | return description; 56 | } 57 | 58 | public int getHeight() { 59 | return Utils.getNative(embed_height, 0); 60 | } 61 | 62 | public String getHtml() { 63 | return embed_html; 64 | } 65 | 66 | public long getId() { 67 | return Utils.getNative(embed_id, -1L); 68 | } 69 | 70 | public int getWidth() { 71 | return Utils.getNative(embed_width, 0); 72 | } 73 | 74 | public String getHostName() { 75 | return hostname; 76 | } 77 | 78 | public String getOriginalUrl() { 79 | return original_url; 80 | } 81 | 82 | public String getResolvedUrl() { 83 | return resolved_url; 84 | } 85 | 86 | public String getTitle() { 87 | return title; 88 | } 89 | 90 | public String getUrl() { 91 | return url; 92 | } 93 | 94 | public Type getType() { 95 | return type != null ? type : Type.undefined; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/volley/MockWebServer.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.volley; 3 | 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.json.JSONObject; 8 | 9 | import fi.iki.elonen.NanoHTTPD; 10 | 11 | public class MockWebServer extends NanoHTTPD { 12 | 13 | private JSONObject response; 14 | private JSONObject session; 15 | 16 | private HashMap responses; 17 | 18 | private String requestUri; 19 | private String requestBody; 20 | private Method requestMethod; 21 | private Map requestHeaders; 22 | private Map requestParams; 23 | 24 | public MockWebServer() { 25 | super(8080); 26 | responses = new HashMap(); 27 | } 28 | 29 | public void mock_setResponse(JSONObject response) { 30 | this.response = response; 31 | } 32 | 33 | public void mock_setResponse(String path, JSONObject response) { 34 | this.responses.put(path, response); 35 | } 36 | 37 | public void mock_setSession(JSONObject session) { 38 | this.session = session; 39 | } 40 | 41 | public String mock_getRequestBody() { 42 | return requestBody; 43 | } 44 | 45 | public String mock_getRequestUri() { 46 | return requestUri; 47 | } 48 | 49 | public Method mock_getRequestMethod() { 50 | return requestMethod; 51 | } 52 | 53 | public Map mock_getRequestHeaders() { 54 | return requestHeaders; 55 | } 56 | 57 | public Map mock_getRequestParams() { 58 | return requestParams; 59 | } 60 | 61 | @Override 62 | public Response serve(String uri, Method method, Map headers, 63 | Map parms, Map files) { 64 | 65 | requestUri = uri; 66 | requestBody = parms != null ? parms.get("NanoHttpd.QUERY_STRING") : ""; 67 | 68 | requestMethod = method; 69 | requestHeaders = headers; 70 | requestParams = parms; 71 | 72 | Response result; 73 | 74 | if (uri.equals("/auth/token")) { 75 | String json = session != null ? session.toString() : "{}"; 76 | result = new Response(json); 77 | } else { 78 | JSONObject r = responses.get(uri); 79 | String json = r != null ? r.toString() : response != null ? response.toString() : "{}"; 80 | result = new Response(json); 81 | } 82 | 83 | return result; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/provider/UserProviderTest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import org.mockito.Mock; 5 | import org.mockito.Mockito; 6 | import org.mockito.MockitoAnnotations; 7 | 8 | import android.net.Uri; 9 | import android.test.InstrumentationTestCase; 10 | 11 | import com.podio.sdk.Request; 12 | import com.podio.sdk.domain.Profile; 13 | import com.podio.sdk.domain.User; 14 | import com.podio.sdk.domain.UserStatus; 15 | import com.podio.sdk.volley.MockRestClient; 16 | 17 | public class UserProviderTest extends InstrumentationTestCase { 18 | 19 | @Mock 20 | Request.ResultListener profileResultListener; 21 | 22 | @Mock 23 | Request.ResultListener userResultListener; 24 | 25 | @Mock 26 | Request.ResultListener statusResultListener; 27 | 28 | @Override 29 | protected void setUp() throws Exception { 30 | super.setUp(); 31 | MockitoAnnotations.initMocks(this); 32 | } 33 | 34 | public void testGetUserData() { 35 | MockRestClient mockClient = new MockRestClient(getInstrumentation().getTargetContext()); 36 | UserProvider provider = new UserProvider(); 37 | provider.setClient(mockClient); 38 | 39 | provider.getUser().withResultListener(userResultListener); 40 | 41 | Mockito.verify(userResultListener, Mockito.timeout(100).times(0)).onRequestPerformed(null); 42 | assertEquals(Uri.parse("https://test/user"), mockClient.uri); 43 | } 44 | 45 | public void testGetUserStatus() { 46 | MockRestClient mockClient = new MockRestClient(getInstrumentation().getTargetContext()); 47 | UserProvider provider = new UserProvider(); 48 | provider.setClient(mockClient); 49 | 50 | provider.getUserStatus().withResultListener(statusResultListener); 51 | 52 | Mockito.verify(statusResultListener, Mockito.timeout(100).times(0)).onRequestPerformed(null); 53 | assertEquals(Uri.parse("https://test/user/status"), mockClient.uri); 54 | } 55 | 56 | public void testGetUserProfile() { 57 | MockRestClient mockClient = new MockRestClient(getInstrumentation().getTargetContext()); 58 | UserProvider provider = new UserProvider(); 59 | provider.setClient(mockClient); 60 | provider.getProfile().withResultListener(profileResultListener); 61 | 62 | Mockito.verify(profileResultListener, Mockito.timeout(100).times(0)).onRequestPerformed(null); 63 | assertEquals(Uri.parse("https://test/user/profile"), mockClient.uri); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/File.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.domain.data.Data; 5 | import com.podio.sdk.internal.Utils; 6 | 7 | /** 8 | */ 9 | public class File implements Data{ 10 | 11 | private final Long file_id; 12 | private final Long size; 13 | private final String description; 14 | private final String hosted_by; 15 | private final String hosted_by_humanized_name; 16 | private final String link; 17 | private final String link_target; 18 | private final String mimetype; 19 | private final String name; 20 | private final String perma_link; 21 | private final String thumbnail_link; 22 | 23 | public File(long fileId) { 24 | this.file_id = fileId; 25 | this.size = null; 26 | this.description = null; 27 | this.hosted_by = null; 28 | this.hosted_by_humanized_name = null; 29 | this.link = null; 30 | this.link_target = null; 31 | this.mimetype = null; 32 | this.name = null; 33 | this.perma_link = null; 34 | this.thumbnail_link = null; 35 | } 36 | 37 | public String getDescription() { 38 | return description; 39 | } 40 | 41 | public long getId() { 42 | return Utils.getNative(file_id, -1L); 43 | } 44 | 45 | public String getHostName() { 46 | return hosted_by; 47 | } 48 | 49 | public String getHumanizedHostName() { 50 | return hosted_by_humanized_name; 51 | } 52 | 53 | public String getLink() { 54 | return link; 55 | } 56 | 57 | public String getLinkTarget() { 58 | return link_target; 59 | } 60 | 61 | public String getMimeType() { 62 | return mimetype; 63 | } 64 | 65 | public String getName() { 66 | return name; 67 | } 68 | 69 | public String getPermaLink() { 70 | return perma_link; 71 | } 72 | 73 | public long getSize() { 74 | return Utils.getNative(size, 0L); 75 | } 76 | 77 | public String getThumbnailLink() { 78 | return thumbnail_link; 79 | } 80 | 81 | @Override 82 | public boolean equals(Object o) { 83 | if (this == o) return true; 84 | if (o == null || getClass() != o.getClass()) return false; 85 | 86 | File file = (File) o; 87 | 88 | return !(file_id != null ? !file_id.equals(file.file_id) : file.file_id != null); 89 | 90 | } 91 | 92 | @Override 93 | public int hashCode() { 94 | return file_id != null ? file_id.hashCode() : 0; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/json/DataReferenceDeserializer.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.json; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonDeserializationContext; 5 | import com.google.gson.JsonDeserializer; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonParseException; 9 | import com.podio.sdk.domain.Application; 10 | import com.podio.sdk.domain.DataReference; 11 | import com.podio.sdk.domain.File; 12 | import com.podio.sdk.domain.Item; 13 | import com.podio.sdk.domain.ReferenceType; 14 | import com.podio.sdk.domain.Space; 15 | import com.podio.sdk.domain.Status; 16 | import com.podio.sdk.domain.Task; 17 | import com.podio.sdk.domain.data.Data; 18 | import com.podio.sdk.domain.data.UnknownData; 19 | import com.podio.sdk.internal.DefaultHashMap; 20 | 21 | import java.lang.reflect.Type; 22 | import java.util.Map; 23 | 24 | /** 25 | * Resolves the reference object received in a URL resolver API call in the references API area 26 | * 27 | */ 28 | public class DataReferenceDeserializer implements JsonDeserializer { 29 | 30 | private Map> dataClassesMap; 31 | 32 | public DataReferenceDeserializer() { 33 | dataClassesMap = new DefaultHashMap>(UnknownData.class); 34 | dataClassesMap.put(ReferenceType.item, Item.class); 35 | dataClassesMap.put(ReferenceType.space, Space.class); 36 | dataClassesMap.put(ReferenceType.status, Status.class); 37 | dataClassesMap.put(ReferenceType.app, Application.class); 38 | dataClassesMap.put(ReferenceType.task, Task.class); 39 | dataClassesMap.put(ReferenceType.file, File.class); 40 | } 41 | 42 | @Override 43 | public DataReference deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 44 | 45 | if (element == null || element.isJsonNull()) { 46 | return null; 47 | } 48 | 49 | JsonObject jsonObject = element.getAsJsonObject(); 50 | ReferenceType referenceType = ReferenceType.getType(jsonObject.get("type").getAsString()); 51 | String title = jsonObject.get("title").getAsString(); 52 | long id = jsonObject.get("id").getAsLong(); 53 | Gson gson = new Gson(); 54 | Data data = gson.fromJson(jsonObject.get("data"), dataClassesMap.get(referenceType)); 55 | 56 | DataReference reference = new DataReference(title, data, referenceType.name(), id); 57 | 58 | return reference; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /sdk/sdk.pom: -------------------------------------------------------------------------------- 1 | 5 | 6 | 4.0.0 7 | com.podio.android 8 | sdk 9 | 0.1.0 10 | Podio Android SDK 11 | The official Android Java wrapper for the Podio API 12 | http://podio.com 13 | 14 | 15 | 16 | The Apache Software License, Version 2.0 17 | http://www.apache.org/licenses/LICENSE-2.0.txt 18 | repo 19 | 20 | 21 | 22 | 23 | 24 | laszlourszuly 25 | László Urszuly 26 | support@podio.com 27 | 28 | 29 | 30 | 31 | scm:git:git@github.com:podio/podio-android.git 32 | scm:git:git@github.com:podio/podio-android.git 33 | git@github.com:podio/podio-android.git 34 | 35 | 36 | 37 | UTF-8 38 | 39 | 40 | 41 | 42 | junit 43 | junit 44 | 3.8.1 45 | test 46 | 47 | 48 | com.google.android 49 | android 50 | 4.1.1.4 51 | provided 52 | 53 | 54 | com.google.code.gson 55 | gson 56 | 2.3.1 57 | compile 58 | 59 | 60 | com.mcxiaoke.volley 61 | library 62 | 1.0.9 63 | compile 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | maven-compiler-plugin 72 | 3.2 73 | 74 | 1.8 75 | 1.8 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/View.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import java.util.Date; 5 | import java.util.Set; 6 | 7 | import com.google.gson.annotations.SerializedName; 8 | import com.podio.sdk.internal.Utils; 9 | 10 | /** 11 | * Domain object representing saved app views that you can use to filter your 12 | * app item lists. 13 | * 14 | */ 15 | public class View { 16 | 17 | public static enum Type { 18 | standard, saved, undefined 19 | } 20 | 21 | private final Long view_id = null; 22 | private final String name = null; 23 | private final String created_on = null; 24 | private final User created_by = null; 25 | private final Set rights = null; 26 | @SerializedName("private") 27 | private final Boolean is_private = null; 28 | private final Integer items = null; 29 | private final Type type = null; 30 | 31 | private View() { 32 | } 33 | 34 | public long getId() { 35 | return Utils.getNative(view_id, -1L); 36 | } 37 | 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | /** 43 | * Gets the end date of the calendar event as a Java Date object. 44 | * 45 | * @return A date object, or null if the date couldn't be parsed. 46 | */ 47 | public Date getCreatedDate() { 48 | return Utils.parseDateTimeUtc(created_on); 49 | } 50 | 51 | public String getCreatedDateString() { 52 | return created_on; 53 | } 54 | 55 | public User getCreatedByUser() { 56 | return created_by; 57 | } 58 | 59 | /** 60 | * Checks whether the list of rights the user has for this application 61 | * contains all the given permissions. 62 | * 63 | * @param permissions 64 | * The list of permissions to check for. 65 | * @return Boolean true if all given permissions are found or no permissions 66 | * are given. Boolean false otherwise. 67 | */ 68 | public boolean hasRights(Right... permissions) { 69 | if (rights != null) { 70 | for (Right permission : permissions) { 71 | if (!rights.contains(permission)) { 72 | return false; 73 | } 74 | } 75 | 76 | return true; 77 | } 78 | 79 | return false; 80 | } 81 | 82 | public boolean isPrivate() { 83 | return Utils.getNative(is_private, false); 84 | } 85 | 86 | public int getItemsCount() { 87 | return Utils.getNative(items, -1); 88 | } 89 | 90 | public Type getType() { 91 | return type != null ? type : Type.undefined; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/PushEvent.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | public abstract class PushEvent { 7 | 8 | /** 9 | * All supported event types. 10 | * 11 | */ 12 | public static enum Type { 13 | conversation_event(Conversation.PushNewEvent.class), 14 | conversation_read(Conversation.PushRead.class), 15 | conversation_read_all(Conversation.PushReadAll.class), 16 | conversation_starred(Conversation.PushStarred.class), 17 | conversation_starred_count(Conversation.PushStarredCount.class), 18 | conversation_unread(Conversation.PushUnread.class), 19 | conversation_unread_count(Conversation.PushUnreadCount.class), 20 | conversation_unstarred(Conversation.PushUnstarred.class), 21 | typing(PushEventTyping.class), 22 | viewing(PushEventViewing.class), 23 | unknown(null); 24 | 25 | private final Class classOfEvent; 26 | 27 | private Type(Class classOfEvent) { 28 | this.classOfEvent = classOfEvent; 29 | } 30 | 31 | public Class getClassObject() { 32 | return classOfEvent; 33 | } 34 | } 35 | 36 | /** 37 | * A helper class, describing an arbitrary reference. 38 | * 39 | */ 40 | protected static class Reference { 41 | private final String type = null; 42 | private final Long id = null; 43 | 44 | String type() { 45 | return type; 46 | } 47 | 48 | long id() { 49 | return Utils.getNative(id, -1L); 50 | } 51 | } 52 | 53 | /** 54 | * The reference to the carrier of the event 55 | */ 56 | private final Reference ref = null; 57 | private final String event = null; 58 | private final Reference created_by = null; 59 | 60 | public String referenceType() { 61 | return ref != null ? ref.type : null; 62 | } 63 | 64 | public long referenceId() { 65 | return ref != null ? Utils.getNative(ref.id, -1L) : -1L; 66 | } 67 | 68 | public Type event() { 69 | try { 70 | return Type.valueOf(event); 71 | } catch (NullPointerException e) { 72 | return Type.unknown; 73 | } catch (IllegalArgumentException e) { 74 | return Type.unknown; 75 | } 76 | } 77 | 78 | public String createdByType() { 79 | return created_by != null ? created_by.type : null; 80 | } 81 | 82 | public long createdById() { 83 | return created_by != null ? Utils.getNative(created_by.id, -1L) : -1L; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/localstore/RemoveRequest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.localstore; 3 | 4 | import android.util.LruCache; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.concurrent.Callable; 9 | 10 | /** 11 | * A specific {@link LocalStoreRequest}, targeting the "remove value" operation. This implementation 12 | * silently removes a value from both the memory cache as well as the disk cache. If the disk store 13 | * isn't prepared yet, the disk write request will block until the disk store is ready. 14 | * 15 | */ 16 | final class RemoveRequest extends LocalStoreRequest { 17 | 18 | /** 19 | * Removes the value associated with the given key from the memory cache as well as the disk 20 | * store. If the disk store isn't initialized yet, the disk write operation will block until 21 | * it's prepared. 22 | * 23 | * @param storeEnabler 24 | * The callback that will provide the memory and disk stores. 25 | * @param key 26 | * The key of the value to remove. 27 | * 28 | * @throws IOException 29 | * If the file system access fails for some reason. 30 | */ 31 | private static final void removeValue(RuntimeStoreEnabler storeEnabler, Object key) throws IOException { 32 | LruCache memoryStore = storeEnabler.getMemoryStore(); 33 | if (memoryStore == null) { 34 | throw new IllegalStateException("You're trying to remove content from a closed store."); 35 | } 36 | 37 | memoryStore.remove(key); 38 | 39 | // Remove from disk. Make sure we wait for the disk store to be ready before we start 40 | // accessing it. 41 | synchronized (storeEnabler.getDiskStoreLock()) { 42 | File diskStore = storeEnabler.getDiskStore(); 43 | if (isReadableDirectory(diskStore)) { 44 | String fileName = getFileName(key); 45 | File file = new File(diskStore, fileName); 46 | file.delete(); 47 | } 48 | } 49 | } 50 | 51 | /** 52 | * Creates a new Request for removing a value from the local store. 53 | * 54 | * @param storeEnabler 55 | * The callback that will provide the memory and disk stores. 56 | * @param key 57 | * The key of the value. 58 | * 59 | * @return A request ready for being enqueued in a queue. 60 | */ 61 | RemoveRequest(final RuntimeStoreEnabler storeEnabler, final Object key) { 62 | super(new Callable() { 63 | @Override 64 | public Void call() throws Exception { 65 | removeValue(storeEnabler, key); 66 | return null; 67 | } 68 | }); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/json/NotificationContextDeserializerSerializer.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.json; 3 | 4 | import com.google.gson.JsonDeserializationContext; 5 | import com.google.gson.JsonDeserializer; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonParseException; 9 | import com.google.gson.JsonSerializationContext; 10 | import com.google.gson.JsonSerializer; 11 | import com.podio.sdk.domain.ReferenceType; 12 | import com.podio.sdk.domain.notification.AppNotificationContext; 13 | import com.podio.sdk.domain.notification.BatchNotificationContext; 14 | import com.podio.sdk.domain.notification.ItemNotificationContext; 15 | import com.podio.sdk.domain.notification.NotificationContext; 16 | import com.podio.sdk.domain.notification.UnknownNotificationContext; 17 | import com.podio.sdk.internal.DefaultHashMap; 18 | 19 | import java.lang.reflect.Type; 20 | import java.util.Map; 21 | 22 | /** 23 | * Notification context contains a dynamic "data" part that can have different content depending on 24 | * the type of context so we need to have this deserializer/serializer to decide what kind of 25 | * context we are handling. 26 | * 27 | */ 28 | class NotificationContextDeserializerSerializer implements JsonDeserializer, JsonSerializer { 29 | 30 | private Map> mNotificationContextClassesMap; 31 | 32 | public NotificationContextDeserializerSerializer() { 33 | mNotificationContextClassesMap = new DefaultHashMap>(UnknownNotificationContext.class); 34 | mNotificationContextClassesMap.put(ReferenceType.app, AppNotificationContext.class); 35 | mNotificationContextClassesMap.put(ReferenceType.item, ItemNotificationContext.class); 36 | mNotificationContextClassesMap.put(ReferenceType.batch, BatchNotificationContext.class); 37 | } 38 | 39 | @Override 40 | public NotificationContext deserialize(JsonElement element, Type type, JsonDeserializationContext gsonContext) throws JsonParseException { 41 | if (element == null || element.isJsonNull()) { 42 | return null; 43 | } 44 | 45 | JsonObject jsonObject = element.getAsJsonObject(); 46 | ReferenceType referenceType = ReferenceType.getType(jsonObject.get("ref").getAsJsonObject().get("type").getAsString()); 47 | 48 | return gsonContext.deserialize(jsonObject, mNotificationContextClassesMap.get(referenceType)); 49 | } 50 | 51 | @Override 52 | public JsonElement serialize(NotificationContext notificationContext, Type typeOfSrc, JsonSerializationContext gsonContext) { 53 | return gsonContext.serialize(notificationContext, mNotificationContextClassesMap.get(notificationContext.getReference().getType())); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/localstore/EraseRequest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.localstore; 3 | 4 | import android.util.LruCache; 5 | 6 | import java.io.File; 7 | import java.util.concurrent.Callable; 8 | 9 | /** 10 | * A specific {@link com.podio.sdk.localstore.LocalStoreRequest LocalStoreRequest} implementation, 11 | * targeting the "destroy store" operation. This implementation clears the memory cache and wipes 12 | * all files from the disk cache that belongs to this very store, leaving other stores intact. If 13 | * the disk store isn't prepared yet, the disk write request will block until the disk store is 14 | * ready. This class also removes the actual store sub directory from the file system. 15 | * 16 | */ 17 | final class EraseRequest extends LocalStoreRequest { 18 | 19 | /** 20 | * Evicts all entries in the given memory cache. 21 | * 22 | * @param memoryStore 23 | * The in-memory cache to clear. 24 | */ 25 | private static void destroyMemoryStore(LruCache memoryStore) { 26 | if (memoryStore != null) { 27 | memoryStore.evictAll(); 28 | } 29 | } 30 | 31 | /** 32 | * Recursively removes all files in the given directory and tries to remove the directory as 33 | * well. 34 | * 35 | * @param diskStore 36 | * The disk cache to clear. 37 | */ 38 | private static void destroyDiskStore(File diskStore) { 39 | if (isWritableDirectory(diskStore)) { 40 | File[] files = diskStore.listFiles(); 41 | 42 | if (files != null) { 43 | for (File file : files) { 44 | if (file.isDirectory()) { 45 | destroyDiskStore(file); 46 | } else if (file.isFile()) { 47 | file.delete(); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | /** 55 | * Creates a new Request for destroying the local store. The request will not deliver anything. 56 | * 57 | * @param storeEnabler 58 | * The callback that will provide the memory and disk stores. 59 | */ 60 | EraseRequest(final RuntimeStoreEnabler storeEnabler) { 61 | super(new Callable() { 62 | @Override 63 | public Void call() throws Exception { 64 | destroyMemoryStore(storeEnabler.getMemoryStore()); 65 | 66 | // We have to synchronize at this point as the destroyDiskStore method is recursive 67 | // and we would otherwise cause a deadlock if synchronizing on the same lock inside 68 | // the method itself. 69 | synchronized (storeEnabler.getDiskStoreLock()) { 70 | destroyDiskStore(storeEnabler.getDiskStore()); 71 | } 72 | return null; 73 | } 74 | }); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/androidasynchttp/AndroidAsyncHttpClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.androidasynchttp; 3 | 4 | import android.content.Context; 5 | 6 | import com.loopj.android.http.AsyncHttpClient; 7 | import com.podio.sdk.Client; 8 | import com.podio.sdk.Filter; 9 | import com.podio.sdk.Request; 10 | import com.podio.sdk.provider.FileProvider; 11 | 12 | import java.io.File; 13 | 14 | import cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory; 15 | 16 | public class AndroidAsyncHttpClient implements Client { 17 | 18 | protected String scheme; 19 | protected String authority; 20 | 21 | private AsyncHttpClient client; 22 | private Context context; 23 | 24 | @Override 25 | public Request authenticateWithUserCredentials(String username, String password) { 26 | throw new UnsupportedOperationException("AndroidAsyncHttpClient only supports uploading to our Files API."); 27 | } 28 | 29 | @Override 30 | public Request authenticateWithAppCredentials(String appId, String appToken) { 31 | throw new UnsupportedOperationException("AndroidAsyncHttpClient only supports uploading to our Files API."); 32 | } 33 | 34 | @Override 35 | public Request authenticateWithTransferToken(String transferToken) { 36 | throw new UnsupportedOperationException("AndroidAsyncHttpClient only supports uploading to our Files API."); 37 | } 38 | 39 | @Override 40 | @Deprecated 41 | public Request forceRefreshTokens() { 42 | throw new UnsupportedOperationException("AndroidAsyncHttpClient only supports uploading to our Files API."); 43 | } 44 | 45 | @Override 46 | public Request request(Request.Method method, Filter filter, Object item, Class classOfResult) { 47 | if (filter instanceof FileProvider.FileFilter && method == Request.Method.POST && item instanceof File) { 48 | String url = filter.buildUri(scheme, authority).toString(); 49 | AndroidAsyncHttpRequest request = new AndroidAsyncHttpRequest<>(client, context, url, (File) item, classOfResult); 50 | request.performRequest(); 51 | 52 | return request; 53 | } else { 54 | throw new UnsupportedOperationException("AndroidAsyncHttpClient only supports uploading to our Files API."); 55 | } 56 | } 57 | 58 | public synchronized void setup(Context context, String scheme, String authority, String userAgent, SSLSocketFactory sslSocketFactory) { 59 | this.context = context; 60 | this.scheme = scheme; 61 | this.authority = authority; 62 | 63 | client = new AsyncHttpClient(); 64 | client.setTimeout(CLIENT_DEFAULT_TIMEOUT_MS); 65 | if (userAgent != null) { 66 | client.setUserAgent(userAgent); 67 | } 68 | if (sslSocketFactory != null) { 69 | client.setSSLSocketFactory(sslSocketFactory); 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/localstore/SetRequest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.localstore; 3 | 4 | import android.util.LruCache; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.concurrent.Callable; 9 | 10 | /** 11 | * A specific {@link com.podio.sdk.localstore.LocalStoreRequest LocalStoreRequest} implementation, 12 | * targeting the "store value" operation. This implementation adds a value to both the memory cache 13 | * as well as the disk cache, silently overwriting any previous values with the same key. If the 14 | * disk store isn't prepared yet, the disk write request will block until the disk store is ready. 15 | * 16 | */ 17 | final class SetRequest extends LocalStoreRequest { 18 | 19 | /** 20 | * Puts the given value in the memory cache and persists it in the disk store. If the disk store 21 | * isn't initialized yet, the disk write operation will block until it's prepared. Any previous 22 | * values are silently overwritten. 23 | * 24 | * @param storeEnabler 25 | * The callback that will provide the memory and disk stores. 26 | * @param key 27 | * The key of the value to store. 28 | * @param value 29 | * The value to store. 30 | * 31 | * @throws IOException 32 | * If the file system operation fails for some reason. 33 | */ 34 | private static void setValue(final RuntimeStoreEnabler storeEnabler, Object key, Object value) throws IOException { 35 | LruCache memoryStore = storeEnabler.getMemoryStore(); 36 | if (memoryStore == null) { 37 | throw new IllegalStateException("You're trying to write content to a closed store."); 38 | } 39 | 40 | memoryStore.put(key, value); 41 | 42 | // Update disk. Make sure we wait for the disk store to be ready before we start accessing 43 | // it. 44 | synchronized (storeEnabler.getDiskStoreLock()) { 45 | File diskStore = storeEnabler.getDiskStore(); 46 | if (isWritableDirectory(diskStore)) { 47 | String fileName = getFileName(key); 48 | File file = new File(diskStore, fileName); 49 | writeObjectToDisk(file, value); 50 | } 51 | } 52 | } 53 | 54 | /** 55 | * Creates a new request for storing a given value. 56 | * 57 | * @param storeEnabler 58 | * The callback that will provide the memory and disk stores. 59 | * @param key 60 | * The key of the value. 61 | * @param value 62 | * The value to store. 63 | */ 64 | SetRequest(final RuntimeStoreEnabler storeEnabler, final Object key, final Object value) { 65 | super(new Callable() { 66 | @Override 67 | public Void call() throws Exception { 68 | setValue(storeEnabler, key, value); 69 | return null; 70 | } 71 | }); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/StreamProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.ReferenceType; 8 | import com.podio.sdk.domain.stream.EventContext; 9 | 10 | /** 11 | * Enables access to the stream API end point. 12 | * 13 | */ 14 | public class StreamProvider extends Provider { 15 | 16 | static class StreamFilter extends Filter { 17 | 18 | protected StreamFilter() { 19 | super("stream"); 20 | } 21 | 22 | public StreamFilter withLimit(int limit) { 23 | this.addQueryParameter("limit", Integer.toString(limit, 10)); 24 | 25 | return this; 26 | } 27 | 28 | public StreamFilter withOffset(int offset) { 29 | this.addQueryParameter("offset", Integer.toString(offset, 10)); 30 | 31 | return this; 32 | } 33 | 34 | public StreamFilter withReference(ReferenceType type, long id) { 35 | this.addPathSegment(type.name()); 36 | this.addPathSegment(Long.toString(id, 10)); 37 | 38 | return this; 39 | } 40 | 41 | public StreamFilter withSpace(long spaceId) { 42 | this.addPathSegment("space"); 43 | this.addPathSegment(Long.toString(spaceId, 10)); 44 | 45 | return this; 46 | } 47 | } 48 | 49 | /** 50 | * Fetches the global stream. 51 | * 52 | * @param limit 53 | * @param offset 54 | * 55 | * @return A ticket which the caller can use to identify this request with. 56 | */ 57 | public Request getGlobalStream(int limit, int offset) { 58 | StreamFilter filter = new StreamFilter(); 59 | filter.withLimit(limit); 60 | filter.withOffset(offset); 61 | 62 | return get(filter, EventContext[].class); 63 | } 64 | 65 | /** 66 | * Fetches the global stream. 67 | * 68 | * @param limit 69 | * @param offset 70 | * @param spaceId The id of the space. 71 | * 72 | * @return A ticket which the caller can use to identify this request with. 73 | */ 74 | public Request getSpaceStream(long spaceId, int limit, int offset) { 75 | StreamFilter filter = new StreamFilter(); 76 | filter.withSpace(spaceId); 77 | filter.withLimit(limit); 78 | filter.withOffset(offset); 79 | 80 | return get(filter, EventContext[].class); 81 | } 82 | 83 | /** 84 | * Fetches a stream object based on the reference type and it's corresponding id. 85 | * 86 | * @param type 87 | * @param id 88 | * 89 | * @return A ticket which the caller can use to identify this request with. 90 | */ 91 | public Request getStreamObject(ReferenceType type, long id) { 92 | StreamFilter filter = new StreamFilter(); 93 | filter.withReference(type, id); 94 | 95 | return get(filter, EventContext.class); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/json/NotificationDeserializerSerializer.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.json; 2 | 3 | 4 | import com.google.gson.JsonDeserializationContext; 5 | import com.google.gson.JsonDeserializer; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonParseException; 9 | import com.google.gson.JsonSerializationContext; 10 | import com.google.gson.JsonSerializer; 11 | import com.podio.sdk.domain.notification.CommentNotification; 12 | import com.podio.sdk.domain.notification.GrantNotification; 13 | import com.podio.sdk.domain.notification.Notification; 14 | import com.podio.sdk.domain.notification.ParticipationNotification; 15 | import com.podio.sdk.domain.notification.RatingNotification; 16 | import com.podio.sdk.domain.notification.UnknownNotification; 17 | import com.podio.sdk.domain.notification.VoteNotification; 18 | import com.podio.sdk.internal.DefaultHashMap; 19 | 20 | import java.lang.reflect.Type; 21 | import java.util.Map; 22 | 23 | /** 24 | * Notifications contains a dynamic "data" part that can have different content depending on the 25 | * type of notifications so we need to have this deserializer/serializer to decide what kind of 26 | * notification we are handling. 27 | * 28 | */ 29 | class NotificationDeserializerSerializer implements JsonDeserializer, JsonSerializer { 30 | 31 | private Map> mNotificationClassesMap; 32 | 33 | public NotificationDeserializerSerializer() { 34 | mNotificationClassesMap = new DefaultHashMap>(UnknownNotification.class); 35 | mNotificationClassesMap.put(Notification.NotificationType.comment, CommentNotification.class); 36 | mNotificationClassesMap.put(Notification.NotificationType.rating, RatingNotification.class); 37 | mNotificationClassesMap.put(Notification.NotificationType.participation, ParticipationNotification.class); 38 | mNotificationClassesMap.put(Notification.NotificationType.vote, VoteNotification.class); 39 | mNotificationClassesMap.put(Notification.NotificationType.grant_create, GrantNotification.class); 40 | } 41 | 42 | @Override 43 | public Notification deserialize(JsonElement element, Type type, JsonDeserializationContext gsonContext) throws JsonParseException { 44 | if (element == null || element.isJsonNull()) { 45 | return null; 46 | } 47 | 48 | JsonObject jsonObject = element.getAsJsonObject(); 49 | 50 | Notification.NotificationType notificationType = Notification.NotificationType.getType(jsonObject.get("type").getAsString()); 51 | 52 | return gsonContext.deserialize(jsonObject, mNotificationClassesMap.get(notificationType)); 53 | } 54 | 55 | @Override 56 | public JsonElement serialize(Notification notification, Type typeOfSrc, JsonSerializationContext gsonContext) { 57 | return gsonContext.serialize(notification, mNotificationClassesMap.get(notification.getType())); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/domain/CalendarEventTest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import java.util.Calendar; 5 | import java.util.TimeZone; 6 | 7 | import android.test.AndroidTestCase; 8 | 9 | import com.google.gson.Gson; 10 | 11 | public class CalendarEventTest extends AndroidTestCase { 12 | 13 | 14 | public void testCalendarEventCanBeCreatedFromJson() { 15 | String json = new StringBuilder("{") 16 | .append("busy:true,") 17 | .append("start_utc:'2014-07-10 15:57:57',") 18 | .append("end_utc:'2014-07-10 15:58:12',") 19 | .append("title:'TITLE',") 20 | .append("description:'DESCRIPTION',") 21 | .append("location:'LOCATION'") 22 | .append("}").toString(); 23 | 24 | Gson gson = new Gson(); 25 | CalendarEvent event = gson.fromJson(json, CalendarEvent.class); 26 | 27 | assertNotNull(event); 28 | assertEquals(true, event.isBusy()); 29 | assertEquals("2014-07-10 15:57:57", event.getStartDateString()); 30 | 31 | Calendar startCalendar = Calendar.getInstance(); 32 | startCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); 33 | startCalendar.setTime(event.getStartDate()); 34 | 35 | assertEquals(2014, startCalendar.get(Calendar.YEAR)); 36 | assertEquals(Calendar.JULY, startCalendar.get(Calendar.MONTH)); 37 | assertEquals(10, startCalendar.get(Calendar.DAY_OF_MONTH)); 38 | assertEquals(15, startCalendar.get(Calendar.HOUR_OF_DAY)); 39 | assertEquals(57, startCalendar.get(Calendar.MINUTE)); 40 | assertEquals(57, startCalendar.get(Calendar.SECOND)); 41 | 42 | assertEquals("2014-07-10 15:58:12", event.getEndDateString()); 43 | 44 | Calendar endCalendar = Calendar.getInstance(); 45 | endCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); 46 | endCalendar.setTime(event.getEndDate()); 47 | 48 | assertEquals(2014, endCalendar.get(Calendar.YEAR)); 49 | assertEquals(Calendar.JULY, endCalendar.get(Calendar.MONTH)); 50 | assertEquals(10, endCalendar.get(Calendar.DAY_OF_MONTH)); 51 | assertEquals(15, endCalendar.get(Calendar.HOUR_OF_DAY)); 52 | assertEquals(58, endCalendar.get(Calendar.MINUTE)); 53 | assertEquals(12, endCalendar.get(Calendar.SECOND)); 54 | 55 | assertEquals("TITLE", event.getTitle()); 56 | assertEquals("DESCRIPTION", event.getDescription()); 57 | assertEquals("LOCATION", event.getLocation()); 58 | } 59 | 60 | public void testCalendarEventCanBeCreatedFromInstantiation() { 61 | CalendarEvent event = new CalendarEvent(); 62 | 63 | assertNotNull(event); 64 | assertEquals(false, event.isBusy()); 65 | assertEquals(null, event.getStartDateString()); 66 | assertEquals(null, event.getStartDate()); 67 | assertEquals(null, event.getEndDateString()); 68 | assertEquals(null, event.getEndDate()); 69 | assertEquals(null, event.getTitle()); 70 | assertEquals(null, event.getDescription()); 71 | assertEquals(null, event.getLocation()); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/domain/EmbedTest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import android.test.AndroidTestCase; 5 | 6 | import com.google.gson.Gson; 7 | 8 | public class EmbedTest extends AndroidTestCase { 9 | 10 | public void testEmbedCanBeCreatedFromJson() { 11 | String json = new StringBuilder("{") 12 | .append("embed_height:1,") 13 | .append("embed_id:1,") 14 | .append("embed_width:1,") 15 | .append("description:'DESCRIPTION',") 16 | .append("embed_html:'EMBEDHTML',") 17 | .append("hostname:'HOSTNAME',") 18 | .append("original_url:'ORIGINALURL',") 19 | .append("resolved_url:'RESOLVEDURL',") 20 | .append("title:'TITLE',") 21 | .append("url:'URL'") 22 | .append("}").toString(); 23 | 24 | Gson gson = new Gson(); 25 | Embed embed = gson.fromJson(json, Embed.class); 26 | 27 | assertNotNull(embed); 28 | assertEquals(1, embed.getHeight()); 29 | assertEquals(1, embed.getId()); 30 | assertEquals(1, embed.getWidth()); 31 | assertEquals("DESCRIPTION", embed.getDescription()); 32 | assertEquals("EMBEDHTML", embed.getHtml()); 33 | assertEquals("HOSTNAME", embed.getHostName()); 34 | assertEquals("ORIGINALURL", embed.getOriginalUrl()); 35 | assertEquals("RESOLVEDURL", embed.getResolvedUrl()); 36 | assertEquals("TITLE", embed.getTitle()); 37 | assertEquals("URL", embed.getUrl()); 38 | } 39 | 40 | 41 | public void testEmbedCanBeCreatedFromInstantiation() { 42 | Embed embed = new Embed("URL"); 43 | assertNotNull(embed); 44 | assertEquals(0, embed.getHeight()); 45 | assertEquals(-1, embed.getId()); 46 | assertEquals(0, embed.getWidth()); 47 | assertEquals(null, embed.getDescription()); 48 | assertEquals(null, embed.getHtml()); 49 | assertEquals(null, embed.getHostName()); 50 | assertEquals(null, embed.getOriginalUrl()); 51 | assertEquals(null, embed.getResolvedUrl()); 52 | assertEquals(null, embed.getTitle()); 53 | assertEquals("URL", embed.getUrl()); 54 | } 55 | 56 | public void testTypeEnumCanBeParsedFromJson() { 57 | Gson gson = new Gson(); 58 | Embed embed; 59 | 60 | embed = gson.fromJson("{type:'link'}", Embed.class); 61 | assertEquals(Embed.Type.link, embed.getType()); 62 | 63 | embed = gson.fromJson("{}", Embed.class); 64 | assertEquals(Embed.Type.undefined, embed.getType()); 65 | 66 | embed = gson.fromJson("{type:'fdafadsfads'}", Embed.class); 67 | assertEquals(Embed.Type.undefined, embed.getType()); 68 | } 69 | 70 | public void testValueOfType() { 71 | assertEquals(Embed.Type.link, Embed.Type.valueOf("link")); 72 | assertEquals(Embed.Type.undefined, Embed.Type.valueOf("undefined")); 73 | 74 | assertEquals(Embed.Type.link, Enum.valueOf(Embed.Type.class, "link")); 75 | assertEquals(Embed.Type.undefined, Enum.valueOf(Embed.Type.class, "undefined")); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/Request.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk; 3 | 4 | public interface Request { 5 | 6 | public static enum Method { 7 | DELETE, GET, POST, PUT 8 | } 9 | 10 | /** 11 | * Callback interface for error events. 12 | * 13 | */ 14 | public interface ErrorListener { 15 | 16 | /** 17 | * Delivers the cause of a request failure. The implementation must return boolean true if 18 | * the event is to be consumed (no subsequent listeners in the chain will be called) or 19 | * boolean false to allow bubbling of the event. 20 | * 21 | * @param cause 22 | * The cause of the error. 23 | * 24 | * @return Boolean flag whether the event is to be consumed or not by this implementation. 25 | */ 26 | public boolean onErrorOccurred(Throwable cause); 27 | 28 | } 29 | 30 | /** 31 | * Callback interface for successfully executed request events. 32 | * 33 | */ 34 | public interface ResultListener { 35 | 36 | /** 37 | * Delivers the result of a successfully performed request. The implementation must return 38 | * boolean true if the event is to be consumed (no subsequent listeners in the chain will be 39 | * called) or boolean false to allow bubbling of the event. 40 | * 41 | * @param content 42 | * The content that was requested. 43 | * 44 | * @return Boolean flag whether the event is to be consumed or not by this implementation. 45 | */ 46 | public boolean onRequestPerformed(E content); 47 | 48 | } 49 | 50 | /** 51 | * Callback interface for session change events. 52 | * 53 | */ 54 | public interface SessionListener { 55 | 56 | /** 57 | * Delivers the new session details on session change. The implementation must return 58 | * boolean true if the event is to be consumed (no subsequent listeners in the chain will be 59 | * called) or boolean false to allow bubbling of the event. 60 | * 61 | * @param authToken 62 | * The new access token. 63 | * @param refreshToken 64 | * The new refresh token. 65 | * @param transferToken 66 | * The new transfer token. 67 | * @param expires 68 | * The Unix epoch when the access token expires. 69 | * 70 | * @return Boolean flag whether the event is to be consumed or not by this implementation. 71 | */ 72 | public boolean onSessionChanged(String authToken, String refreshToken, String transferToken, long expires); 73 | 74 | } 75 | 76 | /** 77 | * Make sure to catch any thrown PodioError 78 | * @param maxSeconds 79 | * @return 80 | * @throws PodioError 81 | */ 82 | public T waitForResult(long maxSeconds) throws PodioError; 83 | 84 | public Request withResultListener(ResultListener contentListener); 85 | 86 | public Request withErrorListener(ErrorListener errorListener); 87 | 88 | public Request withSessionListener(SessionListener sessionListener); 89 | 90 | } 91 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/notification/Notification.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.notification; 3 | 4 | import com.podio.sdk.domain.Byline; 5 | import com.podio.sdk.internal.Utils; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * This class is the base class for all kinds of notifications. 11 | *

12 | * In most cases all information we are interested in is provided by this class so even if you are 13 | * getting notifications of type {@link UnknownNotification} there is still plenty of information 14 | * available in that one. 15 | * 16 | */ 17 | public abstract class Notification { 18 | /** 19 | * The field type enumeration. Each notification can have exactly one of these type values. 20 | */ 21 | public static enum NotificationType { 22 | comment, 23 | rating, 24 | participation, 25 | alert, 26 | team_alert, 27 | creation, 28 | update, 29 | delete, 30 | message, 31 | space_invite, 32 | space_delete, 33 | bulletin, 34 | member_reference_add, 35 | member_reference_remove, 36 | file, 37 | role_change, 38 | conversation_add, 39 | answer, 40 | self_kicked_from_space, 41 | space_create, 42 | meeting_participant_add, 43 | meeting_participant_remove, 44 | reminder, 45 | batch_process, 46 | batch_complete, 47 | space_member_request, 48 | grant_create, 49 | grant_delete, 50 | grant_create_other, 51 | grant_delete_other, 52 | reference, 53 | like, 54 | vote, 55 | item_transaction_confirmed, 56 | file_delete, 57 | unknown; // Custom value to handle errors. 58 | 59 | public static NotificationType getType(String type) { 60 | try { 61 | return NotificationType.valueOf(type); 62 | } catch (NullPointerException e) { 63 | return NotificationType.unknown; 64 | } catch (IllegalArgumentException e) { 65 | return NotificationType.unknown; 66 | } 67 | } 68 | } 69 | 70 | private final Long notification_id = null; 71 | private final String type = null; 72 | private final Byline created_by = null; 73 | private final String created_on = null; 74 | private final String text = null; 75 | private final String text_short = null; 76 | 77 | public long getNotificationId() { 78 | return Utils.getNative(notification_id, -1L); 79 | } 80 | 81 | public NotificationType getType() { 82 | return NotificationType.getType(type); 83 | } 84 | 85 | public Byline getCreatedBy() { 86 | return created_by; 87 | } 88 | 89 | public String getCreatedString() { 90 | return created_on; 91 | } 92 | 93 | public Date getCreatedDate() { 94 | return Utils.parseDateTimeUtc(created_on); 95 | } 96 | 97 | public String getText() { 98 | return text; 99 | } 100 | 101 | public String getTextShort() { 102 | return text_short; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/User.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import java.util.Date; 5 | 6 | import com.podio.sdk.internal.Utils; 7 | 8 | /** 9 | * A Java representation of the UserDTO API domain object. 10 | * 11 | */ 12 | public class User { 13 | 14 | public static enum Status { 15 | inactive, 16 | active, 17 | deleted, 18 | blocked, 19 | unknown 20 | } 21 | 22 | /** 23 | * A Java implementation of the UserMailDTO domain object. 24 | * 25 | */ 26 | public static class Email { 27 | private final Boolean disabled = null; 28 | private final Boolean primary = null; 29 | private final Boolean verified = null; 30 | private final String mail = null; 31 | 32 | public String getAddress() { 33 | return mail; 34 | } 35 | 36 | public boolean isDisabled() { 37 | return Utils.getNative(disabled, false); 38 | } 39 | 40 | public boolean isPrimary() { 41 | return Utils.getNative(primary, false); 42 | } 43 | 44 | public boolean isVerified() { 45 | return Utils.getNative(verified, false); 46 | } 47 | 48 | } 49 | 50 | private final Long user_id = null; 51 | private final String status = null; 52 | private final String created_on = null; 53 | private final String mail = null; 54 | private final Email[] mails = null; 55 | private final String locale = null; 56 | private final String timezone = null; 57 | 58 | @Override 59 | public boolean equals(Object o) { 60 | if (!(o instanceof User)) { 61 | return false; 62 | } 63 | 64 | User other = (User) o; 65 | long uid1 = Utils.getNative(user_id, -1); 66 | long uid2 = other.getUserId(); 67 | 68 | return uid1 == uid2 && uid1 != -1; 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | final int prime = 37; 74 | int result = 1; 75 | result = prime * result + (user_id != null ? user_id.hashCode() : 0); 76 | 77 | return result; 78 | } 79 | 80 | public Date getCreatedDate() { 81 | return Utils.parseDateTimeUtc(created_on); 82 | } 83 | 84 | public String getCreatedDateString() { 85 | return created_on; 86 | } 87 | 88 | public String getEmailAddress() { 89 | return mail; 90 | } 91 | 92 | public Email[] getEmails() { 93 | return mails != null ? mails.clone() : new Email[0]; 94 | } 95 | 96 | public long getUserId() { 97 | return Utils.getNative(user_id, -1L); 98 | } 99 | 100 | public String getLocale() { 101 | return locale; 102 | } 103 | 104 | public Status getStatus() { 105 | try { 106 | return Status.valueOf(status); 107 | } catch (NullPointerException e) { 108 | return Status.unknown; 109 | } catch (IllegalArgumentException e) { 110 | return Status.unknown; 111 | } 112 | } 113 | 114 | public String getTimezone() { 115 | return timezone; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/RatingProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | import com.podio.sdk.domain.Profile; 8 | import com.podio.sdk.domain.Rating; 9 | import com.podio.sdk.domain.ReferenceType; 10 | 11 | /** 12 | * Enables access to the Ratings API end point. 13 | */ 14 | public class RatingProvider extends Provider { 15 | 16 | static class RatingFilter extends Filter { 17 | 18 | protected RatingFilter() { 19 | super("rating"); 20 | } 21 | 22 | public RatingFilter withReference(ReferenceType type, long id) { 23 | this.addPathSegment(type.name()); 24 | this.addPathSegment(Long.toString(id, 10)); 25 | 26 | return this; 27 | } 28 | 29 | public RatingFilter withRatingType(Rating.RatingType ratingType) { 30 | this.addPathSegment(ratingType.name()); 31 | 32 | return this; 33 | } 34 | 35 | public RatingFilter likedBy() { 36 | this.addPathSegment("liked_by"); 37 | return this; 38 | } 39 | } 40 | 41 | /** 42 | * Create a like on a reference type with the given id. The request result will deliver a rating 43 | * object with only rating_id set. 44 | * 45 | * @param type 46 | * The reference type of what you are liking. 47 | * @param id 48 | * The id of the reference type your are liking. 49 | * 50 | * @return A ticket which the caller can use to identify this request with. 51 | */ 52 | public Request createLike(ReferenceType type, long id) { 53 | RatingFilter filter = new RatingFilter(); 54 | filter.withReference(type, id); 55 | filter.withRatingType(Rating.RatingType.like); 56 | Rating.Create create = new Rating.Create(1); 57 | 58 | return post(filter, create, Rating.class); 59 | } 60 | 61 | /** 62 | * Create an unlike on a reference type with the given id. The request result will deliver a 63 | * rating object with only rating_id set. 64 | * 65 | * @param type 66 | * The reference type of what you are unliking. 67 | * @param id 68 | * The id of the reference type your are unliking. 69 | * 70 | * @return A ticket which the caller can use to identify this request with. 71 | */ 72 | public Request createUnlike(ReferenceType type, long id) { 73 | RatingFilter filter = new RatingFilter(); 74 | filter.withReference(type, id); 75 | filter.withRatingType(Rating.RatingType.like); 76 | 77 | return delete(filter); 78 | } 79 | 80 | /** 81 | * get a list of profiles of everyone that liked the given object. 82 | * 83 | * @param type 84 | * The reference type of what of the object. 85 | * @param id 86 | * The id of the reference type of the object. 87 | * 88 | * @return A ticket which the caller can use to identify this request with. 89 | */ 90 | public Request getWhoLikedAnObject(ReferenceType type, long id) { 91 | RatingFilter filter = new RatingFilter(); 92 | filter.withReference(type, id); 93 | filter.likedBy(); 94 | 95 | return get(filter, Profile[].class); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/provider/ClientProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.provider; 3 | 4 | import com.podio.sdk.Filter; 5 | import com.podio.sdk.Provider; 6 | import com.podio.sdk.Request; 7 | 8 | /** 9 | * A Provider implementation that offers means of authenticating with the Podio API. This provider 10 | * doesn't provide any content, but rather the login service. 11 | * 12 | */ 13 | public class ClientProvider extends Provider { 14 | 15 | /** 16 | * Enables means of user authentication, where the caller authenticates with a user name and a 17 | * password. 18 | * 19 | * @param username 20 | * The user name to log in with. 21 | * @param password 22 | * The corresponding password. 23 | * 24 | * @return A request future, enabling the caller to hook in optional callback implementations. 25 | */ 26 | public Request authenticateWithUserCredentials(String username, String password) { 27 | return client.authenticateWithUserCredentials(username, password); 28 | } 29 | 30 | /** 31 | * Enables means of user authentication, where the caller authenticates with a Podio app id and 32 | * app token. 33 | * 34 | * @param appId 35 | * The app id to log in with. 36 | * @param appToken 37 | * The corresponding app token. 38 | * 39 | * @return A request future, enabling the caller to hook in optional callback implementations. 40 | */ 41 | public Request authenticateWithAppCredentials(String appId, String appToken) { 42 | return client.authenticateWithAppCredentials(appId, appToken); 43 | } 44 | 45 | /** 46 | * Enables means of user authentication, where the caller authenticates with a previously issued 47 | * transfer token. 48 | * 49 | * @param transferToken 50 | * The transfer token to log in with. 51 | * 52 | * @return A request future, enabling the caller to hook in optional callback implementations. 53 | */ 54 | public Request authenticateWithTransferToken(String transferToken) { 55 | return client.authenticateWithTransferToken(transferToken); 56 | } 57 | 58 | @Override 59 | protected Request delete(Filter filter) { 60 | throw new UnsupportedOperationException("This implementation can't manipulate content."); 61 | } 62 | 63 | /** 64 | * Enables means of forcing a refresh of auth tokens. *DEPRECATED* This call may interfere with 65 | * the internal execution flow of the SDK and should be avoided at all cost. 66 | */ 67 | @Deprecated 68 | public Request forceRefreshTokens() { 69 | return client.forceRefreshTokens(); 70 | } 71 | 72 | @Override 73 | protected Request get(Filter filter, Class classOfResult) { 74 | throw new UnsupportedOperationException("This implementation can't manipulate content."); 75 | } 76 | 77 | @Override 78 | protected Request post(Filter filter, Object item, Class classOfItem) { 79 | throw new UnsupportedOperationException("This implementation can't manipulate content."); 80 | } 81 | 82 | @Override 83 | protected Request put(Filter filter, Object item, Class classOfItem) { 84 | throw new UnsupportedOperationException("This implementation can't manipulate content."); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/field/LinkedAccountDataField.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain.field; 2 | 3 | import com.podio.sdk.internal.Utils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** 11 | * Created by sai on 8/31/16. 12 | */ 13 | public class LinkedAccountDataField extends Field { 14 | 15 | public static final String NAME = "linked_account"; 16 | public static class Value extends Field.Value { 17 | private final String url; 18 | private final String info; 19 | private final String type; 20 | private final String id; 21 | 22 | public Value(String url, String info, String type, String id) { 23 | this.url = url; 24 | this.info = info; 25 | this.type = type; 26 | this.id = id; 27 | } 28 | 29 | @Override 30 | public Map getCreateData() { 31 | HashMap data = null; 32 | 33 | if(Utils.notEmpty(url) && Utils.notEmpty(id)) { 34 | data = new HashMap<>(); 35 | data.put("url", url); 36 | data.put("info", info); 37 | data.put("type", type); 38 | data.put("id", id); 39 | } 40 | return data; 41 | } 42 | 43 | public Long getLinkedAccountId() { 44 | if(id == null || id.equalsIgnoreCase("null")) { 45 | return null; 46 | } 47 | return Long.parseLong(id); 48 | } 49 | 50 | public String getUrl(){ 51 | return url; 52 | } 53 | 54 | public String getInfo() { 55 | return info; 56 | } 57 | 58 | public String getType() { 59 | return type; 60 | } 61 | 62 | public String getId() { 63 | return id; 64 | } 65 | } 66 | 67 | private final ArrayList values; 68 | 69 | public LinkedAccountDataField() { 70 | super(NAME); 71 | this.values = new ArrayList<>(); 72 | } 73 | 74 | @Override 75 | public void setValues(List values) { 76 | this.values.clear(); 77 | this.values.addAll(values); 78 | } 79 | 80 | @Override 81 | public void addValue(Value value) { 82 | if (values != null && !values.contains(value)) { 83 | values.clear(); 84 | values.add(value); 85 | } 86 | } 87 | 88 | @Override 89 | public Value getValue(int index) { 90 | return values != null ? values.get(index) : null; 91 | } 92 | 93 | @Override 94 | public List getValues() { 95 | return values; 96 | } 97 | 98 | @Override 99 | public void removeValue(Value value) { 100 | if (values != null && values.contains(value)) { 101 | values.remove(value); 102 | } 103 | } 104 | 105 | @Override 106 | public void clearValues() { 107 | values.clear(); 108 | } 109 | 110 | @Override 111 | public int valuesCount() { 112 | return values != null ? values.size() : 0; 113 | } 114 | 115 | @Override 116 | public Type getType() { 117 | return Type.linked_account_data; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Status.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.domain.data.Data; 5 | import com.podio.sdk.internal.Utils; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | /** 12 | * A Java representation of the StatusDTO API domain object. 13 | * 14 | */ 15 | public class Status implements Data{ 16 | 17 | /** 18 | * A class representing the new status message the client wants to create 19 | */ 20 | public static class PushData { 21 | private final String value; 22 | private final List file_ids; 23 | 24 | public PushData(String value, List fileIds){ 25 | this.value = value; 26 | this.file_ids = new ArrayList<>(fileIds); 27 | } 28 | 29 | public String getValue() { 30 | return value; 31 | } 32 | 33 | public List getFileIds() { 34 | return file_ids; 35 | } 36 | } 37 | 38 | private final Long status_id = null; 39 | private final String created_on = null; 40 | private final String value = null; 41 | private final String rich_value = null; 42 | private final List files = null; 43 | private final List rights = null; 44 | private final Byline created_by = null; 45 | private final Integer like_count = null; 46 | private Boolean is_liked = null; 47 | private Embed embed = null; 48 | private File embed_file = null; 49 | 50 | public String getRichValue() { 51 | return rich_value; 52 | } 53 | 54 | public String getValue() { 55 | return value; 56 | } 57 | 58 | public List getFiles() { 59 | return files; 60 | } 61 | 62 | /** 63 | * Checks whether the list of rights the user has for this comment contains all the 64 | * given permissions. 65 | * 66 | * @param permissions 67 | * The list of permissions to check for. 68 | * 69 | * @return Boolean true if all given permissions are found or no permissions are given. Boolean 70 | * false otherwise. 71 | */ 72 | public boolean hasRights(Right... permissions) { 73 | if (rights != null) { 74 | for (Right permission : permissions) { 75 | if (!rights.contains(permission)) { 76 | return false; 77 | } 78 | } 79 | 80 | return true; 81 | } 82 | 83 | return false; 84 | } 85 | 86 | public long getStatusId() { 87 | return Utils.getNative(status_id, -1L); 88 | } 89 | 90 | public Byline getCreatedBy() { 91 | return created_by; 92 | } 93 | 94 | public Date getCreatedOnDate() { 95 | return Utils.parseDateTimeUtc(created_on); 96 | } 97 | 98 | public String getCreatedOnString() { 99 | return created_on; 100 | } 101 | 102 | public Integer getLikeCount() { 103 | return Utils.getNative(like_count, 0); 104 | } 105 | 106 | public Boolean isLiked() { 107 | return is_liked; 108 | } 109 | 110 | /** 111 | * Note that embed file contains a subset of FileDTO attributes so many of these attributes may 112 | * be null. 113 | * 114 | * @return 115 | */ 116 | public File getEmbedFile() { 117 | return embed_file; 118 | } 119 | 120 | public Embed getEmbed() { 121 | return embed; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/json/EventActivityDeserializerSerializer.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.json; 3 | 4 | import com.google.gson.JsonDeserializationContext; 5 | import com.google.gson.JsonDeserializer; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonParseException; 9 | import com.google.gson.JsonSerializationContext; 10 | import com.google.gson.JsonSerializer; 11 | import com.podio.sdk.domain.ReferenceType; 12 | import com.podio.sdk.domain.stream.EventActivity; 13 | import com.podio.sdk.domain.stream.FileEventActivity; 14 | import com.podio.sdk.domain.stream.GrantEventActivity; 15 | import com.podio.sdk.domain.stream.ItemEventActivity; 16 | import com.podio.sdk.domain.stream.ItemParticipationEventActivity; 17 | import com.podio.sdk.domain.stream.QuestionAnswerEventActivity; 18 | import com.podio.sdk.domain.stream.RatingEventActivity; 19 | import com.podio.sdk.domain.stream.TaskActionEventActivity; 20 | import com.podio.sdk.domain.stream.TaskEventActivity; 21 | import com.podio.sdk.domain.stream.UnknownEventActivity; 22 | import com.podio.sdk.domain.stream.VoteEventActivity; 23 | import com.podio.sdk.internal.DefaultHashMap; 24 | 25 | import java.lang.reflect.Type; 26 | import java.util.Map; 27 | 28 | /** 29 | * EventActivity contains a dynamic "data" part that can have different content depending on the 30 | * type of activity so we need to have this deserializer/serializer to decide what kind of activity 31 | * we are handling. 32 | * 33 | */ 34 | class EventActivityDeserializerSerializer implements JsonDeserializer, JsonSerializer { 35 | 36 | private Map> mEventActivityClassesMap; 37 | 38 | public EventActivityDeserializerSerializer() { 39 | mEventActivityClassesMap = new DefaultHashMap>(UnknownEventActivity.class); 40 | mEventActivityClassesMap.put(ReferenceType.grant, GrantEventActivity.class); 41 | mEventActivityClassesMap.put(ReferenceType.item, ItemEventActivity.class); 42 | mEventActivityClassesMap.put(ReferenceType.item_participation, ItemParticipationEventActivity.class); 43 | mEventActivityClassesMap.put(ReferenceType.question_answer, QuestionAnswerEventActivity.class); 44 | mEventActivityClassesMap.put(ReferenceType.rating, RatingEventActivity.class); 45 | mEventActivityClassesMap.put(ReferenceType.task_action, TaskActionEventActivity.class); 46 | mEventActivityClassesMap.put(ReferenceType.task, TaskEventActivity.class); 47 | mEventActivityClassesMap.put(ReferenceType.vote, VoteEventActivity.class); 48 | mEventActivityClassesMap.put(ReferenceType.file, FileEventActivity.class); 49 | } 50 | 51 | @Override 52 | public EventActivity deserialize(JsonElement element, Type type, JsonDeserializationContext gsonContext) throws JsonParseException { 53 | if (element == null || element.isJsonNull()) { 54 | return null; 55 | } 56 | 57 | JsonObject jsonObject = element.getAsJsonObject(); 58 | ReferenceType referenceType = ReferenceType.getType(jsonObject.get("type").getAsString()); 59 | 60 | return gsonContext.deserialize(jsonObject, mEventActivityClassesMap.get(referenceType)); 61 | } 62 | 63 | @Override 64 | public JsonElement serialize(EventActivity eventActivity, Type typeOfSrc, JsonSerializationContext gsonContext) { 65 | return gsonContext.serialize(eventActivity, mEventActivityClassesMap.get(eventActivity.getType())); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/volley/VolleyCallbackManager.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.volley; 3 | 4 | import com.podio.sdk.Request.SessionListener; 5 | import com.podio.sdk.Session; 6 | import com.podio.sdk.internal.CallbackManager; 7 | 8 | import java.util.ArrayList; 9 | 10 | final class VolleyCallbackManager extends CallbackManager { 11 | static final ArrayList GLOBAL_SESSION_LISTENERS; 12 | 13 | static { 14 | GLOBAL_SESSION_LISTENERS = new ArrayList(); 15 | } 16 | 17 | static SessionListener addGlobalSessionListener(SessionListener sessionListener) { 18 | return sessionListener != null && GLOBAL_SESSION_LISTENERS.add(sessionListener) ? 19 | sessionListener : 20 | null; 21 | } 22 | 23 | static SessionListener removeGlobalSessionListener(SessionListener sessionListener) { 24 | int index = GLOBAL_SESSION_LISTENERS.indexOf(sessionListener); 25 | 26 | return GLOBAL_SESSION_LISTENERS.contains(sessionListener) ? 27 | GLOBAL_SESSION_LISTENERS.remove(index) : 28 | null; 29 | } 30 | 31 | private final ArrayList sessionListeners; 32 | private final Object SESSION_LISTENER_LOCK = new Object(); 33 | 34 | VolleyCallbackManager() { 35 | this.sessionListeners = new ArrayList(); 36 | } 37 | 38 | void addSessionListener(SessionListener listener, boolean deliverSessionNow) { 39 | if (listener != null) { 40 | if (deliverSessionNow) { 41 | listener.onSessionChanged(Session.accessToken(), Session.refreshToken(), Session.transferToken(), Session.expires()); 42 | } else { 43 | synchronized (SESSION_LISTENER_LOCK) { 44 | sessionListeners.add(listener); 45 | } 46 | } 47 | } 48 | } 49 | 50 | void deliverSession() { 51 | String accessToken = Session.accessToken(); 52 | String refreshToken = Session.refreshToken(); 53 | String transferToken = Session.transferToken(); 54 | long expires = Session.expires(); 55 | 56 | synchronized (SESSION_LISTENER_LOCK) { 57 | boolean isConsumed = false; 58 | for (SessionListener listener : sessionListeners) { 59 | if (listener != null) { 60 | if (listener.onSessionChanged(accessToken, refreshToken, transferToken, expires)) { 61 | // The callback consumed the event, stop the bubbling. 62 | isConsumed = true; 63 | break; 64 | } 65 | } 66 | } 67 | 68 | sessionListeners.clear(); 69 | if (isConsumed) { 70 | return; 71 | } 72 | } 73 | 74 | for (SessionListener listener : GLOBAL_SESSION_LISTENERS) { 75 | if (listener != null) { 76 | if (listener.onSessionChanged(accessToken, refreshToken, transferToken, expires)) { 77 | // The callback consumed the event, stop the bubbling. 78 | return; 79 | } 80 | } 81 | } 82 | } 83 | 84 | SessionListener removeSessionListener(SessionListener listener) { 85 | synchronized (SESSION_LISTENER_LOCK) { 86 | if (sessionListeners.contains(listener)) { 87 | int index = sessionListeners.indexOf(listener); 88 | return sessionListeners.remove(index); 89 | } 90 | 91 | return null; 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/field/ProgressField.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain.field; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | */ 13 | public class ProgressField extends Field { 14 | /** 15 | * This class describes the particular settings of a Progress field configuration. 16 | * 17 | */ 18 | private static class Settings { 19 | } 20 | 21 | /** 22 | * This class describes the specific configuration of a Progress field. 23 | * 24 | */ 25 | public static class Configuration extends Field.Configuration { 26 | private final Value default_value = null; 27 | private final Settings settings = null; 28 | 29 | public Value getDefaultValue() { 30 | return default_value; 31 | } 32 | } 33 | 34 | /** 35 | * This class describes a Progress field value. 36 | * 37 | */ 38 | public static class Value extends Field.Value { 39 | private final Integer value; 40 | 41 | public Value(int value) { 42 | this.value = value; 43 | } 44 | 45 | @Override 46 | public boolean equals(Object o) { 47 | if (o instanceof Value) { 48 | Value other = (Value) o; 49 | return Utils.getNative(other.value, -1) == Utils.getNative(this.value, -1); 50 | } 51 | return false; 52 | } 53 | 54 | @Override 55 | public Map getCreateData() { 56 | HashMap data = null; 57 | 58 | if (value != null) { 59 | data = new HashMap(); 60 | data.put("value", value); 61 | } 62 | 63 | return data; 64 | } 65 | 66 | @Override 67 | public int hashCode() { 68 | return Utils.getNative(this.value, 0); 69 | } 70 | 71 | public int getValue() { 72 | return Utils.getNative(this.value, -1); 73 | } 74 | } 75 | 76 | // Private fields. 77 | private final Configuration config = null; 78 | private final ArrayList values; 79 | 80 | public ProgressField(String externalId) { 81 | super(externalId); 82 | this.values = new ArrayList(); 83 | } 84 | 85 | @Override 86 | public void setValues(List values) { 87 | this.values.clear(); 88 | this.values.addAll(values); 89 | } 90 | 91 | @Override 92 | public void addValue(Value value) { 93 | if (values != null && !values.contains(value)) { 94 | values.clear(); 95 | values.add(0,value); 96 | } 97 | } 98 | 99 | @Override 100 | public Value getValue(int index) { 101 | return values != null ? values.get(index) : null; 102 | } 103 | 104 | @Override 105 | public List getValues() { 106 | return values; 107 | } 108 | 109 | @Override 110 | public void removeValue(Value value) { 111 | if (values != null && values.contains(value)) { 112 | values.remove(value); 113 | } 114 | } 115 | 116 | @Override 117 | public void clearValues() { 118 | values.clear(); 119 | } 120 | 121 | @Override 122 | public int valuesCount() { 123 | return values != null ? values.size() : 0; 124 | } 125 | 126 | public Configuration getConfiguration() { 127 | return config; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/json/ReferenceGroupDeserializerSerializer.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package com.podio.sdk.json; 4 | 5 | import com.google.gson.JsonDeserializationContext; 6 | import com.google.gson.JsonDeserializer; 7 | import com.google.gson.JsonElement; 8 | import com.google.gson.JsonObject; 9 | import com.google.gson.JsonParseException; 10 | import com.google.gson.JsonSerializationContext; 11 | import com.google.gson.JsonSerializer; 12 | import com.podio.sdk.domain.reference.AppReferenceGroup; 13 | import com.podio.sdk.domain.reference.AppsReferenceGroup; 14 | import com.podio.sdk.domain.reference.OrganisationTagReferenceGroup; 15 | import com.podio.sdk.domain.reference.ProfilesReferenceGroup; 16 | import com.podio.sdk.domain.reference.ReferenceGroup; 17 | import com.podio.sdk.domain.reference.SpaceContactsSpaceMembersReferenceGroup; 18 | import com.podio.sdk.domain.reference.SpacesReferenceGroup; 19 | import com.podio.sdk.domain.reference.TasksReferenceGroup; 20 | import com.podio.sdk.domain.reference.UnknownReferenceGroup; 21 | import com.podio.sdk.internal.DefaultHashMap; 22 | 23 | import java.lang.reflect.Type; 24 | import java.util.Map; 25 | 26 | /** 27 | * Reference groups contains a dynamic "data" and "contents" part that can have different content 28 | * depending on the name of the group so we need to have this deserializer/serializer to decide what 29 | * kind of group we are handling. 30 | * 31 | */ 32 | class ReferenceGroupDeserializerSerializer implements JsonDeserializer, JsonSerializer { 33 | 34 | private Map> referenceGroupNameClassesMap; 35 | 36 | public ReferenceGroupDeserializerSerializer() { 37 | referenceGroupNameClassesMap = new DefaultHashMap>(UnknownReferenceGroup.class); 38 | referenceGroupNameClassesMap.put(ReferenceGroup.ReferenceGroupName.space_contacts, SpaceContactsSpaceMembersReferenceGroup.class); 39 | referenceGroupNameClassesMap.put(ReferenceGroup.ReferenceGroupName.space_members, SpaceContactsSpaceMembersReferenceGroup.class); 40 | referenceGroupNameClassesMap.put(ReferenceGroup.ReferenceGroupName.spaces, SpacesReferenceGroup.class); 41 | referenceGroupNameClassesMap.put(ReferenceGroup.ReferenceGroupName.app, AppReferenceGroup.class); 42 | referenceGroupNameClassesMap.put(ReferenceGroup.ReferenceGroupName.profiles, ProfilesReferenceGroup.class); 43 | referenceGroupNameClassesMap.put(ReferenceGroup.ReferenceGroupName.tasks, TasksReferenceGroup.class); 44 | referenceGroupNameClassesMap.put(ReferenceGroup.ReferenceGroupName.apps, AppsReferenceGroup.class); 45 | referenceGroupNameClassesMap.put(ReferenceGroup.ReferenceGroupName.tag_field, OrganisationTagReferenceGroup.class); 46 | } 47 | 48 | @Override 49 | public ReferenceGroup deserialize(JsonElement element, Type type, JsonDeserializationContext gsonContext) throws JsonParseException { 50 | if (element == null || element.isJsonNull()) { 51 | return null; 52 | } 53 | 54 | JsonObject jsonObject = element.getAsJsonObject(); 55 | ReferenceGroup.ReferenceGroupName referenceGroupName = ReferenceGroup.ReferenceGroupName.getReferenceGroupName(jsonObject.get("name").getAsString()); 56 | 57 | return gsonContext.deserialize(jsonObject, referenceGroupNameClassesMap.get(referenceGroupName)); 58 | } 59 | 60 | @Override 61 | public JsonElement serialize(ReferenceGroup referenceGroup, Type typeOfSrc, JsonSerializationContext gsonContext) { 62 | return gsonContext.serialize(referenceGroup, referenceGroupNameClassesMap.get(referenceGroup.getName())); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/podio/sdk/domain/Grant.java: -------------------------------------------------------------------------------- 1 | 2 | package com.podio.sdk.domain; 3 | 4 | import com.podio.sdk.internal.Utils; 5 | 6 | import java.util.Date; 7 | import java.util.List; 8 | 9 | /** 10 | * A Java representation of the GrantDTO API domain object. 11 | * 12 | */ 13 | public class Grant { 14 | private final Application app = null; 15 | private final Byline created_by = null; 16 | private final List rights = null; 17 | private final Long grant_id = null; 18 | private final Space space = null; 19 | private final String action = null; 20 | private final String created_on = null; 21 | private final String message = null; 22 | private final Profile user = null; 23 | 24 | // These attributes are defined in the API source code, 25 | // but not supported by the SDK right now. 26 | //private final Object access_level = null; 27 | //private final Object ref = null; 28 | 29 | public String getAction() { 30 | return action; 31 | } 32 | 33 | public Application getApp() { 34 | return app; 35 | } 36 | 37 | public Byline getCreatedBy() { 38 | return created_by; 39 | } 40 | 41 | public Date getCreatedDate() { 42 | return Utils.parseDateTimeUtc(created_on); 43 | } 44 | 45 | public String getCreatedDateString() { 46 | return created_on; 47 | } 48 | 49 | public long getGrantId() { 50 | return Utils.getNative(grant_id, -1L); 51 | } 52 | 53 | public String getMessage() { 54 | return message; 55 | } 56 | 57 | public Space getSpace() { 58 | return space; 59 | } 60 | 61 | public Profile getUser() { 62 | return user; 63 | } 64 | 65 | /** 66 | * Checks whether the list of rights the user has for this grant contains all the given 67 | * permissions. 68 | * 69 | * @param rights 70 | * The list of permissions to check for. 71 | * 72 | * @return Boolean true if all given permissions are granted for this Grant. Boolean false 73 | * otherwise. 74 | */ 75 | public boolean hasAllRights(Right... rights) { 76 | if (Utils.isEmpty(this.rights) && Utils.isEmpty(rights)) { 77 | // The user has no rights and wants to verify that. 78 | return true; 79 | } 80 | 81 | if (Utils.notEmpty(this.rights) && Utils.notEmpty(rights)) { 82 | for (Right right : rights) { 83 | if (!this.rights.contains(right.name())) { 84 | return false; 85 | } 86 | } 87 | return true; 88 | } 89 | 90 | return false; 91 | } 92 | 93 | /** 94 | * Checks whether the list of rights the user has for this grant contains any of the 95 | * given permissions. 96 | * 97 | * @param rights 98 | * The list of permissions to check any single one for. 99 | * 100 | * @return Boolean true if any given permission is granted for this Grant. Boolean false 101 | * otherwise. 102 | */ 103 | public boolean hasAnyRights(Right... rights) { 104 | if (Utils.isEmpty(this.rights) && Utils.isEmpty(rights)) { 105 | // The user has no rights and wants to verify that. 106 | return true; 107 | } 108 | 109 | if (Utils.notEmpty(this.rights) && Utils.notEmpty(rights)) { 110 | for (Right right : rights) { 111 | if (this.rights.contains(right.name())) { 112 | return true; 113 | } 114 | } 115 | } 116 | 117 | return false; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /sdk/src/androidTest/java/com/podio/sdk/domain/UserProfileTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.sdk.domain; 2 | 3 | import java.util.Calendar; 4 | import java.util.TimeZone; 5 | 6 | import android.test.AndroidTestCase; 7 | 8 | import com.google.gson.Gson; 9 | 10 | 11 | public class UserProfileTest extends AndroidTestCase { 12 | 13 | public void testUserProfileCanBeCreatedFromJson() { 14 | String json = new StringBuilder("{") 15 | .append("image:{},") 16 | .append("avatar:1,") 17 | .append("org_id:1,") 18 | .append("profile_id:1,") 19 | .append("space_id:1,") 20 | .append("user_id:1,") 21 | .append("location:['LOCATION'],") 22 | .append("mail:['MAIL'],") 23 | .append("phone:['PHONE'],") 24 | .append("rights:['view'],") 25 | .append("title:['TITLE'],") 26 | .append("about:'ABOUT',") 27 | .append("external_id:'EXTERNALID',") 28 | .append("link:'LINK',") 29 | .append("last_seen_on:'2014-07-10 14:13:39',") 30 | .append("name:'NAME'") 31 | .append("}").toString(); 32 | 33 | Gson gson = new Gson(); 34 | Profile profile = gson.fromJson(json, Profile.class); 35 | 36 | assertNotNull(profile); 37 | assertNotNull(profile.getImage()); 38 | assertEquals(1L, profile.getOrganizationId()); 39 | assertEquals(1L, profile.getId()); 40 | assertEquals(1L, profile.getWorkspaceId()); 41 | assertEquals(1L, profile.getUserId()); 42 | 43 | String[] locations = profile.getLocations(); 44 | assertNotNull(locations); 45 | assertEquals(1, locations.length); 46 | assertEquals("LOCATION", locations[0]); 47 | 48 | String[] emails = profile.getEmailAddresses(); 49 | assertNotNull(emails); 50 | assertEquals(1, emails.length); 51 | assertEquals("MAIL", emails[0]); 52 | 53 | String[] phones = profile.getPhoneNumbers(); 54 | assertNotNull(phones); 55 | assertEquals(1, phones.length); 56 | assertEquals("PHONE", phones[0]); 57 | 58 | String[] titles = profile.getTitles(); 59 | assertNotNull(titles); 60 | assertEquals(1, titles.length); 61 | assertEquals("TITLE", titles[0]); 62 | 63 | assertEquals("ABOUT", profile.getAbout()); 64 | assertEquals("EXTERNALID", profile.getExternalId()); 65 | assertEquals("LINK", profile.getLink()); 66 | assertEquals("2014-07-10 14:13:39", profile.getLastSeenDateString()); 67 | 68 | Calendar lastSeenCalendar = Calendar.getInstance(); 69 | lastSeenCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); 70 | lastSeenCalendar.setTime(profile.getLastSeenDate()); 71 | 72 | assertEquals(2014, lastSeenCalendar.get(Calendar.YEAR)); 73 | assertEquals(Calendar.JULY, lastSeenCalendar.get(Calendar.MONTH)); 74 | assertEquals(10, lastSeenCalendar.get(Calendar.DAY_OF_MONTH)); 75 | assertEquals(14, lastSeenCalendar.get(Calendar.HOUR_OF_DAY)); 76 | assertEquals(13, lastSeenCalendar.get(Calendar.MINUTE)); 77 | assertEquals(39, lastSeenCalendar.get(Calendar.SECOND)); 78 | 79 | assertEquals("NAME", profile.getName()); 80 | } 81 | 82 | public void testListsNeverNull() { 83 | Gson gson = new Gson(); 84 | Profile profile = gson.fromJson("{}", Profile.class); 85 | 86 | assertEquals(false, profile.hasRight(Right.view)); 87 | assertEquals(0, profile.getLocations().length); 88 | assertEquals(0, profile.getEmailAddresses().length); 89 | assertEquals(0, profile.getPhoneNumbers().length); 90 | assertEquals(0, profile.getTitles().length); 91 | } 92 | } 93 | --------------------------------------------------------------------------------