/*
* Copyright (c) 2010, 2011 Mashery, Inc. All Rights Reserved.
*
* 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 com.mashery.examples.api.server.etsy;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.ServletException;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.basic.DefaultOAuthConsumer;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.mashery.examples.api.client.etsy.EtsyException;
import com.mashery.examples.api.client.etsy.EtsyService;
import com.mashery.examples.api.client.etsy.FavoriteListing;
import com.mashery.examples.api.client.etsy.NotLoggedInException;
import com.mashery.examples.api.client.etsy.OAuthException;
import com.mashery.examples.api.server.Persistence;
@SuppressWarnings("serial")
public class EtsyServiceImpl extends RemoteServiceServlet implements EtsyService {
private String etsyService;
private String etsyEndpoint;
private String etsyApikey;
private String etsySecret;
@Override
public void init() throws ServletException {
super.init();
etsyService = getInitParameter("etsy.service");
etsyEndpoint = getInitParameter("etsy.endpoint");
etsyApikey = getInitParameter("etsy.apikey");
etsySecret = getInitParameter("etsy.secret");
}
@Override
public com.mashery.examples.api.client.etsy.User getUser() throws EtsyException, OAuthException, NotLoggedInException {
OAuthAccessToken accessToken = getAccessToken();
try {
return getUser(accessToken);
} catch (IOException e) {
throw new EtsyException(e);
}
}
private com.mashery.examples.api.client.etsy.User getUser(OAuthAccessToken accessToken) throws EtsyException, IOException {
// create Etsy getUser service URL
StringBuilder buf = new StringBuilder(etsyEndpoint);
buf.append("/users/__SELF__?includes=Profile");
URL url = new URL(buf.toString());
// call Etsy
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
OAuthConsumer consumer = new DefaultOAuthConsumer(etsyApikey, etsySecret);
consumer.setTokenWithSecret(accessToken.getToken(), accessToken.getSecret());
try {
consumer.sign(conn);
} catch (OAuthMessageSignerException e) {
throw new EtsyException(e);
} catch (OAuthExpectationFailedException e) {
throw new EtsyException(e);
} catch (OAuthCommunicationException e) {
throw new EtsyException(e);
}
int rc = conn.getResponseCode();
String charset = getContentCharset(conn);
if (rc != HttpURLConnection.HTTP_OK)
throw new EtsyException(rc, conn.getResponseMessage());
// parse response
InputStream in = conn.getInputStream();
ObjectMapper mapper = new ObjectMapper();
InputStreamReader ir = charset == null ? new InputStreamReader(in) : new InputStreamReader(in, charset);
EtsyResponse<com.mashery.examples.api.client.etsy.User> result = mapper.readValue(ir, new TypeReference<EtsyResponse<com.mashery.examples.api.client.etsy.User>>() { });
// if there were no results, we'd get a 404
return result.getResults().get(0);
}
@Override
public void deleteAccessTokens() throws NotLoggedInException {
UserService userSvc = UserServiceFactory.getUserService();
if (!userSvc.isUserLoggedIn())
throw new NotLoggedInException();
User user = userSvc.getCurrentUser();
PersistenceManager pm = Persistence.getPMF().getPersistenceManager();
try {
Query query = pm.newQuery(OAuthAccessToken.class, "service == :service && userId == :userId");
query.deletePersistentAll(etsyService, user.getUserId());
} finally {
pm.close();
}
}
@Override
public FavoriteListing createUserFavoriteListing(int listingId) throws EtsyException, OAuthException, NotLoggedInException {
OAuthAccessToken accessToken = getAccessToken();
try {
return createUserFavoriteListings(listingId, accessToken);
} catch (IOException e) {
throw new EtsyException(e);
}
}
private FavoriteListing createUserFavoriteListings(int listingId, OAuthAccessToken accessToken) throws EtsyException, IOException {
// create Etsy findAllUserFavoriteListings service URL
StringBuilder buf = new StringBuilder(etsyEndpoint);
buf.append("/users/__SELF__");
buf.append("/favorites/listings/").append(listingId);
buf.append("?includes=Listing/Images");
URL url = new URL(buf.toString());
// call Etsy
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
OAuthConsumer consumer = new DefaultOAuthConsumer(etsyApikey, etsySecret);
consumer.setTokenWithSecret(accessToken.getToken(), accessToken.getSecret());
try {
consumer.sign(conn);
} catch (OAuthMessageSignerException e) {
throw new EtsyException(e);
} catch (OAuthExpectationFailedException e) {
throw new EtsyException(e);
} catch (OAuthCommunicationException e) {
throw new EtsyException(e);
}
int rc = conn.getResponseCode();
String charset = getContentCharset(conn);
if (rc != HttpURLConnection.HTTP_CREATED)
throw new EtsyException(rc, conn.getResponseMessage());
// parse response
InputStream in = conn.getInputStream();
ObjectMapper mapper = new ObjectMapper();
InputStreamReader ir = charset == null ? new InputStreamReader(in) : new InputStreamReader(in, charset);
EtsyResponse<FavoriteListing> result = mapper.readValue(ir, new TypeReference<EtsyResponse<FavoriteListing>>() { });
return result.getResults().get(0);
}
@Override
public void deleteUserFavoriteListing(int listingId) throws EtsyException, OAuthException, NotLoggedInException {
OAuthAccessToken accessToken = getAccessToken();
try {
deleteUserFavoriteListings(listingId, accessToken);
} catch (IOException e) {
throw new EtsyException(e);
}
}
private void deleteUserFavoriteListings(int listingId, OAuthAccessToken accessToken) throws EtsyException, IOException {
// create Etsy findAllUserFavoriteListings service URL
StringBuilder buf = new StringBuilder(etsyEndpoint);
buf.append("/users/__SELF__");
buf.append("/favorites/listings/").append(listingId);
URL url = new URL(buf.toString());
// call Etsy
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("DELETE");
OAuthConsumer consumer = new DefaultOAuthConsumer(etsyApikey, etsySecret);
consumer.setTokenWithSecret(accessToken.getToken(), accessToken.getSecret());
try {
consumer.sign(conn);
} catch (OAuthMessageSignerException e) {
throw new EtsyException(e);
} catch (OAuthExpectationFailedException e) {
throw new EtsyException(e);
} catch (OAuthCommunicationException e) {
throw new EtsyException(e);
}
int rc = conn.getResponseCode();
if (rc != HttpURLConnection.HTTP_OK)
throw new EtsyException(rc, conn.getResponseMessage());
}
private OAuthAccessToken getAccessToken() throws OAuthException, NotLoggedInException {
UserService userSvc = UserServiceFactory.getUserService();
if (!userSvc.isUserLoggedIn())
throw new NotLoggedInException();
User user = userSvc.getCurrentUser();
PersistenceManager pm = Persistence.getPMF().getPersistenceManager();
OAuthAccessToken accessToken;
try {
Query query = pm.newQuery(OAuthAccessToken.class, "service == :service && userId == :userId");
query.setUnique(true);
accessToken = (OAuthAccessToken) query.execute(etsyService, user.getUserId());
} finally {
pm.close();
}
if (accessToken == null)
throw new OAuthException();
return accessToken;
}
private String getContentCharset(HttpURLConnection conn) {
String charset = null;
String ct = conn.getContentType();
if (ct != null) {
String[] parts = ct.split(";");
for (int i = 1; i < parts.length; ++i) {
if (parts[i].trim().toLowerCase().startsWith("charset")) {
String[] pair = parts[i].split("=", 2);
if (pair[0].trim().equalsIgnoreCase("charset") && pair.length > 1) {
charset = pair[1].trim();
}
}
}
}
return charset;
}
}