package crmdna.venue; import com.google.appengine.api.memcache.MemcacheServiceFactory; import com.googlecode.objectify.Key; import com.googlecode.objectify.Work; import crmdna.client.Client; import crmdna.common.Utils; import crmdna.common.api.APIException; import crmdna.common.api.APIResponse.Status; import crmdna.group.Group; import crmdna.sequence.Sequence; import crmdna.sequence.Sequence.SequenceType; import crmdna.user.User; import crmdna.user.User.ClientLevelPrivilege; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static crmdna.common.AssertUtils.ensureNotNull; import static crmdna.common.OfyService.ofy; public class Venue { public static VenueProp create(String client, String displayName, String address, long groupId, String login) { Client.ensureValid(client); User.ensureClientLevelPrivilege(client, login, ClientLevelPrivilege.UPDATE_VENUE); Group.safeGet(client, groupId); if ((null == displayName) || displayName.equals("")) Utils.throwIncorrectSpecException("display name is null or empty string"); if ((null == address) || address.equals("")) Utils.throwIncorrectSpecException("address is null or empty string"); String name = Utils.removeSpaceUnderscoreBracketAndHyphen(displayName.toLowerCase()); List<Key<VenueEntity>> keys = ofy(client).load().type(VenueEntity.class).filter("name", name).keys().list(); if (keys.size() != 0) throw new APIException().status(Status.ERROR_RESOURCE_ALREADY_EXISTS).message( "There is already a venue with name [" + displayName + "]"); String key = getUniqueKey(client, name); long val = MemcacheServiceFactory.getMemcacheService().increment(key, 1, (long) 0); if (val != 1) throw new APIException().status(Status.ERROR_RESOURCE_ALREADY_EXISTS).message( "There is already a venue with name [" + displayName + "]"); VenueEntity entity = new VenueEntity(); entity.venueId = Sequence.getNext(client, SequenceType.VENUE); entity.name = name; entity.displayName = displayName; entity.address = address; entity.groupId = groupId; ofy(client).save().entity(entity).now(); return entity.toProp(); } private static String getUniqueKey(String namespace, String name) { return namespace + "_" + SequenceType.VENUE + "_" + name; } public static VenueEntity safeGet(String client, long venueId) { Client.ensureValid(client); VenueEntity entity = ofy(client).load().type(VenueEntity.class).id(venueId).now(); if (null == entity) throw new APIException().status(Status.ERROR_RESOURCE_NOT_FOUND).message( "Venue [" + venueId + "] does not exist"); return entity; } public static VenueEntity safeGetByIdOrName(String client, String idOrName) { Client.ensureValid(client); ensureNotNull(idOrName); if (Utils.canParseAsLong(idOrName)) { long venueId = Utils.safeParseAsLong(idOrName); return safeGet(client, venueId); } idOrName = Utils.removeSpaceUnderscoreBracketAndHyphen(idOrName.toLowerCase()); List<VenueEntity> entities = ofy(client).load().type(VenueEntity.class).filter("name", idOrName).list(); if (entities.size() == 0) throw new APIException().status(Status.ERROR_RESOURCE_NOT_FOUND).message( "Venue [" + idOrName + "] does not exist"); if (entities.size() > 1) // should never come here throw new APIException().status(Status.ERROR_RESOURCE_INCORRECT) .message( "Found [" + entities.size() + "] matches for venue [" + idOrName + "]. Please specify Id"); return entities.get(0); } public static VenueProp update(final String client, final long venueId, final String newDisplayName, final String newAddress, final Long newGroupId, String login) { Client.ensureValid(client); User.ensureClientLevelPrivilege(client, login, ClientLevelPrivilege.UPDATE_VENUE); if (newGroupId != null) Group.safeGet(client, newGroupId); ensureValid(newDisplayName, newAddress); VenueEntity entity = safeGet(client, venueId); if (newDisplayName != null) { String newName = Utils.removeSpaceUnderscoreBracketAndHyphen(newDisplayName.toLowerCase()); // if name is changing ensure it is unique if (!entity.name.equals(newName)) { List<Key<VenueEntity>> keys = ofy(client).load().type(VenueEntity.class).filter("name", newName).keys().list(); if (keys.size() != 0) throw new APIException().status(Status.ERROR_RESOURCE_ALREADY_EXISTS).message( "There is already a venue with name [" + newDisplayName + "]"); String key = getUniqueKey(client, newName); long val = MemcacheServiceFactory.getMemcacheService().increment(key, 1, (long) 0); if (val != 1) throw new APIException().status(Status.ERROR_RESOURCE_ALREADY_EXISTS).message( "There is already a venue (in cache) with name [" + newDisplayName + "]"); } } VenueProp venueProp = ofy(client).transact(new Work<VenueProp>() { @Override public VenueProp run() { VenueEntity entity = safeGet(client, venueId); if (newDisplayName != null) { entity.displayName = newDisplayName; entity.name = Utils.removeSpaceUnderscoreBracketAndHyphen(newDisplayName.toLowerCase()); } if (newAddress != null) entity.address = newAddress; if (newGroupId != null) entity.groupId = newGroupId; ofy(client).save().entity(entity).now(); return entity.toProp(); } }); return venueProp; } private static void ensureValid(String displayName, String address) { if (displayName != null) if (displayName.equals("")) Utils.throwIncorrectSpecException("venue display name is empty string"); if (address != null) if (address.equals("")) Utils.throwIncorrectSpecException("venue address is empty string"); } public static List<VenueProp> getAll(String client) { Client.ensureValid(client); List<VenueEntity> entities = ofy(client).load().type(VenueEntity.class).order("name").list(); List<VenueProp> props = new ArrayList<>(); for (VenueEntity entity : entities) props.add(entity.toProp()); Collections.sort(props); return props; } static List<VenueProp> getAllForGroup(String client, long groupId) { Client.ensureValid(client); Group.safeGet(client, groupId); List<VenueEntity> entities = ofy(client).load().type(VenueEntity.class).filter("groupId", groupId).list(); List<VenueProp> props = new ArrayList<>(); for (VenueEntity entity : entities) props.add(entity.toProp()); Collections.sort(props); return props; } public static void delete(String client, long venueId, String login) { Client.ensureValid(client); User.ensureClientLevelPrivilege(client, login, ClientLevelPrivilege.UPDATE_VENUE); // TODO - check other references throw new APIException().status(Status.ERROR_NOT_IMPLEMENTED).message( "deleting venue not yet implemented"); } public static class VenueProp implements Comparable<VenueProp> { public long venueId; public String name; public String displayName; public String address; public long groupId; public String shortName; @Override public int compareTo(VenueProp arg0) { return name.compareTo(arg0.name); } } }