diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/ApiVersion.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/ApiVersion.java
index 9723152..f5e37f7 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/ApiVersion.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/ApiVersion.java
@@ -10,7 +10,8 @@ public enum ApiVersion {
VERSION_5_7("5.7"),
VERSION_5_8("5.8"),
VERSION_5_21("5.21"),
- VERSION_5_27("5.27");
+ VERSION_5_27("5.27"),
+ VERSION_5_33("5.33");
private String version;
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Audio.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Audio.java
index 628b7e9..ed3f9c4 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Audio.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Audio.java
@@ -18,7 +18,7 @@
import java.io.Serializable;
/**
- * Model class representing audio.
+ * Model class representing audio.
* See definition of this object at http://vk.com/dev/audio_object
*
* @author vkolodrevskiy
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Comment.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Comment.java
new file mode 100644
index 0000000..b601782
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Comment.java
@@ -0,0 +1,66 @@
+package org.springframework.social.vkontakte.api;
+
+import org.springframework.social.vkontakte.api.attachment.Attachment;
+import org.springframework.util.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Model class representing a comment on a post on a user wall or community wall.
+ *
+ * @see Comment object | Developers | VK
+ */
+public class Comment {
+ private long id;
+ private long fromId;
+ private Date date;
+ private String text;
+ private long replyToUser;
+ private long replyToComment;
+ private Post.Likes likes;
+ private List extends Attachment> attachments;
+
+ public long getFromId() {
+ return fromId;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public long getReplyToUser() {
+ return replyToUser;
+ }
+
+ public long getReplyToComment() {
+ return replyToComment;
+ }
+
+ public Post.Likes getLikes() {
+ return likes;
+ }
+
+ public List extends Attachment> getAttachments() {
+ return attachments;
+ }
+
+ @Override
+ public String toString() {
+ return "Comment{" +
+ "id='" + id + '\'' +
+ ", date=" + date +
+ ", text='" + text + '\'' +
+ ", likes=" + likes +
+ ", attachments=" + (attachments == null ? null : StringUtils.collectionToDelimitedString(attachments, ",\n")) +
+ '}';
+ }
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/CommentsResponse.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/CommentsResponse.java
new file mode 100644
index 0000000..34ace75
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/CommentsResponse.java
@@ -0,0 +1,42 @@
+package org.springframework.social.vkontakte.api;
+
+import org.springframework.social.vkontakte.api.impl.wall.CommentsQuery;
+
+import java.util.List;
+
+/**
+ * Model class representing a response that contains a list of comments on a post on a user wall or community wall.
+ *
+ * @see IWallOperations#getComments(CommentsQuery)
+ */
+public class CommentsResponse {
+ private final long count;
+ private final List comments;
+ private final List profiles;
+ private final List groups;
+ private final Long realOffset;
+
+ public CommentsResponse(List comments, long count, Long realOffset, List profiles, List groups) {
+ this.comments = comments;
+ this.count = count;
+ this.realOffset = realOffset;
+ this.groups = groups;
+ this.profiles = profiles;
+ }
+
+ public long getCount() {
+ return count;
+ }
+
+ public long getRealOffset() {
+ return realOffset;
+ }
+
+ public List getComments() {
+ return comments;
+ }
+
+ public List getProfiles() {
+ return profiles;
+ }
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Counters.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Counters.java
new file mode 100644
index 0000000..d1c4deb
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/Counters.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2011-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.social.vkontakte.api;
+
+/**
+ * Counters.
+ * https://vk.com/dev/fields
+ *
+ * @author dIsoVi
+ */
+public class Counters {
+ private int albums;
+ private int videos;
+ private int audios;
+ private int notes;
+ private int photos;
+ private int groups;
+ private int gifts;
+ private int friends;
+ private int onlineFriends;
+ private int mutualFriends;
+ private int userPhotos;
+ private int userVideos;
+ private int followers;
+ private int subscriptions;
+ private int pages;
+
+ public int getUserVideos() {
+ return userVideos;
+ }
+
+ public int getUserPhotos() {
+ return userPhotos;
+ }
+
+ public int getAlbums() {
+ return albums;
+ }
+
+ public int getVideos() {
+ return videos;
+ }
+
+ public int getAudios() {
+ return audios;
+ }
+
+ public int getNotes() {
+ return notes;
+ }
+
+ public int getPhotos() {
+ return photos;
+ }
+
+ public int getGroups() {
+ return groups;
+ }
+
+ public int getGifts() {
+ return gifts;
+ }
+
+ public int getFriends() {
+ return friends;
+ }
+
+ public int getOnlineFriends() {
+ return onlineFriends;
+ }
+
+ public int getMutualFriends() {
+ return mutualFriends;
+ }
+
+ public int getFollowers() {
+ return followers;
+ }
+
+ public int getSubscriptions() {
+ return subscriptions;
+ }
+
+ public int getPages() {
+ return pages;
+ }
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IFriendsOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IFriendsOperations.java
index a42cc76..6e788ab 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IFriendsOperations.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IFriendsOperations.java
@@ -15,6 +15,10 @@
*/
package org.springframework.social.vkontakte.api;
+import org.springframework.social.vkontakte.api.impl.json.VKArray;
+import org.springframework.social.vkontakte.api.vkenums.FriendsOrder;
+import org.springframework.social.vkontakte.api.vkenums.NameCase;
+
import java.util.List;
/**
@@ -22,7 +26,7 @@
* @author vkolodrevskiy
*/
public interface IFriendsOperations {
- public final static String DEFAULT_FIELDS = "first_name,last_name,photo_50,photo_100,photo_200,contacts,bdate,sex,screen_name";
+ String DEFAULT_FIELDS = "first_name,last_name,photo_50,photo_100,photo_200,contacts,bdate,sex,screen_name";
/**
* Retrieves a list of user friends for the current authorized user.
* @return a list of user friends profiles.
@@ -30,7 +34,7 @@ public interface IFriendsOperations {
* @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
*/
- public List get();
+ VKArray get();
/**
* Retrieves a list of user friends for the current authorized user.
@@ -40,7 +44,7 @@ public interface IFriendsOperations {
* @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
*/
- public List get(String fields);
+ VKArray get(String fields);
/**
* Retrieves a list of user friends for specified user unique identifier.
@@ -50,7 +54,7 @@ public interface IFriendsOperations {
* @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
*/
- public List get(Long userId);
+ VKArray get(Long userId);
/**
* Retrieves a list of user friends for specified user unique identifier.
@@ -61,12 +65,27 @@ public interface IFriendsOperations {
* @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
*/
- public List get(Long userId, String fields);
+ VKArray get(Long userId, String fields);
+
+ /**
+ * Retrieves a list of user friends for specified user unique identifier.
+ * @param userId user unique identifier for which to get friends.
+ * @param fields VKontakte fields to retrieve, comma-delimited.
+ * @param count Number(positive number) of friends to return. If you want to return all friends pass negative number.
+ * @param offset Offset(positive number) needed to return a specific subset of friends.
+ * @return a list of user friends profiles.
+ * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
+ * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
+ * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
+ */
+ VKArray get(Long userId, String fields, int count, int offset);
/**
* Retrieves a list of user friends for specified user unique identifier.
* @param userId user unique identifier for which to get friends.
* @param fields VKontakte fields to retrieve, comma-delimited.
+ * @param order sort order.
+ * @param nameCase case for declension of user name and surname.
* @param count Number(positive number) of friends to return. If you want to return all friends pass negative number.
* @param offset Offset(positive number) needed to return a specific subset of friends.
* @return a list of user friends profiles.
@@ -74,7 +93,7 @@ public interface IFriendsOperations {
* @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
*/
- public List get(Long userId, String fields, int count, int offset);
+ VKArray get(Long userId, String fields, FriendsOrder order, NameCase nameCase, int count, int offset);
/**
* Retrieves a list of user friends id's that are online for the current authorized user.
@@ -88,7 +107,7 @@ public interface IFriendsOperations {
* @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
*/
- public List> getOnline(boolean onlineMobile, int count, int offset);
+ List> getOnline(boolean onlineMobile, int count, int offset);
/**
* Retrieves a list of user friends that are online for specified user unique identifier.
@@ -103,5 +122,5 @@ public interface IFriendsOperations {
* @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
*/
- public List> getOnline(Long userId, boolean onlineMobile, int count, int offset);
+ List> getOnline(Long userId, boolean onlineMobile, int count, int offset);
}
\ No newline at end of file
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUsersOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUsersOperations.java
index 9680c30..9bfc0c4 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUsersOperations.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUsersOperations.java
@@ -15,53 +15,75 @@
*/
package org.springframework.social.vkontakte.api;
+import org.springframework.social.vkontakte.api.vkenums.NameCase;
+
import java.util.List;
/**
* User operations.
+ *
* @author vkolodrevskiy
*/
public interface IUsersOperations {
- public final static String DEFAULT_FIELDS = "first_name,last_name,photo_50,photo_100,photo_200,contacts,bdate,sex,screen_name";
+ String DEFAULT_FIELDS = "first_name,last_name,photo_50,photo_100,photo_200,contacts,bdate,sex,screen_name";
+
/**
- * Retrieves the profile for the authenticated user.
- * @return the user's profile information.
- * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
- * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
+ * Retrieves the profile for the authenticated user.
+ *
+ * @return the user's profile information.
+ * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
+ * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
- */
- VKontakteProfile getUser();
+ */
+ VKontakteProfile getUser();
/**
* Retrieves the profile for the authenticated user.
+ *
* @param fields VKontakte fields to retrieve, comma-delimited.
* @return the user's profile information.
- * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
- * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
+ * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
+ * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
*/
VKontakteProfile getUser(String fields);
- /**
- * Retrieves profiles for specified user unique identifiers.
- * @param userIds VKontakte user profile unique identifiers, for which to gt data.
- * If null
is passed user profile or the current user will be returned.
- * @return the user's profile information.
- * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
- * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
+ /**
+ * Retrieves profiles for specified user unique identifiers.
+ *
+ * @param userIds VKontakte user profile unique identifiers, for which to gt data.
+ * If {@code null} is passed user profile or the current user will be returned.
+ * @return the user's profile information.
+ * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
+ * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
- */
- List getUsers(List userIds);
+ */
+ List getUsers(List userIds);
/**
* Retrieves profiles for specified user unique identifiers.
+ *
* @param userIds VKontakte user profile unique identifiers, for which to gt data.
- * @param fields VKontakte fields to retrieve, comma-delimited.
- * If null
is passed user profile or the current user will be returned.
+ * @param fields VKontakte fields to retrieve, comma-delimited.
+ * If {@code null} is passed user profile or the current user will be returned.
+ * @return the user's profile information.
+ * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
+ * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
+ * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
+ */
+ List getUsers(List userIds, String fields);
+
+ /**
+ * Retrieves profiles for specified user unique identifiers.
+ *
+ * @param userIds VKontakte user profile unique identifiers, for which to gt data.
+ * @param fields VKontakte fields to retrieve, comma-delimited.
+ * If {@code null} is passed user profile or the current user will be returned.
+ * @param nameCase case for declension of user name and surname.
* @return the user's profile information.
- * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
- * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
+ * @throws org.springframework.social.ApiException if there is an error while communicating with VKontakte.
+ * @throws org.springframework.social.MissingAuthorizationException if VKontakteTemplate was not created with an access token.
* @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
*/
- List getUsers(List userIds, String fields);
+ List getUsers(List userIds, String fields, NameCase nameCase);
}
\ No newline at end of file
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUtilsOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUtilsOperations.java
index e0fa040..a37d123 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUtilsOperations.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IUtilsOperations.java
@@ -20,5 +20,18 @@
* @author dIsoVi
*/
public interface IUtilsOperations {
- public VKObject resolveScreenName(String screenName);
+ /**
+ * utils.resolveScreenName
+ * Detects a type of object (e.g., user, community, application) and its ID by screen name.
+ * @param screenName Screen name of the user, community (e.g., apiclub, andrew, or rules_of_war), or application.
+ * @return an object with type and id
+ */
+ VKObject resolveScreenName(String screenName);
+
+ /**
+ * A universal method for calling a sequence of other methods while saving and filtering interim results.
+ * @param code - Algorithm code in VKScript (https://vk.com/dev/execute)
+ * @return data requested by the algorithm
+ */
+ VKGenericResponse execute(String code);
}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IWallOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IWallOperations.java
index b5a93b5..d7e9589 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IWallOperations.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/IWallOperations.java
@@ -15,6 +15,8 @@
*/
package org.springframework.social.vkontakte.api;
+import org.springframework.social.vkontakte.api.impl.wall.CommentsQuery;
+
import java.util.List;
/**
@@ -62,4 +64,12 @@ public interface IWallOperations {
PostStatus post(PostData postData);
+ /**
+ * Returns a response that contains a list of comments on a post on a user wall or community wall.
+ *
+ * @param query {@link CommentsQuery}
+ * @return a {@link CommentsResponse}, object representing the response on query of comments on a post on a user's or community's wall
+ * @throws org.springframework.social.vkontakte.api.VKontakteErrorException if VKontakte returned error.
+ */
+ CommentsResponse getComments(CommentsQuery query);
}
\ No newline at end of file
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakte.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakte.java
index bd1c262..f14f8bc 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakte.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakte.java
@@ -23,50 +23,67 @@
* @author vkolodrevskiy
*/
public interface VKontakte extends ApiBinding {
-
/**
- * API for performing operations on VKontakte user profiles.
- */
+ * API for performing operations on VKontakte user profiles.
+ *
+ * @return {@link IUsersOperations}
+ */
public IUsersOperations usersOperations();
- /**
- * API for performing operations on feeds.
- */
+ /**
+ * API for performing operations on feeds.
+ *
+ * @return {@link IWallOperations}
+ */
public IWallOperations wallOperations();
- /**
- * API for performing operations with a user's set of friends.
- */
+ /**
+ * API for performing operations with a user's set of friends.
+ *
+ * @return {@link IFriendsOperations}
+ */
public IFriendsOperations friendsOperations();
/**
* API for performing secure operations.
+ *
+ * @return {@link ISecureOperations}
*/
public ISecureOperations secureOperations();
/**
* API for performing operations with a location info.
+ *
+ * @return {@link ILocationOperations}
*/
public ILocationOperations locationOperations();
/**
* API for performing operations with audio.
+ *
+ * @return {@link IAudioOperations}
*/
public IAudioOperations audioOperations();
/**
* API for performing operations with groups.
+ *
+ * @return {@link IGroupsOperations}
*/
public IGroupsOperations groupsOperations();
/**
* API for performing operations with newsfeed.
+ *
+ * @return {@link INewsFeedOperations}
*/
public INewsFeedOperations newsFeedOperations();
/**
* API for performing operations with utils.
+ *
+ * @return {@link IUtilsOperations}
*/
public IUtilsOperations utilsOperations();
}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakteProfile.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakteProfile.java
index c8edcab..c61343f 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakteProfile.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/VKontakteProfile.java
@@ -23,6 +23,12 @@
* @author vkolodrevskiy
*/
public class VKontakteProfile {
+ public VKontakteProfile(long id) {
+ this.id = id;
+ }
+
+ public VKontakteProfile() {
+ }
private final static String PROFILE_URL_EXTESTION = "http://vk.com/";
private long id;
@@ -55,6 +61,7 @@ public class VKontakteProfile {
private String facebook;
private String facebookName;
private String twitter;
+ private String instagram;
private String site;
private String status;
private int commonCount;
@@ -84,6 +91,23 @@ public class VKontakteProfile {
private List relatives;
private VKontakteProfile relationPartner;
private LastSeen lastSeen;
+ private Counters counters;
+
+ public String getInstagram() {
+ return instagram;
+ }
+
+ public void setInstagram(String instagram) {
+ this.instagram = instagram;
+ }
+
+ public Counters getCounters() {
+ return counters;
+ }
+
+ public void setCounters(Counters counters) {
+ this.counters = counters;
+ }
public String getDeactivated() {
return deactivated;
@@ -551,6 +575,9 @@ public void setQuotes(String quotes) {
}
public String getProfileURL() {
+ if (screenName == null) {
+ return PROFILE_URL_EXTESTION + "id" + id;
+ }
return PROFILE_URL_EXTESTION + screenName;
}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/AbstractVKontakteOperations.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/AbstractVKontakteOperations.java
index 4c3e3d7..d4d9fc2 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/AbstractVKontakteOperations.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/AbstractVKontakteOperations.java
@@ -26,6 +26,7 @@
import org.springframework.social.vkontakte.api.VKontakteErrorException;
import org.springframework.social.vkontakte.api.impl.json.VKArray;
import org.springframework.util.Assert;
+import org.springframework.util.MultiValueMap;
import java.net.URI;
import java.util.ArrayList;
@@ -74,6 +75,13 @@ protected URI makeOperationURL(String method, Properties params, ApiVersion apiV
return uri.build();
}
+ protected URI makeOperationPOST(String method, MultiValueMap data, ApiVersion apiVersion) {
+ URIBuilder uri = URIBuilder.fromUri(VK_REST_URL + method);
+ data.set("access_token", accessToken);
+ data.set("v", apiVersion.toString());
+ return uri.build();
+ }
+
protected void preProcessURI(URIBuilder uri) {
// add access_token
// TODO: for some methods we do not need access token, so think about it.
@@ -100,10 +108,11 @@ protected VKArray deserializeArray(VKGenericResponse response, Class i
/**
* for responses of VK API 5.0+
- * @param response
- * @param itemClass
- * @param
- * @return
+ *
+ * @param response {@link VKGenericResponse response}
+ * @param itemClass class of the item
+ * @param item type
+ * @return array
*/
protected VKArray deserializeVK50ItemsResponse(VKGenericResponse response, Class itemClass) {
checkForError(response);
@@ -111,7 +120,7 @@ protected VKArray deserializeVK50ItemsResponse(VKGenericResponse response
JsonNode itemsNode = jsonNode.get("items");
Assert.isTrue(itemsNode.isArray());
int count = jsonNode.get("count").asInt();
- return new VKArray(count, deserializeItems((ArrayNode)itemsNode, itemClass));
+ return new VKArray(count, deserializeItems((ArrayNode) itemsNode, itemClass));
}
protected List deserializeItems(ArrayNode items, Class itemClass) {
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/FriendsTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/FriendsTemplate.java
index 7ad30cb..8ecf0c2 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/FriendsTemplate.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/FriendsTemplate.java
@@ -17,7 +17,14 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import org.springframework.social.vkontakte.api.*;
+import org.springframework.social.vkontakte.api.ApiVersion;
+import org.springframework.social.vkontakte.api.IFriendsOperations;
+import org.springframework.social.vkontakte.api.VKGenericResponse;
+import org.springframework.social.vkontakte.api.VKontakteProfile;
+import org.springframework.social.vkontakte.api.impl.json.VKArray;
+import org.springframework.social.vkontakte.api.vkenums.FriendsOrder;
+import org.springframework.social.vkontakte.api.vkenums.NameCase;
+import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
@@ -38,23 +45,27 @@ public FriendsTemplate(RestTemplate restTemplate, String accessToken, ObjectMapp
this.restTemplate = restTemplate;
}
- public List get(String fields) {
+ public VKArray get(String fields) {
return get(null, fields);
}
- public List get() {
+ public VKArray get() {
return get(null, IFriendsOperations.DEFAULT_FIELDS);
}
- public List get(Long userId) {
+ public VKArray get(Long userId) {
return get(userId, IFriendsOperations.DEFAULT_FIELDS);
}
- public List get(Long userId, String fields) {
+ public VKArray get(Long userId, String fields) {
return get(userId, fields, -1, -1);
}
- public List get(Long userId, String fields, int count, int offset) {
+ public VKArray get(Long userId, String fields, int count, int offset) {
+ return get(userId, fields, FriendsOrder.NONE, NameCase.nom, count, offset);
+ }
+
+ public VKArray get(Long userId, String fields, FriendsOrder order, NameCase nameCase, int count, int offset) {
requireAuthorization();
Properties props = new Properties();
@@ -67,13 +78,22 @@ public List get(Long userId, String fields, int count, int off
if (offset != -1) {
props.put("offset", offset);
}
- props.put("fields", fields);
+ if (!StringUtils.isEmpty(fields)) {
+ props.put("fields", fields);
+ }
+ if (order != FriendsOrder.NONE) {
+ props.put("order", order.toString());
+ }
+ if (nameCase != NameCase.nom) {
+ props.put("name_case", nameCase.toString());
+ }
+
URI uri = makeOperationURL("friends.get", props, ApiVersion.VERSION_5_27);
VKGenericResponse response = restTemplate.getForObject(uri, VKGenericResponse.class);
checkForError(response);
- return deserializeVK50ItemsResponse(response, VKontakteProfile.class).getItems();
+ return deserializeVK50ItemsResponse(response, VKontakteProfile.class);
}
public List> getOnline(boolean onlineMobile, int count, int offset) {
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UsersTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UsersTemplate.java
index 8f7b8fe..acdb7e3 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UsersTemplate.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UsersTemplate.java
@@ -20,11 +20,13 @@
import org.springframework.social.vkontakte.api.IUsersOperations;
import org.springframework.social.vkontakte.api.VKontakteProfile;
import org.springframework.social.vkontakte.api.VKontakteProfiles;
+import org.springframework.social.vkontakte.api.vkenums.NameCase;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.List;
-import java.util.Properties;
/**
* User operations.
@@ -39,35 +41,40 @@ public UsersTemplate(RestTemplate restTemplate, String accessToken, ObjectMapper
this.restTemplate = restTemplate;
}
- public List getUsers(List userIds, String fields) {
+ public List getUsers(List userIds) {
+ return getUsers(userIds, null);
+ }
+
+ public List getUsers(List userIds, String fields) {
+ return getUsers(userIds, fields, NameCase.nom);
+ }
+
+ public List getUsers(List userIds, String fields, NameCase nameCase) {
requireAuthorization();
- Properties props = new Properties();
+ MultiValueMap data = new LinkedMultiValueMap();
- StringBuilder uids = new StringBuilder();
- if(userIds != null) {
- for(Long uid : userIds) {
- if(uids.toString().isEmpty())
- uids.append(uid);
- else uids.append(",").append(uid);
+ if (userIds != null) {
+ StringBuilder sb = new StringBuilder();
+ for(String uid : userIds){
+ sb.append(uid).append(",");
}
- props.put("user_ids", uids.toString());
+ sb.deleteCharAt(sb.length() - 1);
+ data.set("user_ids", sb.toString());
+ }
+ if (nameCase != NameCase.nom) {
+ data.set("name_case", nameCase.toString());
}
- props.put("fields", fields != null? fields: IUsersOperations.DEFAULT_FIELDS);
+ data.set("fields", fields != null? fields: IUsersOperations.DEFAULT_FIELDS);
// see documentation under http://vk.com/dev/users.get
- URI uri = makeOperationURL("users.get", props, ApiVersion.VERSION_5_27);
-
- VKontakteProfiles profiles = restTemplate.getForObject(uri, VKontakteProfiles.class);
+ URI uri = makeOperationPOST("users.get", data, ApiVersion.VERSION_5_27);
+ VKontakteProfiles profiles = restTemplate.postForObject(uri, data, VKontakteProfiles.class);
checkForError(profiles);
return profiles.getProfiles();
}
- public List getUsers(List userIds) {
- return getUsers(userIds, null);
- }
-
public VKontakteProfile getUser() {
return getUsers(null).get(0);
}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UtilsTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UtilsTemplate.java
index b8e3ba4..f4b459d 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UtilsTemplate.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/UtilsTemplate.java
@@ -5,6 +5,8 @@
import org.springframework.social.vkontakte.api.IUtilsOperations;
import org.springframework.social.vkontakte.api.VKGenericResponse;
import org.springframework.social.vkontakte.api.VKObject;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
@@ -17,8 +19,8 @@
public class UtilsTemplate extends AbstractVKontakteOperations implements IUtilsOperations {
private final RestTemplate restTemplate;
- public UtilsTemplate(RestTemplate restTemplate, ObjectMapper objectMapper) {
- super(false, null, objectMapper);
+ public UtilsTemplate(RestTemplate restTemplate, String accessToken, ObjectMapper objectMapper, boolean isAuthorizedForUser) {
+ super(isAuthorizedForUser, accessToken, objectMapper);
this.restTemplate = restTemplate;
}
@@ -29,4 +31,14 @@ public VKObject resolveScreenName(String screenName) {
VKGenericResponse response = restTemplate.getForObject(uri, VKGenericResponse.class);
return deserializeVK50Item(response, VKObject.class);
}
+
+ // TODO: give user the ability to deserialize response by setting template class?
+ public VKGenericResponse execute(String code) {
+ MultiValueMap data = new LinkedMultiValueMap();
+ data.set("code", code);
+ URI uri = makeOperationPOST("execute", data, ApiVersion.VERSION_5_27);
+ VKGenericResponse response = restTemplate.postForObject(uri, data, VKGenericResponse.class);
+ checkForError(response);
+ return response;
+ }
}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/VKontakteTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/VKontakteTemplate.java
index 4403791..6807c82 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/VKontakteTemplate.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/VKontakteTemplate.java
@@ -103,7 +103,7 @@ private void initSubApis() {
audioOperations = new AudioTemplate(getRestTemplate(), accessToken, objectMapper, isAuthorized());
groupsOperations = new GroupsTemplate(getRestTemplate(), accessToken, objectMapper, isAuthorized());
newsFeedOperations = new NewsFeedTemplate(getRestTemplate(), accessToken, objectMapper, isAuthorized());
- utilsOperations = new UtilsTemplate(getRestTemplate(), objectMapper);
+ utilsOperations = new UtilsTemplate(getRestTemplate(), accessToken, objectMapper, isAuthorized());
}
public IUsersOperations usersOperations() {
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/WallTemplate.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/WallTemplate.java
index 6880d04..dc84823 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/WallTemplate.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/WallTemplate.java
@@ -16,8 +16,13 @@
package org.springframework.social.vkontakte.api.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import org.springframework.social.UncategorizedApiException;
import org.springframework.social.vkontakte.api.*;
+import org.springframework.social.vkontakte.api.impl.wall.CommentsQuery;
+import org.springframework.social.vkontakte.api.impl.wall.CommunityWall;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
@@ -27,6 +32,7 @@
/**
* {@link org.springframework.social.vkontakte.api.IWallOperations} implementation.
+ *
* @author vkolodrevskiy
*/
public class WallTemplate extends AbstractVKontakteOperations implements IWallOperations {
@@ -90,4 +96,65 @@ public PostStatus post(PostData postData) {
return response.getStatus();
}
+
+ public CommentsResponse getComments(CommentsQuery query) {
+ MultiValueMap data = new LinkedMultiValueMap();
+
+ if (query.owner instanceof CommunityWall) {
+ data.set("owner_id", "-" + String.valueOf(query.owner.getId()));
+ } else {
+ data.set("owner_id", String.valueOf(query.owner.getId()));
+ }
+
+ data.set("post_id", String.valueOf(query.postId));
+
+ if (query.needLikes) {
+ data.set("need_likes", "1");
+ }
+
+ if (query.startCommentId != null && query.startCommentId > 0) {
+ data.set("start_comment_id", query.startCommentId.toString());
+ }
+
+ if (query.offset != null && query.offset > 0) {
+ data.set("offset", query.offset.toString());
+ }
+
+ if (query.count != null && query.count > 0) {
+ data.set("count", query.count.toString());
+ }
+
+ if (query.sort != null) {
+ data.set("sort", query.sort.toString());
+ }
+
+ if (query.previewLength != null && query.previewLength > 0) {
+ data.set("preview_length", query.previewLength.toString());
+ } else {
+ //Specify 0 as it does not want to truncate comments.
+ data.set("preview_length", "0");
+ }
+
+ if (query.extended) {
+ data.set("extended", "1");
+ }
+
+ URI uri = makeOperationPOST("wall.getComments", data, ApiVersion.VERSION_5_33);
+ VKGenericResponse response = restTemplate.postForObject(uri, data, VKGenericResponse.class);
+ checkForError(response);
+
+ List comments = deserializeVK50ItemsResponse(response, Comment.class).getItems();
+ List profiles = null;
+ List groups = null;
+ if (query.extended) {
+ profiles = deserializeItems((ArrayNode) response.getResponse().get("profiles"), VKontakteProfile.class);
+ groups = deserializeItems((ArrayNode) response.getResponse().get("groups"), Group.class);
+ }
+ long count = response.getResponse().get("count").asLong();
+ Long realOffset = null;
+ if (query.startCommentId != null) {
+ realOffset = response.getResponse().get("real_offset").asLong();
+ }
+ return new CommentsResponse(comments, count, realOffset, profiles, groups);
+ }
}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CommentMixin.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CommentMixin.java
new file mode 100644
index 0000000..1cf58bf
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CommentMixin.java
@@ -0,0 +1,27 @@
+package org.springframework.social.vkontakte.api.impl.json;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.springframework.social.vkontakte.api.impl.json.deserializers.UnixTimeDeserializer;
+
+import java.util.Date;
+
+/**
+ * Mixin for {@link org.springframework.social.vkontakte.api.Comment}
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CommentMixin {
+ @JsonProperty("from_id")
+ long fromId;
+
+ @JsonProperty("date")
+ @JsonDeserialize(using = UnixTimeDeserializer.class)
+ Date date;
+
+ @JsonProperty("reply_to_user")
+ long replyToUser;
+
+ @JsonProperty("reply_to_comment")
+ long replyToComment;
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CountersMixin.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CountersMixin.java
new file mode 100644
index 0000000..4bc6046
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/CountersMixin.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.social.vkontakte.api.impl.json;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CountersMixin {
+ private int albums;
+ private int videos;
+ private int audios;
+ private int notes;
+ private int photos;
+ private int groups;
+ private int gifts;
+ private int friends;
+ @JsonProperty("online_friends")
+ private int onlineFriends;
+ @JsonProperty("mutual_friends")
+ private int mutualFriends;
+ @JsonProperty("user_photos")
+ private int userPhotos;
+ @JsonProperty("user_videos")
+ private int userVideos;
+ private int followers;
+ private int subscriptions;
+ private int pages;
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteModule.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteModule.java
index 5a89dca..319997f 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteModule.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteModule.java
@@ -50,6 +50,7 @@ public void setupModule(SetupContext context) {
context.setMixInAnnotations(Post.Comments.class, PostCommentsMixin.class);
context.setMixInAnnotations(Post.Geo.class, PostGeoMixin.class);
context.setMixInAnnotations(Place.class, PostGeoPlaceMixin.class);
+ context.setMixInAnnotations(Comment.class, CommentMixin.class);
context.setMixInAnnotations(Group.class, GroupMixin.class);
@@ -71,6 +72,7 @@ public void setupModule(SetupContext context) {
context.setMixInAnnotations(City.class, CityMixin.class);
context.setMixInAnnotations(Country.class, CountryMixin.class);
context.setMixInAnnotations(LastSeen.class, LastSeenMixin.class);
+ context.setMixInAnnotations(Counters.class, CountersMixin.class);
context.setMixInAnnotations(Occupation.class, OccupationMixin.class);
context.setMixInAnnotations(Personal.class, PersonalMixin.class);
context.setMixInAnnotations(University.class, UniversityMixin.class);
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteProfileMixin.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteProfileMixin.java
index f3c9b36..5fd497c 100644
--- a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteProfileMixin.java
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/json/VKontakteProfileMixin.java
@@ -21,7 +21,6 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.springframework.social.vkontakte.api.*;
@@ -97,6 +96,7 @@ class VKontakteProfileMixin {
private String facebookName;
@JsonProperty("twitter")
private String twitter;
+ private String instagram;
@JsonProperty("site")
private String site;
@JsonProperty("status")
@@ -155,6 +155,9 @@ class VKontakteProfileMixin {
private VKontakteProfile relationPartner;
@JsonProperty("last_seen")
private LastSeen lastSeen;
+ @JsonProperty("counters")
+ private Counters counters;
+
static class VKGenderDeserializer extends JsonDeserializer {
@Override
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommentsQuery.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommentsQuery.java
new file mode 100644
index 0000000..b30f3ca
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommentsQuery.java
@@ -0,0 +1,111 @@
+package org.springframework.social.vkontakte.api.impl.wall;
+
+import org.springframework.social.vkontakte.api.IWallOperations;
+import org.springframework.social.vkontakte.api.vkenums.SortOrder;
+
+/**
+ * Model class representing query for the list of comments on a post on a user wall or community wall.
+ *
+ * @see IWallOperations#getComments(CommentsQuery)
+ * @see wall.getComments | Developers | VK
+ */
+public final class CommentsQuery {
+ public final WallOwner owner;
+ public final int postId;
+ public final boolean needLikes;
+ public final Integer startCommentId;
+ public final Integer offset;
+ public final Integer count;
+ public final SortOrder sort;
+ public final Integer previewLength;
+ public final boolean extended;
+
+ public CommentsQuery(WallOwner owner, int postId, boolean needLikes, Integer startCommentId, Integer offset, Integer count, SortOrder sort, Integer previewLength, boolean extended) {
+ this.owner = owner;
+ this.postId = postId;
+ this.needLikes = needLikes;
+ this.startCommentId = startCommentId;
+ this.offset = offset;
+ this.count = count;
+ this.sort = sort;
+ this.previewLength = previewLength;
+ this.extended = extended;
+ }
+
+ @Override
+ public String toString() {
+ return "CommentsQuery{" +
+ "owner='" + owner + '\'' +
+ ", postId=" + postId +
+ '}';
+ }
+
+ public static class Builder {
+ private WallOwner owner;
+ private Integer postId;
+ private boolean needLikes;
+ private Integer startCommentId;
+ private Integer offset;
+ private Integer count;
+ private SortOrder sort;
+ private Integer previewLength;
+ private boolean extended;
+
+ /**
+ * @param owner {@link UserWall} or {@link UserWall}
+ * @param postId post ID.
+ */
+ public Builder(WallOwner owner, int postId) {
+ this.owner = owner;
+ this.postId = postId;
+ }
+
+ public Builder needLikes(boolean needLikes) {
+ this.needLikes = needLikes;
+ return this;
+ }
+
+ public Builder startCommentId(int startCommentId) {
+ this.startCommentId = startCommentId;
+ return this;
+ }
+
+ public Builder offset(int offset) {
+ this.offset = offset;
+ return this;
+ }
+
+ /**
+ * @param count number of comments to return (maximum 100)
+ * @return {@link org.springframework.social.vkontakte.api.impl.wall.CommentsQuery.Builder}
+ */
+ public Builder count(int count) {
+ this.count = count;
+ return this;
+ }
+
+ public Builder sort(SortOrder sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ /**
+ * @param previewLength number of characters at which to truncate comments when previewed.
+ * If {@code null} or {@code 0} comments are not truncated.
+ * @return {@link org.springframework.social.vkontakte.api.impl.wall.CommentsQuery.Builder}
+ */
+ public Builder previewLength(int previewLength) {
+ this.previewLength = previewLength;
+ return this;
+ }
+
+ public Builder extended(boolean extended) {
+ this.extended = extended;
+ return this;
+ }
+
+ public CommentsQuery build() {
+ return new CommentsQuery(owner, postId, needLikes, startCommentId, offset, count, sort, previewLength, extended);
+ }
+ }
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommunityWall.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommunityWall.java
new file mode 100644
index 0000000..ef20c18
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/CommunityWall.java
@@ -0,0 +1,21 @@
+package org.springframework.social.vkontakte.api.impl.wall;
+
+/**
+ * Model class representing community wall owner
+ *
+ * @see WallOwner
+ * @see CommentsQuery#owner
+ */
+public final class CommunityWall extends WallOwner {
+ public CommunityWall(final long communityId) {
+ super(communityId);
+ }
+
+ @Override
+ public String toString() {
+ return "CommunityWall{" +
+ "id='" + getId() + '\'' +
+ '}';
+ }
+
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/UserWall.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/UserWall.java
new file mode 100644
index 0000000..7511a71
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/UserWall.java
@@ -0,0 +1,21 @@
+package org.springframework.social.vkontakte.api.impl.wall;
+
+/**
+ * Model class representing user wall owner
+ *
+ * @see WallOwner
+ * @see CommentsQuery#owner
+ */
+public final class UserWall extends WallOwner {
+ public UserWall(final long userId) {
+ super(userId);
+ }
+
+ @Override
+ public String toString() {
+ return "UserWall{" +
+ "id='" + getId() + '\'' +
+ '}';
+ }
+}
+
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/WallOwner.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/WallOwner.java
new file mode 100644
index 0000000..1753477
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/impl/wall/WallOwner.java
@@ -0,0 +1,20 @@
+package org.springframework.social.vkontakte.api.impl.wall;
+
+/**
+ * Model class representing an abstract wall's owner
+ *
+ * @see UserWall
+ * @see CommunityWall
+ * @see CommentsQuery#owner
+ */
+public abstract class WallOwner {
+ private final long id;
+
+ protected WallOwner(final long ownerId) {
+ this.id = ownerId;
+ }
+
+ public long getId() {
+ return id;
+ }
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/FriendsOrder.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/FriendsOrder.java
new file mode 100644
index 0000000..fad570d
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/FriendsOrder.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.social.vkontakte.api.vkenums;
+
+/**
+ * Defines sort order for friends.get operation
+ * API.version = 5.35
+ * @author dIsoVi
+ */
+public enum FriendsOrder {
+ NONE,
+ hints,
+ random,
+ mobile,
+ name
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/NameCase.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/NameCase.java
new file mode 100644
index 0000000..041f1f9
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/NameCase.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.social.vkontakte.api.vkenums;
+
+/**
+ * Case for declension of user name and surname
+ * API.version = 5.35
+ * @author dIsoVi
+ */
+public enum NameCase {
+ nom, // default
+ gen,
+ dat,
+ acc,
+ ins,
+ abl
+}
diff --git a/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/SortOrder.java b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/SortOrder.java
new file mode 100644
index 0000000..1c2301a
--- /dev/null
+++ b/spring-social-vkontakte/src/main/java/org/springframework/social/vkontakte/api/vkenums/SortOrder.java
@@ -0,0 +1,9 @@
+package org.springframework.social.vkontakte.api.vkenums;
+
+/**
+ * Defines sort order for wall.getComments operation
+ */
+public enum SortOrder {
+ asc,
+ desc
+}
diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/FriendsTemplateTest.java b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/FriendsTemplateTest.java
index 6b88af6..2c3bb7d 100644
--- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/FriendsTemplateTest.java
+++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/FriendsTemplateTest.java
@@ -19,6 +19,7 @@
import org.springframework.social.MissingAuthorizationException;
import org.springframework.social.vkontakte.api.VKontakteErrorException;
import org.springframework.social.vkontakte.api.VKontakteProfile;
+import org.springframework.social.vkontakte.api.impl.json.VKArray;
import java.text.ParseException;
import java.util.List;
@@ -41,11 +42,22 @@ public void get_currentUser() throws ParseException {
.andExpect(method(GET))
.andRespond(withSuccess(jsonResource("list-of-friends-5_27"), APPLICATION_JSON));
- List friends = vkontakte.friendsOperations().get();
+ VKArray friends = vkontakte.friendsOperations().get();
assertFriends(friends);
}
- @Test(expected = MissingAuthorizationException.class)
+ @Test
+ public void getFriendsWithoutFields() throws Exception {
+ mockServer.expect(requestTo("https://api.vk.com/method/friends.get?access_token=ACCESS_TOKEN&v=5.27"))
+ .andExpect(method(GET))
+ .andRespond(withSuccess(jsonResource("friends-get-without-fields-5_35"), APPLICATION_JSON));
+ VKArray friends = vkontakte.friendsOperations().get("");
+ assertEquals(184760, friends.getItems().get(0).getId());
+ assertEquals(3, friends.getItems().size());
+ assertEquals(718, friends.getCount());
+ }
+
+ @Test(expected = MissingAuthorizationException.class)
public void get_currentUser_unauthorized() {
unauthorizedVKontakte.friendsOperations().get();
}
@@ -56,7 +68,7 @@ public void get_byUserId() throws ParseException {
.andExpect(method(GET))
.andRespond(withSuccess(jsonResource("list-of-friends-5_27"), APPLICATION_JSON));
- List friends = vkontakte.friendsOperations().get(1L);
+ VKArray friends = vkontakte.friendsOperations().get(1L);
assertFriends(friends);
}
@@ -132,7 +144,9 @@ public void getOnlineAllParametersPresent() {
vkontakte.friendsOperations().getOnline(123L, true, 5, 6);
}
- private void assertFriends(List profiles) throws ParseException {
+ private void assertFriends(VKArray profilesArray) throws ParseException {
+ List profiles = profilesArray.getItems();
+ assertEquals(705, profilesArray.getCount());
assertEquals(5, profiles.size());
assertEquals(15439101, profiles.get(0).getId());
}
diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UsersTemplateTest.java b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UsersTemplateTest.java
index d30a91c..9805c46 100644
--- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UsersTemplateTest.java
+++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UsersTemplateTest.java
@@ -19,13 +19,13 @@
import org.springframework.social.MissingAuthorizationException;
import org.springframework.social.vkontakte.api.VKontakteErrorException;
import org.springframework.social.vkontakte.api.VKontakteProfile;
+import org.springframework.social.vkontakte.api.vkenums.NameCase;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
-import static org.springframework.http.HttpMethod.GET;
+import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
@@ -40,23 +40,26 @@ public class UsersTemplateTest extends AbstractVKontakteApiTest {
@Test
public void getUser_currentUser() {
mockServer
- .expect(requestTo("https://api.vk.com/method/users.get?access_token=ACCESS_TOKEN&v=5.27&fields=sex%2C+bdate%2C+city%2C+country%2C+photo_50%2C+photo_100%2C+photo_200_orig%2C+photo_200%2C+photo_400_orig%2C+photo_max%2C+photo_max_orig%2C+photo_id%2C+online%2C+online_mobile%2C+domain%2C+has_mobile%2C+contacts%2C+connections%2C+site%2C+education%2C+universities%2C+schools%2C+can_post%2C+can_see_all_posts%2C+can_see_audio%2C+can_write_private_message%2C+status%2C+last_seen%2C+common_count%2C+relation%2C+relatives%2C+counters%2C+screen_name%2C+maiden_name%2C+timezone%2C+occupation%2Cactivities%2C+interests%2C+music%2C+movies%2C+tv%2C+books%2C+games%2C+about%2C+quotes%2C+personal%2C+friends_status"))
- .andExpect(method(GET)).andRespond(withSuccess(jsonResource("list-of-profiles-5_27"), APPLICATION_JSON));
+ .expect(requestTo("https://api.vk.com/method/users.get"))
+ .andExpect(method(POST)).andRespond(withSuccess(jsonResource("list-of-profiles-5_27"), APPLICATION_JSON));
VKontakteProfile profile = vkontakte.usersOperations().getUser("sex, bdate, city, country, photo_50, photo_100, photo_200_orig, photo_200, photo_400_orig, photo_max, photo_max_orig, photo_id, online, online_mobile, domain, has_mobile, contacts, connections, site, education, universities, schools, can_post, can_see_all_posts, can_see_audio, can_write_private_message, status, last_seen, common_count, relation, relatives, counters, screen_name, maiden_name, timezone, occupation,activities, interests, music, movies, tv, books, games, about, quotes, personal, friends_status");
assertEquals(1, profile.getId());
assertEquals("Павел", profile.getFirstName());
assertEquals("Дуров", profile.getLastName());
+ assertEquals(705, profile.getCounters().getFriends());
+ assertEquals(12, profile.getCounters().getUserPhotos());
+ assertEquals("durov", profile.getInstagram());
}
@Test
public void getUsers_currentUser() {
mockServer
- .expect(requestTo("https://api.vk.com/method/users.get?access_token=ACCESS_TOKEN&v=5.27&fields=first_name%2Clast_name%2Cphoto_50%2Cphoto_100%2Cphoto_200%2Ccontacts%2Cbdate%2Csex%2Cscreen_name&user_ids=1%2C2183%2C77478"))
- .andExpect(method(GET)).andRespond(withSuccess(jsonResource("list-of-profiles-5_27"), APPLICATION_JSON));
- Long[] userIds = {1L, 2183L, 77478L};
- List profiles = vkontakte.usersOperations().getUsers(Arrays.asList(userIds));
+ .expect(requestTo("https://api.vk.com/method/users.get"))
+ .andExpect(method(POST)).andRespond(withSuccess(jsonResource("list-of-profiles-5_27"), APPLICATION_JSON));
+ String[] userIds = {"durov", "2183", "77478"};
+ List profiles = vkontakte.usersOperations().getUsers(Arrays.asList(userIds), null, NameCase.abl);
assertProfiles(profiles);
}
@@ -68,15 +71,15 @@ public void getUser_unauthorized() {
@Test(expected = MissingAuthorizationException.class)
public void getUsers_unauthorized() {
- Long[] userIds = {1L, 2L};
+ String[] userIds = {"1", "2"};
unauthorizedVKontakte.usersOperations().getUsers(Arrays.asList(userIds));
}
@Test(expected = VKontakteErrorException.class)
public void getUser_expiredToken() {
mockServer
- .expect(requestTo("https://api.vk.com/method/users.get?access_token=ACCESS_TOKEN&v=5.27&fields=first_name%2Clast_name%2Cphoto_50%2Cphoto_100%2Cphoto_200%2Ccontacts%2Cbdate%2Csex%2Cscreen_name"))
- .andExpect(method(GET)).andRespond(withSuccess(jsonResource("error-code-5"), APPLICATION_JSON));
+ .expect(requestTo("https://api.vk.com/method/users.get"))
+ .andExpect(method(POST)).andRespond(withSuccess(jsonResource("error-code-5"), APPLICATION_JSON));
vkontakte.usersOperations().getUser();
}
@@ -84,9 +87,9 @@ public void getUser_expiredToken() {
@Test(expected = VKontakteErrorException.class)
public void getUsers_expiredToken() {
mockServer
- .expect(requestTo("https://api.vk.com/method/users.get?access_token=ACCESS_TOKEN&v=5.27&fields=first_name%2Clast_name%2Cphoto_50%2Cphoto_100%2Cphoto_200%2Ccontacts%2Cbdate%2Csex%2Cscreen_name&user_ids=1%2C2"))
- .andExpect(method(GET)).andRespond(withSuccess(jsonResource("error-code-5"), APPLICATION_JSON));
- Long[] userIds = {1L, 2L};
+ .expect(requestTo("https://api.vk.com/method/users.get"))
+ .andExpect(method(POST)).andRespond(withSuccess(jsonResource("error-code-5"), APPLICATION_JSON));
+ String[] userIds = {"1", "2"};
vkontakte.usersOperations().getUsers(Arrays.asList(userIds));
}
diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UtilsTemplateTest.java b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UtilsTemplateTest.java
index 4dae470..7acbbb2 100644
--- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UtilsTemplateTest.java
+++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/UtilsTemplateTest.java
@@ -16,10 +16,12 @@
package org.springframework.social.vkontakte.api.impl;
import org.junit.Test;
+import org.springframework.social.vkontakte.api.VKGenericResponse;
import org.springframework.social.vkontakte.api.VKObject;
import static org.junit.Assert.assertEquals;
import static org.springframework.http.HttpMethod.GET;
+import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
@@ -32,7 +34,7 @@
public class UtilsTemplateTest extends AbstractVKontakteApiTest {
@Test
public void resolveScreenName() {
- mockServer.expect(requestTo("https://api.vk.com/method/utils.resolveScreenName?access_token=&v=5.27&screen_name=durov"))
+ mockServer.expect(requestTo("https://api.vk.com/method/utils.resolveScreenName?access_token=ACCESS_TOKEN&v=5.27&screen_name=durov"))
.andExpect(method(GET))
.andRespond(withSuccess(jsonResource("utils-resolve-screen-name-5.27"), APPLICATION_JSON));
VKObject vkObject = vkontakte.utilsOperations().resolveScreenName("durov");
@@ -42,10 +44,38 @@ public void resolveScreenName() {
@Test
public void resolveScreenNameEmpty() {
- mockServer.expect(requestTo("https://api.vk.com/method/utils.resolveScreenName?access_token=&v=5.27&screen_name=durov"))
+ mockServer.expect(requestTo("https://api.vk.com/method/utils.resolveScreenName?access_token=ACCESS_TOKEN&v=5.27&screen_name=durov"))
.andExpect(method(GET))
.andRespond(withSuccess(jsonResource("utils-resolve-screen-name-empty-5.27"), APPLICATION_JSON));
VKObject vkObject = vkontakte.utilsOperations().resolveScreenName("durov");
assertEquals(null, vkObject);
}
+
+ @Test
+ public void testExecute() throws Exception {
+ mockServer.expect(requestTo("https://api.vk.com/method/execute"))
+ .andExpect(method(POST))
+ .andRespond(withSuccess(jsonResource("utils-execute-response-5_35"), APPLICATION_JSON));
+ String code = "var posts = API.wall.get({\"count\": 1});\n" +
+ "\n" +
+ "if (posts.count<0) {\n" +
+ " return {\"post\": null, \"copy_owner\": null};\n" +
+ "} else {\n" +
+ " var post = posts.items[0];\n" +
+ " var copy_owner=null;\n" +
+ " if (post.copy_history[0]){\n" +
+ " if (post.copy_history[0].owner_id > 0) {\n" +
+ " copy_owner = API.users.get({\"user_id\": post.copy_history[0].owner_id})[0];\n" +
+ " } else\n" +
+ " if (post.copy_history[0].owner_id < 0) {\n" +
+ " copy_owner = API.groups.getById({\"group_ids\": -post.copy_history[0].owner_id})[0];\n" +
+ " }\n" +
+ " return {\"post\": post, \"copy_owner\": copy_owner};\n" +
+ " } else {\n" +
+ " return {\"post\": post, \"copy_owner\": null};\n" +
+ " }\n" +
+ "}";
+ VKGenericResponse response = vkontakte.utilsOperations().execute(code);
+ assertEquals(1, response.getResponse().get("post").get("copy_history").size());
+ }
}
diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/WallTemplateTest.java b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/WallTemplateTest.java
index 1892a50..becde61 100644
--- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/WallTemplateTest.java
+++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/WallTemplateTest.java
@@ -16,15 +16,26 @@
package org.springframework.social.vkontakte.api.impl;
import org.junit.Test;
+import org.springframework.social.vkontakte.api.Comment;
+import org.springframework.social.vkontakte.api.CommentsResponse;
import org.springframework.social.vkontakte.api.Post;
-import org.springframework.social.vkontakte.api.attachment.*;
+import org.springframework.social.vkontakte.api.VKontakteProfile;
+import org.springframework.social.vkontakte.api.attachment.Attachment;
+import org.springframework.social.vkontakte.api.attachment.AttachmentType;
+import org.springframework.social.vkontakte.api.attachment.PhotosListAttachment;
+import org.springframework.social.vkontakte.api.attachment.StickerAttachment;
+import org.springframework.social.vkontakte.api.impl.wall.CommentsQuery;
+import org.springframework.social.vkontakte.api.impl.wall.CommunityWall;
+import org.springframework.social.vkontakte.api.impl.wall.UserWall;
+import org.springframework.social.vkontakte.api.vkenums.SortOrder;
import java.util.List;
+
import static org.junit.Assert.assertEquals;
import static org.springframework.http.HttpMethod.GET;
+import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.MediaType.APPLICATION_JSON;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.*;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
/**
@@ -43,7 +54,63 @@ public void getPosts() {
assertEquals(AttachmentType.PHOTOS_LIST, photosListAttachment.getType());
assertEquals(306810815, ((PhotosListAttachment)photosListAttachment).getPhotosList().get(0).getPhotoId());
assertEquals(45555, posts.get(1).getId());
+ assertEquals(22694, posts.get(1).getLikes().getCount());
+ assertEquals(false, posts.get(1).getLikes().isUserLikes());
assertEquals(2, posts.get(1).getAttachments().size());
assertEquals(3, ((StickerAttachment)posts.get(22).getCopyHistory().get(0).getAttachments().get(0)).getSticker().getProductId());
}
+
+ @Test
+ public void getCommunityWallComments() {
+ mockServer
+ .expect(requestTo("https://api.vk.com/method/wall.getComments"))
+ .andExpect(method(POST))
+ .andExpect(content().string("owner_id=-85635407&post_id=3199&preview_length=0&access_token=ACCESS_TOKEN&v=5.33"))
+ .andRespond(withSuccess(jsonResource("wall-getComments-response-5_33"), APPLICATION_JSON));
+ CommentsQuery request = new CommentsQuery.Builder(new CommunityWall(85635407), 3199).build();
+
+ CommentsResponse response = vkontakte.wallOperations().getComments(request);
+
+ assertEquals(16, response.getCount());
+ }
+
+ @Test
+ public void getUserWallComments() {
+ mockServer
+ .expect(requestTo("https://api.vk.com/method/wall.getComments"))
+ .andExpect(method(POST))
+ .andExpect(content().string("owner_id=85635407&post_id=3199&need_likes=1&start_comment_id=3204&offset=2&count=3&sort=desc&preview_length=9999&extended=1&access_token=ACCESS_TOKEN&v=5.33"))
+ .andRespond(withSuccess(jsonResource("wall-getComments-response-5_33"), APPLICATION_JSON));
+ CommentsQuery request = new CommentsQuery(new UserWall(85635407), 3199, true, 3204, 2, 3, SortOrder.desc, 9999, true);
+
+ CommentsResponse response = vkontakte.wallOperations().getComments(request);
+
+ assertEquals(16, response.getCount());
+ assertEquals(10, response.getRealOffset());
+
+ assertEquals(6, response.getComments().size());
+ assertEquals(4, response.getProfiles().size());
+
+ assertComment(response.getComments().get(0));
+ assertProfile(response.getProfiles().get(0));
+ }
+
+ private void assertComment(Comment comment) {
+ assertEquals(3205, comment.getId());
+ assertEquals(1375980597000L, comment.getDate().getTime());
+ assertEquals(85635407, comment.getFromId());
+ assertEquals("[id3197366|Андрей], поправил", comment.getText());
+ assertEquals(3197366, comment.getReplyToUser());
+ assertEquals(3200, comment.getReplyToComment());
+ assertEquals(666, comment.getLikes().getCount());
+ assertEquals(true, comment.getLikes().isUserLikes());
+ assertEquals(2, comment.getAttachments().size());
+ }
+
+ private void assertProfile(VKontakteProfile profile) {
+ assertEquals(3197366, profile.getId());
+ assertEquals("suppo", profile.getScreenName());
+ assertEquals("M", profile.getGender());
+ assertEquals(true, profile.isOnline());
+ }
}
diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/friends-get-without-fields-5_35.json b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/friends-get-without-fields-5_35.json
new file mode 100644
index 0000000..73a4296
--- /dev/null
+++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/friends-get-without-fields-5_35.json
@@ -0,0 +1,10 @@
+{
+ "response": {
+ "count": 718,
+ "items": [
+ 184760,
+ 3271875,
+ 680751
+ ]
+ }
+}
\ No newline at end of file
diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/list-of-profiles-5_27.json b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/list-of-profiles-5_27.json
index 3e8a12b..e06f53e 100644
--- a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/list-of-profiles-5_27.json
+++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/list-of-profiles-5_27.json
@@ -45,9 +45,13 @@
"audios": 0,
"notes": 6,
"photos": 188,
+ "groups": 123,
+ "gifts": 11,
"friends": 705,
"online_friends": 131,
"mutual_friends": 1,
+ "user_photos": 12,
+ "user_videos": 1,
"followers": 6155681,
"subscriptions": 0,
"pages": 37
diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/utils-execute-response-5_35.json b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/utils-execute-response-5_35.json
new file mode 100644
index 0000000..fec87a5
--- /dev/null
+++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/utils-execute-response-5_35.json
@@ -0,0 +1,240 @@
+{
+ "response": {
+ "post": {
+ "id": 175,
+ "from_id": 16051904,
+ "owner_id": 16051904,
+ "date": 1438767744,
+ "post_type": "post",
+ "text": "",
+ "copy_history": [
+ {
+ "id": 23577,
+ "owner_id": -60114472,
+ "from_id": -60114472,
+ "date": 1438743721,
+ "post_type": "post",
+ "text": "René Magritte",
+ "attachments": [
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542583,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a54/j29vXksmjtw.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a55/_inafzIXl6o.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26a56/JQ58ZpF7T98.jpg",
+ "photo_807": "https://pp.vk.me/c543101/v543101677/26a57/cEhY5JqPABw.jpg",
+ "width": 640,
+ "height": 532,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "3d8a69e9341e4e44ec"
+ }
+ },
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542584,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a5c/LRUr-ydV7ls.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a5d/ciOtHI88vP0.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26a5e/rftPC6GvRyQ.jpg",
+ "photo_807": "https://pp.vk.me/c543101/v543101677/26a5f/zCtqiD0EF04.jpg",
+ "width": 640,
+ "height": 799,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "e48368517e6a8e40b4"
+ }
+ },
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542585,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a64/_bJgQpcgrCs.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a65/3ebcbffCBFs.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26a66/9pmrLtry6aE.jpg",
+ "photo_807": "https://pp.vk.me/c543101/v543101677/26a67/-xMdKLMKxM8.jpg",
+ "width": 500,
+ "height": 700,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "dfb59f861e40c302a0"
+ }
+ },
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542586,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a6c/Eb1Pw97d8eA.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a6d/RIqRAdkMqaQ.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26a6e/BsfgVP9YbBg.jpg",
+ "photo_807": "https://pp.vk.me/c543101/v543101677/26a6f/n3jpPk3QG-4.jpg",
+ "width": 640,
+ "height": 351,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "9b2e6deb9886ce6b61"
+ }
+ },
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542587,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a74/b_ivrxTPuCk.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a75/2mC0wLr14rY.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26a76/IqiEm_LOvEA.jpg",
+ "photo_807": "https://pp.vk.me/c543101/v543101677/26a77/kP1O2I4kRi0.jpg",
+ "width": 640,
+ "height": 480,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "cf4c1d0dc3bc4c1e07"
+ }
+ },
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542588,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a7c/oR5QFjFZ6AM.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a7d/1clxLbH68LM.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26a7e/UVzIS9L9No8.jpg",
+ "photo_807": "https://pp.vk.me/c543101/v543101677/26a7f/lnDK5g2U8Ww.jpg",
+ "photo_1280": "https://pp.vk.me/c543101/v543101677/26a80/nf1UMlRiCy0.jpg",
+ "width": 640,
+ "height": 843,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "22cace3b223e511a59"
+ }
+ },
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542589,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a85/ImP5oYSw_rg.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a86/I3D8WGB6qzI.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26a87/PylA1209YpE.jpg",
+ "photo_807": "https://pp.vk.me/c543101/v543101677/26a88/_JW0W06DwjU.jpg",
+ "photo_1280": "https://pp.vk.me/c543101/v543101677/26a89/0h_oeDL1mQo.jpg",
+ "width": 640,
+ "height": 869,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "a1161d3406f887a021"
+ }
+ },
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542590,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a8e/reBCRflPqUc.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a8f/pPfh5BxfoQU.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26a90/3MBQfGrEhwY.jpg",
+ "photo_807": "https://pp.vk.me/c543101/v543101677/26a91/zdpgvjpLA7U.jpg",
+ "width": 640,
+ "height": 526,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "81e00501271e98c8af"
+ }
+ },
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542591,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a96/qhlqwJRED20.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a97/c5TlU2G4cws.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26a98/cvIkwyIEBME.jpg",
+ "photo_807": "https://pp.vk.me/c543101/v543101677/26a99/XyNPm9aljK0.jpg",
+ "width": 640,
+ "height": 798,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "f5b0c2cdec3c770910"
+ }
+ },
+ {
+ "type": "photo",
+ "photo": {
+ "id": 375542592,
+ "album_id": -7,
+ "owner_id": -60114472,
+ "user_id": 100,
+ "photo_75": "https://pp.vk.me/c543101/v543101677/26a9e/5Y8x_UVykgA.jpg",
+ "photo_130": "https://pp.vk.me/c543101/v543101677/26a9f/piwJlIg7jMY.jpg",
+ "photo_604": "https://pp.vk.me/c543101/v543101677/26aa0/Bbmw97OK6ag.jpg",
+ "width": 398,
+ "height": 600,
+ "text": "",
+ "date": 1438743720,
+ "access_key": "fe711c8eb518cc4499"
+ }
+ }
+ ],
+ "post_source": {
+ "type": "api"
+ }
+ }
+ ],
+ "can_edit": 1,
+ "can_delete": 1,
+ "can_pin": 1,
+ "post_source": {
+ "type": "vk"
+ },
+ "comments": {
+ "count": 0,
+ "can_post": 1
+ },
+ "likes": {
+ "count": 0,
+ "user_likes": 0,
+ "can_like": 1,
+ "can_publish": 0
+ },
+ "reposts": {
+ "count": 0,
+ "user_reposted": 0
+ }
+ },
+ "copy_owner": {
+ "id": 60114472,
+ "name": "Albertina",
+ "screen_name": "al_bertina",
+ "is_closed": 0,
+ "type": "page",
+ "is_admin": 0,
+ "is_member": 1,
+ "photo_50": "https://pp.vk.me/c312927/v312927711/4e8d/Gd1mm_PHYaI.jpg",
+ "photo_100": "https://pp.vk.me/c312927/v312927711/4e8c/mEkXL9VFsEA.jpg",
+ "photo_200": "https://pp.vk.me/c312927/v312927711/4e8b/8zPo3HESmow.jpg"
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/wall-getComments-response-5_33.json b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/wall-getComments-response-5_33.json
new file mode 100644
index 0000000..ddf6bcc
--- /dev/null
+++ b/spring-social-vkontakte/src/test/java/org/springframework/social/vkontakte/api/impl/wall-getComments-response-5_33.json
@@ -0,0 +1,153 @@
+{
+ "response": {
+ "count": 16,
+ "real_offset": 10,
+ "items": [
+ {
+ "id": 3205,
+ "from_id": 85635407,
+ "date": 1375980597,
+ "text": "[id3197366|Андрей], поправил",
+ "likes": {
+ "count": 666,
+ "user_likes": 1,
+ "can_like": 1
+ },
+ "reply_to_user": 3197366,
+ "reply_to_comment": 3200,
+ "attachments": [
+ {
+ "type": "photo",
+ "photo": {
+ "id": 308701914,
+ "album_id": -5,
+ "owner_id": 85635407,
+ "photo_75": "https:\/\/pp.vk.me\/c6035\/v6035288\/6ef0\/q4rguINFKc0.jpg",
+ "photo_130": "https:\/\/pp.vk.me\/c6035\/v6035288\/6ef1\/sjEQyroiYac.jpg",
+ "photo_604": "https:\/\/pp.vk.me\/c6035\/v6035288\/6ef2\/24e6zf6JT8E.jpg",
+ "width": 591,
+ "height": 118,
+ "text": "Original: http:\/\/s2.1pic.org\/files\/2013\/08\/08\/e89e7b5e6b7cfe6d8aa5.jpg",
+ "date": 1375979968,
+ "access_key": "f5083a22fe3d0b6f2f"
+ }
+ },
+ {
+ "type": "audio",
+ "audio": {
+ "id": 283017386,
+ "owner_id": 85635407,
+ "artist": "San Cisco",
+ "title": "Beach",
+ "duration": 227,
+ "url": "http://cs6191.vk.me/u156280183/audios/7453f3072442.mp3?extra=DtlNCRK0Wf-9AiLZiBKfB7rTCZjeeF2C7ri88acWH0rk-meDbDZMbGmTBaygzzeklPz7qxOlpASUpLjeJmNJCi0aVxUkz9w",
+ "lyrics_id": 125602217,
+ "album_id": 2,
+ "genre_id": 9
+ }
+ }
+ ]
+ },
+ {
+ "id": 3204,
+ "from_id": 85635407,
+ "date": 1375980529,
+ "text": "[id19498153|Макс], не могу =(",
+ "likes": {
+ "count": 0,
+ "user_likes": 0,
+ "can_like": 1
+ },
+ "reply_to_user": 19498153,
+ "reply_to_comment": 3203
+ },
+ {
+ "id": 3203,
+ "from_id": 19498153,
+ "date": 1375980513,
+ "text": "Лимит увеличь, молю!",
+ "likes": {
+ "count": 2,
+ "user_likes": 0,
+ "can_like": 1
+ }
+ },
+ {
+ "id": 3202,
+ "from_id": 40001922,
+ "date": 1375980076,
+ "text": "Наконец-то! Спасибо.",
+ "likes": {
+ "count": 2,
+ "user_likes": 0,
+ "can_like": 1
+ }
+ },
+ {
+ "id": 3201,
+ "from_id": 3197366,
+ "date": 1375979984,
+ "text": "И, я думаю, если я не админ, то мне не нужны фотографии сообщества, не?",
+ "likes": {
+ "count": 0,
+ "user_likes": 0,
+ "can_like": 1
+ }
+ },
+ {
+ "id": 3200,
+ "from_id": 3197366,
+ "date": 1375979966,
+ "text": "Однако баг:",
+ "likes": {
+ "count": 1,
+ "user_likes": 0,
+ "can_like": 1
+ }
+ }
+ ],
+ "profiles": [
+ {
+ "id": 3197366,
+ "first_name": "Андрей",
+ "last_name": "Андреев",
+ "sex": 2,
+ "screen_name": "suppo",
+ "photo_50": "https:\/\/pp.vk.me\/c629516\/v629516366\/2509e\/j1RWzBSsx34.jpg",
+ "photo_100": "https:\/\/pp.vk.me\/c629516\/v629516366\/2509d\/Y_WW-9c59KA.jpg",
+ "online": 1
+ },
+ {
+ "id": 19498153,
+ "first_name": "Максим",
+ "last_name": "Долженко",
+ "sex": 2,
+ "screen_name": "md",
+ "photo_50": "https:\/\/pp.vk.me\/c624816\/v624816153\/3866c\/bkxkxJ0xn5I.jpg",
+ "photo_100": "https:\/\/pp.vk.me\/c624816\/v624816153\/3866b\/fyT0u8Fr0Jo.jpg",
+ "online": 1
+ },
+ {
+ "id": 40001922,
+ "first_name": "Sergey",
+ "last_name": "Golitsyn",
+ "sex": 2,
+ "screen_name": "golitsyn",
+ "photo_50": "https:\/\/pp.vk.me\/c311621\/v311621922\/9ac0\/qtqzaeBwJkA.jpg",
+ "photo_100": "https:\/\/pp.vk.me\/c311621\/v311621922\/9abf\/0oziI23A7gI.jpg",
+ "online": 0
+ },
+ {
+ "id": 85635407,
+ "first_name": "Олег",
+ "last_name": "Илларионов",
+ "sex": 2,
+ "screen_name": "derp",
+ "photo_50": "https:\/\/pp.vk.me\/c620831\/v620831407\/1638f\/6qaLGdESeIw.jpg",
+ "photo_100": "https:\/\/pp.vk.me\/c620831\/v620831407\/1638e\/wKAZXphhssY.jpg",
+ "online": 0
+ }
+ ],
+ "groups": []
+ }
+}
\ No newline at end of file