Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Overriding getOAuth2Version() in SoundCloudTemplate to correct issue …

…with token not being set correctly in request headers. Api restructuring, correction of SoundCloudErrorHandler, and commenting
  • Loading branch information...
commit 5fc8e7919b753533d179825658077f13204feece 1 parent fffb992
@michaellavelle authored
Showing with 644 additions and 126 deletions.
  1. +22 −0 .classpath
  2. +13 −0 .project
  3. +5 −0 .settings/org.eclipse.jdt.core.prefs
  4. +1 −0  bin
  5. +11 −0 src/main/java/org/springframework/social/soundcloud/api/MeOperations.java
  6. +15 −0 src/main/java/org/springframework/social/soundcloud/api/ResolveOperations.java
  7. +11 −1 src/main/java/org/springframework/social/soundcloud/api/SoundCloud.java
  8. +0 −1  src/main/java/org/springframework/social/soundcloud/api/SoundCloudProfile.java
  9. +26 −0 src/main/java/org/springframework/social/soundcloud/api/Track.java
  10. +12 −1 src/main/java/org/springframework/social/soundcloud/api/UserOperations.java
  11. +13 −0 src/main/java/org/springframework/social/soundcloud/api/UsersOperations.java
  12. +18 −0 src/main/java/org/springframework/social/soundcloud/api/impl/AbstractSoundCloudOperations.java
  13. +21 −0 src/main/java/org/springframework/social/soundcloud/api/impl/AbstractSoundCloudResourceOperations.java
  14. +55 −0 src/main/java/org/springframework/social/soundcloud/api/impl/AbstractUserTemplate.java
  15. +22 −0 src/main/java/org/springframework/social/soundcloud/api/impl/MeTemplate.java
  16. +58 −0 src/main/java/org/springframework/social/soundcloud/api/impl/ResolveTemplate.java
  17. +99 −83 src/main/java/org/springframework/social/soundcloud/api/impl/SoundCloudErrorHandler.java
  18. +48 −9 src/main/java/org/springframework/social/soundcloud/api/impl/SoundCloudTemplate.java
  19. +10 −14 src/main/java/org/springframework/social/soundcloud/api/impl/UserTemplate.java
  20. +28 −0 src/main/java/org/springframework/social/soundcloud/api/impl/UsersTemplate.java
  21. +3 −0  src/main/java/org/springframework/social/soundcloud/api/impl/json/SoundCloudModule.java
  22. +0 −4 src/main/java/org/springframework/social/soundcloud/api/impl/json/SoundCloudProfileMixin.java
  23. +14 −0 src/main/java/org/springframework/social/soundcloud/api/impl/json/TrackList.java
  24. +23 −0 src/main/java/org/springframework/social/soundcloud/api/impl/json/TrackMixin.java
  25. +3 −3 src/main/java/org/springframework/social/soundcloud/connect/SoundCloudAdapter.java
  26. +4 −0 src/main/java/org/springframework/social/soundcloud/connect/SoundCloudConnectionFactory.java
  27. +16 −1 src/main/java/org/springframework/social/soundcloud/connect/SoundCloudOAuth2Template.java
  28. +4 −0 src/main/java/org/springframework/social/soundcloud/connect/SoundCloudServiceProvider.java
  29. +10 −9 src/test/java/org/springframework/social/soundcloud/connect/SoundCloudAdapterTest.java
  30. BIN  target/classes/org/springframework/social/soundcloud/api/MeOperations.class
  31. BIN  target/classes/org/springframework/social/soundcloud/api/ResolveOperations.class
  32. BIN  target/classes/org/springframework/social/soundcloud/api/SoundCloud.class
  33. BIN  target/classes/org/springframework/social/soundcloud/api/SoundCloudProfile.class
  34. BIN  target/classes/org/springframework/social/soundcloud/api/Track.class
  35. BIN  target/classes/org/springframework/social/soundcloud/api/UserOperations.class
  36. BIN  target/classes/org/springframework/social/soundcloud/api/UsersOperations.class
  37. BIN  target/classes/org/springframework/social/soundcloud/api/impl/AbstractSoundCloudOperations.class
  38. BIN  target/classes/org/springframework/social/soundcloud/api/impl/AbstractSoundCloudResourceOperations.class
  39. BIN  target/classes/org/springframework/social/soundcloud/api/impl/AbstractUserTemplate.class
  40. BIN  target/classes/org/springframework/social/soundcloud/api/impl/MeTemplate.class
  41. BIN  target/classes/org/springframework/social/soundcloud/api/impl/ResolveTemplate.class
  42. BIN  target/classes/org/springframework/social/soundcloud/api/impl/SoundCloudErrorHandler$1.class
  43. BIN  target/classes/org/springframework/social/soundcloud/api/impl/SoundCloudErrorHandler$2.class
  44. BIN  target/classes/org/springframework/social/soundcloud/api/impl/SoundCloudErrorHandler.class
  45. BIN  target/classes/org/springframework/social/soundcloud/api/impl/SoundCloudTemplate.class
  46. BIN  target/classes/org/springframework/social/soundcloud/api/impl/UserTemplate.class
  47. BIN  target/classes/org/springframework/social/soundcloud/api/impl/UsersTemplate.class
  48. BIN  target/classes/org/springframework/social/soundcloud/api/impl/json/SoundCloudModule.class
  49. BIN  target/classes/org/springframework/social/soundcloud/api/impl/json/SoundCloudProfileMixin.class
  50. BIN  target/classes/org/springframework/social/soundcloud/api/impl/json/TrackList.class
  51. BIN  target/classes/org/springframework/social/soundcloud/api/impl/json/TrackMixin.class
  52. BIN  target/classes/org/springframework/social/soundcloud/connect/SoundCloudAdapter.class
  53. BIN  target/classes/org/springframework/social/soundcloud/connect/SoundCloudConnectionFactory.class
  54. BIN  target/classes/org/springframework/social/soundcloud/connect/SoundCloudOAuth2Template.class
  55. BIN  target/classes/org/springframework/social/soundcloud/connect/SoundCloudServiceProvider.class
  56. +5 −0 target/maven-archiver/pom.properties
  57. BIN  target/spring-social-soundcloud-1.0.0-SNAPSHOT.jar
  58. +70 −0 target/surefire-reports/TEST-org.springframework.social.soundcloud.connect.SoundCloudAdapterTest.xml
  59. +4 −0 target/surefire-reports/org.springframework.social.soundcloud.connect.SoundCloudAdapterTest.txt
  60. BIN  target/test-classes/org/springframework/social/soundcloud/connect/SoundCloudAdapterTest$1.class
  61. BIN  ...test-classes/org/springframework/social/soundcloud/connect/SoundCloudAdapterTest$TestConnectionValues.class
  62. BIN  target/test-classes/org/springframework/social/soundcloud/connect/SoundCloudAdapterTest.class
