/*
* Copyright 2011, Nabil Benothman, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.ubike.rest.service;
import com.sun.jersey.api.NotFoundException;
import com.ubike.model.UbikeUser;
import com.ubike.model.Statistic;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.DELETE;
import javax.ws.rs.Produces;
import javax.ws.rs.Consumes;
import javax.ws.rs.QueryParam;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import com.sun.jersey.api.core.ResourceContext;
import com.sun.jersey.api.view.Viewable;
import com.ubike.faces.bean.BaseBean;
import javax.ws.rs.WebApplicationException;
import javax.persistence.NoResultException;
import com.ubike.model.Account;
import com.ubike.model.MemberShip;
import com.ubike.model.PrivacyPreferences;
import com.ubike.model.Trip;
import com.ubike.rest.converter.UbikeUserConverter;
import com.ubike.services.MemberShipServiceLocal;
import com.ubike.util.StatisticManager;
import com.ubike.services.TripManagerLocal;
import com.ubike.services.UserServiceLocal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.core.MediaType;
import org.springframework.context.annotation.Scope;
import org.springframework.security.annotation.Secured;
import org.springframework.stereotype.Component;
/**
* {@code UbikeUserResource}
* <p></p>
*
* Created on Jun 6, 2011 at 7:17:22 PM
*
* @author <a href="mailto:nabil.benothman@gmail.com">Nabil Benothman</a>
*/
@Stateless
@Component
@Scope("request")
public class UbikeUserResource {
@Context
protected UriInfo uriInfo;
@Context
protected ResourceContext resourceContext;
protected Long id;
@EJB
private UserServiceLocal userService;
@EJB
private MemberShipServiceLocal memberShipService;
@EJB
private TripManagerLocal tml;
/**
* Creates a new instance of UbikeUserResource
*/
public UbikeUserResource() {
}
/**
*
* @param id
*/
public void setId(Long id) {
this.id = id;
}
/**
* Get method for retrieving an instance of UbikeUser identified by id in HTML format.
*
* @param id identifier for the entity
* @return an instance of Viewable
*/
@GET
@Secured({"ROLE_USER", "USER_ACCESS"})
@Produces({MediaType.TEXT_HTML})
public Viewable getHTML(@QueryParam("expandLevel") @DefaultValue("1") int expandLevel) {
try {
UbikeUser user = getEntityWithTripsAndMemberShips();
BaseBean.setSessionAttribute("client", user);
BaseBean.setSessionAttribute("tmp_trips", user.getTrips());
BaseBean.setSessionAttribute("tmp_members", user.getMemberShips());
// Extracting entity statistics
extractStatistics(user);
return new Viewable("/userInfo.jsp", user);
} finally {
}
}
/**
* Get method for retrieving an instance of UbikeUser identified by id in XML format.
*
* @param id identifier for the entity
* @return an instance of UbikeUserConverter
*/
@GET
@Secured({"ROLE_USER", "USER_ACCESS"})
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public UbikeUserConverter getXML(@QueryParam("expandLevel") @DefaultValue("1") int expandLevel) {
return new UbikeUserConverter(getEntityWithTripsAndMemberShips(),
uriInfo.getAbsolutePath(), expandLevel);
}
/**
* Put method for updating an instance of UbikeUser identified by id using XML as the input format.
*
* @param id identifier for the entity
* @param data an UbikeUserConverter entity that is deserialized from a XML stream
*/
@Secured({"ROLE_USER", "USER_ACCESS"})
@PUT
@Consumes({"application/xml", "application/json"})
public void put(UbikeUserConverter data) {
updateEntity(getEntity(), data.resolveEntity(this.userService.getEntityManager()));
}
/**
* Delete method for deleting an instance of UbikeUser identified by id.
*
* @param id identifier for the entity
*/
@Secured({"ROLE_ADMIN", "ADMIN_ACCESS"})
@DELETE
public void delete() {
deleteEntity(getEntity());
}
/**
* Returns an instance of UbikeUser identified by id.
*
* @param id identifier for the entity
* @return an instance of UbikeUser
*/
public UbikeUser getEntity() {
try {
return this.userService.find(this.id);
} catch (NoResultException ex) {
throw new WebApplicationException(new Throwable("Resource for " + uriInfo.getAbsolutePath() + " does not exist."), 404);
}
}
/**
*
* @return
*/
public UbikeUser getEntityWithTrips() {
try {
return this.userService.findWithTrips(this.id);
} catch (NoResultException ex) {
throw new WebApplicationException(new Throwable("Resource for " + uriInfo.getAbsolutePath() + " does not exist."), 404);
}
}
/**
*
* @return
*/
public UbikeUser getEntityWithMemberShips() {
try {
return this.userService.findWithMemberShips(this.id);
} catch (NoResultException ex) {
throw new WebApplicationException(new Throwable("Resource for " + uriInfo.getAbsolutePath() + " does not exist."), 404);
}
}
/**
*
* @return
*/
public UbikeUser getEntityWithTripsAndMemberShips() {
try {
return this.userService.findWithTripsAndMemberShips(this.id);
} catch (NoResultException ex) {
throw new WebApplicationException(new Throwable("Resource for " + uriInfo.getAbsolutePath() + " does not exist."), 404);
}
}
/**
* Updates entity using data from newEntity.
*
* @param entity the entity to update
* @param newEntity the entity containing the new data
* @return the updated entity
*/
protected UbikeUser updateEntity(UbikeUser entity, UbikeUser newEntity) {
List<Trip> trips = entity.getTrips();
List<Trip> tripsNew = newEntity.getTrips();
Account account = entity.getAccount();
Account accountNew = newEntity.getAccount();
List<MemberShip> memberShips = entity.getMemberShips();
List<MemberShip> memberShipsNew = newEntity.getMemberShips();
PrivacyPreferences preferences = entity.getPreferences();
PrivacyPreferences preferencesNew = newEntity.getPreferences();
userService.update(newEntity);
for (Trip value : trips) {
if (!tripsNew.contains(value)) {
throw new WebApplicationException(new Throwable(
"Cannot remove items from trips"));
}
}
for (Trip value : tripsNew) {
if (!trips.contains(value)) {
UbikeUser oldEntity = value.getOwner();
value.setOwner(entity);
if (oldEntity != null && !oldEntity.equals(entity)) {
oldEntity.getTrips().remove(value);
}
}
}
if (account != null && !account.equals(accountNew)) {
account.setOwner(null);
}
if (accountNew != null && !accountNew.equals(account)) {
accountNew.setOwner(entity);
}
for (MemberShip value : memberShips) {
if (!memberShipsNew.contains(value)) {
throw new WebApplicationException(new Throwable(
"Cannot remove items from memberShips"));
}
}
for (MemberShip value : memberShipsNew) {
if (!memberShips.contains(value)) {
UbikeUser oldEntity = value.getMember();
value.setMember(entity);
if (oldEntity != null && !oldEntity.equals(entity)) {
oldEntity.getMemberShips().remove(value);
}
}
}
if (preferences != null && !preferences.equals(preferencesNew)) {
preferences.setOwner(null);
}
if (preferencesNew != null && !preferencesNew.equals(preferences)) {
preferencesNew.setOwner(entity);
}
return entity;
}
/**
* Deletes the entity.
*
* @param entity the entity to delete
*/
protected void deleteEntity(UbikeUser entity) {
if (!entity.getTrips().isEmpty()) {
throw new WebApplicationException(new Throwable(
"Cannot delete entity because trips is not empty."));
}
Account account = entity.getAccount();
if (account != null) {
account.setOwner(null);
}
if (!entity.getMemberShips().isEmpty()) {
throw new WebApplicationException(new Throwable(
"Cannot delete entity because memberShips is not empty."));
}
PrivacyPreferences preferences = entity.getPreferences();
if (preferences != null) {
preferences.setOwner(null);
}
this.userService.remove(entity.getId());
}
/**
* Returns a dynamic instance of TripsResource used for entity navigation.
*
* @param id identifier for the parent entity
* @return an instance of TripsResource
*/
@Secured({"ROLE_USER", "USER_ACCESS"})
@Path("trips/")
public TripsResource getTripsResource() {
TripsResourceSub resource = resourceContext.getResource(
TripsResourceSub.class);
resource.setParent(getEntityWithTrips());
return resource;
}
/**
* Returns a dynamic instance of AccountResource used for entity navigation.
*
* @param id identifier for the parent entity
* @return an instance of AccountResource
*/
@Secured({"ROLE_USER", "USER_ACCESS"})
@Path("account/")
public AccountResource getAccountResource() {
AccountResourceSub resource = resourceContext.getResource(
AccountResourceSub.class);
resource.setParent(getEntity());
return resource;
}
/**
* Returns a dynamic instance of MemberShipsResource used for entity navigation.
*
* @param id identifier for the parent entity
* @return an instance of MemberShipsResource
*/
@Secured({"ROLE_USER", "USER_ACCESS"})
@Path("memberShips/")
public MemberShipsResource getMemberShipsResource() {
MemberShipsResourceSub resource = resourceContext.getResource(
MemberShipsResourceSub.class);
resource.setParent(getEntityWithMemberShips());
return resource;
}
/**
* @return The list of the all members of all user groups
*/
@Secured({"ROLE_USER", "USER_ACCESS"})
@Path("friends/")
public UbikeUsersResource getFriends() {
FriendsResource resource = resourceContext.getResource(FriendsResource.class);
resource.setParent(getEntity());
resource.setName("uBike user friends list");
resource.setService(memberShipService);
return resource;
}
/**
*
* @param entity
* @return
*
private List<UbikeUser> extractFriends() {
// We use a HashSet to garantee that an element is not added more than once
List<UbikeUser> friends = new ArrayList<UbikeUser>();
List<MemberShip> memberShips = this.memberShipService.getFriends(id);
for (MemberShip m : memberShips) {
if (!m.getMember().getId().equals(id)) {
friends.add(m.getMember());
}
}
return friends;
}
/**
* Extract alla the statistic related to the given user
*/
private void extractStatistics(UbikeUser user) {
StatisticManager statMan = new StatisticManager(tml);
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
List<Statistic> today = statMan.getDailyStat(user, date);
List<Statistic> thisWeek = statMan.getWeeklyStat(user, date);
List<Statistic> thisMonth = statMan.getMonthlyStat(user, date);
List<Statistic> thisYear = statMan.getYearlyStat(user, date);
List<Statistic> general = statMan.getGeneralStat(user);
cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR) - 1);
List<Statistic> lastWeek = statMan.getWeeklyStat(user, cal.getTime());
cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR) + 1);
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - 1);
List<Statistic> lastMonth = statMan.getMonthlyStat(user, cal.getTime());
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - 1);
List<Statistic> lastYear = statMan.getYearlyStat(user, cal.getTime());
BaseBean.setSessionAttribute("today", today);
BaseBean.setSessionAttribute("thisWeek", thisWeek);
BaseBean.setSessionAttribute("lastWeek", lastWeek);
BaseBean.setSessionAttribute("thisMonth", thisMonth);
BaseBean.setSessionAttribute("lastMonth", lastMonth);
BaseBean.setSessionAttribute("thisYear", thisYear);
BaseBean.setSessionAttribute("lastYear", lastYear);
BaseBean.setSessionAttribute("general", general);
}
/**
* Returns a dynamic instance of PrivacyPreferencesResource used for entity navigation.
*
* @param id identifier for the parent entity
* @return an instance of PrivacyPreferencesResource
*/
@Secured({"ROLE_USER", "USER_ACCESS"})
@Path("preferences/")
public PrivacyPreferencesResource getPreferencesResource() {
PreferencesResourceSub resource = resourceContext.getResource(
PreferencesResourceSub.class);
resource.setParent(getEntity());
return resource;
}
public static class FriendsResource extends UbikeUsersResource {
private UbikeUser parent;
private MemberShipServiceLocal memberShipService;
public void setParent(UbikeUser parent) {
this.parent = parent;
}
public void setService(MemberShipServiceLocal memberShipService) {
this.memberShipService = memberShipService;
}
@Override
protected List<UbikeUser> getEntities(int start, int max) {
Long id = this.parent.getId();
System.out.println("MemberShipServiceLocal -> " + memberShipService);
List<MemberShip> memberShips = this.memberShipService.getFriends(id);
java.util.Map<Long, UbikeUser> users = new java.util.HashMap<Long, UbikeUser>();
for (MemberShip m : memberShips) {
users.put(m.getMember().getId(), m.getMember());
}
users.remove(id);
return new java.util.ArrayList<UbikeUser>(users.values());
}
}
public static class TripsResourceSub extends TripsResource {
private UbikeUser parent;
public void setParent(UbikeUser parent) {
this.parent = parent;
}
@Override
protected List<Trip> getEntities(int start, int max) {
List<Trip> result = new java.util.ArrayList<Trip>();
int index = 0;
parent.getTrips().size();
for (Trip e : parent.getTrips()) {
if (index >= start && (index - start) < max) {
result.add(e);
}
index++;
}
return result;
}
}
public static class AccountResourceSub extends AccountResource {
private UbikeUser parent;
public void setParent(UbikeUser parent) {
this.parent = parent;
}
@Override
public Account getEntity() {
Account entity = parent.getAccount();
if (entity == null) {
throw new NotFoundException("Resource for " + uriInfo.getAbsolutePath()
+ " does not exist.", uriInfo.getAbsolutePath());
}
return entity;
}
}
public static class MemberShipsResourceSub extends MemberShipsResource {
private UbikeUser parent;
public void setParent(UbikeUser parent) {
this.parent = parent;
}
@Override
protected List<MemberShip> getEntities(int start, int max) {
List<MemberShip> result = new java.util.ArrayList<MemberShip>();
int index = 0;
for (MemberShip e : parent.getMemberShips()) {
if (index >= start && (index - start) < max) {
result.add(e);
}
index++;
}
return result;
}
}
public static class PreferencesResourceSub extends PrivacyPreferencesResource {
private UbikeUser parent;
public void setParent(UbikeUser parent) {
this.parent = parent;
}
@Override
public PrivacyPreferences getEntity() {
PrivacyPreferences entity = parent.getPreferences();
if (entity == null) {
throw new NotFoundException("Resource for " + uriInfo.getAbsolutePath()
+ " does not exist.", uriInfo.getAbsolutePath());
}
return entity;
}
}
}