Merge branch 'master' into bug2059

This commit is contained in:
Steffen Schaefer committed 2017-07-12 10:08:31 +02:00
commit 3eb791898c
29 files changed
+194 -121

No files matched your search

@@ -23,6 +23,7 @@ public enum BoatClassMasterdata {
ALBIN_EXPRESS ("Albin Express", true, 7.77, 2.50, BoatHullType.MONOHULL, false),
ALBIN_BALLAD ("Albin Ballad", true, 9.12, 2.95, BoatHullType.MONOHULL, false),
B_ONE ("B/ONE", true, 7.80, 2.49, BoatHullType.MONOHULL, true, "B-ONE"),
CADET ("Cadet", true, 3.20, 1.38, BoatHullType.MONOHULL, true),
CANOE_IC ("International Canoe", true, 5.20, 1.01, BoatHullType.MONOHULL, true, "Canoe IC", "Canoe-IC", "IC", "Kanu IC", "International Canoe", "International 10 Sq.m. Sailing Canoe"),
CANOE_TAIFUN ("Canoe Taifun", true, 5.20, 1.32, BoatHullType.MONOHULL, false, "Taifun", "Taifun Kanu", "Kanu Taifun"),
CONTENDER ("Contender", true, 4.88, 1.42, BoatHullType.MONOHULL, false),
@@ -73,6 +74,7 @@ public enum BoatClassMasterdata {
MELGES_24 ("Melges 24", true, 7.32, 2.50, BoatHullType.MONOHULL, true, "Melges-24", "M24"),
MINI_TRANSAT ("Mini Transat 6.50", true, 6.50, 3.00, BoatHullType.MONOHULL, true, "Mini Transat"),
MUSTO_SKIFF ("Musto Skiff", true, 4.55, 1.35, BoatHullType.MONOHULL, true, "Musto Performance Skiff", "MPS", "Musto"),
NACRA_15 ("Nacra 15", true, 4.70, 2.35, BoatHullType.CATAMARAN, true, "N15", "Nacra-15"),
NACRA_17 ("Nacra 17", true, 5.25, 2.59, BoatHullType.CATAMARAN, true, "N17", "Nacra-17"),
O_JOLLE ("O-Jolle", true, 5.00, 1.66, BoatHullType.MONOHULL, false, "O Jolle", "OJolle", "Olympiajolle"),
OK ("OK Dinghy", true, 5.25, 2.59, BoatHullType.MONOHULL, false, "OK-Dinghy", "OK-Jolle", "OK"),
@@ -101,6 +103,9 @@ public enum BoatClassMasterdata {
SUNBEAM_22 ("Sunbeam 22", true, 6.70, 2.15, BoatHullType.MONOHULL, true, "Sunbeam 22.1"),
SWAN_45 ("Swan 45", true, 13.83, 3.91, BoatHullType.MONOHULL, true, "Swan", "Swan-45"),
TARTAN_10 ("Tartan 10", true, 10.10, 2.82, BoatHullType.MONOHULL, true),
TECHNO_293 ("Techno 293", true, 2.93, 0.79, BoatHullType.SURFERBOARD, false, "Techno-293"),
TECHNO_293_PLUS ("Techno 293 Plus", true, 2.93, 0.79, BoatHullType.SURFERBOARD, false, "Techno-293-Plus", "Techno 293+"),
TEENY ("Teeny", true, 3.15, 1.37, BoatHullType.MONOHULL, true),
TORNADO ("Tornado Catamaran", true, 6.10, 3.02, BoatHullType.CATAMARAN, true, "Tornado", "Tornado Cat"),
TOM_28_MAX ("Tom 28 MAX", true, 8.48, 2.48, BoatHullType.MONOHULL, true, "Tom 28"),
TRIAS ("Trias", true, 9.20, 2.12, BoatHullType.MONOHULL, true),
@@ -57,7 +57,7 @@ public class ConnectivityUtils {
}
post.setEntity(new UrlEncodedFormEntity(urlParameters));
// TODO check if this is necessary at all
post.setHeader("Origin", "https://www.igtimi.com");
post.setHeader("Origin", baseUrl);
post.setHeader("Referer", referer);
post.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36");
HttpResponse responseForSignIn = client.execute(post);
@@ -104,7 +104,7 @@ public class IgtimiConnectionFactoryImpl implements IgtimiConnectionFactory {
}
private String getSignInUrl() {
return "https://www.igtimi.com/users/sign_in";
return getBaseUrl()+"/users/sign_in";
}
private String getOauthTokenUrl() {
@@ -119,6 +119,7 @@ public class IgtimiConnectionFactoryImpl implements IgtimiConnectionFactory {
* @return no trailing slash
*/
private String getBaseUrl() {
// return "http://staging.igtimi.com"; // Use this for testing a staged Igtimi server version
return "https://www.igtimi.com";
}
@@ -400,9 +401,8 @@ public class IgtimiConnectionFactoryImpl implements IgtimiConnectionFactory {
final String[] action = new String[1];
final Map<String, String> inputFieldsToSubmit = new HashMap<>();
try {
String pageContent = ConnectivityUtils.getContent(response);
String unescapedHtml = StringEscapeUtils.unescapeHtml(pageContent);
parser.parse(new ByteArrayInputStream(unescapedHtml.getBytes("UTF-8")), new DefaultHandler() {
String pageContent = ConnectivityUtils.getContent(response).replaceAll("<link (.*[^/])>", "<link $1 />");
parser.parse(new ByteArrayInputStream(pageContent.getBytes("UTF-8")), new DefaultHandler() {
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
@@ -424,6 +424,7 @@ public class IgtimiConnectionFactoryImpl implements IgtimiConnectionFactory {
});
} catch (SAXParseException e) {
// swallow; we try to grab what we can; let's hope it was enough...
logger.log(Level.FINE, "Exception trying to parse Igtimi authorization document", e);
}
response.getEntity().getContent().close();
final RedirectStrategy oldRedirectStrategy = client.getRedirectStrategy();
@@ -497,7 +498,7 @@ public class IgtimiConnectionFactoryImpl implements IgtimiConnectionFactory {
public Iterable<URI> getWebsocketServers() throws IllegalStateException, ClientProtocolException, IOException, ParseException, URISyntaxException {
HttpClient client = getHttpClient();
HttpGet getWebsocketServers = new HttpGet("https://www.igtimi.com/server_listers/web_sockets");
HttpGet getWebsocketServers = new HttpGet(getBaseUrl()+"/server_listers/web_sockets");
JSONObject serversJson = ConnectivityUtils.getJsonFromResponse(client.execute(getWebsocketServers));
final List<URI> result = new ArrayList<>();
for (Object serverUrl : (JSONArray) serversJson.get("web_socket_servers")) {
@@ -73,6 +73,31 @@ public abstract class BaseRegattaLogDeviceMappingFinder<ItemT extends WithID>
}
}
/**
* Checks if the regatta log has one or more device mappings for {@code item} that cover the time point
* {@code fixTimePoint}.
*/
public boolean hasMappingFor(ItemT item, TimePoint fixTimePoint) {
boolean result = false;
Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events = new HashMap<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>>();
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents = new HashMap<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent>();
findUnrevokedMappingAndClosingEvents(events, closingEvents);
final List<RegattaLogDeviceMappingEvent<ItemT>> mappingsList = events.get(item);
if (mappingsList != null) {
for (final RegattaLogDeviceMappingEvent<ItemT> event : mappingsList) {
final TimePoint from = event.getFrom();
final RegattaLogCloseOpenEndedDeviceMappingEvent closingEvent = closingEvents.get(event.getId());
final TimePoint toInclusive = closingEvent != null ? closingEvent.getClosingTimePointInclusive() : event.getToInclusive();
final TimeRange mappingTimeRange = new TimeRangeImpl(from, toInclusive, /* inclusive */ true);
if (mappingTimeRange.includes(fixTimePoint)) {
result = true;
break;
}
}
}
return result;
}
protected abstract RegattaLogDeviceMappingEvent<ItemT> createDeviceMappingEvent(ItemT item,
AbstractLogEventAuthor author, TimePoint plus, TimePoint toInclusive, DeviceIdentifier deviceId);
@@ -38,6 +38,7 @@ public class BoatClassImageResolver {
boatClassIconsMap.put(BoatClassMasterdata.ALBIN_EXPRESS.getDisplayName(), imageResources.AlbinExpressIcon());
boatClassIconsMap.put(BoatClassMasterdata.ALBIN_BALLAD.getDisplayName(), imageResources.AlbinBalladIcon());
boatClassIconsMap.put(BoatClassMasterdata.B_ONE.getDisplayName(), imageResources.BOne());
boatClassIconsMap.put(BoatClassMasterdata.CADET.getDisplayName(), imageResources.CadetIcon());
boatClassIconsMap.put(BoatClassMasterdata.CANOE_IC.getDisplayName(), imageResources.CanoeICIcon());
boatClassIconsMap.put(BoatClassMasterdata.CANOE_TAIFUN.getDisplayName(), imageResources.CanoeTaifunIcon());
boatClassIconsMap.put(BoatClassMasterdata.CONTENDER.getDisplayName(), imageResources.ContenderIcon());
@@ -86,6 +87,7 @@ public class BoatClassImageResolver {
boatClassIconsMap.put(BoatClassMasterdata.MELGES_24.getDisplayName(), imageResources.Melges24Icon());
boatClassIconsMap.put(BoatClassMasterdata.MINI_TRANSAT.getDisplayName(), imageResources.MiniTransatIcon());
boatClassIconsMap.put(BoatClassMasterdata.MUSTO_SKIFF.getDisplayName(), imageResources.MustoSkiffIcon());
boatClassIconsMap.put(BoatClassMasterdata.NACRA_15.getDisplayName(), imageResources.Nacra15Icon());
boatClassIconsMap.put(BoatClassMasterdata.NACRA_17.getDisplayName(), imageResources.Nacra17Icon());
boatClassIconsMap.put(BoatClassMasterdata.O_JOLLE.getDisplayName(), imageResources.OJolleIcon());
boatClassIconsMap.put(BoatClassMasterdata.OK.getDisplayName(), imageResources.OKIcon());
@@ -113,6 +115,9 @@ public class BoatClassImageResolver {
boatClassIconsMap.put(BoatClassMasterdata.SUNBEAM_22.getDisplayName(), imageResources.Sunbeam22Icon());
boatClassIconsMap.put(BoatClassMasterdata.SWAN_45.getDisplayName(), imageResources.Swan45Icon());
boatClassIconsMap.put(BoatClassMasterdata.TARTAN_10.getDisplayName(), imageResources.Tartan10Icon());
boatClassIconsMap.put(BoatClassMasterdata.TECHNO_293.getDisplayName(), imageResources.Techno293Icon());
boatClassIconsMap.put(BoatClassMasterdata.TECHNO_293_PLUS.getDisplayName(), imageResources.Techno293PlusIcon());
boatClassIconsMap.put(BoatClassMasterdata.TEENY.getDisplayName(), imageResources.TeenyIcon());
boatClassIconsMap.put(BoatClassMasterdata.TORNADO.getDisplayName(), imageResources.TornadoIcon());
boatClassIconsMap.put(BoatClassMasterdata.TOM_28_MAX.getDisplayName(), imageResources.Tom28MaxIcon());
boatClassIconsMap.put(BoatClassMasterdata.TRIAS.getDisplayName(), imageResources.TriasIcon());
@@ -52,6 +52,9 @@ public interface BoatClassImageResources extends ClientBundle {
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/B_ONE.png")
ImageResource BOne();
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/CADET.png")
ImageResource CadetIcon();
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/CANOE_IC.png")
ImageResource CanoeICIcon();
@@ -160,6 +163,9 @@ public interface BoatClassImageResources extends ClientBundle {
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/MUSTO_SKIFF.png")
ImageResource MustoSkiffIcon();
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/NACRA_15.png")
ImageResource Nacra15Icon();
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/NACRA_17.png")
ImageResource Nacra17Icon();
@@ -202,6 +208,15 @@ public interface BoatClassImageResources extends ClientBundle {
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/SWAN_45.png")
ImageResource Swan45Icon();
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/TECHNO_293.png")
ImageResource Techno293Icon();
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/TECHNO_293_PLUS.png")
ImageResource Techno293PlusIcon();
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/TEENY.png")
ImageResource TeenyIcon();
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/TORNADO.png")
ImageResource TornadoIcon();
@@ -6,6 +6,8 @@ import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.authz.AuthorizationException;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
import com.sap.sailing.gwt.server.HomeServiceUtil;
@@ -13,6 +15,7 @@ import com.sap.sailing.news.EventNewsService;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.statistics.TrackedRaceStatisticsCache;
import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException;
import com.sap.sse.gwt.dispatch.shared.exceptions.ServerDispatchException;
import com.sap.sse.security.SecurityService;
import com.sap.sse.security.User;
import com.sap.sse.security.UserStore;
@@ -93,7 +96,11 @@ public class SailingDispatchContextImpl implements SailingDispatchContext {
public void setPreferenceForCurrentUser(String preferenceKey, Object preference) {
User currentUser = securityService.getCurrentUser();
if (currentUser != null) {
securityService.setPreferenceObject(currentUser.getName(), preferenceKey, preference);
try {
securityService.setPreferenceObject(currentUser.getName(), preferenceKey, preference);
} catch (AuthorizationException e) {
throw new ServerDispatchException(e);
}
}
}
@@ -658,11 +658,9 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
MarkTrackDTO getMarkTrack(String leaderboardName, String raceColumnName, String fleetName, String markIdAsString);
/**
* The service may decide whether a mark fix can be removed. It may, for example, be impossible to
* cleanly remove a mark fix if a tracked race already exists and the mark fixes are already part of
* the GPS fix track which currently does not support a remove operation. However, when only the
* regatta log is the basis of the service and no tracked race exists yet, mark fixes may be removed
* by revoking the device mappings.
* The service may decide whether a mark fix can be removed. This is generally possible if there
* is a mark device mapping that can be manipulated in such a way that the {@code fix} will no longer
* be mapped.
*/
boolean canRemoveMarkFix(String leaderboardName, String raceColumnName, String fleetName, String markIdAsString, GPSFixDTO fix);
@@ -1543,7 +1543,7 @@ theDeletionOfThisFix=The deletion of this fix is currently not possible.
loadingMarkFixes=Loading mark fixes...
fixSuccessfullyAdded=Fix successfully added.
fixPositionSuccessfullyEdited=Fix position successfully edited.
fixSuccessfullyRemoved=Fix successfully removed.
fixSuccessfullyRemoved=Fix successfully removed. Remove the race and start tracking for it again for removal to take effect.
dragToChangePosition=Drag to change position\nRight-click to get menu to delete
moveFix=Move fix
manage2SailEvent=Manage2Sail Event
@@ -1526,7 +1526,7 @@ theDeletionOfThisFix=The Löschung des Fixes is aktuell nicht möglich.
loadingMarkFixes=Lade Marker Fixe...
fixSuccessfullyAdded=Fix erfolgreich hinzugefügt.
fixPositionSuccessfullyEdited=Fixposition erfolgreich editiert.
fixSuccessfullyRemoved=Fix erfolgreich bewegt.
fixSuccessfullyRemoved=Fix erfolgreich gelöscht. Rennen löschen und erneut laden, damit Änderungen sichtbar werden.
dragToChangePosition=Ziehen um die Position zu verändern\nRechtsklick für Menü mit Löschfunktion
moveFix=Position durch Ziehen ändern
manage2SailEvent=Manage2Sail Veranstaltung
@@ -597,7 +597,7 @@ applyMinimumWindConfidenceTooltip=Si se marca el valor del cuadro anterior, se u
windRangeDistribution=Distribución en el rango de viento
pleaseSeeToolTips=Pase el cursor por encima de las opciones para obtener información sobre herramientas si está disponible.
competitorColumnTooltip=Nombres de los navegantes de este competidor
competitorNationalityColumnTooltip=Nacionalidad de este competidor
competitorNationalityColumnTooltip=Nacionalidad de este competidor.
sailIdColumnTooltip=Muestra la bandera del país y el número de vela del competidor.
rankColumnTooltip=Posición general de este competidor en la regata.
carryColumnTooltip=Puntos acumulados de carreras anteriores.
@@ -1388,7 +1388,7 @@ numberWindFixes=Correcciones de viento
sailedMiles=Millas navegadas
millionValue={0,number,#0.0} mil
billionValue={0,number,#0.0} bil
noResults=No hay resultados aquí. A lo major, se puede consultar "Información del navegante".
noResults=No existen resultados disponibles aquí. Verifique con "Info de navegante".
noNews=No hay noticias disponibles
pointsValue={0,number,#0.00}
openLeaderboard=Abrir tabla de clasificación
@@ -1788,3 +1788,4 @@ useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Utilice
unknownLeaderboardType=Tipo de tabla de clasificación {0} desconocido
selectCompetitorsToEliminate=Seleccionar competidores a eliminar
trackedRaceAlreadyLinked=La carrera ya se ha vinculado a una columna de la carrera. ¿Desea realmente modificar el enlace?
reallyRemoveSeries=¿Desea realmente eliminar la serie "{0}"? Nota: todos los logs de las columnas de carrera anexas también se eliminarán de forma permanente.
@@ -1388,7 +1388,7 @@ numberWindFixes=Points vent
sailedMiles=Milles navigués
millionValue={0,number,#0.0} mil
billionValue={0,number,#0.0} bil
noResults=Il n''y a pas des résultats ici. Peut-etre consultez "Informations concurrents".
noResults=Aucun résultat disponible. Vous pouvez consulter les ''Informations concurrents''.
noNews=Aucune actualité disponible.
pointsValue={0,number,#0.00}
openLeaderboard=Ouvrir palmarès
@@ -1788,3 +1788,4 @@ useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Utilisez
unknownLeaderboardType=Type de palmarès {0} inconnu
selectCompetitorsToEliminate=Sélectionner des concurrents à éliminer
trackedRaceAlreadyLinked=La course est déjà liée à une colonne de course. Voulez-vous vraiment modifier le lien ?
reallyRemoveSeries=Voulez-vous vraiment supprimer la série "{0}" ? Note : tous les journaux de la course seront également supprimés de manière permanente pour cette course.
@@ -1388,7 +1388,7 @@ numberWindFixes=風フィックス
sailedMiles=帆走マイル
millionValue={0,number,#0.0} 百万
billionValue={0,number,#0.0} 十億
noResults=結果はまだ利用可能でありません。
noResults=ここで利用可能な結果はありません。"セーラー情報" を確認してみてください。
noNews=利用可能なニュースがありません。
pointsValue={0,number,#0.00}
openLeaderboard=リーダーボードを開く
@@ -1788,3 +1788,4 @@ useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes="推定
unknownLeaderboardType=未知のリーダーボードタイプ {0}
selectCompetitorsToEliminate=予選敗退の競技者を選択
trackedRaceAlreadyLinked=このレースはすでにレース列にリンクされています。リンクを変更しますか。
reallyRemoveSeries=シリーズ ''{0}'' を削除しますか。注記: 付属しているレース列のレースログもすべて永続的に削除されます。
@@ -1388,7 +1388,7 @@ numberWindFixes=Pontos fixos de vento
sailedMiles=Milhas navegadas
millionValue={0,número,#0.0} mil
billionValue={0,número,#0.0} bil
noResults=Ainda não estão disponíveis resultados.
noResults=Ainda não estão disponíveis resultados. Verificar "Informação do velejador".
noNews=Não estão disponíveis novidades.
pointsValue={0,número,#0.00}
openLeaderboard=Abrir painel de classificação
@@ -1788,3 +1788,4 @@ useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Utilizar
unknownLeaderboardType=Tipo de painel de classificação desconhecido {0}
selectCompetitorsToEliminate=Selecionar competidores a eliminar
trackedRaceAlreadyLinked=A corrida é sempre ligada a uma coluna da corrida. Modificar o link?
reallyRemoveSeries=Você quer realmente remover a série ''{0}''? Nota: todos os registros da corrida para a coluna da corrida anexada também serão removidos definitivamente!
@@ -1388,7 +1388,7 @@ numberWindFixes=Замеры ветра
sailedMiles=Пройдено миль
millionValue={0,number,#0.0} mil
billionValue={0,number,#0.0} bil
noResults=Результаты пока недоступны.
noResults=Результаты недоступны. Проверьте "Информацию о членах экипажа".
noNews=Новости пока недоступны.
pointsValue={0,number,#0.00}
openLeaderboard=Открыть таблицу лидеров
@@ -1788,3 +1788,4 @@ useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Испо
unknownLeaderboardType=Неизвестный тип таблицы лидеров {0}
selectCompetitorsToEliminate=Выберите участников для исключения
trackedRaceAlreadyLinked=Эта гонка уже связана со столбцом гонки. Действительно изменить связь?
reallyRemoveSeries=Действительно удалить серии ''{0}''? Примечание: все журналы для вложенных столбцов гонки также будут окончательно удалены!
@@ -1388,7 +1388,7 @@ numberWindFixes=风力修复
sailedMiles=航行英里
millionValue={0,number,#0.0} 百万
billionValue={0,number,#0.0} 十亿
noResults=没有可用的结果。
noResults=没有可用的结果。可以检查“水手信息”。
noNews=没有可用的消息。
pointsValue={0,number,#0.00}
openLeaderboard=打开积分榜
@@ -1788,3 +1788,4 @@ useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=仅使
unknownLeaderboardType=积分榜类型{0}未知
selectCompetitorsToEliminate=选择要淘汰的参赛队
trackedRaceAlreadyLinked=比赛轮次已链接到比赛轮次列。是否确定更改此链接?
reallyRemoveSeries=是否确定移除系列赛 "{0}"?注意:随附比赛轮次列的所有比赛轮次日志也将永久移除!
@@ -31,13 +31,13 @@ public class BoatClassVectorGraphicsResolver {
BoatClassMasterdata.OPTIMIST, BoatClassMasterdata.PWA,
BoatClassMasterdata.RS_AERO, BoatClassMasterdata.RS_X,
BoatClassMasterdata.SPLASH_BLUE, BoatClassMasterdata.SPLASH_RED, BoatClassMasterdata.SPLASH_GREEN,
BoatClassMasterdata.STAR);
BoatClassMasterdata.STAR, BoatClassMasterdata.TECHNO_293, BoatClassMasterdata.TECHNO_293_PLUS);
BoatClassVectorGraphics _49er = new _49erVectorGraphics(BoatClassMasterdata._49ER, BoatClassMasterdata._49ERFX,
BoatClassMasterdata._29ER, BoatClassMasterdata._18Footer);
BoatClassVectorGraphics extreme40 = new Extreme40VectorGraphics(BoatClassMasterdata.EXTREME_40,
BoatClassMasterdata.D_35, BoatClassMasterdata.SKUD_18, BoatClassMasterdata.WETA);
BoatClassVectorGraphics gc32 = new GC32VectorGraphics(BoatClassMasterdata.GC_32, BoatClassMasterdata.M32);
BoatClassVectorGraphics smallMultihull = new SmallMultihullVectorGraphics(BoatClassMasterdata.NACRA_17,
BoatClassVectorGraphics smallMultihull = new SmallMultihullVectorGraphics(BoatClassMasterdata.NACRA_15, BoatClassMasterdata.NACRA_17,
BoatClassMasterdata.F_16, BoatClassMasterdata.F_18, BoatClassMasterdata.HOBIE_WILD_CAT, BoatClassMasterdata.HOBIE_16,
BoatClassMasterdata.HOBIE_TIGER, BoatClassMasterdata.A_CAT, BoatClassMasterdata.TORNADO,
BoatClassMasterdata.FLYING_PHANTOM);
@@ -45,13 +45,13 @@ public class BoatClassVectorGraphicsResolver {
BoatClassMasterdata.B_ONE, BoatClassMasterdata.J80, BoatClassMasterdata.LASER_SB3, BoatClassMasterdata.LONGTZE,
BoatClassMasterdata.RS_FEVA, BoatClassMasterdata.RS100);
BoatClassVectorGraphics dinghyWithSpinnaker = new DinghyWithSpinnakerVectorGraphics(BoatClassMasterdata._420,
BoatClassMasterdata._470, BoatClassMasterdata._5O5, BoatClassMasterdata.FLYING_DUTCHMAN,
BoatClassMasterdata._470, BoatClassMasterdata._5O5, BoatClassMasterdata.CADET, BoatClassMasterdata.FLYING_DUTCHMAN,
BoatClassMasterdata.FOLKBOAT, BoatClassMasterdata.DYAS, BoatClassMasterdata.DRAGON_INT,
BoatClassMasterdata.ELLIOTT_6M, BoatClassMasterdata.H_BOAT, BoatClassMasterdata.ALBIN_EXPRESS,
BoatClassMasterdata.FARR_30, BoatClassMasterdata.J24, BoatClassMasterdata.PLATU_25,
BoatClassMasterdata.TOM_28_MAX, BoatClassMasterdata.DELPHIA_24,
BoatClassMasterdata.RS200, BoatClassMasterdata.RS400, BoatClassMasterdata.RS500, BoatClassMasterdata.RS800,
BoatClassMasterdata.STREAMLINE, BoatClassMasterdata.SWAN_45, BoatClassMasterdata.X_99,
BoatClassMasterdata.STREAMLINE, BoatClassMasterdata.SWAN_45, BoatClassMasterdata.TEENY, BoatClassMasterdata.X_99,
BoatClassMasterdata.TRIAS);
defaultBoatVectorGraphics = dinghyWithSpinnaker; // TODO see bug 2571; this should be a slup-rigged icon working for 470, 505, J/70 etc.
@@ -6435,22 +6435,26 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
@Override
public boolean canRemoveMarkFix(String leaderboardName, String raceColumnName, String fleetName,
String markIdAsString, GPSFixDTO fix) {
final boolean result;
boolean result = false;
final Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
if (leaderboard != null) {
final RaceColumn raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
if (raceColumn != null) {
final TimePoint fixTimePoint = new MillisecondsTimePoint(fix.timepoint);
final RegattaLog regattaLog = raceColumn.getRegattaLog();
final BaseRegattaLogDeviceMappingFinder<Mark> mappingFinder = new RegattaLogDeviceMarkMappingFinder(regattaLog);
final Fleet fleet = raceColumn.getFleetByName(fleetName);
if (fleet != null) {
result = raceColumn.getTrackedRace(fleet) == null;
} else {
result = false;
for (final Mark mark : raceColumn.getAvailableMarks(fleet)) {
if (mark.getId().toString().equals(markIdAsString)) {
result = mappingFinder.hasMappingFor(mark, fixTimePoint);
if (result) {
break;
}
}
}
}
} else {
result = false;
}
} else {
result = false;
}
return result;
}
@@ -6463,8 +6467,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
if (raceColumn != null) {
final TimePoint fixTimePoint = new MillisecondsTimePoint(fix.timepoint);
final RegattaLog regattaLog = raceColumn.getRegattaLog();
final BaseRegattaLogDeviceMappingFinder<Mark> mappingFinder = new RegattaLogDeviceMarkMappingFinder(
regattaLog);
final BaseRegattaLogDeviceMappingFinder<Mark> mappingFinder = new RegattaLogDeviceMarkMappingFinder(regattaLog);
final Fleet fleet = raceColumn.getFleetByName(fleetName);
if (fleet != null) {
for (final Mark mark : raceColumn.getAvailableMarks(fleet)) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

@@ -141,7 +141,7 @@ public class StorableSettingsRepresentation {
}
public static JSONObject getSubSettingsRepresentation(JSONObject root, Iterator<String> subPath) {
if (!subPath.hasNext()) {
if (root == null || !subPath.hasNext()) {
return root;
} else {
String current = subPath.next();
@@ -12,6 +12,7 @@ public class UserManagementException extends Exception implements Serializable {
public static final String PASSWORD_DOES_NOT_MEET_REQUIREMENTS = "Password does not meet requirements";
public static final String USERNAME_DOES_NOT_MEET_REQUIREMENTS = "Username does not meet requirements";
public static final String CANNOT_RESET_PASSWORD_WITHOUT_VALIDATED_EMAIL = "Cannot reset password without validated e-mail address";
public static final String USER_DOESNT_HAVE_PERMISSION = "The user does not have the required permission";
private final String message;
@@ -60,25 +60,26 @@ public interface UserManagementService extends RemoteService {
*
* @param key must not be <code>null</code>
* @param value must not be <code>null</code>
* @throws UserManagementException
*/
void setPreference(String username, String key, String value);
void setPreference(String username, String key, String value) throws UserManagementException;
void setPreferences(String username, Map<String, String> keyValuePairs);
void setPreferences(String username, Map<String, String> keyValuePairs) throws UserManagementException;
/**
* Permitted only for users with role {@link DefaultRoles#ADMIN} or when the subject's user name matches
* <code>username</code>.
*/
void unsetPreference(String username, String key);
void unsetPreference(String username, String key) throws UserManagementException;
/**
* @return <code>null</code> if no preference for the user identified by <code>username</code> is found
*/
String getPreference(String username, String key);
String getPreference(String username, String key) throws UserManagementException;
Map<String, String> getPreferences(String username, List<String> keys);
Map<String, String> getPreferences(String username, List<String> keys) throws UserManagementException;
Map<String, String> getAllPreferences(String username);
Map<String, String> getAllPreferences(String username) throws UserManagementException;
String getAccessToken(String username);
@@ -22,6 +22,7 @@ import javax.servlet.http.HttpSession;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.subject.Subject;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
@@ -166,27 +167,27 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
throw new UserManagementException(UserManagementException.INVALID_CREDENTIALS);
}
}
@Override
public void updateUserProperties(final String username, String fullName, String company, String localeName) throws UserManagementException {
private void ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(String username) throws UserManagementException {
final Subject subject = SecurityUtils.getSubject();
// the signed-in subject has role ADMIN or is changing own user
if (subject.hasRole(DefaultRoles.ADMIN.getRolename()) || username.equals(subject.getPrincipal().toString())) {
getSecurityService().updateUserProperties(username, fullName, company,
localeName == null || localeName.isEmpty() ? null : Locale.forLanguageTag(localeName));
} else {
if (!subject.hasRole(DefaultRoles.ADMIN.name()) && (subject.getPrincipal() == null
|| !username.equals(subject.getPrincipal().toString()))) {
throw new UserManagementException(UserManagementException.INVALID_CREDENTIALS);
}
}
@Override
public void updateUserProperties(final String username, String fullName, String company, String localeName) throws UserManagementException {
ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(username);
getSecurityService().updateUserProperties(username, fullName, company,
localeName == null || localeName.isEmpty() ? null : Locale.forLanguageTag(localeName));
}
@Override
public void updateSimpleUserEmail(String username, String newEmail, String validationBaseURL) throws UserManagementException, MailException {
final Subject subject = SecurityUtils.getSubject();
if (subject.hasRole(DefaultRoles.ADMIN.getRolename()) || username.equals(subject.getPrincipal().toString())) {
getSecurityService().updateSimpleUserEmail(username, newEmail, validationBaseURL);
} else {
throw new UserManagementException(UserManagementException.INVALID_CREDENTIALS);
}
ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(username);
getSecurityService().updateSimpleUserEmail(username, newEmail, validationBaseURL);
}
@Override
@@ -425,30 +426,45 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
}
@Override
public void setPreference(String username, String key, String value) {
getSecurityService().setPreference(username, key, value);
}
@Override
public void setPreferences(String username, Map<String, String> keyValuePairs) {
for (Entry<String, String> entry : keyValuePairs.entrySet()) {
getSecurityService().setPreference(username, entry.getKey(), entry.getValue());
public void setPreference(String username, String key, String value) throws UserManagementException {
try {
getSecurityService().setPreference(username, key, value);
} catch (AuthorizationException e) {
throw new UserManagementException(UserManagementException.USER_DOESNT_HAVE_PERMISSION);
}
}
@Override
public void unsetPreference(String username, String key) {
getSecurityService().unsetPreference(username, key);
}
@Override
public String getPreference(String username, String key) {
return getSecurityService().getPreference(username, key);
}
@Override
public Map<String, String> getPreferences(String username, List<String> keys) {
public void setPreferences(String username, Map<String, String> keyValuePairs) throws UserManagementException {
try {
for (Entry<String, String> entry : keyValuePairs.entrySet()) {
getSecurityService().setPreference(username, entry.getKey(), entry.getValue());
}
} catch (AuthorizationException e) {
throw new UserManagementException(UserManagementException.USER_DOESNT_HAVE_PERMISSION);
}
}
@Override
public void unsetPreference(String username, String key) throws UserManagementException {
try {
getSecurityService().unsetPreference(username, key);
} catch (AuthorizationException e) {
throw new UserManagementException(UserManagementException.USER_DOESNT_HAVE_PERMISSION);
}
}
@Override
public String getPreference(String username, String key) throws UserManagementException {
try {
return getSecurityService().getPreference(username, key);
} catch (AuthorizationException e) {
throw new UserManagementException(UserManagementException.USER_DOESNT_HAVE_PERMISSION);
}
}
@Override
public Map<String, String> getPreferences(String username, List<String> keys) throws UserManagementException {
Map<String, String> requestedPreferences = new HashMap<>();
for (String key : keys) {
requestedPreferences.put(key, getPreference(username, key));
@@ -457,15 +473,19 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
}
@Override
public Map<String, String> getAllPreferences(String username) {
final Map<String, String> allPreferences = getSecurityService().getAllPreferences(username);
final Map<String, String> result = new HashMap<>();
for (Map.Entry<String, String> entry : allPreferences.entrySet()) {
if(!entry.getKey().startsWith("_")) {
result.put(entry.getKey(), entry.getValue());
public Map<String, String> getAllPreferences(String username) throws UserManagementException {
try {
final Map<String, String> allPreferences = getSecurityService().getAllPreferences(username);
final Map<String, String> result = new HashMap<>();
for (Map.Entry<String, String> entry : allPreferences.entrySet()) {
if(!entry.getKey().startsWith("_")) {
result.put(entry.getKey(), entry.getValue());
}
}
return result;
} catch (AuthorizationException e) {
throw new UserManagementException(UserManagementException.USER_DOESNT_HAVE_PERMISSION);
}
return result;
}
@Override
@@ -138,7 +138,7 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
* @param key must not be <code>null</code>
* @param value must not be <code>null</code>
*/
Void setPreference(String username, String key, String value);
void setPreference(String username, String key, String value);
void setPreferenceObject(String name, String preferenceKey, Object preference);
+24 -38
View File
@@ -31,6 +31,7 @@ import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.config.Ini;
import org.apache.shiro.config.Ini.Section;
@@ -885,29 +886,29 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
public ReplicatingCacheManager getCacheManager() {
return cacheManager;
}
private void ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(String username) {
final Subject subject = SecurityUtils.getSubject();
if (!subject.hasRole(DefaultRoles.ADMIN.name()) && (subject.getPrincipal() == null
|| !username.equals(subject.getPrincipal().toString()))) {
final String currentUserName = subject.getPrincipal() == null ? "<anonymous>"
: subject.getPrincipal().toString();
throw new AuthorizationException(
"User " + currentUserName + " does not have the permission required to access data of user " + username);
}
}
@Override
public Void setPreference(final String username, final String key, final String value) {
final Subject subject = SecurityUtils.getSubject();
if (subject.hasRole(DefaultRoles.ADMIN.name()) || username.equals(subject.getPrincipal().toString())) {
apply(s->s.internalSetPreference(username, key, value));
} else {
throw new SecurityException("User " + subject.getPrincipal().toString()
+ " does not have permission to set preference for user " + username);
}
return null;
public void setPreference(final String username, final String key, final String value) {
ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(username);
apply(s->s.internalSetPreference(username, key, value));
}
@Override
public void setPreferenceObject(final String username, final String key, final Object value) {
final Subject subject = SecurityUtils.getSubject();
if (subject.hasRole(DefaultRoles.ADMIN.name()) || username.equals(subject.getPrincipal().toString())) {
final String preferenceObjectAsString = internalSetPreferenceObject(username, key, value);
apply(s->s.internalSetPreference(username, key, preferenceObjectAsString));
} else {
throw new SecurityException("User " + subject.getPrincipal().toString()
+ " does not have permission to set preference object for user " + username);
}
ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(username);
final String preferenceObjectAsString = internalSetPreferenceObject(username, key, value);
apply(s->s.internalSetPreference(username, key, preferenceObjectAsString));
}
@Override
@@ -923,13 +924,8 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
@Override
public void unsetPreference(String username, String key) {
Subject subject = SecurityUtils.getSubject();
if (subject.hasRole(DefaultRoles.ADMIN.name()) || username.equals(subject.getPrincipal().toString())) {
apply(s->s.internalUnsetPreference(username, key));
} else {
throw new SecurityException("User " + subject.getPrincipal().toString()
+ " does not have permission to unset preference for user " + username);
}
ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(username);
apply(s->s.internalUnsetPreference(username, key));
}
@Override
@@ -966,24 +962,14 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
@Override
public String getPreference(String username, String key) {
Subject subject = SecurityUtils.getSubject();
if (subject.hasRole(DefaultRoles.ADMIN.name()) || username.equals(subject.getPrincipal().toString())) {
return store.getPreference(username, key);
} else {
throw new org.apache.shiro.authz.AuthorizationException("User " + subject.getPrincipal().toString()
+ " does not have permission to read preferences of user " + username);
}
ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(username);
return store.getPreference(username, key);
}
@Override
public Map<String, String> getAllPreferences(String username) {
Subject subject = SecurityUtils.getSubject();
if (subject.hasRole(DefaultRoles.ADMIN.name()) || username.equals(subject.getPrincipal().toString())) {
return store.getAllPreferences(username);
} else {
throw new org.apache.shiro.authz.AuthorizationException("User " + subject.getPrincipal().toString()
+ " does not have permission to read preferences of user " + username);
}
ensureThatUserInQuestionIsLoggedInOrCurrentUserIsAdmin(username);
return store.getAllPreferences(username);
}
@Override