Bug 4104: Added new exception handling in TaggingService.

This commit is contained in:
Henri Kohlberg
2018-09-21 17:23:54 +02:00
parent 3712b9c7a4
commit 0aee3e84d5
10 changed files with 435 additions and 368 deletions
@@ -17,12 +17,13 @@ Export-Package: com.sap.sailing.domain.common,
com.sap.sailing.domain.common.quadtree,
com.sap.sailing.domain.common.quadtree.impl;x-friends:="com.sap.sailing.domain.test",
com.sap.sailing.domain.common.racelog,
com.sap.sailing.domain.common.sharding,
com.sap.sailing.domain.common.racelog.tracking,
com.sap.sailing.domain.common.racelog.utils,
com.sap.sailing.domain.common.scalablevalue.impl,
com.sap.sailing.domain.common.security,
com.sap.sailing.domain.common.sensordata,
com.sap.sailing.domain.common.sharding,
com.sap.sailing.domain.common.tagging,
com.sap.sailing.domain.common.trackfiles,
com.sap.sailing.domain.common.tracking,
com.sap.sailing.domain.common.tracking.impl,
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.common.tagging;
public class RaceLogNotFoundException extends Exception {
private static final long serialVersionUID = -1935079125197798550L;
public RaceLogNotFoundException() {
}
public RaceLogNotFoundException(String message) {
super(message);
}
}
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.common.tagging;
public class ServiceNotFoundException extends Exception {
private static final long serialVersionUID = 4354757061181985766L;
public ServiceNotFoundException() {
}
public ServiceNotFoundException(String message) {
super(message);
}
}
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.common.tagging;
public class TagAlreadyExistsException extends Exception {
private static final long serialVersionUID = -3908869597780348971L;
public TagAlreadyExistsException() {
}
public TagAlreadyExistsException(String message) {
super(message);
}
}
@@ -63,6 +63,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.http.client.ClientProtocolException;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.AuthorizationException;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
@@ -289,6 +290,9 @@ import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.common.security.Permission;
import com.sap.sailing.domain.common.security.Permission.Mode;
import com.sap.sailing.domain.common.sharding.ShardingType;
import com.sap.sailing.domain.common.tagging.RaceLogNotFoundException;
import com.sap.sailing.domain.common.tagging.ServiceNotFoundException;
import com.sap.sailing.domain.common.tagging.TagAlreadyExistsException;
import com.sap.sailing.domain.common.tracking.BravoFix;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
@@ -6464,12 +6468,27 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet
public SuccessInfo addTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
String comment, String imageURL, boolean visibleForPublic, TimePoint raceTimepoint) {
SuccessInfo successInfo = new SuccessInfo(true, null, null, null);
boolean successful = getService().getTaggingService().addTag(leaderboardName, raceColumnName, fleetName, tag,
comment, imageURL, visibleForPublic, raceTimepoint);
if (!successful) {
String message = serverStringMessages.get(getClientLocale(),
getService().getTaggingService().getLastErrorCode().getCode());
successInfo = new SuccessInfo(false, message, null, null);
try {
getService().getTaggingService().addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
visibleForPublic, raceTimepoint);
} catch (AuthorizationException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "missingAuthorization"),
null, null);
} catch (IllegalArgumentException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "invalidParameters"), null,
null);
} catch (RaceLogNotFoundException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "raceLogNotFound"), null,
null);
} catch (ServiceNotFoundException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "securityServiceNotFound"),
null, null);
} catch (TagAlreadyExistsException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "tagAlreadyExists"), null,
null);
} catch (Exception e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "unknownError"), null,
null);
}
return successInfo;
}
@@ -6477,12 +6496,26 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet
@Override
public SuccessInfo removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag) {
SuccessInfo successInfo = new SuccessInfo(true, null, null, null);
boolean successful = getService().getTaggingService().removeTag(leaderboardName, raceColumnName, fleetName,
tag);
if (!successful) {
String message = serverStringMessages.get(getClientLocale(),
getService().getTaggingService().getLastErrorCode().getCode());
successInfo = new SuccessInfo(false, message, null, null);
try {
getService().getTaggingService().removeTag(leaderboardName, raceColumnName, fleetName, tag);
} catch (AuthorizationException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "missingAuthorization"),
null, null);
} catch (IllegalArgumentException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "invalidParameters"), null,
null);
} catch (NotRevokableException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "tagNotRevokable"), null,
null);
} catch (RaceLogNotFoundException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "raceLogNotFound"), null,
null);
} catch (ServiceNotFoundException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "securityServiceNotFound"),
null, null);
} catch (Exception e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "unknownError"), null,
null);
}
return successInfo;
}
@@ -6491,12 +6524,30 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet
public SuccessInfo updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate,
String tag, String comment, String imageURL, boolean visibleForPublic) {
SuccessInfo successInfo = new SuccessInfo(true, null, null, null);
boolean successful = getService().getTaggingService().updateTag(leaderboardName, raceColumnName, fleetName,
tagToUpdate, tag, comment, imageURL, visibleForPublic);
if (!successful) {
String message = serverStringMessages.get(getClientLocale(),
getService().getTaggingService().getLastErrorCode().getCode());
successInfo = new SuccessInfo(false, message, null, null);
try {
getService().getTaggingService().updateTag(leaderboardName, raceColumnName, fleetName, tagToUpdate, tag,
comment, imageURL, visibleForPublic);
} catch (AuthorizationException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "missingAuthorization"),
null, null);
} catch (IllegalArgumentException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "invalidParameters"), null,
null);
} catch (NotRevokableException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "tagNotRevokable"), null,
null);
} catch (RaceLogNotFoundException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "raceLogNotFound"), null,
null);
} catch (ServiceNotFoundException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "securityServiceNotFound"),
null, null);
} catch (TagAlreadyExistsException e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "tagAlreadyExists"), null,
null);
} catch (Exception e) {
successInfo = new SuccessInfo(false, serverStringMessages.get(getClientLocale(), "unknownError"), null,
null);
}
return successInfo;
}
@@ -6504,19 +6555,39 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet
@Override
public List<TagDTO> getAllTags(String leaderboardName, String raceColumnName, String fleetName) {
List<TagDTO> result = new ArrayList<TagDTO>();
result.addAll(getService().getTaggingService().getPrivateTags(leaderboardName, raceColumnName, fleetName));
result.addAll(getService().getTaggingService().getPublicTags(leaderboardName, raceColumnName, fleetName));
try {
result.addAll(getService().getTaggingService().getPublicTags(leaderboardName, raceColumnName, fleetName));
} catch (RaceLogNotFoundException e) {
// do nothing and try to return as much tags as possible (private tags)
}
try {
result.addAll(getService().getTaggingService().getPrivateTags(leaderboardName, raceColumnName, fleetName));
} catch (ServiceNotFoundException e) {
// do nothing and try to return as much tags as possible (public tags)
}
return result;
}
@Override
public List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName) {
return getService().getTaggingService().getPublicTags(leaderboardName, raceColumnName, fleetName);
List<TagDTO> result = new ArrayList<TagDTO>();
try {
result.addAll(getService().getTaggingService().getPublicTags(leaderboardName, raceColumnName, fleetName));
} catch (RaceLogNotFoundException e) {
// do nothing as method will always return at least an empty list
}
return result;
}
@Override
public List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName) {
return getService().getTaggingService().getPrivateTags(leaderboardName, raceColumnName, fleetName);
List<TagDTO> result = new ArrayList<TagDTO>();
try {
result.addAll(getService().getTaggingService().getPrivateTags(leaderboardName, raceColumnName, fleetName));
} catch (ServiceNotFoundException e) {
// do nothing as method will always return at least an empty list
}
return result;
}
/**
@@ -4,12 +4,9 @@ slicingTimeRangeOutOfBounds=The TimeRange to slice is not part of the race
slicingCouldNotObtainRace=Could not obtain sliced race
slicingError=Error slicing race
unknownError=Unknown error
notLoggedIn=You are not logged in
missingPermissions=Missing permissions
securityServiceNotFound=Security service not found
racelogNotFound=Racelog not found
tagNotRevokable=This tag cannot be revoked
tagAlreadyExists=Tag does already exist, duplicated tags are not allowed
tagAlreadyRemoved=Tag cannot be removed twice!
tagNotEmpty=Tag may not be empty
timepointNotEmpty=Timepoint may not be empty
missingAuthorization=You are not logged in or missing the required permission!
securityServiceNotFound=Security service not found!
raceLogNotFound=Racelog not found!
tagNotRevokable=This tag cannot be revoked!
tagAlreadyExists=Tag does already exist, duplicated tags are not allowed!
invalidParameters=One of the given parameters does not have a valid value!
@@ -3,13 +3,10 @@ slicingRaceColumnAlreadyUsedThe=Der Rennspaltenname ist in der Regatta bereits v
slicingTimeRangeOutOfBounds=Die angegebene Zeitspanne ist ausserhalb des Rennens
slicingCouldNotObtainRace=Das geschnittene Rennen konnte nicht gefunden werden
slicingError=Fehler beim Schneiden des Rennens
unknownError=Unbekannter Fehler
notLoggedIn=Du bist nicht eingeloggt
missingPermissions=Fehlende Berechtigung
securityServiceNotFound=Sicherheits-Service konnte nicht gefunden werden
racelogNotFound=Racelog konnte nicht gefunden werden
tagNotRevokable=Dieser Tag ist nicht umkehrbar
tagAlreadyExists=Dieser Tag existiert bereits
tagAlreadyRemoved=Dieser Tag wurde bereits geloescht
tagNotEmpty=Der Tag darf nicht leer sein
timepointNotEmpty=Der Zeitpunkt darf nicht leer sein
unknownError=Unbekannter Fehler!
missingAuthorization=Du bist nicht eingeloggt oder dir fehlen die benoetigten Informationen!
securityServiceNotFound=Sicherheits-Service konnte nicht gefunden werden!
raceLogNotFound=Racelog konnte nicht gefunden werden!
tagNotRevokable=Dieser Tag ist nicht umkehrbar!
tagAlreadyExists=Dieser Tag existiert bereits!
invalidParameters=Einer der Parameter hat einen ungueltigen Wert!
@@ -21,10 +21,14 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import org.apache.shiro.authz.AuthorizationException;
import org.json.simple.JSONArray;
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
import com.sap.sailing.domain.common.dto.TagDTO;
import com.sap.sailing.domain.common.racelog.RaceLogServletConstants;
import com.sap.sailing.domain.common.tagging.RaceLogNotFoundException;
import com.sap.sailing.domain.common.tagging.TagAlreadyExistsException;
import com.sap.sailing.server.gateway.jaxrs.AbstractSailingServerResource;
import com.sap.sailing.server.tagging.TagDTODeSerializer;
import com.sap.sailing.server.tagging.TaggingService;
@@ -68,32 +72,31 @@ public class TagsResource extends AbstractSailingServerResource {
@PathParam(RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME) String raceColumnName,
@PathParam(RaceLogServletConstants.PARAMS_RACE_FLEET_NAME) String fleetName,
@DefaultValue("both") @QueryParam("visibility") String visibility) {
boolean lookForPublic = visibility.equalsIgnoreCase("both") || visibility.equalsIgnoreCase("public");
boolean lookForPrivate = visibility.equalsIgnoreCase("both") || visibility.equalsIgnoreCase("private");
Response response;
TaggingService taggingService = getService().getTaggingService();
if (taggingService != null) {
List<TagDTO> tags = new ArrayList<TagDTO>();
final TaggingService taggingService = getService().getTaggingService();
final List<TagDTO> tags = new ArrayList<TagDTO>();
final boolean lookForPublic = visibility.equalsIgnoreCase("both") || visibility.equalsIgnoreCase("public");
final boolean lookForPrivate = visibility.equalsIgnoreCase("both") || visibility.equalsIgnoreCase("private");
try {
if (lookForPublic) {
Util.addAll(taggingService.getPublicTags(leaderboardName, raceColumnName, fleetName), tags);
}
if (lookForPrivate) {
Util.addAll(taggingService.getPrivateTags(leaderboardName, raceColumnName, fleetName), tags);
try {
Util.addAll(taggingService.getPrivateTags(leaderboardName, raceColumnName, fleetName), tags);
} catch (AuthorizationException e) {
// do nothing when user is not logged in
}
}
// remove revoked tags from result
tags.removeIf(tag -> tag.getRevokedAt() != null && tag.getRevokedAt().asMillis() != 0);
JSONArray jsonTags = serializer.serialize(tags);
response = Response.ok(jsonTags.toJSONString()).type(APPLICATION_JSON_UTF8).build();
} else {
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8)
.entity("Tagging Service not found!").build();
logger.warning("Tagging Service not found!");
} catch (RaceLogNotFoundException e) {
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
} catch (Exception e) {
logger.warning("Could not load tags! " + e.getMessage());
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8).build();
}
return response;
}
@@ -106,11 +109,12 @@ public class TagsResource extends AbstractSailingServerResource {
* @param visible
* default is <code>false</code>
*
* @return status 201 (created) if creation was successful, otherwise 400 (bad request)
* @return status 201 (created) if creation was successful, otherwise 400 (bad request) 401 (unauthorized) or 500
* (internal server error)
* @see TaggingService#addTag(String, String, String, String, String, String, boolean, TimePoint)
*/
@POST
@Produces({ APPLICATION_JSON_UTF8, TEXT_PLAIN_UTF8 })
@Produces({ TEXT_PLAIN_UTF8 })
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createTag(@Context UriInfo uriInfo,
@PathParam(RaceLogServletConstants.PARAMS_LEADERBOARD_NAME) String leaderboardName,
@@ -119,15 +123,18 @@ public class TagsResource extends AbstractSailingServerResource {
@FormParam("comment") String comment, @FormParam("image") String imageURL,
@FormParam("public") boolean visibleForPublic, @FormParam("raceTimepoint") long raceTimepoint) {
Response response;
TaggingService taggingService = getService().getTaggingService();
boolean successful = taggingService.addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
visibleForPublic, new MillisecondsTimePoint(raceTimepoint));
if (successful) {
final TaggingService taggingService = getService().getTaggingService();
try {
taggingService.addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL, visibleForPublic,
new MillisecondsTimePoint(raceTimepoint));
response = Response.created(uriInfo.getRequestUri()).build();
} else {
String errorMessage = taggingService.getLastErrorCode().getMessage();
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).entity(errorMessage).build();
logger.warning("Could not save tag! " + errorMessage);
} catch (IllegalArgumentException | RaceLogNotFoundException | TagAlreadyExistsException e) {
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
} catch (AuthorizationException e) {
response = Response.status(Status.UNAUTHORIZED).type(TEXT_PLAIN_UTF8).build();
} catch (Exception e) {
logger.warning("Could not save tag! " + e.getMessage());
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8).build();
}
return response;
}
@@ -135,12 +142,13 @@ public class TagsResource extends AbstractSailingServerResource {
/**
* Removes tag given as json string.
*
* @return status 204 (no content) if deletion was successful, otherwise 400 (bad request)
* @return status 204 (no content) if deletion was successful, otherwise 400 (bad request), 401 (unauthorized) or
* 500 (internal server error)
* @see TagDTO
* @see TaggingService#removeTag(String, String, String, TagDTO)
*/
@DELETE
@Produces({ APPLICATION_JSON_UTF8, TEXT_PLAIN_UTF8 })
@Produces({ TEXT_PLAIN_UTF8 })
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response deleteTag(@PathParam(RaceLogServletConstants.PARAMS_LEADERBOARD_NAME) String leaderboardName,
@PathParam(RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME) String raceColumnName,
@@ -149,13 +157,16 @@ public class TagsResource extends AbstractSailingServerResource {
Response response;
TagDTO tagToRemove = serializer.deserializeTag(tagJson);
TaggingService taggingService = getService().getTaggingService();
boolean successful = taggingService.removeTag(leaderboardName, raceColumnName, fleetName, tagToRemove);
if (successful) {
try {
taggingService.removeTag(leaderboardName, raceColumnName, fleetName, tagToRemove);
response = Response.noContent().build();
} else {
String errorMessage = taggingService.getLastErrorCode().getMessage();
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).entity(errorMessage).build();
logger.warning("Could not remove tag! " + errorMessage);
} catch (IllegalArgumentException | NotRevokableException | RaceLogNotFoundException e) {
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
} catch (AuthorizationException e) {
response = Response.status(Status.UNAUTHORIZED).type(TEXT_PLAIN_UTF8).build();
} catch (Exception e) {
logger.warning("Could not remove tag! " + e.getMessage());
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8).build();
}
return response;
}
@@ -168,12 +179,13 @@ public class TagsResource extends AbstractSailingServerResource {
* @param tag
* may not be empty
*
* @return status 204 (no content) if update was successful, otherwise 400 (bad request)
* @return status 204 (no content) if update was successful, otherwise 400 (bad request), 401 (unauthorized) or 500
* (internal server error)
* @see TagDTO
* @see TaggingService#updateTag(String, String, String, TagDTO, String, String, String, boolean)
*/
@PUT
@Produces({ APPLICATION_JSON_UTF8, TEXT_PLAIN_UTF8 })
@Produces({ TEXT_PLAIN_UTF8 })
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response updateTag(@PathParam(RaceLogServletConstants.PARAMS_LEADERBOARD_NAME) String leaderboardName,
@PathParam(RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME) String raceColumnName,
@@ -182,28 +194,32 @@ public class TagsResource extends AbstractSailingServerResource {
@FormParam("comment") String commentParam, @FormParam("image") String imageURLParam,
@FormParam("public") String visibleForPublicParam) {
Response response;
boolean successful = true;
TagDTO tagToUpdate = serializer.deserializeTag(tagJson);
TaggingService taggingService = getService().getTaggingService();
final TagDTO tagToUpdate = serializer.deserializeTag(tagJson);
final TaggingService taggingService = getService().getTaggingService();
// only call update method when any of the parameters needs to be changed
if (tagParam != null || commentParam != null || imageURLParam != null || visibleForPublicParam != null) {
// keep old values when no new values are provided
String tag = tagParam == null ? tagToUpdate.getTag() : tagParam;
String comment = commentParam == null ? tagToUpdate.getComment() : commentParam;
String imageURL = imageURLParam == null ? tagToUpdate.getImageURL() : imageURLParam;
boolean visibleForPublic = visibleForPublicParam == null ? tagToUpdate.isVisibleForPublic()
: visibleForPublicParam.equalsIgnoreCase("true") ? true : false;
successful = taggingService.updateTag(leaderboardName, raceColumnName, fleetName, tagToUpdate, tag, comment,
imageURL, visibleForPublic);
}
if (successful) {
response = Response.noContent().build();
String tag = (tagParam == null ? tagToUpdate.getTag() : tagParam);
String comment = (commentParam == null ? tagToUpdate.getComment() : commentParam);
String imageURL = (imageURLParam == null ? tagToUpdate.getImageURL() : imageURLParam);
boolean visibleForPublic = (visibleForPublicParam == null ? tagToUpdate.isVisibleForPublic()
: visibleForPublicParam.equalsIgnoreCase("true") ? true : false);
try {
taggingService.updateTag(leaderboardName, raceColumnName, fleetName, tagToUpdate, tag, comment,
imageURL, visibleForPublic);
response = Response.noContent().build();
} catch (IllegalArgumentException | NotRevokableException | RaceLogNotFoundException
| TagAlreadyExistsException e) {
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
} catch (AuthorizationException e) {
response = Response.status(Status.UNAUTHORIZED).type(TEXT_PLAIN_UTF8).build();
} catch (Exception e) {
logger.warning("Could not update tag! " + e.getMessage());
response = Response.status(Status.INTERNAL_SERVER_ERROR).type(TEXT_PLAIN_UTF8).build();
}
} else {
String errorMessage = taggingService.getLastErrorCode().getMessage();
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).entity(errorMessage).build();
logger.warning("Could not update tag! " + errorMessage);
response = Response.noContent().build();
}
return response;
}
@@ -2,13 +2,18 @@ package com.sap.sailing.server.tagging;
import java.util.List;
import org.apache.shiro.authz.AuthorizationException;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
import com.sap.sailing.domain.common.dto.TagDTO;
import com.sap.sailing.domain.common.tagging.RaceLogNotFoundException;
import com.sap.sailing.domain.common.tagging.ServiceNotFoundException;
import com.sap.sailing.domain.common.tagging.TagAlreadyExistsException;
import com.sap.sse.common.TimePoint;
// TODO: Replace error handling by throwing exceptions, see "topleveltranslations.json"
// TODO: CommentTooLong
// TODO: see "translation_v2.json" for new translation files
// TODO: use document settings id for tags/tag-buttons/... as race identifier
/**
* This service is used to perform all CRUD operations on {@link TagDTO tags} and is used by the
@@ -19,38 +24,6 @@ import com.sap.sse.common.TimePoint;
*/
public interface TaggingService {
/**
* Enum used to identify issues.
*/
public enum ErrorCode {
UNKNOWN_ERROR("unknownError", "Unknown error"),
NOT_LOGGED_IN("notLoggedIn", "You are not logged in"),
MISSING_PERMISSIONS("missingPermissions", "Missing permissions"),
SECURITY_SERIVCE_NOT_FOUND("securityServiceNotFound", "Security service not found"),
RACELOG_NOT_FOUND("racelogNotFound", "Racelog not found"),
TAG_NOT_REVOKABLE("tagNotRevokable", "This tag cannot be revoked"),
TAG_ALREADY_EXISTS("tagAlreadyExists", "Tag does already exist, duplicated tags are not allowed"),
TAG_ALREADY_REMOVED("tagAlreadyRemoved", "Tag cannot be removed twice!"),
TAG_NOT_EMPTY("tagNotEmpty", "Tag may not be empty"),
TIMEPOINT_NOT_EMPTY("timepointNotEmpty", "Timepoint may not be empty");
private final String code;
private final String message;
ErrorCode(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public String getMessage() {
return message;
}
}
/**
* Saves given properties as tag for given race. Checks if all parameters are valid and all required parameters are
* set.
@@ -73,10 +46,21 @@ public interface TaggingService {
* tag will be saved in {@link com.sap.sse.security.UserStore UserStore} (only visible for the creator)
* @param raceTimepoint
* timepoint in race when user created tag, must <b>NOT</b> be <code>null</code>
* @return <code>true</code> if tag was saved successfully, otherwise <code>false</code>
* @throws AuthorizationException
* thrown if user is not logged in or is missing permissions
* @throws IllegalArgumentException
* thrown if one of the required parameters has an invalid value
* @throws RaceLogNotFoundException
* thrown if racelog cannot be found (e.g. when <code>leaderboardName</code>,
* <code>raceColumnName</code> or <code>fleetName</code> are missing)
* @throws ServiceNotFoundException
* thrown if security service cannot be found
* @throws TagAlreadyExistsException
* thrown if tag already exists
*/
boolean addTag(String leaderboardName, String raceColumnName, String fleetName, String tag, String comment,
String imageURL, boolean visibleForPublic, TimePoint raceTimepoint);
void addTag(String leaderboardName, String raceColumnName, String fleetName, String tag, String comment,
String imageURL, boolean visibleForPublic, TimePoint raceTimepoint) throws AuthorizationException,
IllegalArgumentException, RaceLogNotFoundException, ServiceNotFoundException, TagAlreadyExistsException;
/**
* Removes public {@link TagDTO tag} from {@link com.sap.sailing.domain.abstractlog.race.RaceLog RaceLog} and
@@ -90,9 +74,21 @@ public interface TaggingService {
* required to identify {@link RaceLog}, must <b>NOT</b> be <code>null</code>
* @param tag
* tag to remove
* @return <code>true</code> if tag was removed successfully, otherwise <code>false</code>
* @throws AuthorizationException
* thrown if user is not logged in or is missing permissions
* @throws IllegalArgumentException
* thrown if one of the required parameters has an invalid value
* @throws NotRevokableException
* thrown if tag is public and not revokable from racelog
* @throws RaceLogNotFoundException
* thrown if racelog cannot be found (e.g. when <code>leaderboardName</code>,
* <code>raceColumnName</code> or <code>fleetName</code> are missing)
* @throws ServiceNotFoundException
* thrown if security service cannot be found
*/
boolean removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag);
void removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag)
throws AuthorizationException, IllegalArgumentException, NotRevokableException, RaceLogNotFoundException,
ServiceNotFoundException;
/**
* Updates given <code>tagToUpdate</code> with the given parameters <code>tag</code>, <code>comment</code>,
@@ -114,10 +110,24 @@ public interface TaggingService {
* new iamge URL
* @param visibleForPublic
* new privacy status
* @return <code>true</code> if tag was updated successfully, otherwise <code>false</code>
* @throws AuthorizationException
* thrown if user is not logged in or is missing permissions
* @throws IllegalArgumentException
* thrown if one of the required parameters has an invalid value
* @throws NotRevokableException
* thrown if tag is public and not revokable from racelog
* @throws TagAlreadyExistsException
* thrown if tag already exists
* @throws RaceLogNotFoundException
* thrown if racelog cannot be found (e.g. when <code>leaderboardName</code>,
* <code>raceColumnName</code> or <code>fleetName</code> are missing)
* @throws ServiceNotFoundException
* thrown if security service cannot be found
*/
boolean updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate, String tag,
String comment, String imageURL, boolean visibleForPublic);
void updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate, String tag,
String comment, String imageURL, boolean visibleForPublic)
throws AuthorizationException, IllegalArgumentException, NotRevokableException, RaceLogNotFoundException,
ServiceNotFoundException, TagAlreadyExistsException;
/**
* Returns all public tags for the specified race.
@@ -130,8 +140,12 @@ public interface TaggingService {
* required to identify {@link RaceLog}, must <b>NOT</b> be <code>null</code>
* @return list of {@link TagDTO tags}, empty list in case an error occurs or there are no tags available but
* <b>never null</b>!
* @throws RaceLogNotFoundException
* thrown if racelog cannot be found (e.g. when <code>leaderboardName</code>,
* <code>raceColumnName</code> or <code>fleetName</code> are missing)
*/
List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName);
List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName)
throws RaceLogNotFoundException;
/**
* Returns all public tags since the given <code>searchSinceTimePoint</code> for the specified race.
@@ -156,15 +170,9 @@ public interface TaggingService {
* required to identify {@link RaceLog}, must <b>NOT</b> be <code>null</code>
* @return list of {@link TagDTO tags}, empty list in case an error occurs or there are no tags available but
* <b>never null</b>!
* @throws ServiceNotFoundException
* thrown if security service cannot be found
*/
List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName);
/**
* Returns the last error code of the current user. Needs to be converted into error message to display this message
* to the user.
*
* @return last {@link ErrorCode error code} which occured if error is known, otherwise
* {@link ErrorCode#UNKNOWN_ERROR unknown error}
*/
ErrorCode getLastErrorCode();
List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName)
throws ServiceNotFoundException;
}
@@ -1,9 +1,7 @@
package com.sap.sailing.server.tagging;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.AuthorizationException;
@@ -19,6 +17,9 @@ import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
import com.sap.sailing.domain.common.dto.TagDTO;
import com.sap.sailing.domain.common.security.Permission;
import com.sap.sailing.domain.common.security.Permission.Mode;
import com.sap.sailing.domain.common.tagging.RaceLogNotFoundException;
import com.sap.sailing.domain.common.tagging.ServiceNotFoundException;
import com.sap.sailing.domain.common.tagging.TagAlreadyExistsException;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.common.TimePoint;
@@ -30,255 +31,203 @@ public class TaggingServiceImpl implements TaggingService {
private final RacingEventService racingService;
private final TagDTODeSerializer serializer;
private final Map<Subject, ErrorCode> lastErrorCodes;
public TaggingServiceImpl(RacingEventService racingService) {
this.racingService = racingService;
serializer = new TagDTODeSerializer();
lastErrorCodes = new HashMap<Subject, ErrorCode>();
}
private void setLastErrorCode(ErrorCode errorCode) {
lastErrorCodes.put(SecurityUtils.getSubject(), errorCode);
}
private String getCurrentUsername() {
String result = null;
/**
* Returns current username.
*
* @throws AuthorizationException
* @return username of current user
*/
private String getCurrentUsername() throws AuthorizationException {
Object principal = SecurityUtils.getSubject().getPrincipal();
if (principal != null) {
result = principal.toString();
} else {
setLastErrorCode(ErrorCode.NOT_LOGGED_IN);
if (principal == null) {
throw new AuthorizationException();
}
return result;
return principal.toString();
}
private SecurityService getSecurityService() {
/**
* Returns instance of {@link SecurityService} to access the user store.
*
* @return instance of {@link SecurityService}
* @throws ServiceNotFoundException
*/
private SecurityService getSecurityService() throws ServiceNotFoundException {
SecurityService securityService = Activator.getSecurityService();
if (securityService == null) {
setLastErrorCode(ErrorCode.SECURITY_SERIVCE_NOT_FOUND);
throw new ServiceNotFoundException("Security service not found!");
}
return securityService;
}
private boolean addPublicTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
String comment, String imageURL, TimePoint raceTimepoint) {
boolean successful = true;
try {
// TODO: As soon as permission-vertical branch got merged into master, apply
// new permission system at this permission check (see bug 4104, comment 9)
// functionality: Check if user has the permission to add RaceLogEvents to RaceLog.
SecurityUtils.getSubject().checkPermission(
Permission.LEADERBOARD.getStringPermissionForObjects(Mode.UPDATE, leaderboardName));
RaceLog raceLog = racingService.getRaceLog(leaderboardName, raceColumnName, fleetName);
if (raceLog == null) {
setLastErrorCode(ErrorCode.RACELOG_NOT_FOUND);
successful = false;
} else {
// check if tag already exists
boolean alreadyExists = false;
List<TagDTO> publicTags = getPublicTags(leaderboardName, raceColumnName, fleetName);
for (TagDTO publicTag : publicTags) {
// ignore revoked tags as TagDTO.equals() does ignore revokedAt timepoint
if (publicTag.getRevokedAt() == null && publicTag.equals(tag, comment, imageURL,
true, racingService.getServerAuthor().getName(), raceTimepoint)) {
alreadyExists = true;
break;
}
}
if (alreadyExists) {
setLastErrorCode(ErrorCode.TAG_ALREADY_EXISTS);
successful = false;
} else {
raceLog.add(new RaceLogTagEventImpl(tag, comment, imageURL, raceTimepoint,
racingService.getServerAuthor(), raceLog.getCurrentPassId()));
}
}
} catch (AuthorizationException e) {
setLastErrorCode(ErrorCode.MISSING_PERMISSIONS);
successful = false;
}
return successful;
}
private boolean addPrivateTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
String comment, String imageURL, TimePoint raceTimepoint) {
boolean successful = true;
SecurityService securityService = Activator.getSecurityService();
if (securityService == null) {
setLastErrorCode(ErrorCode.SECURITY_SERIVCE_NOT_FOUND);
successful = false;
} else {
Subject subject = SecurityUtils.getSubject();
if (subject.getPrincipal() != null) {
String username = subject.getPrincipal().toString();
TagDTODeSerializer serializer = new TagDTODeSerializer();
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
String privateTagsJson = securityService.getPreference(username, key);
List<TagDTO> privateTags = serializer.deserializeTags(privateTagsJson);
TagDTO tagToAdd = new TagDTO(tag, comment, imageURL, false, username, raceTimepoint,
MillisecondsTimePoint.now());
if (privateTags.contains(tagToAdd)) {
setLastErrorCode(ErrorCode.TAG_ALREADY_EXISTS);
successful = false;
} else {
privateTags.add(tagToAdd);
securityService.setPreference(username, key, serializer.serializeTags(privateTags));
}
} else {
setLastErrorCode(ErrorCode.NOT_LOGGED_IN);
successful = false;
}
}
return successful;
}
private boolean removePublicTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag) {
boolean successful = true;
private void addPublicTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
String comment, String imageURL, TimePoint raceTimepoint)
throws RaceLogNotFoundException, TagAlreadyExistsException {
// TODO: As soon as permission-vertical branch got merged into master, apply
// new permission system at this permission check (see bug 4104, comment 9)
// functionality: Check if user has the permission to add RaceLogEvents to RaceLog.
SecurityUtils.getSubject()
.checkPermission(Permission.LEADERBOARD.getStringPermissionForObjects(Mode.UPDATE, leaderboardName));
RaceLog raceLog = racingService.getRaceLog(leaderboardName, raceColumnName, fleetName);
if (raceLog == null) {
setLastErrorCode(ErrorCode.RACELOG_NOT_FOUND);
successful = false;
} else {
ReadonlyRaceState raceState = ReadonlyRaceStateImpl.getOrCreate(racingService, raceLog);
Iterable<RaceLogTagEvent> foundTagEvents = raceState.getTagEvents();
for (RaceLogTagEvent tagEvent : foundTagEvents) {
if (tagEvent.getRevokedAt() != null) {
continue;
} else if (tagEvent.getTag().equals(tag.getTag()) && tagEvent.getComment().equals(tag.getComment())
&& tagEvent.getImageURL().equals(tag.getImageURL())
&& tagEvent.getUsername().equals(tag.getUsername())
&& tagEvent.getLogicalTimePoint().equals(tag.getRaceTimepoint())) {
try {
// TODO: As soon as permission-vertical branch got merged into master, apply
// new permission system at this permission check (see bug 4104, comment 9)
// functionality: Check if user has the permission to delete tag from RaceLog (same user or
// admin).
Subject subject = SecurityUtils.getSubject();
subject.checkPermission(
Permission.LEADERBOARD.getStringPermissionForObjects(Mode.UPDATE, leaderboardName));
if ((subject.getPrincipal() != null && subject.getPrincipal().equals(tag.getUsername()))
|| subject.hasRole("admin")) {
raceLog.revokeEvent(tagEvent.getAuthor(), tagEvent, "Revoked");
} else {
setLastErrorCode(ErrorCode.MISSING_PERMISSIONS);
successful = false;
}
} catch (AuthorizationException e) {
setLastErrorCode(ErrorCode.MISSING_PERMISSIONS);
successful = false;
} catch (NotRevokableException e) {
setLastErrorCode(ErrorCode.TAG_NOT_REVOKABLE);
successful = false;
}
break;
}
throw new RaceLogNotFoundException();
}
// check if tag already exists
List<TagDTO> publicTags = getPublicTags(leaderboardName, raceColumnName, fleetName);
for (TagDTO publicTag : publicTags) {
// ignore revoked tags as TagDTO.equals() does ignore revokedAt timepoint
if (publicTag.getRevokedAt() == null && publicTag.equals(tag, comment, imageURL, true,
racingService.getServerAuthor().getName(), raceTimepoint)) {
throw new TagAlreadyExistsException();
}
}
return successful;
raceLog.add(new RaceLogTagEventImpl(tag, comment, imageURL, raceTimepoint, racingService.getServerAuthor(),
raceLog.getCurrentPassId()));
}
private boolean removePrivateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag) {
boolean successful = true;
String username = getCurrentUsername();
if (username == null) {
setLastErrorCode(ErrorCode.NOT_LOGGED_IN);
successful = false;
} else {
List<TagDTO> privateTags = getPrivateTags(leaderboardName, raceColumnName, fleetName);
privateTags.remove(tag);
SecurityService securityService = getSecurityService();
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
// error code will be set during collection of required data
if (username != null && securityService != null && key != null) {
if (privateTags.isEmpty()) {
securityService.unsetPreference(username, key);
} else {
securityService.setPreference(username, key, serializer.serializeTags(privateTags));
private void addPrivateTag(String leaderboardName, String raceColumnName, String fleetName, String tag,
String comment, String imageURL, TimePoint raceTimepoint)
throws AuthorizationException, ServiceNotFoundException, TagAlreadyExistsException {
SecurityService securityService = Activator.getSecurityService();
if (securityService == null) {
throw new ServiceNotFoundException("Security service not found!");
}
Subject subject = SecurityUtils.getSubject();
if (subject.getPrincipal() == null) {
throw new AuthorizationException();
}
String username = subject.getPrincipal().toString();
TagDTODeSerializer serializer = new TagDTODeSerializer();
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
String privateTagsJson = securityService.getPreference(username, key);
List<TagDTO> privateTags = serializer.deserializeTags(privateTagsJson);
TagDTO tagToAdd = new TagDTO(tag, comment, imageURL, false, username, raceTimepoint,
MillisecondsTimePoint.now());
if (privateTags.contains(tagToAdd)) {
throw new TagAlreadyExistsException();
}
privateTags.add(tagToAdd);
securityService.setPreference(username, key, serializer.serializeTags(privateTags));
}
private void removePublicTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag)
throws AuthorizationException, NotRevokableException, RaceLogNotFoundException {
RaceLog raceLog = racingService.getRaceLog(leaderboardName, raceColumnName, fleetName);
if (raceLog == null) {
throw new RaceLogNotFoundException();
}
ReadonlyRaceState raceState = ReadonlyRaceStateImpl.getOrCreate(racingService, raceLog);
Iterable<RaceLogTagEvent> foundTagEvents = raceState.getTagEvents();
for (RaceLogTagEvent tagEvent : foundTagEvents) {
if (tagEvent.getRevokedAt() != null) {
continue;
} else if (tagEvent.getTag().equals(tag.getTag()) && tagEvent.getComment().equals(tag.getComment())
&& tagEvent.getImageURL().equals(tag.getImageURL())
&& tagEvent.getUsername().equals(tag.getUsername())
&& tagEvent.getLogicalTimePoint().equals(tag.getRaceTimepoint())) {
// TODO: As soon as permission-vertical branch got merged into master, apply
// new permission system at this permission check (see bug 4104, comment 9)
// functionality: Check if user has the permission to delete tag from RaceLog (same user or
// admin).
Subject subject = SecurityUtils.getSubject();
subject.checkPermission(
Permission.LEADERBOARD.getStringPermissionForObjects(Mode.UPDATE, leaderboardName));
if (!(subject.getPrincipal() != null && subject.getPrincipal().equals(tag.getUsername()))
|| subject.hasRole("admin")) {
throw new AuthorizationException();
}
raceLog.revokeEvent(tagEvent.getAuthor(), tagEvent, "Revoked");
break;
}
}
}
private void removePrivateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag)
throws AuthorizationException, ServiceNotFoundException {
String username = getCurrentUsername();
List<TagDTO> privateTags = getPrivateTags(leaderboardName, raceColumnName, fleetName);
privateTags.remove(tag);
SecurityService securityService = getSecurityService();
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
// error code will be set during collection of required data
if (username != null && securityService != null && key != null) {
if (privateTags.isEmpty()) {
securityService.unsetPreference(username, key);
} else {
securityService.setPreference(username, key, serializer.serializeTags(privateTags));
}
}
return successful;
}
@Override
public boolean addTag(String leaderboardName, String raceColumnName, String fleetName, String tag, String comment,
String imageURL, boolean visibleForPublic, TimePoint raceTimepoint) {
boolean successful;
public void addTag(String leaderboardName, String raceColumnName, String fleetName, String tag, String comment,
String imageURL, boolean visibleForPublic, TimePoint raceTimepoint) throws AuthorizationException,
IllegalArgumentException, RaceLogNotFoundException, ServiceNotFoundException, TagAlreadyExistsException {
// prefill optional parameters
comment = comment == null ? "" : comment;
imageURL = imageURL == null ? "" : imageURL;
// check all parameters for validity
if (tag == null || tag.isEmpty()) {
setLastErrorCode(ErrorCode.TAG_NOT_EMPTY);
successful = false;
} else if (raceTimepoint == null || raceTimepoint.asMillis() == 0) {
throw new IllegalArgumentException("Tag may not be empty!");
}
if (raceTimepoint == null || raceTimepoint.asMillis() == 0) {
// TODO: Check if timepoint is near start/end of race (+/- x%)
setLastErrorCode(ErrorCode.TIMEPOINT_NOT_EMPTY);
successful = false;
throw new IllegalArgumentException("Timepoint may not be empty!");
}
if (visibleForPublic) {
addPublicTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL, raceTimepoint);
} else {
// all parameters are valid => save tag
if (visibleForPublic) {
successful = addPublicTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
raceTimepoint);
} else {
successful = addPrivateTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
raceTimepoint);
}
addPrivateTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL, raceTimepoint);
}
return successful;
}
@Override
public boolean removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag) {
boolean successful = true;
// check all parameters for validity
public void removeTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tag)
throws AuthorizationException, IllegalArgumentException, NotRevokableException, RaceLogNotFoundException,
ServiceNotFoundException {
if (tag == null) {
setLastErrorCode(ErrorCode.TAG_NOT_EMPTY);
successful = false;
throw new IllegalArgumentException("Tag may not be empty!");
}
if (tag.isVisibleForPublic()) {
removePublicTag(leaderboardName, raceColumnName, fleetName, tag);
} else {
// all parameters are valid => remove tag
if (tag.isVisibleForPublic()) {
successful = removePublicTag(leaderboardName, raceColumnName, fleetName, tag);
} else {
successful = removePrivateTag(leaderboardName, raceColumnName, fleetName, tag);
}
removePrivateTag(leaderboardName, raceColumnName, fleetName, tag);
}
return successful;
}
@Override
public boolean updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate,
String tag, String comment, String imageURL, boolean visibleForPublic) {
boolean successful = true;
public void updateTag(String leaderboardName, String raceColumnName, String fleetName, TagDTO tagToUpdate,
String tag, String comment, String imageURL, boolean visibleForPublic)
throws AuthorizationException, IllegalArgumentException, NotRevokableException, RaceLogNotFoundException,
ServiceNotFoundException, TagAlreadyExistsException {
String username = getCurrentUsername();
if (username != null && tagToUpdate.getUsername().equals(username)) {
if (removeTag(leaderboardName, raceColumnName, fleetName, tagToUpdate)) {
successful = addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL,
visibleForPublic, tagToUpdate.getRaceTimepoint());
} else {
successful = false;
}
removeTag(leaderboardName, raceColumnName, fleetName, tagToUpdate);
addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL, visibleForPublic,
tagToUpdate.getRaceTimepoint());
}
return successful;
}
@Override
public List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName) {
public List<TagDTO> getPublicTags(String leaderboardName, String raceColumnName, String fleetName)
throws RaceLogNotFoundException {
final List<TagDTO> result = new ArrayList<TagDTO>();
RaceLog raceLog = racingService.getRaceLog(leaderboardName, raceColumnName, fleetName);
if (raceLog == null) {
setLastErrorCode(ErrorCode.RACELOG_NOT_FOUND);
} else {
ReadonlyRaceState raceState = ReadonlyRaceStateImpl.getOrCreate(racingService, raceLog);
Iterable<RaceLogTagEvent> foundTagEvents = raceState.getTagEvents();
for (RaceLogTagEvent tagEvent : foundTagEvents) {
result.add(new TagDTO(tagEvent.getTag(), tagEvent.getComment(), tagEvent.getImageURL(),
true, tagEvent.getUsername(), tagEvent.getLogicalTimePoint(), tagEvent.getCreatedAt(),
tagEvent.getRevokedAt()));
}
throw new RaceLogNotFoundException();
}
ReadonlyRaceState raceState = ReadonlyRaceStateImpl.getOrCreate(racingService, raceLog);
Iterable<RaceLogTagEvent> foundTagEvents = raceState.getTagEvents();
for (RaceLogTagEvent tagEvent : foundTagEvents) {
result.add(new TagDTO(tagEvent.getTag(), tagEvent.getComment(), tagEvent.getImageURL(), true,
tagEvent.getUsername(), tagEvent.getLogicalTimePoint(), tagEvent.getCreatedAt(),
tagEvent.getRevokedAt()));
}
return result;
}
@@ -297,8 +246,8 @@ public class TaggingServiceImpl implements TaggingService {
&& tagEvent.getCreatedAt().after(searchSince))
|| (searchSince != null && tagEvent.getRevokedAt() != null
&& tagEvent.getRevokedAt().after(searchSince))) {
result.add(new TagDTO(tagEvent.getTag(), tagEvent.getComment(), tagEvent.getImageURL(),
true, tagEvent.getUsername(), tagEvent.getLogicalTimePoint(), tagEvent.getCreatedAt(),
result.add(new TagDTO(tagEvent.getTag(), tagEvent.getComment(), tagEvent.getImageURL(), true,
tagEvent.getUsername(), tagEvent.getLogicalTimePoint(), tagEvent.getCreatedAt(),
tagEvent.getRevokedAt()));
}
}
@@ -307,27 +256,13 @@ public class TaggingServiceImpl implements TaggingService {
}
@Override
public List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName) {
public List<TagDTO> getPrivateTags(String leaderboardName, String raceColumnName, String fleetName)
throws AuthorizationException, ServiceNotFoundException {
final List<TagDTO> result = new ArrayList<TagDTO>();
SecurityService securityService = getSecurityService();
if (securityService != null) {
String username = getCurrentUsername();
if (username != null) {
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
String privateTagsJson = securityService.getPreference(username, key);
List<TagDTO> privateTags = serializer.deserializeTags(privateTagsJson);
result.addAll(privateTags);
}
}
String key = serializer.generateUniqueKey(leaderboardName, raceColumnName, fleetName);
String privateTagsJson = getSecurityService().getPreference(getCurrentUsername(), key);
List<TagDTO> privateTags = serializer.deserializeTags(privateTagsJson);
result.addAll(privateTags);
return result;
}
@Override
public ErrorCode getLastErrorCode() {
ErrorCode lastErrorCode = lastErrorCodes.get(SecurityUtils.getSubject());
if (lastErrorCode == null) {
lastErrorCode = ErrorCode.UNKNOWN_ERROR;
}
return lastErrorCode;
}
}