Browse files

#13 Fixing issue with JSON bind exception when shouts list is empty, …

…and adding getFriends to user operations
  • Loading branch information...
1 parent 640139a commit 3841d0262ed6fc0d234ee2257f097f9d5099c048 @michaellavelle committed Dec 2, 2011
View
3 src/main/java/org/springframework/social/lastfm/api/UserOperations.java
@@ -32,6 +32,9 @@
public List<Track> getLovedTracks(String userName);
public List<Shout> getShouts(String userName);
+
+ public List<LastFmProfile> getFriends(String userName);
+
public List<Track> getTopTracks(String userName);
View
1 src/main/java/org/springframework/social/lastfm/api/impl/LastFmErrorHandler.java
@@ -153,6 +153,7 @@ private String readFully(InputStream in) throws IOException {
while (reader.ready()) {
sb.append(reader.readLine());
}
+ System.out.println(sb.toString());
return sb.toString();
}
View
14 src/main/java/org/springframework/social/lastfm/api/impl/UserTemplate.java
@@ -26,6 +26,7 @@
import org.springframework.social.lastfm.api.Track;
import org.springframework.social.lastfm.api.TrackDescriptor;
import org.springframework.social.lastfm.api.UserOperations;
+import org.springframework.social.lastfm.api.impl.json.LastFmFriendsResponse;
import org.springframework.social.lastfm.api.impl.json.LastFmLovedTracksResponse;
import org.springframework.social.lastfm.api.impl.json.LastFmProfileResponse;
import org.springframework.social.lastfm.api.impl.json.LastFmRecentTracksResponse;
@@ -186,4 +187,17 @@ public void shout(String userName, String message) {
LastFmShoutsResponse.class).getShoutListResponse().getShouts();
}
+ @Override
+ public List<LastFmProfile> getFriends(String userName) {
+ Map<String, String> additionalParams = new HashMap<String, String>();
+ additionalParams.put("user", userName);
+
+ LastFmApiMethodParameters methodParameters = new LastFmApiMethodParameters(
+ "user.getfriends", apiKey, null, null, additionalParams);
+
+ return restTemplate
+ .getForObject(buildLastFmApiUrl(methodParameters),
+ LastFmFriendsResponse.class).getUserListResponse().getUsers();
+ }
+
}
View
40 src/main/java/org/springframework/social/lastfm/api/impl/json/LastFmFriendsResponse.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 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.lastfm.api.impl.json;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * @author Michael Lavelle
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LastFmFriendsResponse {
+
+ private LastFmUserListResponse userListResponse;
+
+ @JsonCreator
+ public LastFmFriendsResponse(
+ @JsonProperty("friends") LastFmUserListResponse userListResponse) {
+ this.userListResponse = userListResponse;
+ }
+
+
+ public LastFmUserListResponse getUserListResponse() {
+ return userListResponse;
+ }
+}
View
2 src/main/java/org/springframework/social/lastfm/api/impl/json/LastFmModule.java
@@ -54,10 +54,12 @@ public void setupModule(SetupContext context) {
LastFmProfileMixin.class);
context.setMixInAnnotations(TrackListContainer.class, TrackMixin.class);
context.setMixInAnnotations(ShoutListContainer.class, ShoutMixin.class);
+ context.setMixInAnnotations(UserListContainer.class, LastFmProfileMixin.class);
context.setMixInAnnotations(Track.class, TrackMixin.class);
context.setMixInAnnotations(Shout.class, ShoutMixin.class);
+
context.setMixInAnnotations(SimpleTrack.class, SimpleTrackMixin.class);
context.setMixInAnnotations(TrackSearchResult.class,
TrackSearchResultMixin.class);
View
17 src/main/java/org/springframework/social/lastfm/api/impl/json/LastFmShoutListResponse.java
@@ -15,6 +15,7 @@
*/
package org.springframework.social.lastfm.api.impl.json;
+import java.util.ArrayList;
import java.util.List;
import org.codehaus.jackson.annotate.JsonCreator;
@@ -30,16 +31,22 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public class LastFmShoutListResponse {
- private List<Shout> shouts;
+ private ShoutListContainer shoutListContainer;
@JsonCreator
- public LastFmShoutListResponse(
- @JsonProperty("shout") ShoutListContainer shoutsContainer) {
- this.shouts = shoutsContainer.getShouts();
+ public LastFmShoutListResponse() {
+ this.shoutListContainer = new ShoutListContainer(new ArrayList<Shout>());
}
+
+
+ @JsonProperty("shout")
+ public void setShoutListContainer(ShoutListContainer shoutListContainer) {
+ this.shoutListContainer = shoutListContainer;
+ }
+
public List<Shout> getShouts() {
- return shouts;
+ return shoutListContainer.getShouts();
}
View
53 src/main/java/org/springframework/social/lastfm/api/impl/json/LastFmUserListResponse.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011 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.lastfm.api.impl.json;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.springframework.social.lastfm.api.LastFmProfile;
+import org.springframework.social.lastfm.api.Shout;
+import org.springframework.social.lastfm.api.SimpleTrack;
+import org.springframework.social.lastfm.api.Track;
+
+/**
+ * @author Michael Lavelle
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LastFmUserListResponse {
+
+ private UserListContainer userListContainer;
+
+
+ @JsonProperty("user")
+ public void setUsers(UserListContainer userListContainer) {
+ this.userListContainer = userListContainer;
+ }
+
+ @JsonCreator
+ public LastFmUserListResponse() {
+ this.userListContainer = new UserListContainer(new ArrayList<LastFmProfile>());
+ }
+
+ public List<LastFmProfile> getUsers() {
+ return userListContainer.getUsers();
+ }
+
+
+}
View
62 src/main/java/org/springframework/social/lastfm/api/impl/json/UserListContainer.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2011 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.lastfm.api.impl.json;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.springframework.social.lastfm.api.Artist;
+import org.springframework.social.lastfm.api.Image;
+import org.springframework.social.lastfm.api.LastFmProfile;
+import org.springframework.social.lastfm.api.Shout;
+import org.springframework.social.lastfm.api.SimpleTrack;
+import org.springframework.social.lastfm.api.Track;
+
+/**
+ * @author Michael Lavelle
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+/**
+ * Container for a shout list - allows for automatic JSON binding from *either* a list of Shouts
+ * or a Map representation of a single shout, as LastFm responds with different Json structures
+ * depending on whether a single shout is returned
+ *
+ * @author Michael Lavelle
+ */
+public class UserListContainer {
+
+ private List<LastFmProfile> users;
+
+ @JsonCreator
+ public UserListContainer(List<LastFmProfile> users) {
+ this.users = users;
+ }
+
+ public UserListContainer(String id, String name, String realName, String url,
+ List<Image> images) {
+ this.users = Arrays.asList(new LastFmProfile(id,name,realName,url,images));
+
+ }
+
+ public List<LastFmProfile> getUsers() {
+ return users;
+ }
+
+}
View
69 src/test/java/org/springframework/social/lastfm/api/UserTemplateTest.java
@@ -155,6 +155,75 @@ public void getShoutsSingleShoutResponse() {
assertShoutData(shouts.get(0));
}
+
+ @Test
+ public void getShoutsEmptyShoutsResponse() {
+
+ mockServer
+ .expect(requestTo("http://ws.audioscrobbler.com/2.0/?format=json&api_key=someApiKey&method=user.getshouts&user=mattslip"))
+ .andExpect(method(GET))
+ .andExpect(header("User-Agent", "someUserAgent"))
+ .andRespond(
+ withResponse(jsonResource("testdata/empty-shouts-response"),
+ responseHeaders));
+
+ List<Shout> shouts = lastFm.userOperations().getShouts("mattslip");
+ assertNotNull(shouts);
+ assertEquals(shouts.size(),0);
+ }
+
+ @Test
+ public void getFriendsEmptyFriendsResponse() {
+
+ mockServer
+ .expect(requestTo("http://ws.audioscrobbler.com/2.0/?format=json&api_key=someApiKey&method=user.getfriends&user=mattslip"))
+ .andExpect(method(GET))
+ .andExpect(header("User-Agent", "someUserAgent"))
+ .andRespond(
+ withResponse(jsonResource("testdata/empty-friends-response"),
+ responseHeaders));
+
+ List<LastFmProfile> friends = lastFm.userOperations().getFriends("mattslip");
+ assertNotNull(friends);
+ assertEquals(0,friends.size());
+ }
+
+ @Test
+ public void getFriends() {
+
+ mockServer
+ .expect(requestTo("http://ws.audioscrobbler.com/2.0/?format=json&api_key=someApiKey&method=user.getfriends&user=mattslip"))
+ .andExpect(method(GET))
+ .andExpect(header("User-Agent", "someUserAgent"))
+ .andRespond(
+ withResponse(jsonResource("testdata/friends"),
+ responseHeaders));
+
+ List<LastFmProfile> friends = lastFm.userOperations().getFriends("mattslip");
+ assertNotNull(friends);
+ assertEquals(3,friends.size());
+ }
+
+ @Test
+ public void getFriendsSingleFriendResponse() {
+
+ mockServer
+ .expect(requestTo("http://ws.audioscrobbler.com/2.0/?format=json&api_key=someApiKey&method=user.getfriends&user=mattslip"))
+ .andExpect(method(GET))
+ .andExpect(header("User-Agent", "someUserAgent"))
+ .andRespond(
+ withResponse(jsonResource("testdata/single-friend-response"),
+ responseHeaders));
+
+ List<LastFmProfile> friends = lastFm.userOperations().getFriends("mattslip");
+ assertNotNull(friends);
+ assertEquals(1,friends.size());
+ assertEquals("michaellavelle",friends.get(0).getName());
+ assertEquals("Michael Lavelle",friends.get(0).getRealName());
+ assertEquals("http://www.last.fm/user/michaellavelle",friends.get(0).getUrl());
+
+
+ }
/**
* Tests for the case where the loved tracks response contains only a single
View
1 ...test/resources/org/springframework/social/lastfm/api/testdata/empty-friends-response.json
@@ -0,0 +1 @@
+{"friends":{"#text":"\n","for":"mattslip","page":"0","perPage":"50","totalPages":"0","total":"0"}}
View
1 src/test/resources/org/springframework/social/lastfm/api/testdata/empty-shouts-response.json
@@ -0,0 +1 @@
+{"shouts":{"#text":"\n","user":"mattslip","page":"0","perPage":"50","totalPages":"0","total":"0"}}
View
1 src/test/resources/org/springframework/social/lastfm/api/testdata/friends.json
@@ -0,0 +1 @@
+{"friends":{"user":[{"name":"michaellavelle","realname":"Michael Lavelle","image":[{"#text":"http:\/\/userserve-ak.last.fm\/serve\/34\/71048878.jpg","size":"small"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/64\/71048878.jpg","size":"medium"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/126\/71048878.jpg","size":"large"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/252\/71048878.jpg","size":"extralarge"}],"url":"http:\/\/www.last.fm\/user\/cloudplaylists","id":"45738338","country":"","age":"","gender":"n","subscriber":"0","playcount":"131","playlists":"0","bootstrap":"1","registered":{"#text":"2011-11-17 18:43","unixtime":"1321555392"},"type":"user"},{"name":"electronicrumor","realname":"Clive 'Crash' Lewis","image":[{"#text":"http:\/\/userserve-ak.last.fm\/serve\/34\/43818993.jpg","size":"small"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/64\/43818993.jpg","size":"medium"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/126\/43818993.jpg","size":"large"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/252\/43818993.jpg","size":"extralarge"}],"url":"http:\/\/www.last.fm\/user\/electronicrumor","id":"18991221","country":"UK","age":"","gender":"m","subscriber":"0","playcount":"1772","playlists":"1","bootstrap":"0","registered":{"#text":"2009-05-29 10:17","unixtime":"1243592254"},"type":"user"},{"name":"londonpreppy","realname":"","image":[{"#text":"http:\/\/userserve-ak.last.fm\/serve\/34\/7885917.jpg","size":"small"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/64\/7885917.jpg","size":"medium"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/126\/7885917.jpg","size":"large"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/252\/7885917.jpg","size":"extralarge"}],"url":"http:\/\/www.last.fm\/user\/londonpreppy","id":"10895150","country":"","age":"","gender":"m","subscriber":"0","playcount":"69602","playlists":"0","bootstrap":"0","registered":{"#text":"2008-06-16 20:21","unixtime":"1213647697"},"type":"user"}],"@attr":{"for":"mattslip","page":"1","perPage":"50","totalPages":"1","total":"3"}}}
View
1 ...test/resources/org/springframework/social/lastfm/api/testdata/single-friend-response.json
@@ -0,0 +1 @@
+{"friends":{"user":{"name":"michaellavelle","realname":"Michael Lavelle","image":[{"#text":"http:\/\/userserve-ak.last.fm\/serve\/34\/56822959.jpg","size":"small"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/64\/56822959.jpg","size":"medium"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/126\/56822959.jpg","size":"large"},{"#text":"http:\/\/userserve-ak.last.fm\/serve\/252\/56822959.jpg","size":"extralarge"}],"url":"http:\/\/www.last.fm\/user\/michaellavelle","id":"24378090","country":"","age":"","gender":"n","subscriber":"0","playcount":"34942","playlists":"6","bootstrap":"0","registered":{"#text":"2009-12-05 19:43","unixtime":"1260042206"},"type":"user"},"@attr":{"for":"pauliny1","page":"1","perPage":"50","totalPages":"1","total":"1"}}}

0 comments on commit 3841d02

Please sign in to comment.