View
22 .classpath
@@ -0,0 +1,22 @@
+<classpath>
+ <classpathentry kind="src" path="src/test/java" output="target/test-classes" including="**/*.java"/>
+ <classpathentry kind="src" path="src/main/java" including="**/*.java"/>
+ <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/codehaus/jackson/jackson-core-asl/1.8.5/jackson-core-asl-1.8.5.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/codehaus/jackson/jackson-mapper-asl/1.8.5/jackson-mapper-asl-1.8.5.jar"/>
+ <classpathentry kind="var" path="M2_REPO/junit/junit/4.8.2/junit-4.8.2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/mockito/mockito-all/1.8.5/mockito-all-1.8.5.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-aop/3.1.0.M2/spring-aop-3.1.0.M2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-asm/3.1.0.M2/spring-asm-3.1.0.M2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/3.1.0.M2/spring-beans-3.1.0.M2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/3.1.0.M2/spring-context-3.1.0.M2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/3.1.0.M2/spring-core-3.1.0.M2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-expression/3.1.0.M2/spring-expression-3.1.0.M2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/social/spring-social-core/1.0.0.RC3/spring-social-core-1.0.0.RC3.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/social/spring-social-test/1.0.0.RC3/spring-social-test-1.0.0.RC3.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-test/3.1.0.M2/spring-test-3.1.0.M2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-web/3.1.0.M2/spring-web-3.1.0.M2.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+</classpath>
View
13 .project
@@ -0,0 +1,13 @@
+<projectDescription>
+ <name>spring-social-soundcloud</name>
+ <comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
+ <projects/>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
5 .settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+#Sat Sep 03 18:33:41 BST 2011
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
1  bin
@@ -0,0 +1 @@
+Subproject commit fffb9920c0954e5544f792054d7695bfd29bb1b2
View
11 src/main/java/org/springframework/social/soundcloud/api/MeOperations.java
@@ -0,0 +1,11 @@
+package org.springframework.social.soundcloud.api;
+
+/**
+* Defines operations for interacting with the current authenticated SoundCloud User, a special
+* case of UserOperations
+* @author Michael Lavelle
+*/
+public interface MeOperations extends UserOperations{
+
+
+}
View
15 src/main/java/org/springframework/social/soundcloud/api/ResolveOperations.java
@@ -0,0 +1,15 @@
+package org.springframework.social.soundcloud.api;
+
+
+/**
+* Defines operations for interacting with a SoundCloud resource
+* @author Michael Lavelle
+*/
+public interface ResolveOperations {
+
+ public <T> T resolveSoundCloudResource(String resourceUrl,Class<T> t);
+ public SoundCloudProfile resolveUserProfile(String username);
+ public Track resolveTrack(String trackUrl);
+
+
+}
View
12 src/main/java/org/springframework/social/soundcloud/api/SoundCloud.java
@@ -1,8 +1,18 @@
package org.springframework.social.soundcloud.api;
+import org.springframework.social.soundcloud.api.impl.SoundCloudTemplate;
+
+/**
+* Interface specifying a basic set of operations for interacting with SoundCloud.
+* Implemented by {@link SoundCloudTemplate}.
+* @author Michael Lavelle
+*/
public interface SoundCloud {
- public UserOperations userOperations();
+ public MeOperations meOperations();
+ public UsersOperations usersOperations();
+ public ResolveOperations resolveOperations();
+
}
View
1  src/main/java/org/springframework/social/soundcloud/api/SoundCloudProfile.java
@@ -1,7 +1,6 @@
package org.springframework.social.soundcloud.api;
import java.io.Serializable;
-import java.util.List;
/**
* Model class containing a SoundCloud user's profile information.
View
26 src/main/java/org/springframework/social/soundcloud/api/Track.java
@@ -0,0 +1,26 @@
+package org.springframework.social.soundcloud.api;
+
+public class Track {
+
+ private String permalinkUrl;
+ private String title;
+ public String getPermalinkUrl() {
+ return permalinkUrl;
+ }
+ public void setPermalinkUrl(String permalinkUrl) {
+ this.permalinkUrl = permalinkUrl;
+ }
+ public String getTitle() {
+ return title;
+ }
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public Track(String permalinkUrl,String title)
+ {
+ this.title = title;
+ this.permalinkUrl = permalinkUrl;
+ }
+
+}
View
13 src/main/java/org/springframework/social/soundcloud/api/UserOperations.java
@@ -1,7 +1,18 @@
package org.springframework.social.soundcloud.api;
+import java.util.List;
+
+/**
+* Defines operations for interacting with a SoundCloud User
+* @author Michael Lavelle
+*/
public interface UserOperations {
-
+
public SoundCloudProfile getUserProfile();
+ public void updateUserProfile(SoundCloudProfile profile);
+ public List<Track> getFavorites();
+ public List<Track> getTracks();
+ public void favoriteTrack(long trackId);
+
}
View
13 src/main/java/org/springframework/social/soundcloud/api/UsersOperations.java
@@ -0,0 +1,13 @@
+package org.springframework.social.soundcloud.api;
+
+/**
+* Defines a means of obtaining UserOperations for a given SoundCloud user id
+* @author Michael Lavelle
+*/
+public interface UsersOperations {
+
+ public UserOperations userOperations(long userId);
+ public UserOperations userOperations(String username);
+
+
+}
View
18 ...ain/java/org/springframework/social/soundcloud/api/impl/AbstractSoundCloudOperations.java
@@ -1,5 +1,23 @@
package org.springframework.social.soundcloud.api.impl;
+import org.springframework.web.client.RestTemplate;
+
public abstract class AbstractSoundCloudOperations {
+
+ protected final RestTemplate restTemplate;
+ protected final boolean isAuthorizedForUser;
+ public AbstractSoundCloudOperations(RestTemplate restTemplate, boolean isAuthorizedForUser) {
+ this.restTemplate = restTemplate;
+ this.isAuthorizedForUser = isAuthorizedForUser;
+ }
+
+ protected String getApiBaseUrl()
+ {
+ return "https://api.soundcloud.com";
+ }
+
+
+
+
}
View
21 .../org/springframework/social/soundcloud/api/impl/AbstractSoundCloudResourceOperations.java
@@ -0,0 +1,21 @@
+package org.springframework.social.soundcloud.api.impl;
+
+import org.springframework.web.client.RestTemplate;
+
+public abstract class AbstractSoundCloudResourceOperations extends AbstractSoundCloudOperations{
+
+ public AbstractSoundCloudResourceOperations(RestTemplate restTemplate, boolean isAuthorizedForUser) {
+ super(restTemplate,isAuthorizedForUser);
+ }
+
+ protected abstract String getApiResourceBaseUrl();
+
+ protected String getApiResourceUrl(String resourcePath)
+ {
+ return getApiResourceBaseUrl() + resourcePath;
+ }
+
+
+
+
+}
View
55 src/main/java/org/springframework/social/soundcloud/api/impl/AbstractUserTemplate.java
@@ -0,0 +1,55 @@
+package org.springframework.social.soundcloud.api.impl;
+
+import java.util.List;
+
+import org.springframework.social.soundcloud.api.SoundCloudProfile;
+import org.springframework.social.soundcloud.api.Track;
+import org.springframework.social.soundcloud.api.UserOperations;
+import org.springframework.social.soundcloud.api.impl.json.TrackList;
+import org.springframework.web.client.RestTemplate;
+
+public abstract class AbstractUserTemplate extends AbstractSoundCloudResourceOperations implements UserOperations {
+
+ public AbstractUserTemplate(RestTemplate restTemplate,
+ boolean isAuthorizedForUser) {
+ super(restTemplate, isAuthorizedForUser);
+ }
+ protected abstract String getUsersResourcePrefix();
+
+ @Override
+ protected String getApiResourceBaseUrl() {
+ return getApiBaseUrl() + getUsersResourcePrefix();
+ }
+
+
+ @Override
+ public void favoriteTrack(long trackId) {
+ restTemplate.put(getApiResourceUrl("/favorites/" + trackId),null);
+
+ }
+
+
+ @Override
+ public void updateUserProfile(SoundCloudProfile profile) {
+ restTemplate.put(getApiResourceUrl(""), profile);
+ }
+
+
+ @Override
+ public SoundCloudProfile getUserProfile() {
+ return restTemplate.getForObject(getApiResourceUrl(""), SoundCloudProfile.class);
+ }
+
+ @Override
+ public List<Track> getFavorites() {
+ return restTemplate.getForObject(getApiResourceUrl("/favorites"), TrackList.class);
+ }
+
+ @Override
+ public List<Track> getTracks() {
+ return restTemplate.getForObject(getApiResourceUrl("/tracks"), TrackList.class);
+ }
+
+
+
+}
View
22 src/main/java/org/springframework/social/soundcloud/api/impl/MeTemplate.java
@@ -0,0 +1,22 @@
+package org.springframework.social.soundcloud.api.impl;
+
+import org.springframework.social.soundcloud.api.MeOperations;
+import org.springframework.web.client.RestTemplate;
+
+public class MeTemplate extends AbstractUserTemplate implements MeOperations {
+
+ public MeTemplate(RestTemplate restTemplate, boolean isAuthorizedForUser) {
+ super(restTemplate, isAuthorizedForUser);
+ }
+
+ @Override
+ protected String getUsersResourcePrefix() {
+ return "/me";
+ }
+
+
+
+
+
+
+}
View
58 src/main/java/org/springframework/social/soundcloud/api/impl/ResolveTemplate.java
@@ -0,0 +1,58 @@
+package org.springframework.social.soundcloud.api.impl;
+
+
+
+import org.springframework.social.soundcloud.api.ResolveOperations;
+import org.springframework.social.soundcloud.api.SoundCloudProfile;
+import org.springframework.social.soundcloud.api.Track;
+import org.springframework.web.client.RestTemplate;
+
+public class ResolveTemplate extends AbstractSoundCloudResourceOperations implements ResolveOperations {
+
+
+
+
+ public ResolveTemplate(RestTemplate restTemplate,
+ boolean isAuthorizedForUser) {
+ super(restTemplate, isAuthorizedForUser);
+ }
+
+ protected String getResolvableResourceBaseUrl()
+ {
+ return "http://soundcloud.com";
+ }
+
+ protected String getResolvableResourceUrl(String resourcePath)
+ {
+ return getResolvableResourceBaseUrl() + resourcePath;
+ }
+
+ @Override
+ protected String getApiResourceBaseUrl() {
+ return getApiBaseUrl() + "/resolve";
+ }
+
+ @Override
+ public <T> T resolveSoundCloudResource(String resourceUrl,Class<T> t)
+ {
+ return restTemplate.getForObject(getApiResourceUrl("?url=" + resourceUrl), t);
+ }
+
+ @Override
+ public SoundCloudProfile resolveUserProfile(String username)
+ {
+ return resolveSoundCloudResource(getResolvableResourceUrl("/" + username),SoundCloudProfile.class);
+ }
+
+ @Override
+ public Track resolveTrack(String trackUrl)
+ {
+ return resolveSoundCloudResource(trackUrl,Track.class);
+ }
+
+
+
+
+
+
+}
View
182 src/main/java/org/springframework/social/soundcloud/api/impl/SoundCloudErrorHandler.java
@@ -5,6 +5,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.codehaus.jackson.JsonFactory;
@@ -13,19 +16,13 @@
import org.codehaus.jackson.type.TypeReference;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.social.DuplicateStatusException;
-import org.springframework.social.ExpiredAuthorizationException;
-import org.springframework.social.InsufficientPermissionException;
import org.springframework.social.InternalServerErrorException;
import org.springframework.social.InvalidAuthorizationException;
-import org.springframework.social.MissingAuthorizationException;
import org.springframework.social.NotAuthorizedException;
import org.springframework.social.OperationNotPermittedException;
-import org.springframework.social.RateLimitExceededException;
import org.springframework.social.ResourceNotFoundException;
-import org.springframework.social.RevokedAuthorizationException;
+import org.springframework.social.ServerDownException;
import org.springframework.social.UncategorizedApiException;
-
import org.springframework.web.client.DefaultResponseErrorHandler;
/**
@@ -37,7 +34,8 @@
@Override
public void handleError(ClientHttpResponse response) throws IOException {
- Map<String, String> errorDetails = extractErrorDetailsFromResponse(response);
+ List<Map<String,String>> errorDetails = extractErrorDetailsFromResponse(response);
+
if (errorDetails == null) {
handleUncategorizedError(response, errorDetails);
}
@@ -54,122 +52,140 @@ public boolean hasError(ClientHttpResponse response) throws IOException {
return true;
}
// only bother checking the body for errors if we get past the default error check
- String content = readFully(response.getBody());
- return content.startsWith("{\"error\":") || content.equals("false");
+ String content = readFully(response.getBody());
+ return content.startsWith("{\"errors\":");
+
+ }
+
+
+ private boolean isMessageContainingText(List<String> messages,String text)
+ {
+ for (String message :messages)
+ {
+ return message.contains(text);
+ }
+ return false;
+ }
+
+ private boolean isMessageStartsWithText(List<String> messages,String text)
+ {
+ for (String message :messages)
+ {
+ return message.startsWith(text);
+ }
+ return false;
+ }
+
+ private String constructMessage(List<String> messages)
+ {
+ return messages.toString();
}
/**
- * Examines the error data returned from Facebook and throws the most applicable exception.
- * @param errorDetails a Map containing a "type" and a "message" corresponding to the Graph API's error response structure.
+ * Examines the error data returned from SoundCloud and throws the most applicable exception.
+ * @param errorDetails a Map containing an "error_message"
*/
- void handleSoundCloudError(HttpStatus statusCode, Map<String, String> errorDetails) {
+ void handleSoundCloudError(HttpStatus statusCode, List<Map<String, String>> errorDetailsList) {
// Can't trust the type to be useful. It's often OAuthException, even for things not OAuth-related.
// Can rely only on the message (which itself isn't very consistent).
- String message = errorDetails.get("message");
-
+ List<String> messages = new ArrayList<String>();
+ for (Map<String,String> errorDetails : errorDetailsList)
+ {
+ String message = errorDetails.get("error_message");
+ messages.add(message);
+ }
+ String message = constructMessage(messages);
+
if (statusCode == HttpStatus.OK) {
- if (message.contains("Some of the aliases you requested do not exist")) {
- throw new ResourceNotFoundException(message);
- }
+
} else if (statusCode == HttpStatus.BAD_REQUEST) {
- if (message.contains("Unknown path components")) {
throw new ResourceNotFoundException(message);
- } else if (message.equals("An access token is required to request this resource.")) {
- throw new MissingAuthorizationException();
- } else if (message.equals("An active access token must be used to query information about the current user.")) {
- throw new MissingAuthorizationException();
- } else if (message.startsWith("Error validating access token")) {
- handleInvalidAccessToken(message);
- } else if (message.equals("Error validating application.")) { // Access token with incorrect app ID
- throw new InvalidAuthorizationException(message);
- } else if (message.equals("Invalid access token signature.")) { // Access token that fails signature validation
- throw new InvalidAuthorizationException(message);
- } else if (message.contains("Application does not have the capability to make this API call.") || message.contains("App must be on whitelist")) {
- throw new OperationNotPermittedException(message);
- } else if (message.contains("Invalid fbid") || message.contains("The parameter url is required")) {
- throw new OperationNotPermittedException("Invalid object for this operation");
- } else if (message.contains("Duplicate status message") ) {
- throw new DuplicateStatusException(message);
- } else if (message.contains("Feed action request limit reached")) {
- throw new RateLimitExceededException();
- }
+
} else if (statusCode == HttpStatus.UNAUTHORIZED) {
- if (message.startsWith("Error validating access token")) {
+ if (isMessageStartsWithText(messages,"invalid_token")) {
handleInvalidAccessToken(message);
}
throw new NotAuthorizedException(message);
} else if (statusCode == HttpStatus.FORBIDDEN) {
- if (message.contains("Requires extended permission")) {
- String requiredPermission = message.split(": ")[1];
- throw new InsufficientPermissionException(requiredPermission);
- } else if (message.contains("Permissions error")) {
- throw new InsufficientPermissionException();
- } else {
+
throw new OperationNotPermittedException(message);
- }
} else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR) {
- if (message.equals("User must be an owner of the friendlist")) { // watch for pattern in similar message in other resources
- // TODO MLthrow new ResourceOwnershipException(message);
- } else if (message.equals("The member must be a friend of the current user.")) {
- // TODO ML throw new NotAFriendException(message);
- } else {
throw new InternalServerErrorException(message);
- }
}
+ else if (statusCode == HttpStatus.SERVICE_UNAVAILABLE) {
+ throw new ServerDownException(message);
+ }
}
private void handleInvalidAccessToken(String message) {
- if (message.contains("Session has expired at unix time")) {
- throw new ExpiredAuthorizationException();
- } else if (message.contains("The session has been invalidated because the user has changed the password.")) {
- throw new RevokedAuthorizationException();
- } else if (message.contains("The session is invalid because the user logged out.")) {
- throw new RevokedAuthorizationException();
- } else if (message.contains("has not authorized application")) {
- // Per https://developers.facebook.com/blog/post/500/, this could be in the message when the user removes the application.
- // In reality, "The session has been invalidated because the user has changed the password." is what you get in that case.
- // Leaving this check in place in case there FB does return this message (could be a bug in FB?)
- throw new RevokedAuthorizationException();
- } else {
- throw new InvalidAuthorizationException(message);
+ if (message.contains("invalid_token")) {
+ throw new InvalidAuthorizationException("An invalid token was supplied");
+ }
+ else {
+ throw new InvalidAuthorizationException(message);
}
}
- private void handleUncategorizedError(ClientHttpResponse response, Map<String, String> errorDetails) {
+ private void handleUncategorizedError(ClientHttpResponse response, List<Map<String, String>> errorDetails) {
try {
super.handleError(response);
} catch (Exception e) {
if (errorDetails != null) {
- throw new UncategorizedApiException(errorDetails.get("message"), e);
+ String m = "";
+ throw new UncategorizedApiException(m, e);
} else {
- throw new UncategorizedApiException("No error details from Facebook", e);
+ throw new UncategorizedApiException("No error details from SoundCloud", e);
}
}
}
/*
- * Attempts to extract Facebook error details from the response.
+ * Attempts to extract SoundCloud error details from the response.
* Returns null if the response doesn't match the expected JSON error response.
*/
@SuppressWarnings("unchecked")
- private Map<String, String> extractErrorDetailsFromResponse(ClientHttpResponse response) throws IOException {
+ private List<Map<String,String>> extractErrorDetailsFromResponse(ClientHttpResponse response) throws IOException {
+
ObjectMapper mapper = new ObjectMapper(new JsonFactory());
- String json = readFully(response.getBody());
- if (json.equals("false")) {
- // Sometimes FB returns "false" when requesting an object that the access token doesn't have permission for.
- throw new InsufficientPermissionException();
+ List<String> authenticateHeaders = response.getHeaders().get("Www-Authenticate");
+ String authenticateHeader = authenticateHeaders == null || authenticateHeaders.size() == 0 ? null : authenticateHeaders.get(0);
+ String json = null;
+ if (authenticateHeader != null)
+ {
+ json = "{" + authenticateHeader.replace('=', ':').replace("OAuth realm", "\"OAuth realm\"").replace("error", "\"error\"") + "}";
+ try {
+ Map<String, String> responseMap = mapper.<Map<String, String>>readValue(json, new TypeReference<Map<String, String>>() {});
+ List<Map<String,String>> errorsList = new ArrayList<Map<String,String>>();
+ if (responseMap.containsKey("error")) {
+ Map<String,String> errorMap = new HashMap<String,String>();
+ errorMap.put("error_message", responseMap.get("error"));
+ errorsList.add( errorMap);
+ return errorsList;
+ }
+
+ } catch (JsonParseException e) {
+ return null;
+ }
}
-
- try {
- Map<String, Object> responseMap = mapper.<Map<String, Object>>readValue(json, new TypeReference<Map<String, Object>>() {});
- if (responseMap.containsKey("error")) {
- return (Map<String, String>) responseMap.get("error");
- }
- } catch (JsonParseException e) {
- return null;
+ else
+ {
+ json = readFully(response.getBody());
+ try {
+ Map<String, Object> responseMap = mapper.<Map<String, Object>>readValue(json, new TypeReference<Map<String, Object>>() {});
+ if (responseMap.containsKey("errors")) {
+ return (List<Map<String,String>>) responseMap.get("errors");
+ }
+ else
+ {
+ return null;
+ }
+ } catch (JsonParseException e) {
+ return null;
+ }
}
- return null;
+ return null;
+
}
private String readFully(InputStream in) throws IOException {
View
57 src/main/java/org/springframework/social/soundcloud/api/impl/SoundCloudTemplate.java
@@ -6,9 +6,13 @@
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
+import org.springframework.social.NotAuthorizedException;
import org.springframework.social.oauth2.AbstractOAuth2ApiBinding;
+import org.springframework.social.oauth2.OAuth2Version;
+import org.springframework.social.soundcloud.api.MeOperations;
+import org.springframework.social.soundcloud.api.ResolveOperations;
import org.springframework.social.soundcloud.api.SoundCloud;
-import org.springframework.social.soundcloud.api.UserOperations;
+import org.springframework.social.soundcloud.api.UsersOperations;
import org.springframework.social.soundcloud.api.impl.json.SoundCloudModule;
import org.springframework.social.support.ClientHttpRequestFactorySelector;
import org.springframework.web.client.RestTemplate;
@@ -16,9 +20,22 @@
public class SoundCloudTemplate extends AbstractOAuth2ApiBinding implements
SoundCloud {
- private UserOperations userOperations;
+ private MeOperations meOperations;
+ private UsersOperations usersOperations;
+ private ResolveOperations resolveOperations;
+
+
+
private ObjectMapper objectMapper;
+
+
+
+ @Override
+ protected OAuth2Version getOAuth2Version() {
+ return OAuth2Version.DRAFT_10;
+ }
+
/**
* Create a new instance of SoundCloudTemplate. This constructor creates a
@@ -34,16 +51,15 @@ public SoundCloudTemplate() {
}
/**
- * Create a new instance of FacebookTemplate. This constructor creates the
- * FacebookTemplate using a given access token.
+ * Create a new instance of SoundCloudTemplate. This constructor creates the
+ * SoundCloudTemplate using a given access token.
*
* @param accessToken
- * An access token given by Facebook after a successful OAuth 2
+ * An access token given by SoundCloud after a successful OAuth 2
* authentication (or through Facebook's JS library).
*/
public SoundCloudTemplate(String accessToken) {
super(accessToken);
- System.out.println("MY ACCESS TOKEN IS:" + accessToken);
initialize(accessToken);
}
@@ -56,12 +72,16 @@ public SoundCloudTemplate(String accessToken) {
}
@Override
- public UserOperations userOperations() {
- return userOperations;
+ public MeOperations meOperations() {
+ return meOperations;
}
private void initSubApis(String accessToken) {
- userOperations = new UserTemplate(getRestTemplate(),accessToken,isAuthorized());
+ usersOperations = new UsersTemplate(getRestTemplate(),isAuthorized());
+ meOperations = new MeTemplate(getRestTemplate(),isAuthorized());
+ resolveOperations = new ResolveTemplate(getRestTemplate(),isAuthorized());
+
+
}
@@ -71,10 +91,19 @@ private void initialize(String accessToken) {
getRestTemplate().setErrorHandler(new SoundCloudErrorHandler());
// Wrap the request factory with a BufferingClientHttpRequestFactory so
// that the error handler can do repeat reads on the response.getBody()
+
super.setRequestFactory(ClientHttpRequestFactorySelector
.bufferRequests(getRestTemplate().getRequestFactory()));
initSubApis(accessToken);
+
+
+
+
}
+
+
+
+
private void registerSoundCloudJsonModule(RestTemplate restTemplate2) {
objectMapper = new ObjectMapper();
@@ -88,5 +117,15 @@ private void registerSoundCloudJsonModule(RestTemplate restTemplate2) {
}
}
}
+
+ @Override
+ public UsersOperations usersOperations() {
+ return usersOperations;
+ }
+
+ @Override
+ public ResolveOperations resolveOperations() {
+ return resolveOperations;
+ }
}
View
24 src/main/java/org/springframework/social/soundcloud/api/impl/UserTemplate.java
@@ -1,28 +1,24 @@
package org.springframework.social.soundcloud.api.impl;
-import org.codehaus.jackson.JsonNode;
-import org.springframework.social.soundcloud.api.SoundCloudProfile;
import org.springframework.social.soundcloud.api.UserOperations;
import org.springframework.web.client.RestTemplate;
-public class UserTemplate implements UserOperations {
+public class UserTemplate extends AbstractUserTemplate implements UserOperations {
- private final RestTemplate restTemplate;
- private String accessToken;
+ public UserTemplate(RestTemplate restTemplate, long userId, boolean isAuthorizedForUser) {
+ super(restTemplate, isAuthorizedForUser);
+ this.userId = userId;
+ }
+
+ private long userId;
+
@Override
- public SoundCloudProfile getUserProfile() {
- return restTemplate.getForObject("https://api.soundcloud.com/me?oauth_token=" + accessToken, SoundCloudProfile.class);
+ protected String getUsersResourcePrefix() {
+ return "/users/" + userId;
}
-
- public UserTemplate(RestTemplate restTemplate, String accessToken, boolean isAuthorizedForUser) {
- this.restTemplate = restTemplate;
- this.accessToken = accessToken;
- }
-
-
View
28 src/main/java/org/springframework/social/soundcloud/api/impl/UsersTemplate.java
@@ -0,0 +1,28 @@
+package org.springframework.social.soundcloud.api.impl;
+
+import org.springframework.social.soundcloud.api.ResolveOperations;
+import org.springframework.social.soundcloud.api.SoundCloudProfile;
+import org.springframework.social.soundcloud.api.UserOperations;
+import org.springframework.social.soundcloud.api.UsersOperations;
+import org.springframework.web.client.RestTemplate;
+
+public class UsersTemplate extends AbstractSoundCloudOperations implements UsersOperations {
+
+ public UsersTemplate(RestTemplate restTemplate, boolean isAuthorizedForUser) {
+ super(restTemplate, isAuthorizedForUser);
+ }
+
+ @Override
+ public UserOperations userOperations(long userId) {
+ return new UserTemplate(restTemplate,userId,isAuthorizedForUser);
+ }
+
+ @Override
+ public UserOperations userOperations(String username) {
+ ResolveOperations resolveOperations = new ResolveTemplate(restTemplate,isAuthorizedForUser);
+ SoundCloudProfile soundCloudProfile = resolveOperations.resolveUserProfile(username);
+ return new UserTemplate(restTemplate,Long.parseLong(soundCloudProfile.getId()),isAuthorizedForUser);
+ }
+
+
+}
View
3  src/main/java/org/springframework/social/soundcloud/api/impl/json/SoundCloudModule.java
@@ -4,6 +4,7 @@
import org.codehaus.jackson.Version;
import org.codehaus.jackson.map.module.SimpleModule;
import org.springframework.social.soundcloud.api.SoundCloudProfile;
+import org.springframework.social.soundcloud.api.Track;
/**
@@ -20,6 +21,8 @@ public SoundCloudModule() {
@Override
public void setupModule(SetupContext context) {
context.setMixInAnnotations(SoundCloudProfile.class, SoundCloudProfileMixin.class);
+ context.setMixInAnnotations(Track.class, TrackMixin.class);
+
}
}
View
4 ...main/java/org/springframework/social/soundcloud/api/impl/json/SoundCloudProfileMixin.java
@@ -2,10 +2,6 @@
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
View
14 src/main/java/org/springframework/social/soundcloud/api/impl/json/TrackList.java
@@ -0,0 +1,14 @@
+package org.springframework.social.soundcloud.api.impl.json;
+
+import java.util.ArrayList;
+
+import org.springframework.social.soundcloud.api.Track;
+
+public class TrackList extends ArrayList<Track> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+}
View
23 src/main/java/org/springframework/social/soundcloud/api/impl/json/TrackMixin.java
@@ -0,0 +1,23 @@
+package org.springframework.social.soundcloud.api.impl.json;
+
+
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * Annotated mixin to add Jackson annotations to Track.
+ * @author Michael Lavelle
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+abstract class TrackMixin {
+
+
+ @JsonCreator
+ TrackMixin(
+ @JsonProperty("permalink_url") String permalinkUrl,
+ @JsonProperty("title") String title) {}
+
+
+}
View
6 src/main/java/org/springframework/social/soundcloud/connect/SoundCloudAdapter.java
@@ -16,14 +16,14 @@
@Override
public UserProfile fetchUserProfile(SoundCloud soundCloud) {
- SoundCloudProfile profile = soundCloud.userOperations().getUserProfile();
+ SoundCloudProfile profile = soundCloud.meOperations().getUserProfile();
return new UserProfileBuilder().setName(profile.getFullName()).setUsername(profile.getUsername()).build();
}
@Override
public void setConnectionValues(SoundCloud soundCloud, ConnectionValues values) {
- SoundCloudProfile profile = soundCloud.userOperations().getUserProfile();
+ SoundCloudProfile profile = soundCloud.meOperations().getUserProfile();
values.setProviderUserId(profile.getId());
values.setDisplayName(profile.getFullName());
values.setProfileUrl(profile.getPermalinkUrl());
@@ -35,7 +35,7 @@ public void setConnectionValues(SoundCloud soundCloud, ConnectionValues values)
@Override
public boolean test(SoundCloud soundCloud) {
try {
- soundCloud.userOperations().getUserProfile();
+ soundCloud.meOperations().getUserProfile();
return true;
} catch (ApiException e) {
return false;
View
4 src/main/java/org/springframework/social/soundcloud/connect/SoundCloudConnectionFactory.java
@@ -3,6 +3,10 @@
import org.springframework.social.connect.support.OAuth2ConnectionFactory;
import org.springframework.social.soundcloud.api.SoundCloud;
+/**
+* SoundCloud ConnectionFactory implementation.
+* @author Michael Lavelle
+*/
public class SoundCloudConnectionFactory extends OAuth2ConnectionFactory<SoundCloud> {
public SoundCloudConnectionFactory(String clientId, String clientSecret) {
View
17 src/main/java/org/springframework/social/soundcloud/connect/SoundCloudOAuth2Template.java
@@ -1,15 +1,30 @@
package org.springframework.social.soundcloud.connect;
+import java.util.Map;
+
import org.springframework.social.oauth2.AccessGrant;
import org.springframework.social.oauth2.OAuth2Template;
-import org.springframework.util.MultiValueMap;
+/**
+* SoundCloud-specific extension of OAuth2Template
+* @author Michael Lavelle
+*/
public class SoundCloudOAuth2Template extends OAuth2Template {
public SoundCloudOAuth2Template(String clientId, String clientSecret) {
super(clientId, clientSecret, "https://soundcloud.com/connect", "https://api.soundcloud.com/oauth2/token");
}
+ @Override
+ protected AccessGrant createAccessGrant(String accessToken, String scope,
+ String refreshToken, Integer expiresIn, Map<String, Object> response) {
+ return super.createAccessGrant(accessToken, scope, refreshToken, expiresIn,
+ response);
+ }
+
+
+
+
View
4 src/main/java/org/springframework/social/soundcloud/connect/SoundCloudServiceProvider.java
@@ -4,6 +4,10 @@
import org.springframework.social.soundcloud.api.SoundCloud;
import org.springframework.social.soundcloud.api.impl.SoundCloudTemplate;
+/**
+* SoundCloud ServiceProvider implementation.
+* @author Michael Lavelle
+*/
public class SoundCloudServiceProvider extends AbstractOAuth2ServiceProvider<SoundCloud>{
View
19 src/test/java/org/springframework/social/soundcloud/connect/SoundCloudAdapterTest.java
@@ -1,15 +1,16 @@
package org.springframework.social.soundcloud.connect;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.social.connect.ConnectionValues;
import org.springframework.social.connect.UserProfile;
+import org.springframework.social.soundcloud.api.MeOperations;
import org.springframework.social.soundcloud.api.SoundCloud;
import org.springframework.social.soundcloud.api.SoundCloudProfile;
-import org.springframework.social.soundcloud.api.UserOperations;
public class SoundCloudAdapterTest {
@@ -20,8 +21,8 @@
@Test
public void fetchProfileForFirstNameLastName() {
- UserOperations userOperations = Mockito.mock(UserOperations.class);
- Mockito.when(soundCloud.userOperations()).thenReturn(userOperations);
+ MeOperations userOperations = Mockito.mock(MeOperations.class);
+ Mockito.when(soundCloud.meOperations()).thenReturn(userOperations);
Mockito.when(userOperations.getUserProfile()).thenReturn(new SoundCloudProfile("12345678", "michaellavelle", "http://a1.sndcdn.com/images/default_avatar_large.png?8460df1","http://soundcloud.com/michaellavelle","Michael Lavelle","https://api.soundcloud.com/users/7031365","London"));
UserProfile profile = apiAdapter.fetchUserProfile(soundCloud);
assertEquals("Michael Lavelle", profile.getName());
@@ -33,8 +34,8 @@ public void fetchProfileForFirstNameLastName() {
@Test
public void fetchProfileForOnlyFirstName() {
- UserOperations userOperations = Mockito.mock(UserOperations.class);
- Mockito.when(soundCloud.userOperations()).thenReturn(userOperations);
+ MeOperations userOperations = Mockito.mock(MeOperations.class);
+ Mockito.when(soundCloud.meOperations()).thenReturn(userOperations);
Mockito.when(userOperations.getUserProfile()).thenReturn(new SoundCloudProfile("01248", "mattslip", "http://a1.sndcdn.com/images/default_avatar_large.png?8460df1","http://soundcloud.com/mattslip","mattslip","https://api.soundcloud.com/users/3510549","London"));
UserProfile profile = apiAdapter.fetchUserProfile(soundCloud);
assertEquals("mattslip", profile.getName());
@@ -47,9 +48,9 @@ public void fetchProfileForOnlyFirstName() {
@Test
public void setConnectionValues() {
- UserOperations userOperations = Mockito.mock(UserOperations.class);
- Mockito.when(soundCloud.userOperations()).thenReturn(userOperations);
- Mockito.when(userOperations.getUserProfile()).thenReturn(new SoundCloudProfile("12345678", "michaellavelle", "http://a1.sndcdn.com/images/default_avatar_large.png?8460df1","http://soundcloud.com/michaellavelle","Michael Lavelle","https://api.soundcloud.com/users/7031365","London"));
+ MeOperations meOperations = Mockito.mock(MeOperations.class);
+ Mockito.when(soundCloud.meOperations()).thenReturn(meOperations);
+ Mockito.when(meOperations.getUserProfile()).thenReturn(new SoundCloudProfile("12345678", "michaellavelle", "http://a1.sndcdn.com/images/default_avatar_large.png?8460df1","http://soundcloud.com/michaellavelle","Michael Lavelle","https://api.soundcloud.com/users/7031365","London"));
TestConnectionValues connectionValues = new TestConnectionValues();
apiAdapter.setConnectionValues(soundCloud, connectionValues);
assertEquals("Michael Lavelle", connectionValues.getDisplayName());
View
BIN  target/classes/org/springframework/social/soundcloud/api/MeOperations.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/ResolveOperations.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/SoundCloud.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/SoundCloudProfile.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/Track.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/UserOperations.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/UsersOperations.class
Binary file not shown
View
BIN  ...classes/org/springframework/social/soundcloud/api/impl/AbstractSoundCloudOperations.class
Binary file not shown
View
BIN  ...org/springframework/social/soundcloud/api/impl/AbstractSoundCloudResourceOperations.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/AbstractUserTemplate.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/MeTemplate.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/ResolveTemplate.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/SoundCloudErrorHandler$1.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/SoundCloudErrorHandler$2.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/SoundCloudErrorHandler.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/SoundCloudTemplate.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/UserTemplate.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/UsersTemplate.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/json/SoundCloudModule.class
Binary file not shown
View
BIN  .../classes/org/springframework/social/soundcloud/api/impl/json/SoundCloudProfileMixin.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/json/TrackList.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/api/impl/json/TrackMixin.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/connect/SoundCloudAdapter.class
Binary file not shown
View
BIN  ...t/classes/org/springframework/social/soundcloud/connect/SoundCloudConnectionFactory.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/connect/SoundCloudOAuth2Template.class
Binary file not shown
View
BIN  target/classes/org/springframework/social/soundcloud/connect/SoundCloudServiceProvider.class
Binary file not shown
View
5 target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Thu Sep 08 13:20:15 BST 2011
+version=1.0.0-SNAPSHOT
+groupId=org.springframework.social
+artifactId=spring-social-soundcloud
View
BIN  target/spring-social-soundcloud-1.0.0-SNAPSHOT.jar
Binary file not shown
View
70 ...fire-reports/TEST-org.springframework.social.soundcloud.connect.SoundCloudAdapterTest.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite failures="0" time="0.27" errors="0" skipped="0" tests="3" name="org.springframework.social.soundcloud.connect.SoundCloudAdapterTest">
+ <properties>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="sun.boot.library.path" value="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries"/>
+ <property name="java.vm.version" value="17.1-b03-307"/>
+ <property name="awt.nativeDoubleBuffering" value="true"/>
+ <property name="gopherProxySet" value="false"/>
+ <property name="mrj.build" value="10M3261"/>
+ <property name="java.vm.vendor" value="Apple Inc."/>
+ <property name="java.vendor.url" value="http://www.apple.com/"/>
+ <property name="path.separator" value=":"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="user.country" value="US"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="user.dir" value="/Users/michael/Documents/workspace/spring-social-soundcloud"/>
+ <property name="java.runtime.version" value="1.6.0_22-b04-307-10M3261"/>
+ <property name="java.awt.graphicsenv" value="apple.awt.CGraphicsEnvironment"/>
+ <property name="basedir" value="/Users/michael/Documents/workspace/spring-social-soundcloud"/>
+ <property name="java.endorsed.dirs" value="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/endorsed"/>
+ <property name="os.arch" value="x86_64"/>
+ <property name="surefire.real.class.path" value="/var/folders/Do/DogJlFz+FeG52cZB+y3XF++++TI/-Tmp-/surefirebooter7876333337697360988.jar"/>
+ <property name="java.io.tmpdir" value="/var/folders/Do/DogJlFz+FeG52cZB+y3XF++++TI/-Tmp-/"/>
+ <property name="line.separator" value="
+"/>
+ <property name="java.vm.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="os.name" value="Mac OS X"/>
+ <property name="sun.jnu.encoding" value="MacRoman"/>
+ <property name="java.library.path" value=".:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+ <property name="surefire.test.class.path" value="/Users/michael/Documents/workspace/spring-social-soundcloud/target/test-classes:/Users/michael/Documents/workspace/spring-social-soundcloud/target/classes:/Users/michael/.m2/repository/org/springframework/social/spring-social-core/1.0.0.RC3/spring-social-core-1.0.0.RC3.jar:/Users/michael/.m2/repository/org/springframework/spring-web/3.1.0.M2/spring-web-3.1.0.M2.jar:/Users/michael/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar:/Users/michael/.m2/repository/org/springframework/spring-beans/3.1.0.M2/spring-beans-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/spring-core/3.1.0.M2/spring-core-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/spring-asm/3.1.0.M2/spring-asm-3.1.0.M2.jar:/Users/michael/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar:/Users/michael/.m2/repository/org/springframework/spring-context/3.1.0.M2/spring-context-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/spring-aop/3.1.0.M2/spring-aop-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/spring-expression/3.1.0.M2/spring-expression-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/social/spring-social-test/1.0.0.RC3/spring-social-test-1.0.0.RC3.jar:/Users/michael/.m2/repository/org/mockito/mockito-all/1.8.5/mockito-all-1.8.5.jar:/Users/michael/.m2/repository/org/codehaus/jackson/jackson-mapper-asl/1.8.5/jackson-mapper-asl-1.8.5.jar:/Users/michael/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.8.5/jackson-core-asl-1.8.5.jar:/Users/michael/.m2/repository/junit/junit/4.8.2/junit-4.8.2.jar:/Users/michael/.m2/repository/org/springframework/spring-test/3.1.0.M2/spring-test-3.1.0.M2.jar:"/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="java.class.version" value="50.0"/>
+ <property name="sun.management.compiler" value="HotSpot 64-Bit Server Compiler"/>
+ <property name="os.version" value="10.6.5"/>
+ <property name="http.nonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
+ <property name="user.home" value="/Users/michael"/>
+ <property name="user.timezone" value=""/>
+ <property name="java.awt.printerjob" value="apple.awt.CPrinterJob"/>
+ <property name="java.specification.version" value="1.6"/>
+ <property name="file.encoding" value="MacRoman"/>
+ <property name="user.name" value="michael"/>
+ <property name="java.class.path" value="/Users/michael/Documents/workspace/spring-social-soundcloud/target/test-classes:/Users/michael/Documents/workspace/spring-social-soundcloud/target/classes:/Users/michael/.m2/repository/org/springframework/social/spring-social-core/1.0.0.RC3/spring-social-core-1.0.0.RC3.jar:/Users/michael/.m2/repository/org/springframework/spring-web/3.1.0.M2/spring-web-3.1.0.M2.jar:/Users/michael/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar:/Users/michael/.m2/repository/org/springframework/spring-beans/3.1.0.M2/spring-beans-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/spring-core/3.1.0.M2/spring-core-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/spring-asm/3.1.0.M2/spring-asm-3.1.0.M2.jar:/Users/michael/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar:/Users/michael/.m2/repository/org/springframework/spring-context/3.1.0.M2/spring-context-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/spring-aop/3.1.0.M2/spring-aop-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/spring-expression/3.1.0.M2/spring-expression-3.1.0.M2.jar:/Users/michael/.m2/repository/org/springframework/social/spring-social-test/1.0.0.RC3/spring-social-test-1.0.0.RC3.jar:/Users/michael/.m2/repository/org/mockito/mockito-all/1.8.5/mockito-all-1.8.5.jar:/Users/michael/.m2/repository/org/codehaus/jackson/jackson-mapper-asl/1.8.5/jackson-mapper-asl-1.8.5.jar:/Users/michael/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.8.5/jackson-core-asl-1.8.5.jar:/Users/michael/.m2/repository/junit/junit/4.8.2/junit-4.8.2.jar:/Users/michael/.m2/repository/org/springframework/spring-test/3.1.0.M2/spring-test-3.1.0.M2.jar:"/>
+ <property name="java.vm.specification.version" value="1.0"/>
+ <property name="sun.arch.data.model" value="64"/>
+ <property name="java.home" value="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"/>
+ <property name="java.specification.vendor" value="Sun Microsystems Inc."/>
+ <property name="user.language" value="en"/>
+ <property name="awt.toolkit" value="apple.awt.CToolkit"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="java.version" value="1.6.0_22"/>
+ <property name="java.ext.dirs" value="/Library/Java/Extensions:/System/Library/Java/Extensions:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext"/>
+ <property name="sun.boot.class.path" value="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/jsfd.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/classes.jar:/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/Resources/Java/JavaRuntimeSupport.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/ui.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/laf.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/sunrsasign.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/jsse.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/jce.jar:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/charsets.jar"/>
+ <property name="java.vendor" value="Apple Inc."/>
+ <property name="localRepository" value="/Users/michael/.m2/repository"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.vendor.url.bug" value="http://bugreport.apple.com/"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
+ <property name="mrj.version" value="1060.1.6.0_22-307"/>
+ <property name="socksNonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
+ <property name="ftp.nonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
+ <property name="sun.cpu.isalist" value=""/>
+ </properties>
+ <testcase time="0.24" classname="org.springframework.social.soundcloud.connect.SoundCloudAdapterTest" name="fetchProfileForFirstNameLastName"/>
+ <testcase time="0.002" classname="org.springframework.social.soundcloud.connect.SoundCloudAdapterTest" name="fetchProfileForOnlyFirstName"/>
+ <testcase time="0.002" classname="org.springframework.social.soundcloud.connect.SoundCloudAdapterTest" name="setConnectionValues"/>
+</testsuite>
View
4 .../surefire-reports/org.springframework.social.soundcloud.connect.SoundCloudAdapterTest.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.springframework.social.soundcloud.connect.SoundCloudAdapterTest
+-------------------------------------------------------------------------------
+Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.277 sec
View
BIN  .../test-classes/org/springframework/social/soundcloud/connect/SoundCloudAdapterTest$1.class
Binary file not shown
View
BIN  ...pringframework/social/soundcloud/connect/SoundCloudAdapterTest$TestConnectionValues.class
Binary file not shown
View
BIN  ...et/test-classes/org/springframework/social/soundcloud/connect/SoundCloudAdapterTest.class
Binary file not shown
Please sign in to comment.
Something went wrong with that request. Please try again.