package org.springframework.social.instagram.api.impl; import java.util.Arrays; import java.util.List; import org.codehaus.jackson.map.ObjectMapper; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; import org.springframework.social.instagram.api.Instagram; import org.springframework.social.instagram.api.LocationOperations; import org.springframework.social.instagram.api.MediaOperations; import org.springframework.social.instagram.api.TagOperations; import org.springframework.social.instagram.api.UserOperations; import org.springframework.social.oauth2.AbstractOAuth2ApiBinding; import org.springframework.social.support.URIBuilder; import org.springframework.web.client.RestTemplate; /** * This is the central class for interacting with Instagram. * <p> * Not all operations through Instagram require OAuth 2-based authentication. However, * to perform authenticated operations, such as commenting and liking, InstagramTemplate * must be constructed with a valid access token. * </p> * <p> * There are quite a few operations that do not require OAuth authentication. In those cases, * you may use a {@link InstagramTemplate} that is created through the default constructor. * Attempts to perform secured operations through such an instance, however, * will result in {@link IllegalStateException} being thrown. * </p> */ public class InstagramTemplate extends AbstractOAuth2ApiBinding implements Instagram { private final String accessToken; private final String clientId; private final TagOperations tagOperations; private final LocationOperations locationOperations; private final MediaOperations mediaOperations; private final UserOperations userOperations; /** * Create a new instance of InstagramTemplate. * This constructor creates a new InstagramTemplate able to perform unauthenticated * operations against Instagram's API. Some operations do not require OAuth authentication. A TwitterTemplate created with this constructor will support those operations. * Those operations requiring authentication will throw {@link BadCredentialsException}. * @param clientId */ public InstagramTemplate(String clientId) { this(clientId, null, false); } /** * Create a new instance of InstagramTemplate. * @param clientId the application's client ID * @param accessToken an access token acquired through OAuth authentication with Instagram */ public InstagramTemplate(String clientId, String accessToken) { this(clientId, accessToken, true); } private InstagramTemplate(String clientId, String accessToken, boolean isAuthorizedForUser) { super(accessToken); this.clientId = clientId; this.accessToken = accessToken; MappingJacksonHttpMessageConverter json = new MappingJacksonHttpMessageConverter(); json.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "javascript"))); getRestTemplate().getMessageConverters().add(json); registerInstagramJsonModule(getRestTemplate()); getRestTemplate().setErrorHandler(new InstagramErrorHandler()); tagOperations = new TagTemplate(this, isAuthorizedForUser); locationOperations = new LocationTemplate(this, isAuthorizedForUser); mediaOperations = new MediaTemplate(this, isAuthorizedForUser); userOperations = new UserTemplate(this, isAuthorizedForUser); } private void registerInstagramJsonModule(RestTemplate restTemplate) { List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters(); for (HttpMessageConverter<?> converter : converters) { if(converter instanceof MappingJacksonHttpMessageConverter) { MappingJacksonHttpMessageConverter jsonConverter = (MappingJacksonHttpMessageConverter) converter; ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new InstagramModule()); jsonConverter.setObjectMapper(objectMapper); } } } public URIBuilder withAccessToken(String uri) { return (accessToken == null) ? URIBuilder.fromUri(uri).queryParam("client_id", clientId) : URIBuilder.fromUri(uri).queryParam("access_token", accessToken); } public TagOperations tagOperations() { return tagOperations; } public LocationOperations locationOperations() { return locationOperations; } public MediaOperations mediaOperations() { return mediaOperations; } public UserOperations userOperations() { return userOperations; } }