Commit 4a8ff917 authored by Kiryl Kazakevich's avatar Kiryl Kazakevich
Browse files

SITE-6364 - Example application does not display existing subscriptions when...

SITE-6364 - Example application does not display existing subscriptions when view subscriptions chosen.
parent cd2e8391
Showing with 182 additions and 545 deletions
+182 -545
......@@ -66,44 +66,6 @@
<version>${org.springframework-version}</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.6.ga</version>
<exclusions>
<exclusion>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.3.1.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.2.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-tools</artifactId>
<version>3.2.0.ga</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
......
package com.fitbit.api.client.subscription.dao;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
public interface IGenericDao<T, ID extends Serializable> extends Serializable {
boolean contains(T entity);
T find(ID id);
T getReference(ID id);
void refresh(T entity);
void persist(T entity);
T merge(T entity);
void remove(T entity);
List<T> findAll();
List<T> findByQuery(String queryString);
List<T> findByQuery(String queryString, Object... values);
List<T> findByQuery(String queryString, Map<String, ?> params);
T findSingleByQuery(String queryString);
T findSingleByQuery(String queryString, Object... values);
T findSingleByQuery(String queryString, Map<String, ?> params);
long getCount(String queryString);
long getCount(String queryString, Object... values);
long getCount(String queryString, Map<String, ?> params);
void flush();
List findCustomQuery(String queryString);
List findCustomQuery(String queryString, Object... values);
List findCustomQuery(String queryString, Map<String, ?> params);
int executeQuery(String queryString);
int executeQuery(String queryString, Object... values);
int executeQuery(String queryString, Map<String, ?> params);
}
\ No newline at end of file
package com.fitbit.api.client.subscription.dao;
import com.fitbit.api.client.subscription.model.Subscription;
public interface ISubscriptionDao extends IGenericDao<Subscription, Long> {
}
package com.fitbit.api.client.subscription.dao.impl;
import com.fitbit.api.client.subscription.dao.IGenericDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
public abstract class GenericDao<T, ID extends Serializable> implements IGenericDao<T, ID> {
private static final Logger log = LoggerFactory.getLogger(GenericDao.class);
private Class<T> persistentClass;
@PersistenceContext
protected EntityManager entityManager;
@SuppressWarnings({"unchecked"})
public GenericDao() {
persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
if (log.isInfoEnabled()) {
log.info(String.format("New instance of Dao for '%s' class is created", persistentClass.getSimpleName()));
}
}
public boolean contains(T entity) {
if (log.isDebugEnabled()) {
log.debug(String.format("Calling %sDao.contains() with entity: %s", persistentClass.getSimpleName(), entity));
}
return entityManager.contains(entity);
}
public T find(ID id) {
if (log.isDebugEnabled()) {
log.debug(String.format("Calling %sDao.find() with id: %s", persistentClass.getSimpleName(), id));
}
return entityManager.find(persistentClass, id);
}
public T getReference(ID id) {
if (log.isDebugEnabled()) {
log.debug(String.format("Calling %sDao.getReference() with id: %s", persistentClass.getSimpleName(), id));
}
return entityManager.getReference(persistentClass, id);
}
public void refresh(T entity) {
if (log.isDebugEnabled()) {
log.debug(String.format("Calling %sDao.refresh().", persistentClass.getSimpleName()));
}
entityManager.refresh(entity);
}
public void persist(T entity) {
if (log.isDebugEnabled()) {
log.debug(String.format("Calling %sDao.persist() with entity: %s", persistentClass.getSimpleName(), entity));
}
entityManager.persist(entity);
}
public T merge(T entity) {
if (log.isDebugEnabled()) {
log.debug(String.format("Calling %sDao.merge() with entity: %s", persistentClass.getSimpleName(), entity));
}
return entityManager.merge(entity);
}
public void remove(T entity) {
if (log.isDebugEnabled()) {
log.debug(String.format("Calling %sDao.remove() with entity: %s", persistentClass.getSimpleName(), entity));
}
entityManager.remove(entity);
}
public List<T> findAll() {
if (log.isDebugEnabled()) {
log.debug(String.format("Calling %sDao.findAll()", persistentClass.getSimpleName()));
}
return findByQuery("from " + persistentClass.getName());
}
@SuppressWarnings({"unchecked"})
public List<T> findByQuery(String queryString) {
return entityManager.createQuery(queryString).getResultList();
}
@SuppressWarnings({"unchecked"})
public List<T> findByQuery(String queryString, Object... values) {
Query query = entityManager.createQuery(queryString);
for (int i = 0; i < values.length; i++) {
query.setParameter(i + 1, values[i]);
}
return query.getResultList();
}
@SuppressWarnings({"unchecked"})
public List<T> findByQuery(String queryString, Map<String, ?> params) {
Query query = entityManager.createQuery(queryString);
for (Map.Entry<String, ?> entry : params.entrySet()) {
query.setParameter(entry.getKey(), entry.getValue());
}
return query.getResultList();
}
@SuppressWarnings({"unchecked"})
public T findSingleByQuery(String queryString) {
try {
return (T) entityManager.createQuery(queryString).getSingleResult();
} catch (NoResultException e) {
return null;
}
}
@SuppressWarnings({"unchecked"})
public T findSingleByQuery(String queryString, Object... values) {
Query query = entityManager.createQuery(queryString);
for (int i = 0; i < values.length; i++) {
query.setParameter(i + 1, values[i]);
}
try {
return (T) query.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
@SuppressWarnings({"unchecked"})
public T findSingleByQuery(String queryString, Map<String, ?> params) {
Query query = entityManager.createQuery(queryString);
for (Map.Entry<String, ?> entry : params.entrySet()) {
query.setParameter(entry.getKey(), entry.getValue());
}
try {
return (T) query.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
public long getCount(String queryString) {
if (queryString.toLowerCase().startsWith("from")) {
queryString = "SELECT COUNT(*) " + queryString;
}
try {
return (Long) entityManager.createQuery(queryString).getSingleResult();
} catch (NoResultException e) {
return 0;
}
}
public long getCount(String queryString, Object... values) {
if (queryString.toLowerCase().startsWith("from")) {
queryString = "SELECT COUNT(*) " + queryString;
}
Query query = entityManager.createQuery(queryString);
for (int i = 0; i < values.length; i++) {
query.setParameter(i + 1, values[i]);
}
try {
return (Long) query.getSingleResult();
} catch (NoResultException e) {
return 0;
}
}
public long getCount(String queryString, Map<String, ?> params) {
if (queryString.toLowerCase().startsWith("from")) {
queryString = "SELECT COUNT(*) " + queryString;
}
Query query = entityManager.createQuery(queryString);
for (Map.Entry<String, ?> entry : params.entrySet()) {
query.setParameter(entry.getKey(), entry.getValue());
}
try {
return (Long) query.getSingleResult();
} catch (NoResultException e) {
return 0;
}
}
public void flush() {
entityManager.flush();
}
public int executeQuery(String queryString) {
Query query = entityManager.createQuery(queryString);
return query.executeUpdate();
}
public int executeQuery(String queryString, Object... values) {
Query query = entityManager.createQuery(queryString);
for (int i = 0; i < values.length; i++) {
query.setParameter(i + 1, values[i]);
}
return query.executeUpdate();
}
public int executeQuery(String queryString, Map<String, ?> params) {
Query query = entityManager.createQuery(queryString);
for (Map.Entry<String, ?> entry : params.entrySet()) {
query.setParameter(entry.getKey(), entry.getValue());
}
return query.executeUpdate();
}
public List findCustomQuery(String queryString) {
if (log.isDebugEnabled()) {
// TODO: parameters enumeration
log.debug(String.format("Calling %sDao.findByQuery() with queryString: %s", persistentClass.getSimpleName(), queryString));
}
return entityManager.createQuery(queryString).getResultList();
}
public List findCustomQuery(String queryString, Object... values) {
return findByQuery(queryString, values);
}
public List findCustomQuery(String queryString, Map<String, ?> params) {
return findByQuery(queryString, params, null);
}
}
package com.fitbit.api.client.subscription.dao.impl;
import com.fitbit.api.client.subscription.dao.ISubscriptionDao;
import com.fitbit.api.client.subscription.model.Subscription;
import org.springframework.stereotype.Repository;
@Repository
public class SubscriptionDao extends GenericDao<Subscription, Long> implements ISubscriptionDao {
}
package com.fitbit.api.client.subscription.model;
import com.fitbit.api.model.APICollectionType;
import com.fitbit.api.model.ResourceOwnerType;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "subscription")
public class Subscription {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Column(name = "subscriber_id")
private String subscriberId;
@Column(name = "subscription_id")
private String subscriptionId;
@Column(name = "resource_owner_id")
private String resourceOwnerId;
@Column(name = "resource_owner_type")
@Enumerated(value = EnumType.STRING)
private ResourceOwnerType resourceOwnerType;
@Column(name = "collection_type")
@Enumerated(value = EnumType.STRING)
private APICollectionType collectionType;
@Column(name = "known_subscription")
private boolean knownSubscription;
@Column(name = "last_update_notification_date")
private Date lastUpdateNotificationDate;
public String getSubscriberId() {
return subscriberId;
}
public void setSubscriberId(String subscriberId) {
this.subscriberId = subscriberId;
}
public String getSubscriptionId() {
return subscriptionId;
}
public void setSubscriptionId(String subscriptionId) {
this.subscriptionId = subscriptionId;
}
public String getResourceOwnerId() {
return resourceOwnerId;
}
public void setResourceOwnerId(String resourceOwnerId) {
this.resourceOwnerId = resourceOwnerId;
}
public ResourceOwnerType getResourceOwnerType() {
return resourceOwnerType;
}
public void setResourceOwnerType(ResourceOwnerType resourceOwnerType) {
this.resourceOwnerType = resourceOwnerType;
}
public APICollectionType getCollectionType() {
return collectionType;
}
public void setCollectionType(APICollectionType collectionType) {
this.collectionType = collectionType;
}
public boolean isKnownSubscription() {
return knownSubscription;
}
public void setKnownSubscription(boolean knownSubscription) {
this.knownSubscription = knownSubscription;
}
public Date getLastUpdateNotificationDate() {
return lastUpdateNotificationDate;
}
public void setLastUpdateNotificationDate(Date lastUpdateNotificationDate) {
this.lastUpdateNotificationDate = lastUpdateNotificationDate;
}
}
package com.fitbit.api.client.subscription.storage;
import com.fitbit.api.client.FitbitApiSubscriptionStorage;
import com.fitbit.api.client.LocalSubscriptionDetail;
import com.fitbit.api.client.subscription.dao.ISubscriptionDao;
import com.fitbit.api.client.subscription.model.Subscription;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
@Transactional
public class PersistenceFitbitApiSubscriptionStorage implements FitbitApiSubscriptionStorage {
@Resource
private ISubscriptionDao subscriptionDao;
@Override
public void save(LocalSubscriptionDetail localSubscription) {
Subscription subscription = subscriptionDao.findSingleByQuery("FROM Subscription s WHERE s.subscriptionId = ?", localSubscription.getSubscriptionDetail().getSubscriptionId());
if (subscription == null) {
subscriptionDao.persist(SubscriptionAdaptor.toSubscription(localSubscription));
}
}
@Override
public LocalSubscriptionDetail getBySubscriptionId(String subscriptionId) {
Subscription subscription = subscriptionDao.findSingleByQuery("FROM Subscription s WHERE s.subscriptionId = ?", subscriptionId);
return subscription != null ? SubscriptionAdaptor.toLocalSubscriptionDetails(subscription) : null;
}
@Override
public void delete(LocalSubscriptionDetail localSubscription) {
Subscription subscription = subscriptionDao.findSingleByQuery("FROM Subscription s WHERE s.subscriptionId = ?", localSubscription.getSubscriptionDetail().getSubscriptionId());
if (subscription != null) {
subscriptionDao.remove(subscription);
}
}
@Override
public List<LocalSubscriptionDetail> getAllSubscriptions() {
return SubscriptionAdaptor.toLocalSubscriptionDetailsList(subscriptionDao.findAll());
}
}
package com.fitbit.api.client.subscription.storage;
import com.fitbit.api.client.LocalSubscriptionDetail;
import com.fitbit.api.client.subscription.model.Subscription;
//import com.fitbit.api.client.subscription.model.Subscription;
import com.fitbit.api.model.FitbitResourceOwner;
import com.fitbit.api.model.SubscriptionDetail;
......@@ -13,7 +13,7 @@ public final class SubscriptionAdaptor {
private SubscriptionAdaptor() {
}
public static LocalSubscriptionDetail toLocalSubscriptionDetails(Subscription subscription) {
/* public static LocalSubscriptionDetail toLocalSubscriptionDetails(Subscription subscription) {
SubscriptionDetail subscriptionDetail = new SubscriptionDetail(subscription.getSubscriberId(), subscription.getSubscriptionId(), FitbitResourceOwner.fromIdentifier(subscription.getResourceOwnerType(), subscription.getResourceOwnerId()), subscription.getCollectionType());
LocalSubscriptionDetail localSubscriptionDetail = new LocalSubscriptionDetail(subscriptionDetail, subscription.isKnownSubscription());
localSubscriptionDetail.setLastUpdateNotificationDate(subscription.getLastUpdateNotificationDate());
......@@ -38,5 +38,5 @@ public final class SubscriptionAdaptor {
subscription.setKnownSubscription(localSubscriptionDetail.isKnownSubscription());
subscription.setLastUpdateNotificationDate(localSubscriptionDetail.getLastUpdateNotificationDate());
return subscription;
}
}*/
}
......@@ -13,14 +13,12 @@ import com.fitbit.api.common.model.units.UnitSystem;
import com.fitbit.api.common.model.user.Account;
import com.fitbit.api.common.model.user.UserInfo;
import com.fitbit.api.common.service.FitbitApiService;
import com.fitbit.api.model.APICollectionType;
import com.fitbit.api.model.APIResourceCredentials;
import com.fitbit.api.model.ApiRateLimitStatus;
import com.fitbit.api.model.FitbitUser;
import com.fitbit.api.model.*;
import com.fitbit.web.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -33,7 +31,7 @@ import javax.servlet.http.HttpServletResponse;
import java.util.*;
@Controller
public class FitbitApiClientController {
public class FitbitApiClientController implements InitializingBean {
protected Log log = LogFactory.getLog(getClass());
private static final int APP_USER_COOKIE_TTL = 60 * 60 * 24 * 7 * 4;
......@@ -66,6 +64,20 @@ public class FitbitApiClientController {
@Value("#{config['showAccountRegistrationForm']}")
private Boolean showAccountRegistrationForm;
private FitbitAPIClientService<FitbitApiClientAgent> apiClientService;
@Override
public void afterPropertiesSet() throws Exception {
apiClientService = new FitbitAPIClientService<FitbitApiClientAgent>(
new FitbitApiClientAgent(getApiBaseUrl(), getFitbitSiteBaseUrl(), credentialsCache),
clientConsumerKey,
clientSecret,
credentialsCache,
entityCache,
subscriptionStore
);
}
@RequestMapping("/")
public String index(HttpServletRequest request, HttpServletResponse response) {
// If the user does not have token credentials, simply show the page with no data:
......@@ -135,7 +147,11 @@ public class FitbitApiClientController {
if (!isAuthorized(context, request)) {
showAuthorize(request, response);
}
request.setAttribute("subscriptions", subscriptionStore.getAllSubscriptions());
try {
request.setAttribute("subscriptions", apiClientService.getClient().getSubscriptions(context.getOurUser()));
} catch (FitbitAPIException e) {
log.error("Subscription error: " + e, e);
}
return "subscriptions";
}
......@@ -163,7 +179,11 @@ public class FitbitApiClientController {
request.setAttribute("errors", Collections.singletonList(e.getMessage()));
log.error("Unable to subscribe: " + e, e);
}
request.setAttribute("subscriptions", subscriptionStore.getAllSubscriptions());
try {
request.setAttribute("subscriptions", apiClientService.getClient().getSubscriptions(context.getOurUser()));
} catch (FitbitAPIException e) {
log.error("Subscription error: " + e, e);
}
return "subscriptions";
}
......@@ -195,7 +215,11 @@ public class FitbitApiClientController {
request.setAttribute("errors", Collections.singletonList(e.getMessage()));
log.error("Unable to unsubscribe: " + e, e);
}
request.setAttribute("subscriptions", subscriptionStore.getAllSubscriptions());
try {
request.setAttribute("subscriptions", apiClientService.getClient().getSubscriptions(context.getOurUser()));
} catch (FitbitAPIException e) {
log.error("Subscription error: " + e, e);
}
return "subscriptions";
}
......@@ -209,6 +233,12 @@ public class FitbitApiClientController {
showAuthorize(request, response);
}
try {
apiClientService.getClient().getSubscriptions(context.getOurUser(), APICollectionType.activities);
} catch (FitbitAPIException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
request.setAttribute("unitSystem", UnitSystem.getUnitSystem(Locale.US));
try {
......@@ -769,20 +799,23 @@ public class FitbitApiClientController {
}
public void populate(RequestContext context, HttpServletRequest request, HttpServletResponse response) {
context.setApiClientService(
new FitbitAPIClientService<FitbitApiClientAgent>(
new FitbitApiClientAgent(getApiBaseUrl(), getFitbitSiteBaseUrl(), credentialsCache),
clientConsumerKey,
clientSecret,
credentialsCache,
entityCache,
subscriptionStore
));
context.setApiClientService(apiClientService);
context.setOurUser(getOrMakeExampleAppUser(request, response));
APIResourceCredentials resourceCredentials = context.getApiClientService().getResourceCredentialsByUser(context.getOurUser());
boolean isAuthorized = resourceCredentials != null && resourceCredentials.isAuthorized();
boolean isSubscribed = false;
if (null != context.getOurUser() && null != subscriptionStore.getBySubscriptionId(getActivitiesSubscriptionId(context))) {
isSubscribed = true;
if (isAuthorized) {
List<ApiSubscription> subscriptions = Collections.emptyList();
try {
subscriptions = apiClientService.getClient().getSubscriptions(context.getOurUser());
} catch (FitbitAPIException e) {
log.error("Subscription error: " + e, e);
}
if (null != context.getOurUser() && subscriptions.size() > 0) {
isSubscribed = true;
}
}
request.setAttribute("actionBean", context);
request.setAttribute("isSubscribed", isSubscribed);
......
......@@ -20,21 +20,18 @@
<th width="13%">Fitbit Owner Type</th>
<th width="13%">Fitbit Owner ID</th>
<th width="13%">Feed type</th>
<th width="19%">Last Notification</th>
<th width="19%">Notes</th>
<%--<th width="19%">Last Notification</th>--%>
<%--<th width="19%">Notes</th>--%>
</tr>
</thead>
<%--@elvariable id="subscriptions" type="java.util.List<com.fitbit.api.model.ApiSubscription>"--%>
<c:forEach items="${subscriptions}" var="subscription">
<tr
<c:if test="${actionBean.ourUser.userId == subscription.subscriptionDetail.subscriptionId}">
style="background-color: lightyellow; font-weight: bold;"
</c:if>
>
<td>${subscription.subscriptionDetail.subscriptionId}</td>
<td>${subscription.subscriptionDetail.owner.resourceOwnerType}</td>
<td>${subscription.subscriptionDetail.owner.id}</td>
<td>${subscription.subscriptionDetail.collectionType}</td>
<td>
<tr>
<td>${subscription.subscriptionId}</td>
<td>${subscription.ownerType}</td>
<td>${subscription.ownerId}</td>
<td>${subscription.collectionType}</td>
<%-- <td>
<c:choose>
<c:when test="${not empty subscription.lastUpdateNotificationDate}">
<fmt:formatDate value="${subscription.lastUpdateNotificationDate}"
......@@ -49,7 +46,7 @@
<c:if test="${not subscription.knownSubscription}">
Auto-created after receiving update notification.
</c:if>
</td>
</td>--%>
</tr>
</c:forEach>
</table>
......
......@@ -10,21 +10,4 @@
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<!-- <context:component-scan base-package="com.fitbit.api.client.subscription.dao"/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="fitbit-api-unit"/>
</bean>
<tx:annotation-driven/>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>-->
</beans>
\ No newline at end of file
......@@ -24,6 +24,7 @@ import com.fitbit.api.model.*;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormat;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -1091,7 +1092,7 @@ public class FitbitApiClientAgent extends FitbitAPIClientSupport implements Seri
public Water getLoggedWater(LocalUserDetail localUser, FitbitUser fitbitUser, LocalDate date) throws FitbitAPIException {
setAccessToken(localUser);
// Example: GET /1/user/228TQ4/foods/log/water/date/2010-02-25.json
String url = APIUtil.constructFullUrl(getApiBaseUrl(), getApiVersion(), fitbitUser, APICollectionType.water, date, APIFormat.JSON);
String url = APIUtil.contextualizeUrl(getApiBaseUrl(), getApiVersion(), "/user/" + fitbitUser.getId() + "/foods/log/water/date/" + DateTimeFormat.forPattern("yyyy-MM-dd").print(date), APIFormat.JSON);
Response res = httpGet(url, true);
throwExceptionIfError(res);
......@@ -1245,7 +1246,7 @@ public class FitbitApiClientAgent extends FitbitAPIClientSupport implements Seri
/**
* Invite another user to be a friend given his userId
*
* @param localUser authorized user
* @param localUser authorized user
* @param invitedUserId invited user id
*
* @throws com.fitbit.api.FitbitAPIException Fitbit API Exception
......@@ -1266,7 +1267,7 @@ public class FitbitApiClientAgent extends FitbitAPIClientSupport implements Seri
/**
* Invite another user to be a friend given his email
*
* @param localUser authorized user
* @param localUser authorized user
* @param invitedUserEmail invited user's email
*
* @throws com.fitbit.api.FitbitAPIException Fitbit API Exception
......@@ -1287,7 +1288,7 @@ public class FitbitApiClientAgent extends FitbitAPIClientSupport implements Seri
/**
* Accept friend invitation from another user
*
* @param localUser authorized user
* @param localUser authorized user
* @param fitbitUser inviting user
*
* @throws com.fitbit.api.FitbitAPIException Fitbit API Exception
......@@ -1308,7 +1309,7 @@ public class FitbitApiClientAgent extends FitbitAPIClientSupport implements Seri
/**
* Reject friend invitation from another user
*
* @param localUser authorized user
* @param localUser authorized user
* @param fitbitUser inviting user
*
* @throws com.fitbit.api.FitbitAPIException Fitbit API Exception
......@@ -1567,6 +1568,35 @@ public class FitbitApiClientAgent extends FitbitAPIClientSupport implements Seri
httpDelete(url, true);
}
public List<ApiSubscription> getSubscriptions(LocalUserDetail localUser) throws FitbitAPIException {
String url = APIUtil.contextualizeUrl(getApiBaseUrl(), getApiVersion(), "/user/-/apiSubscriptions", APIFormat.JSON);
return getSubscriptions(localUser, url);
}
public List<ApiSubscription> getSubscriptions(LocalUserDetail localUser, APICollectionType collectionType) throws FitbitAPIException {
String url = APIUtil.contextualizeUrl(getApiBaseUrl(), getApiVersion(), "/user/-/" + collectionType +"/apiSubscriptions", APIFormat.JSON);
return getSubscriptions(localUser, url);
}
private List<ApiSubscription> getSubscriptions(LocalUserDetail localUser, String url) throws FitbitAPIException {
setAccessToken(localUser);
Response res = httpGet(url, true);
throwExceptionIfError(res);
try {
JSONObject jsonObject = res.asJSONObject();
JSONArray jsonArray = jsonObject.getJSONArray("apiSubscriptions");
List<ApiSubscription> result = new ArrayList<ApiSubscription>(jsonArray.length());
for(int i = 0; i < jsonArray.length(); i++) {
ApiSubscription apiSubscription = new ApiSubscription(jsonArray.getJSONObject(i));
result.add(apiSubscription);
}
return result;
} catch (JSONException e) {
throw new FitbitAPIException("Error retrieving water: " + e, e);
}
}
/**
* Get time series in the specified range for a given resource of a user (as an unauthorized)
*
......
......@@ -7,8 +7,7 @@ public enum APICollectionType {
sleep("sleep"),
body("body"),
user("user"),
weight("body/weight"),
water("foods/log/water");
weight("body/weight");
String urlPath;
String subscriptionPath;
......
package com.fitbit.api.model;
import org.json.JSONException;
import org.json.JSONObject;
public class ApiSubscription {
private String subscriberId;
private String subscriptionId;
private String ownerId;
private ResourceOwnerType ownerType;
private APICollectionType collectionType;
public ApiSubscription(String subscriberId, String subscriptionId, ResourceOwnerType ownerType, String ownerId, APICollectionType collectionType) {
this.subscriberId = subscriberId;
this.subscriptionId = subscriptionId;
this.ownerId = ownerId;
this.ownerType = ownerType;
this.collectionType = collectionType;
}
public ApiSubscription(JSONObject json) {
try {
this.subscriberId = json.getString("subscriberId");
this.subscriptionId = json.getString("subscriptionId");
this.ownerType = ResourceOwnerType.valueOf(json.getString("ownerType"));
this.ownerId = json.getString("ownerId");
if (json.has("collectionType")) {
this.collectionType = APICollectionType.valueOf(json.getString("collectionType"));
}
} catch (JSONException e) {
throw new IllegalArgumentException("Given JSON object '" + json + "' does not contain all required elements: " + e, e);
}
}
public String getSubscriberId() {
return subscriberId;
}
public String getSubscriptionId() {
return subscriptionId;
}
public String getOwnerId() {
return ownerId;
}
public ResourceOwnerType getOwnerType() {
return ownerType;
}
public APICollectionType getCollectionType() {
return collectionType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ApiSubscription that = (ApiSubscription) o;
if (collectionType != that.collectionType) return false;
if (!ownerId.equals(that.ownerId)) return false;
if (ownerType != that.ownerType) return false;
if (!subscriberId.equals(that.subscriberId)) return false;
if (!subscriptionId.equals(that.subscriptionId)) return false;
return true;
}
@Override
public int hashCode() {
int result = subscriberId.hashCode();
result = 31 * result + subscriptionId.hashCode();
result = 31 * result + ownerId.hashCode();
result = 31 * result + ownerType.hashCode();
result = 31 * result + (collectionType != null ? collectionType.hashCode() : 0);
return result;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment