Merge branch 'master' into polars

Conflicts:
	java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarDataMiner.java
	java/com.sap.sailing.server.gateway/META-INF/MANIFEST.MF
	java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
	java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
	java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch
	java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
	java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
	java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch
	java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch
	java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch
This commit is contained in:
Frederik Petersen committed 2015-03-02 16:13:26 +01:00
commit c0f6f39e1e
135 files changed
+2448 -1095

No files matched your search

View File
File mode changed.
@@ -15,6 +15,7 @@ import com.sap.sailing.datamining.Activator;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.test.util.OpenFunctionManager;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Moving;
import com.sap.sailing.domain.base.Nationality;
@@ -23,18 +24,16 @@ import com.sap.sailing.domain.common.Speed;
import com.sap.sse.common.Named;
import com.sap.sse.datamining.factories.FunctionFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.impl.functions.SimpleFunctionRegistry;
public class TestSailingFunctionsRegistration {
private static FunctionFactory functionFactory = new FunctionFactory();
private FunctionRegistry functionRegistry;
private OpenFunctionManager functionRegistry;
@Before
public void setUpFunctionRegistryAndProvider() {
functionRegistry = new SimpleFunctionRegistry();
functionRegistry = new OpenFunctionManager();
functionRegistry.registerAllWithInternalFunctionPolicy(Activator.getDefault().getInternalClassesWithMarkedMethods());
}
@@ -76,7 +75,7 @@ public class TestSailingFunctionsRegistration {
@Test
public void testImportantRegisteredStatistics() throws NoSuchMethodException, SecurityException {
Collection<Function<?>> expectedStatistics = createExpectedImportantRegisteredStatistics();
Collection<Function<?>> providedStatistics = functionRegistry.getStatistics();
Collection<Function<?>> providedStatistics = functionRegistry.getAllStatistics();
for (Function<?> statistic : expectedStatistics) {
assertThat("The expected statistic '" + statistic + "' wasn't provided.",
providedStatistics.contains(statistic), is(true));
@@ -0,0 +1,18 @@
package com.sap.sailing.datamining.test.util;
import java.util.Collection;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.impl.functions.FunctionManager;
public class OpenFunctionManager extends FunctionManager {
public Collection<Function<?>> getDimensions() {
return asSet(dimensions);
}
public Collection<Function<?>> getExternalFunctions() {
return asSet(externalFunctions);
}
}
@@ -3,7 +3,8 @@ DistanceTraveled=zur
Boat=Boot
Team=Team
Name=Name
NationalityAcronym=Nationalität
Nationality=Nationalitäts
Acronym=Abkürzung
SailID=Segelnummer
LegNumber=Nummer des Schenkels
LegType=Art des Schenkels
@@ -13,12 +14,30 @@ CourseArea=Regattabahn
BoatClass=Bootsklasse
Fleet=Flotte
Race=Rennen
SailingDomainRetrieverChain=Segel-Domänen Datenbeschaffer
LegSailingDomainRetrieverChain=Segel-Domänen Leg-Beschaffer
GPSFixSailingDomainRetrieverChain=Segel-Domänen GPS-Fix-Beschaffer
MarkPassingSailingDomainRetrieverChain=Segel-Domänen Tonnenrundungs-Beschaffer
LeaderboardGroup=Ranglisten Gruppe
RegattaLeaderboard=Regatta Rangliste
Leg=Schenkel
MarkPassing=Tonnenrundung
LegOfCompetitor=Schenkel eines Teilnehmers
GpsFix=GPS-Fix
Speed=Geschwindigkeit
SpeedTenSecondsBefore=Geschwindigkeit 10s vorher
InKnots=in Knoten
WindStrength=Windstärke
WindStrengthInBeaufort=Windstärke in Beaufort
BftClusterGroup=Windstärke in Beaufort
Bft0=Windstille
Bft1=leiser Zug
Bft2=leichte Brise
Bft3=schwacher Wind
Bft4=mäßiger Wind
Bft5=frischer Wind
Bft6=starker Wind
Bft7=steifer Wind
Bft8=stürmischer Wind
Bft9=Sturm
Bft10=schwerer Sturm
Bft11=orkanartiger Sturm
Bft12=Orkan
@@ -1,4 +1,5 @@
Speed=Speed
SpeedTenSecondsBefore=Speed 10s before
InKnots=in knots
DistanceTraveled=Distance Traveled
Name=Name
@@ -6,7 +7,8 @@ LegType=Leg Type
SailID=Sail Number
Year=Year
LegNumber=Leg Number
NationalityAcronym=Nationality
Nationality=Nationality
Acronym=Acronym
Regatta=Regatta
CourseArea=Course Area
BoatClass=Boat Class
@@ -15,10 +17,27 @@ Race=Race
Competitor=Competitor
Boat=Boat
Team=Team
SailingDomainRetrieverChain=Sailing Domain Retriever
LegSailingDomainRetrieverChain=Sailing Domain Leg Retriever
GPSFixSailingDomainRetrieverChain=Sailing Domain GPS Fix Retriever
MarkPassingSailingDomainRetrieverChain=Sailing Domain Mark Passing Retriever
LeaderboardGroup=Leaderboard Group
RegattaLeaderboard=Regatta Leaderboard
Leg=Leg
MarkPassing=Mark Passing
LegOfCompetitor=Leg of competitor
GpsFix=GPS-Fix
WindStrength=Wind Strength
WindStrengthInBeaufort=Wind Strength in Beaufort
BftClusterGroup=Wind Strength in Beaufort
Bft0=Calm
Bft1=Light air
Bft2=Light breeze
Bft3=Gentle breeze
Bft4=Moderate breeze
Bft5=Fresh breeze
Bft6=Strong breeze
Bft7=High wind
Bft8=Gale
Bft9=Strong gale
Bft10=Storm
Bft11=Violent storm
Bft12=Hurricane
@@ -9,6 +9,7 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasMarkPassingContext;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
@@ -31,7 +32,7 @@ public class Activator implements BundleActivator, DataMiningBundleService {
public Activator() {
dataRetrieverChainDefinitions = new SailingDataRetrieverChainDefinitions();
sailingServerStringMessages = new ResourceBundleStringMessagesImpl(STRING_MESSAGES_BASE_NAME, Activator.class.getClassLoader());
sailingServerStringMessages = new ResourceBundleStringMessagesImpl(STRING_MESSAGES_BASE_NAME, getClass().getClassLoader());
clusterGroups = new SailingClusterGroups();
}
@@ -59,6 +60,7 @@ public class Activator implements BundleActivator, DataMiningBundleService {
internalClasses.add(HasTrackedLegContext.class);
internalClasses.add(HasTrackedLegOfCompetitorContext.class);
internalClasses.add(HasGPSFixContext.class);
internalClasses.add(HasMarkPassingContext.class);
return internalClasses;
}
@@ -28,79 +28,79 @@ public class SailingClusterGroups {
ClusterBoundary<Speed> lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
Speed upperBoundWindSpeed = new KnotSpeedImpl(1.0);
ClusterBoundary<Speed> upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Calm", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft0", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(1.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(4.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Light air", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft1", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(4.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(7.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Light breeze", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft2", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(7.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(11.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Gentle breeze", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft3", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(11.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(16.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Moderate breeze", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft4", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(16.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(22.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Fresh breeze", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft5", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(22.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(28.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Strong breeze", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft6", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(28.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(34.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("High wind", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft7", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(34.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(41.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Gale", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft8", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(41.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(48.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Strong gale", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft9", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(48.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(56.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Storm", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft10", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(56.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
upperBoundWindSpeed = new KnotSpeedImpl(64.0);
upperBound = new ComparatorClusterBoundary<Speed>(comparableComparator, upperBoundWindSpeed, ComparisonStrategy.LOWER_THAN);
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Violent Storm", lowerBound, upperBound));
clusters.add(new ClusterWithLowerAndUpperBoundaries<Speed>("Bft11", lowerBound, upperBound));
lowerBoundWindSpeed = new KnotSpeedImpl(64.0);
lowerBound = new ComparatorClusterBoundary<Speed>(comparableComparator, lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
clusters.add(new ClusterWithSingleBoundary<Speed>("Hurricane", lowerBound));
clusters.add(new ClusterWithSingleBoundary<Speed>("Bft12", lowerBound));
windStrengthInBeaufortCluster = new FixClusterGroup<Speed>("Wind Strength", clusters);
windStrengthInBeaufortCluster = new FixClusterGroup<Speed>("BftClusterGroup", clusters);
}
public ClusterGroup<Speed> getWindStrengthInBeaufortCluster() {
@@ -4,20 +4,21 @@ import java.util.ArrayList;
import java.util.Collection;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasMarkPassingContext;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.impl.components.GPSFixRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.LeaderboardGroupRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.RegattaLeaderboardFilteringRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegFilteringRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegOfCompetitorFilteringRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedRaceFilteringRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.MarkPassingRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.RegattaLeaderboardRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegOfCompetitorRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedRaceRetrievalProcessor;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.SimpleDataRetrieverChainDefinition;
public class SailingDataRetrieverChainDefinitions {
@@ -27,33 +28,29 @@ public class SailingDataRetrieverChainDefinitions {
public SailingDataRetrieverChainDefinitions() {
dataRetrieverChainDefinitions = new ArrayList<>();
DataRetrieverChainDefinition<RacingEventService, HasTrackedLegOfCompetitorContext> legOfCompetitorRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
RacingEventService.class, HasTrackedLegOfCompetitorContext.class, "SailingDomainRetrieverChain");
@SuppressWarnings("unchecked")
Class<Processor<RacingEventService, LeaderboardGroup>> leaderboardGroupRetrieverType = (Class<Processor<RacingEventService, LeaderboardGroup>>) (Class<?>) LeaderboardGroupRetrievalProcessor.class;
legOfCompetitorRetrieverChainDefinition.startWith(leaderboardGroupRetrieverType, LeaderboardGroup.class, "LeaderboardGroup");
@SuppressWarnings("unchecked")
Class<Processor<LeaderboardGroup, RegattaLeaderboard>> regattaLeaderboardRetrieverType = (Class<Processor<LeaderboardGroup, RegattaLeaderboard>>) (Class<?>) RegattaLeaderboardFilteringRetrievalProcessor.class;
legOfCompetitorRetrieverChainDefinition.addAfter(leaderboardGroupRetrieverType, regattaLeaderboardRetrieverType,
final DataRetrieverChainDefinition<RacingEventService, HasTrackedLegOfCompetitorContext> trackedRaceRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
RacingEventService.class, HasTrackedLegOfCompetitorContext.class, "RaceSailingDomainRetrieverChain");
trackedRaceRetrieverChainDefinition.startWith(LeaderboardGroupRetrievalProcessor.class, LeaderboardGroup.class, "LeaderboardGroup");
trackedRaceRetrieverChainDefinition.addAfter(LeaderboardGroupRetrievalProcessor.class, RegattaLeaderboardRetrievalProcessor.class,
RegattaLeaderboard.class, "RegattaLeaderboard");
@SuppressWarnings("unchecked")
Class<Processor<RegattaLeaderboard, HasTrackedRaceContext>> raceRetrieverType = (Class<Processor<RegattaLeaderboard, HasTrackedRaceContext>>) (Class<?>) TrackedRaceFilteringRetrievalProcessor.class;
legOfCompetitorRetrieverChainDefinition.addAfter(regattaLeaderboardRetrieverType, raceRetrieverType,
trackedRaceRetrieverChainDefinition.addAfter(RegattaLeaderboardRetrievalProcessor.class, TrackedRaceRetrievalProcessor.class,
HasTrackedRaceContext.class, "Race");
@SuppressWarnings("unchecked")
Class<Processor<HasTrackedRaceContext, HasTrackedLegContext>> legRetrieverType = (Class<Processor<HasTrackedRaceContext, HasTrackedLegContext>>) (Class<?>) TrackedLegFilteringRetrievalProcessor.class;
legOfCompetitorRetrieverChainDefinition.addAfter(raceRetrieverType, legRetrieverType, HasTrackedLegContext.class, "Leg");
@SuppressWarnings("unchecked")
Class<Processor<HasTrackedLegContext, HasTrackedLegOfCompetitorContext>> legOfCompetitorRetrieverType = (Class<Processor<HasTrackedLegContext, HasTrackedLegOfCompetitorContext>>) (Class<?>) TrackedLegOfCompetitorFilteringRetrievalProcessor.class;
legOfCompetitorRetrieverChainDefinition.endWith(legRetrieverType, legOfCompetitorRetrieverType,
final DataRetrieverChainDefinition<RacingEventService, HasMarkPassingContext> markPassingRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
trackedRaceRetrieverChainDefinition, HasMarkPassingContext.class, "MarkPassingSailingDomainRetrieverChain");
markPassingRetrieverChainDefinition.endWith(TrackedRaceRetrievalProcessor.class, MarkPassingRetrievalProcessor.class, HasMarkPassingContext.class, "MarkPassing");
dataRetrieverChainDefinitions.add(markPassingRetrieverChainDefinition);
final DataRetrieverChainDefinition<RacingEventService, HasTrackedLegOfCompetitorContext> legOfCompetitorRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
trackedRaceRetrieverChainDefinition, HasTrackedLegOfCompetitorContext.class, "LegSailingDomainRetrieverChain");
legOfCompetitorRetrieverChainDefinition.addAfter(TrackedRaceRetrievalProcessor.class, TrackedLegRetrievalProcessor.class, HasTrackedLegContext.class, "Leg");
legOfCompetitorRetrieverChainDefinition.endWith(TrackedLegRetrievalProcessor.class, TrackedLegOfCompetitorRetrievalProcessor.class,
HasTrackedLegOfCompetitorContext.class, "LegOfCompetitor");
dataRetrieverChainDefinitions.add(legOfCompetitorRetrieverChainDefinition);
DataRetrieverChainDefinition<RacingEventService, HasGPSFixContext> gpsFixRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
legOfCompetitorRetrieverChainDefinition, HasGPSFixContext.class, "SailingDomainRetrieverChain");
@SuppressWarnings("unchecked")
Class<Processor<HasTrackedLegOfCompetitorContext, HasGPSFixContext>> gpsFixRetrieverType = (Class<Processor<HasTrackedLegOfCompetitorContext, HasGPSFixContext>>) (Class<?>) GPSFixRetrievalProcessor.class;
gpsFixRetrieverChainDefinition.endWith(legOfCompetitorRetrieverType, gpsFixRetrieverType,
final DataRetrieverChainDefinition<RacingEventService, HasGPSFixContext> gpsFixRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
legOfCompetitorRetrieverChainDefinition, HasGPSFixContext.class, "GPSFixSailingDomainRetrieverChain");
gpsFixRetrieverChainDefinition.endWith(TrackedLegOfCompetitorRetrievalProcessor.class, GPSFixRetrievalProcessor.class,
HasGPSFixContext.class, "GpsFix");
dataRetrieverChainDefinitions.add(gpsFixRetrieverChainDefinition);
}
@@ -1,19 +1,22 @@
package com.sap.sailing.datamining.data;
import java.util.Locale;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.annotations.Dimension;
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public interface HasGPSFixContext {
@Connector
public HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext();
@Connector
@Connector(ordinal=1)
public GPSFixMoving getGPSFix();
@Dimension(messageKey="WindStrength", ordinal=10)
public ClusterDTO getWindStrength();
@Dimension(messageKey="WindStrengthInBeaufort", ordinal=11)
public ClusterDTO getWindStrengthAsBeaufortCluster(Locale locale, ResourceBundleStringMessages stringMessages);
}
@@ -0,0 +1,29 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.annotations.Dimension;
public interface HasMarkPassingContext {
@Connector
HasTrackedRaceContext getTrackedRaceContext();
@Connector
MarkPassing getMarkPassing();
@Connector(messageKey="Competitor")
Competitor getCompetitor();
@Connector(messageKey="Speed", ordinal=1)
Speed getSpeed();
@Connector(messageKey="SpeedTenSecondsBefore", ordinal=2)
Speed getSpeedTenSecondsBefore();
@Dimension(messageKey="LegType", ordinal=6)
String getPreviousLegTypeSignifier() throws NoWindException;
}
@@ -0,0 +1,47 @@
package com.sap.sailing.datamining.impl.components;
import java.util.Collection;
import java.util.NavigableSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.HashSet;
import com.sap.sailing.datamining.data.HasMarkPassingContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.impl.data.MarkPassingWithContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor;
public class MarkPassingRetrievalProcessor extends
AbstractSimpleRetrievalProcessor<HasTrackedRaceContext, HasMarkPassingContext> {
public MarkPassingRetrievalProcessor(ExecutorService executor,
Collection<Processor<HasMarkPassingContext, ?>> resultReceivers) {
super(HasTrackedRaceContext.class, HasMarkPassingContext.class, executor, resultReceivers);
}
@Override
protected Iterable<HasMarkPassingContext> retrieveData(HasTrackedRaceContext element) {
TrackedRace trackedRace = element.getTrackedRace();
Set<HasMarkPassingContext> result = new HashSet<>();
trackedRace.getRace().getCourse().lockForRead();
try {
for (Competitor competitor : trackedRace.getRace().getCompetitors()) {
NavigableSet<MarkPassing> markPassingsForCompetitor = trackedRace.getMarkPassings(competitor);
trackedRace.lockForRead(markPassingsForCompetitor);
try {
markPassingsForCompetitor.stream().forEach(mp->result.add(new MarkPassingWithContext(element, mp)));
} finally {
trackedRace.unlockAfterRead(markPassingsForCompetitor);
}
}
} finally {
trackedRace.getRace().getCourse().unlockAfterRead();
}
return result;
}
}
@@ -10,10 +10,10 @@ import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor;
public class RegattaLeaderboardFilteringRetrievalProcessor extends
public class RegattaLeaderboardRetrievalProcessor extends
AbstractSimpleRetrievalProcessor<LeaderboardGroup, RegattaLeaderboard> {
public RegattaLeaderboardFilteringRetrievalProcessor(ExecutorService executor,
public RegattaLeaderboardRetrievalProcessor(ExecutorService executor,
Collection<Processor<RegattaLeaderboard, ?>> resultReceivers) {
super(LeaderboardGroup.class, RegattaLeaderboard.class, executor, resultReceivers);
}
@@ -11,10 +11,10 @@ import com.sap.sailing.domain.base.Competitor;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor;
public class TrackedLegOfCompetitorFilteringRetrievalProcessor extends
public class TrackedLegOfCompetitorRetrievalProcessor extends
AbstractSimpleRetrievalProcessor<HasTrackedLegContext, HasTrackedLegOfCompetitorContext> {
public TrackedLegOfCompetitorFilteringRetrievalProcessor(ExecutorService executor,
public TrackedLegOfCompetitorRetrievalProcessor(ExecutorService executor,
Collection<Processor<HasTrackedLegOfCompetitorContext, ?>> resultReceivers) {
super(HasTrackedLegContext.class, HasTrackedLegOfCompetitorContext.class, executor, resultReceivers);
}
@@ -11,10 +11,10 @@ import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor;
public class TrackedLegFilteringRetrievalProcessor extends
public class TrackedLegRetrievalProcessor extends
AbstractSimpleRetrievalProcessor<HasTrackedRaceContext, HasTrackedLegContext> {
public TrackedLegFilteringRetrievalProcessor(ExecutorService executor,
public TrackedLegRetrievalProcessor(ExecutorService executor,
Collection<Processor<HasTrackedLegContext, ?>> resultReceivers) {
super(HasTrackedRaceContext.class, HasTrackedLegContext.class, executor, resultReceivers);
}
@@ -14,10 +14,10 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor;
public class TrackedRaceFilteringRetrievalProcessor extends
public class TrackedRaceRetrievalProcessor extends
AbstractSimpleRetrievalProcessor<Leaderboard, HasTrackedRaceContext> {
public TrackedRaceFilteringRetrievalProcessor(ExecutorService executor,
public TrackedRaceRetrievalProcessor(ExecutorService executor,
Collection<Processor<HasTrackedRaceContext, ?>> resultReceivers) {
super(Leaderboard.class, HasTrackedRaceContext.class, executor, resultReceivers);
}
@@ -1,5 +1,7 @@
package com.sap.sailing.datamining.impl.data;
import java.util.Locale;
import com.sap.sailing.datamining.Activator;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
@@ -7,6 +9,7 @@ import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.Wind;
import com.sap.sse.datamining.data.Cluster;
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public class GPSFixWithContext implements HasGPSFixContext {
@@ -31,10 +34,10 @@ public class GPSFixWithContext implements HasGPSFixContext {
}
@Override
public ClusterDTO getWindStrength() {
public ClusterDTO getWindStrengthAsBeaufortCluster(Locale locale, ResourceBundleStringMessages stringMessages) {
Wind wind = getWind();
Cluster<?> cluster = Activator.getDefault().getClusterGroups().getWindStrengthInBeaufortCluster().getClusterFor(wind);
return new ClusterDTO(cluster.toString());
return new ClusterDTO(cluster.getAsLocalizedString(locale, stringMessages));
}
private Wind getWind() {
@@ -0,0 +1,74 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasMarkPassingContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedRace;
public class MarkPassingWithContext implements HasMarkPassingContext {
private final HasTrackedRaceContext trackedRaceContext;
private final MarkPassing markPassing;
public MarkPassingWithContext(HasTrackedRaceContext trackedRaceContext, MarkPassing markPassing) {
super();
this.trackedRaceContext = trackedRaceContext;
this.markPassing = markPassing;
}
@Override
public HasTrackedRaceContext getTrackedRaceContext() {
return trackedRaceContext;
}
@Override
public MarkPassing getMarkPassing() {
return markPassing;
}
@Override
public Competitor getCompetitor() {
return markPassing.getCompetitor();
}
@Override
public Speed getSpeed() {
return getTrackedRace().getTrack(getCompetitor()).getEstimatedSpeed(getMarkPassing().getTimePoint());
}
@Override
public Speed getSpeedTenSecondsBefore() {
return getTrackedRace().getTrack(getCompetitor()).getEstimatedSpeed(getMarkPassing().getTimePoint().minus(10000 /* ms */));
}
private TrackedRace getTrackedRace() {
return trackedRaceContext.getTrackedRace();
}
@Override
public String getPreviousLegTypeSignifier() throws NoWindException {
final String result;
TrackedLeg previousLeg = getPreviousLeg();
if (previousLeg == null) {
result = "Start";
} else {
result = previousLeg.getLegType(getMarkPassing().getTimePoint()).toString();
}
return result;
}
private TrackedLeg getPreviousLeg() {
final TrackedLeg result;
Waypoint waypoint = markPassing.getWaypoint();
if (waypoint == getTrackedRace().getRace().getCourse().getFirstWaypoint()) {
result = null;
} else {
result = getTrackedRace().getTrackedLegFinishingAt(waypoint);
}
return result;
}
}
@@ -20,6 +20,8 @@ Export-Package: com.sap.sailing.domain.common,
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.trackfiles
Require-Bundle: com.sap.sse.datamining.shared,
com.sap.sse.common
com.sap.sse.common,
com.sap.sse.security.common
@@ -0,0 +1,29 @@
package com.sap.sailing.domain.common.security;
public enum Permission implements com.sap.sse.security.shared.Permission {
MANAGE_EVENTS,
MANAGE_REGATTAS,
MANAGE_TRACKED_RACES,
SHOW_TRACKED_RACES,
MANAGE_RACELOG_TRACKING,
MANAGE_ALL_COMPETITORS,
MANAGE_COURSE_LAYOUT,
MANAGE_WIND,
MANAGE_IGTIMI_ACCOUNTS,
MANAGE_LEADERBOARDS,
MANAGE_LEADERBOARD_GROUPS,
MANAGE_RESULT_IMPORT_URLS,
MANAGE_STRUCTURE_IMPORT_URLS,
MANAGE_MEDIA,
MANAGE_SAILING_SERVER_INSTANCES,
MANAGE_REPLICATION,
MANAGE_MASTERDATA_IMPORT,
MANAGE_DEVICE_CONFIGURATION,
MANAGE_USERS,
MANAGE_FILE_STORAGE;
@Override
public String getStringPermission() {
return name()+":";
}
}
@@ -1,9 +1,8 @@
package com.sap.sailing.gwt.ui.usermanagement;
package com.sap.sailing.domain.common.security;
import com.sap.sse.security.shared.DefaultRoles;
import com.sap.sse.security.shared.Role;
public enum UserRoles {
administrator(DefaultRoles.ADMIN.getRolename()),
public enum Roles implements Role {
spectator("spectator"),
moderator("moderator"),
sailor("sailor"),
@@ -11,7 +10,7 @@ public enum UserRoles {
eventmanager("eventmanager"),
mediaeditor("mediaeditor");
private UserRoles(String rolename) {
private Roles(String rolename) {
this.rolename = rolename;
}
@@ -0,0 +1,21 @@
package com.sap.sailing.domain.common.security;
import java.util.Collections;
import com.sap.sse.security.shared.DefaultRoles;
import com.sap.sse.security.shared.PermissionsForRoleProvider;
public class SailingPermissionsForRoleProvider implements PermissionsForRoleProvider {
public static final SailingPermissionsForRoleProvider INSTANCE = new SailingPermissionsForRoleProvider();
@Override
public Iterable<String> getPermissions(String role) {
final Iterable<String> result;
if (DefaultRoles.ADMIN.getRolename().equals(role)) {
return Collections.<String>singletonList("*");
} else {
result = Collections.emptyList();
}
return result;
}
}
@@ -6,7 +6,7 @@ import com.sap.sse.common.Named;
import com.sap.sse.datamining.shared.annotations.Dimension;
public interface Nationality extends Named, IsManagedByCache<SharedDomainFactory> {
@Dimension(messageKey="NationalityAcronym")
@Dimension(messageKey="Acronym")
String getThreeLetterIOCAcronym();
CountryCode getCountryCode();
@@ -3,6 +3,6 @@ package com.sap.sailing.domain.base;
import com.sap.sse.datamining.shared.annotations.Connector;
public interface WithNationality {
@Connector(ordinal=7)
@Connector(messageKey="Nationality", ordinal=8)
Nationality getNationality();
}
@@ -45,7 +45,8 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sse.operationaltransformation,
com.sap.sse,
com.sap.sse.security.common,
com.sap.sse.filestorage
com.sap.sse.filestorage,
org.apache.shiro.core;bundle-version="1.2.2"
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
Bundle-ActivationPolicy: lazy
Import-Package: com.sap.sailing.polars,
@@ -9,6 +9,8 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.sap.sailing.domain.common.security.Permission;
import com.sap.sailing.domain.common.security.SailingPermissionsForRoleProvider;
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
import com.sap.sailing.gwt.ui.client.LeaderboardGroupsDisplayer;
import com.sap.sailing.gwt.ui.client.LeaderboardGroupsRefresher;
@@ -49,8 +51,8 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
}
private void createUI() {
AdminConsolePanel panel = new AdminConsolePanel(getUserService(), sailingService,
getStringMessages().releaseNotes(), "/release_notes_admin.html", /* error reporter */ this, SecurityStylesheetResources.INSTANCE.css());
AdminConsolePanel panel = new AdminConsolePanel(getUserService(), SailingPermissionsForRoleProvider.INSTANCE,
sailingService, getStringMessages().releaseNotes(), "/release_notes_admin.html", /* error reporter */ this, SecurityStylesheetResources.INSTANCE.css());
BetterDateTimeBox.initialize();
regattasDisplayers = new HashSet<>();
leaderboardsDisplayers = new HashSet<>();
@@ -63,7 +65,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
getWidget().fillEvents();
fillLeaderboardGroups();
}
}, getStringMessages().events(), SailingAdminConsoleFeatures.MANAGE_EVENTS);
}, getStringMessages().events(), Permission.MANAGE_EVENTS);
leaderboardGroupsDisplayers.add(eventManagementPanel);
RegattaManagementPanel regattaManagementPanel = new RegattaManagementPanel(
@@ -74,13 +76,12 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
public void refreshAfterBecomingVisible() {
fillRegattas();
}
}, getStringMessages().regattas(), SailingAdminConsoleFeatures.MANAGE_REGATTAS);
}, getStringMessages().regattas(), Permission.MANAGE_REGATTAS);
regattasDisplayers.add(regattaManagementPanel);
/* LEADERBOARDS */
final TabLayoutPanel leaderboardTabPanel = panel.addVerticalTab(getStringMessages().leaderboards(),
"LeaderboardPanel", SailingAdminConsoleFeatures.MANAGE_LEADERBOARDS);
final TabLayoutPanel leaderboardTabPanel = panel.addVerticalTab(getStringMessages().leaderboards(), "LeaderboardPanel");
final LeaderboardConfigPanel leaderboardConfigPanel = new LeaderboardConfigPanel(sailingService, this, this,
getStringMessages(), /* showRaceDetails */true, this);
leaderboardConfigPanel.ensureDebugId("LeaderboardConfiguration");
@@ -89,7 +90,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
public void refreshAfterBecomingVisible() {
fillLeaderboards();
}
}, getStringMessages().leaderboardConfiguration(), SailingAdminConsoleFeatures.MANAGE_LEADERBOARDS);
}, getStringMessages().leaderboardConfiguration(), Permission.MANAGE_LEADERBOARDS);
regattasDisplayers.add(leaderboardConfigPanel);
leaderboardsDisplayers.add(leaderboardConfigPanel);
@@ -102,20 +103,19 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
fillLeaderboards();
fillLeaderboardGroups();
}
}, getStringMessages().leaderboardGroups(), SailingAdminConsoleFeatures.MANAGE_LEADERBOARD_GROUPS);
}, getStringMessages().leaderboardGroups(), Permission.MANAGE_LEADERBOARD_GROUPS);
regattasDisplayers.add(leaderboardGroupConfigPanel);
leaderboardGroupsDisplayers.add(leaderboardGroupConfigPanel);
leaderboardsDisplayers.add(leaderboardGroupConfigPanel);
/* RACES */
final TabLayoutPanel racesTabPanel = panel.addVerticalTab(getStringMessages().races(),
"RacesPanel", SailingAdminConsoleFeatures.MANAGE_TRACKED_RACES);
final TabLayoutPanel racesTabPanel = panel.addVerticalTab(getStringMessages().races(), "RacesPanel");
TrackedRacesManagementPanel trackedRacesManagementPanel = new TrackedRacesManagementPanel(sailingService, this,
this, getStringMessages());
trackedRacesManagementPanel.ensureDebugId("TrackedRacesManagement");
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<TrackedRacesManagementPanel>(trackedRacesManagementPanel),
getStringMessages().trackedRaces(), SailingAdminConsoleFeatures.SHOW_TRACKED_RACES);
getStringMessages().trackedRaces(), Permission.SHOW_TRACKED_RACES);
regattasDisplayers.add(trackedRacesManagementPanel);
final CompetitorPanel competitorPanel = new CompetitorPanel(sailingService, getStringMessages(), this);
@@ -124,17 +124,17 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
public void refreshAfterBecomingVisible() {
getWidget().refreshCompetitorList();
}
}, getStringMessages().competitors(), SailingAdminConsoleFeatures.MANAGE_ALL_COMPETITORS);
}, getStringMessages().competitors(), Permission.MANAGE_ALL_COMPETITORS);
RaceCourseManagementPanel raceCourseManagementPanel = new RaceCourseManagementPanel(sailingService, this, this, getStringMessages());
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<RaceCourseManagementPanel>(raceCourseManagementPanel), getStringMessages().courseLayout(), SailingAdminConsoleFeatures.MANAGE_COURSE_LAYOUT);
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<RaceCourseManagementPanel>(raceCourseManagementPanel), getStringMessages().courseLayout(), Permission.MANAGE_COURSE_LAYOUT);
regattasDisplayers.add(raceCourseManagementPanel);
final AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor();
WindPanel windPanel = new WindPanel(sailingService, asyncActionsExecutor, this, this, getStringMessages());
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<WindPanel>(windPanel), getStringMessages().wind(),
SailingAdminConsoleFeatures.MANAGE_WIND);
Permission.MANAGE_WIND);
regattasDisplayers.add(windPanel);
final MediaPanel mediaPanel = new MediaPanel(regattasDisplayers, sailingService, this, mediaService, this, getStringMessages());
@@ -143,29 +143,28 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
public void refreshAfterBecomingVisible() {
getWidget().onShow();
}
}, getStringMessages().mediaPanel(), SailingAdminConsoleFeatures.MANAGE_MEDIA);
}, getStringMessages().mediaPanel(), Permission.MANAGE_MEDIA);
/* CONNECTORS */
final TabLayoutPanel connectorsTabPanel = panel.addVerticalTab(getStringMessages().connectors(),
"TrackingProviderPanel", SailingAdminConsoleFeatures.MANAGE_TRACKED_RACES);
final TabLayoutPanel connectorsTabPanel = panel.addVerticalTab(getStringMessages().connectors(), "TrackingProviderPanel");
TracTracEventManagementPanel tractracEventManagementPanel = new TracTracEventManagementPanel(sailingService,
this, this, getStringMessages());
tractracEventManagementPanel.ensureDebugId("TracTracEventManagement");
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<TracTracEventManagementPanel>(tractracEventManagementPanel),
getStringMessages().tracTracEvents(), SailingAdminConsoleFeatures.MANAGE_TRACKED_RACES);
getStringMessages().tracTracEvents(), Permission.MANAGE_TRACKED_RACES);
regattasDisplayers.add(tractracEventManagementPanel);
SwissTimingReplayConnectorPanel swissTimingReplayConnectorPanel = new SwissTimingReplayConnectorPanel(
sailingService, this, this, getStringMessages());
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<SwissTimingReplayConnectorPanel>(swissTimingReplayConnectorPanel),
getStringMessages().swissTimingArchiveConnector(), SailingAdminConsoleFeatures.MANAGE_TRACKED_RACES);
getStringMessages().swissTimingArchiveConnector(), Permission.MANAGE_TRACKED_RACES);
regattasDisplayers.add(swissTimingReplayConnectorPanel);
SwissTimingEventManagementPanel swisstimingEventManagementPanel = new SwissTimingEventManagementPanel(
sailingService, this, this, getStringMessages());
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<SwissTimingEventManagementPanel>(swisstimingEventManagementPanel),
getStringMessages().swissTimingEvents(), SailingAdminConsoleFeatures.MANAGE_TRACKED_RACES);
getStringMessages().swissTimingEvents(), Permission.MANAGE_TRACKED_RACES);
regattasDisplayers.add(swisstimingEventManagementPanel);
final RaceLogTrackingEventManagementPanel raceLogTrackingEventManagementPanel = new RaceLogTrackingEventManagementPanel(
@@ -175,56 +174,56 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
public void refreshAfterBecomingVisible() {
fillLeaderboards();
}
}, getStringMessages().raceLogTracking(), SailingAdminConsoleFeatures.MANAGE_TRACKED_RACES);
}, getStringMessages().raceLogTracking(), Permission.MANAGE_TRACKED_RACES);
regattasDisplayers.add(raceLogTrackingEventManagementPanel);
leaderboardsDisplayers.add(raceLogTrackingEventManagementPanel);
IgtimiAccountsPanel igtimiAccountsPanel = new IgtimiAccountsPanel(sailingService, this, getStringMessages());
igtimiAccountsPanel.ensureDebugId("IgtimiAccounts");
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<IgtimiAccountsPanel>(igtimiAccountsPanel),
getStringMessages().igtimiAccounts(), SailingAdminConsoleFeatures.MANAGE_IGTIMI_ACCOUNTS);
getStringMessages().igtimiAccounts(), Permission.MANAGE_IGTIMI_ACCOUNTS);
ResultImportUrlsManagementPanel resultImportUrlsManagementPanel = new ResultImportUrlsManagementPanel(sailingService, this, getStringMessages());
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<ResultImportUrlsManagementPanel>(resultImportUrlsManagementPanel),
getStringMessages().resultImportUrls(), SailingAdminConsoleFeatures.MANAGE_RESULT_IMPORT_URLS);
getStringMessages().resultImportUrls(), Permission.MANAGE_RESULT_IMPORT_URLS);
StructureImportManagementPanel structureImportUrlsManagementPanel = new StructureImportManagementPanel(sailingService, this, getStringMessages(), this, eventManagementPanel);
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<StructureImportManagementPanel>(structureImportUrlsManagementPanel),
getStringMessages().structureImportUrls(), SailingAdminConsoleFeatures.MANAGE_STRUCTURE_IMPORT_URLS);
getStringMessages().structureImportUrls(), Permission.MANAGE_STRUCTURE_IMPORT_URLS);
/* ADVANCED */
final TabLayoutPanel advancedTabPanel = panel.addVerticalTab(getStringMessages().advanced(),
"AdvancedPanel", SailingAdminConsoleFeatures.MANAGE_REPLICATION);
final TabLayoutPanel advancedTabPanel = panel.addVerticalTab(getStringMessages().advanced(), "AdvancedPanel");
final ReplicationPanel replicationPanel = new ReplicationPanel(sailingService, this, getStringMessages());
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<ReplicationPanel>(replicationPanel) {
@Override
public void refreshAfterBecomingVisible() {
replicationPanel.updateReplicaList();
}
}, getStringMessages().replication(), SailingAdminConsoleFeatures.MANAGE_REPLICATION);
}, getStringMessages().replication(), Permission.MANAGE_REPLICATION);
final MasterDataImportPanel masterDataImportPanel = new MasterDataImportPanel(getStringMessages(), sailingService,
this, eventManagementPanel, this, this);
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<MasterDataImportPanel>(masterDataImportPanel),
getStringMessages().masterDataImportPanel(), SailingAdminConsoleFeatures.MANAGE_MASTERDATA_IMPORT);
getStringMessages().masterDataImportPanel(), Permission.MANAGE_MASTERDATA_IMPORT);
RemoteSailingServerInstancesManagementPanel sailingServerInstancesManagementPanel = new RemoteSailingServerInstancesManagementPanel(sailingService, this, getStringMessages());
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<RemoteSailingServerInstancesManagementPanel>(sailingServerInstancesManagementPanel),
getStringMessages().sailingServers(), SailingAdminConsoleFeatures.MANAGE_SAILING_SERVER_INSTANCES);
getStringMessages().sailingServers(), Permission.MANAGE_SAILING_SERVER_INSTANCES);
final DeviceConfigurationUserPanel deviceConfigurationUserPanel = new DeviceConfigurationUserPanel(sailingService,
getStringMessages(), this);
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<DeviceConfigurationUserPanel>(deviceConfigurationUserPanel),
getStringMessages().deviceConfiguration(), SailingAdminConsoleFeatures.MANAGE_DEVICE_CONFIGURATION);
getStringMessages().deviceConfiguration(), Permission.MANAGE_DEVICE_CONFIGURATION);
final UserManagementPanel userManagementPanel = new UserManagementPanel(getUserService(), StringMessages.INSTANCE);
final UserManagementPanel userManagementPanel = new UserManagementPanel(getUserService(), StringMessages.INSTANCE,
SailingPermissionsForRoleProvider.INSTANCE);
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<UserManagementPanel>(userManagementPanel),
getStringMessages().userManagement(), SailingAdminConsoleFeatures.MANAGE_USERS);
getStringMessages().userManagement(), Permission.MANAGE_USERS);
final FileStoragePanel fileStoragePanel = new FileStoragePanel(sailingService, this);
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<FileStoragePanel>(fileStoragePanel),
getStringMessages().fileStorage(), SailingAdminConsoleFeatures.MANAGE_FILE_STORAGE);
getStringMessages().fileStorage(), Permission.MANAGE_FILE_STORAGE);
panel.initUI();
fillRegattas();
@@ -1,27 +0,0 @@
package com.sap.sailing.gwt.ui.adminconsole;
import com.sap.sailing.gwt.ui.usermanagement.UserRoles;
import com.sap.sse.gwt.adminconsole.AdminConsoleFeatures;
public interface SailingAdminConsoleFeatures {
final AdminConsoleFeatures MANAGE_EVENTS = new AdminConsoleFeatures("MANAGE_EVENTS", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_REGATTAS = new AdminConsoleFeatures("MANAGE_REGATTAS", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_TRACKED_RACES = new AdminConsoleFeatures("MANAGE_TRACKED_RACES", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures SHOW_TRACKED_RACES = new AdminConsoleFeatures("SHOW_TRACKED_RACES", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_RACELOG_TRACKING = new AdminConsoleFeatures("MANAGE_RACELOG_TRACKING", UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_ALL_COMPETITORS = new AdminConsoleFeatures("MANAGE_ALL_COMPETITORS", UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_COURSE_LAYOUT = new AdminConsoleFeatures("MANAGE_COURSE_LAYOUT", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_WIND = new AdminConsoleFeatures("MANAGE_WIND", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_IGTIMI_ACCOUNTS = new AdminConsoleFeatures("MANAGE_IGTIMI_ACCOUNTS", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_LEADERBOARDS = new AdminConsoleFeatures("MANAGE_LEADERBOARDS", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_LEADERBOARD_GROUPS = new AdminConsoleFeatures("MANAGE_LEADERBOARD_GROUPS", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_RESULT_IMPORT_URLS = new AdminConsoleFeatures("MANAGE_RESULT_IMPORT_URLS", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_STRUCTURE_IMPORT_URLS = new AdminConsoleFeatures("MANAGE_STRUCTURE_IMPORT_URLS", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_MEDIA = new AdminConsoleFeatures("MANAGE_MEDIA", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_SAILING_SERVER_INSTANCES = new AdminConsoleFeatures("MANAGE_SAILING_SERVER_INSTANCES", UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_REPLICATION = new AdminConsoleFeatures("MANAGE_REPLICATION", UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_MASTERDATA_IMPORT = new AdminConsoleFeatures("MANAGE_MASTERDATA_IMPORT", UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_DEVICE_CONFIGURATION = new AdminConsoleFeatures("MANAGE_DEVICE_CONFIGURATION", UserRoles.eventmanager.getRolename(), UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_USERS = new AdminConsoleFeatures("MANAGE_USERS", UserRoles.administrator.getRolename());
final AdminConsoleFeatures MANAGE_FILE_STORAGE = new AdminConsoleFeatures("MANAGE_FILE_STORAGE", UserRoles.administrator.getRolename());
}
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.media.MediaTrack;
import com.sap.sailing.domain.common.media.MediaTrack.MediaType;
import com.sap.sailing.domain.common.media.MediaTrack.Status;
import com.sap.sailing.domain.common.security.Roles;
import com.sap.sailing.gwt.ui.client.MediaServiceAsync;
import com.sap.sailing.gwt.ui.client.RaceTimesInfoProvider;
import com.sap.sailing.gwt.ui.client.StringMessages;
@@ -37,7 +38,6 @@ import com.sap.sailing.gwt.ui.client.media.shared.VideoPlayer;
import com.sap.sailing.gwt.ui.client.media.shared.VideoSynchPlayer;
import com.sap.sailing.gwt.ui.client.shared.components.Component;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
import com.sap.sailing.gwt.ui.usermanagement.UserRoles;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.gwt.client.ErrorReporter;
@@ -49,6 +49,7 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
import com.sap.sse.gwt.client.player.Timer.PlayStates;
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
import com.sap.sse.gwt.client.useragent.UserAgentDetails.AgentTypes;
import com.sap.sse.security.shared.DefaultRoles;
import com.sap.sse.security.ui.client.UserService;
import com.sap.sse.security.ui.shared.UserDTO;
@@ -478,8 +479,8 @@ public class MediaPlayerManagerComponent implements Component<Void>, PlayStateLi
};
final VideoSynchPlayer videoPlayer;
final UserDTO currentUser = userService.getCurrentUser();
boolean showSynchControls = currentUser != null && (currentUser.hasRole(UserRoles.administrator.getRolename()) ||
currentUser.hasRole(UserRoles.eventmanager.getRolename()) || currentUser.hasRole(UserRoles.mediaeditor.getRolename()));
boolean showSynchControls = currentUser != null && (currentUser.hasRole(DefaultRoles.ADMIN.getRolename()) ||
currentUser.hasRole(Roles.eventmanager.getRolename()) || currentUser.hasRole(Roles.mediaeditor.getRolename()));
if (videoTrack.isYoutube()) {
videoPlayer = new VideoYoutubePlayer(videoTrack, getRaceStartTime(), showSynchControls, raceTimer);
} else {
@@ -1,50 +1,55 @@
[main]
shiro.loginUrl = /security/ui/Login.html
shiro.successUrl = /UserManagement.html
# Use Built-in Chache Manager
anyofroles = com.sap.sse.security.AnyOfRolesFilter
anyofroles.loginUrl = ../security/ui/Login.html
credentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
# base64 encoding, not hex in this example:
credentialsMatcher.storedCredentialsHexEncoded = false
credentialsMatcher.hashIterations = 1024
# Realm configuration:
permissionsForRoleProvider = com.sap.sailing.domain.common.security.SailingPermissionsForRoleProvider
upRealm = com.sap.sse.security.UsernamePasswordRealm
upRealm.credentialsMatcher = $credentialsMatcher
upRealm.permissionsForRoleProvider = $permissionsForRoleProvider
oauthRealm = com.sap.sse.security.OAuthRealm
accessTokenRealm = com.sap.sse.security.AccessTokenRealm
securityManager.realms = $upRealm, $oauthRealm, $accessTokenRealm
oauthRealm.permissionsForRoleProvider = $permissionsForRoleProvider
bearerTokenRealm = com.sap.sse.security.BearerTokenRealm
bearerTokenRealm.permissionsForRoleProvider = $permissionsForRoleProvider
# Putting it all together:
sessionManager = com.sap.sse.security.SecurityWebSessionManager
securityManager.sessionManager = $sessionManager
#globalCookie = com.sap.sse.security.GlobalCookie
#securityManager.sessionManager.sessionIdCookie = $globalCookie
authc = com.sap.sse.security.CustomFilter
authc.loginUrl = ../security/ui/Login.html?app=Sailing%20Analytics
authc.successUrl = /security/ui/UserManagement.html
roles.loginUrl = ../security/ui/Login.html
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAO
cacheManager = com.sap.sse.security.SessionCacheManager
securityManager.cacheManager = $cacheManager
#securityManager.sessionMode = native
# Authentication Filter Configurations
# ------------------------------------
# Set default login and success URLs for all filters:
shiro.loginUrl = ../security/ui/Login.html?app=Sailing%20Analytics
shiro.successUrl = ../security/ui/UserManagement.html
# A filter that requires the user to have at least one of the roles specified as
# filter parameter. This makes it different from the default roles[...] filter
# which requires the user to have ALL of the roles specified as parameters.
anyofroles = com.sap.sse.security.AnyOfRolesFilter
# A custom filter for GWT pages that require an authenticated user.
# Forwards unauthenticated users to the default login page. When
# addressed directly (and not based on a redirect), users who logged
# on successfully will be redirected to the UserManagement.html page
# where they can adjust their profile.
customGwt = com.sap.sse.security.CustomFilter
# This authentication filter accepts a bearer access token in the HTTP
# Authorization header field, as in
# Authorization: Bearer 1029741026501365024376093245
# If no such bearer token is provided, the filter falls back to basic HTTP
# authentication ("Authentication: Basic ...") and then regular form-based
# authentication with POST parameters "username" and "password".
bearerToken = com.sap.sse.security.BearerTokenOrBasicOrFormAuthenticationFilter
[urls]
# The /security/ui/Login.html is not restricted to authenticated users (otherwise no one could log in!), but
# the 'authc' filter must still be specified for it so it can process that url's
# login submissions. It is 'smart' enough to allow those requests through as specified by the
# shiro.loginUrl above.
/security/ui/UserManagement.html = authc,roles[admin]
/LeaderboardEditing.html = authc,anyofroles[admin,eventmanager]
/LeaderboardEditing.html = customGwt,anyofroles[admin,eventmanager]
# The admin console displays its features based on the user's roles
/AdminConsole.html = authc
/AdminConsole.html = customGwt
@@ -37,9 +37,11 @@ import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.polars.impl.CubicEquation;
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.data.ClusterGroup;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
import com.sap.sse.datamining.impl.components.ParallelFilteringProcessor;
import com.sap.sse.datamining.impl.components.ParallelMultiDimensionsValueNestingGroupingProcessor;
@@ -94,10 +96,13 @@ public class PolarDataMiner {
Collection<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>> movingAverageGrouperResultReceivers = new ArrayList<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>>();
movingAverageGrouperResultReceivers.add(movingAverageProcessor);
Collection<Function<?>> movingAverageDimensions = PolarDataDimensionCollectionFactory.getMovingAverageClusterKeyDimensions();
Collection<Pair<Function<?>, ParameterProvider>> dimensionsWithParameterProviders = new ArrayList<>();
for (Function<?> function : PolarDataDimensionCollectionFactory.getClusterKeyDimensions()) {
dimensionsWithParameterProviders.add(new Pair<Function<?>, ParameterProvider>(function, ParameterProvider.NULL));
}
Processor<GPSFixMovingWithPolarContext, GroupedDataEntry<GPSFixMovingWithPolarContext>> movingAverageGroupingProcessor = new ParallelMultiDimensionsValueNestingGroupingProcessor<GPSFixMovingWithPolarContext>(
GPSFixMovingWithPolarContext.class, executor, movingAverageGrouperResultReceivers, movingAverageDimensions);
GPSFixMovingWithPolarContext.class, executor, grouperResultReceivers, dimensionsWithParameterProviders);
cubicRegressionPerCourseProcessor = new CubicRegressionPerCourseProcessor();
@@ -13,7 +13,7 @@
<!--
The context root (the server) against which the tests should be executed.
-->
<context-root>http://riccardo:riccardo@localhost:8085/</context-root>
<context-root>http://localhost:8085/</context-root>
<!--
The folder where screenshots (attachments) are stored.
@@ -13,7 +13,7 @@
<!--
The context root (the server) against which the tests should be executed.
-->
<context-root>http://riccardo:riccardo@localhost:8888/</context-root>
<context-root>http://localhost:8888/</context-root>
<screenshots-folder>./bin/surefire-reports/</screenshots-folder>
@@ -114,12 +114,13 @@ public abstract class AbstractSeleniumTest {
Cookie result = null;
URL url = new URL(contextRoot + LOGIN_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.connect();
connection.getOutputStream().write("username=admin&password=admin".getBytes());
if (connection.getResponseCode() != 200) {
throw new RuntimeException(connection.getResponseMessage());
if (connection.getResponseCode() / 100 != 3) { // expecting something like "302 Found" which redirects to the success page
throw new RuntimeException("" + connection.getResponseCode() + " "+connection.getResponseMessage());
}
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
if (cookies != null) {
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -49,7 +49,11 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sse.shared.android,
com.sap.sse.filestorage,
com.sun.jersey.contribs.jersey-multipart;bundle-version="1.17.1",
org.apache.commons.math;bundle-version="2.1.0"
com.sap.sse.security,
org.apache.commons.math;bundle-version="2.1.0",
org.apache.shiro.core;bundle-version="1.2.2",
org.apache.shiro.web;bundle-version="1.2.2",
org.apache.shiro.ehcache;bundle-version="1.2.3"
Bundle-ClassPath: .
Web-ContextPath: /sailingserver
Export-Package: com.sap.sailing.server.gateway,
@@ -16,6 +16,30 @@
</init-param>
</servlet>
<!-- Apache Shiro -->
<context-param>
<param-name>shiroEnvironmentClass</param-name>
<param-value>org.apache.shiro.web.env.IniWebEnvironment</param-value>
</context-param>
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<!-- Make sure any request you want accessible to Shiro is filtered. "/*"
catches all requests. Usually this filter mapping is defined first (before all
others) to ensure that Shiro works in subsequent filters in the filter chain: -->
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>AdminApp</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.impl.AdminApp</servlet-class>
@@ -253,12 +277,12 @@
<param-value>com.sap.sailing.server.gateway.jaxrs.AccessControlAndEncodingResponseFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST API</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<servlet>
</servlet-mapping>
<servlet>
<servlet-name>Jersey REST SPI</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.jaxrs.RestServletContainer</servlet-class>
<init-param>
@@ -270,10 +294,10 @@
<param-value>com.sap.sailing.server.gateway.jaxrs.AccessControlAndEncodingResponseFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST SPI</servlet-name>
<url-pattern>/spi/*</url-pattern>
</servlet-mapping>
</servlet-mapping>
</web-app>
@@ -1,4 +1,5 @@
source.. = src/
source.. = src/,\
resources/
output.. = bin/
bin.includes = META-INF/,\
.,\
+64
View File
@@ -0,0 +1,64 @@
[main]
credentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
credentialsMatcher.storedCredentialsHexEncoded = false
credentialsMatcher.hashIterations = 1024
# Realm configuration:
# --------------------
permissionsForRoleProvider = com.sap.sailing.domain.common.security.SailingPermissionsForRoleProvider
upRealm = com.sap.sse.security.UsernamePasswordRealm
upRealm.credentialsMatcher = $credentialsMatcher
upRealm.permissionsForRoleProvider = $permissionsForRoleProvider
oauthRealm = com.sap.sse.security.OAuthRealm
oauthRealm.permissionsForRoleProvider = $permissionsForRoleProvider
bearerTokenRealm = com.sap.sse.security.BearerTokenRealm
bearerTokenRealm.permissionsForRoleProvider = $permissionsForRoleProvider
# Putting it all together:
sessionManager = com.sap.sse.security.SecurityWebSessionManager
securityManager.sessionManager = $sessionManager
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAO
cacheManager = com.sap.sse.security.SessionCacheManager
securityManager.cacheManager = $cacheManager
# Authentication Filter Configurations
# ------------------------------------
# A filter that requires the user to have at least one of the roles specified as
# filter parameter. This makes it different from the default roles[...] filter
# which requires the user to have ALL of the roles specified as parameters.
anyofroles = com.sap.sse.security.AnyOfRolesFilter
# A custom filter for GWT pages that require an authenticated user.
# Forwards unauthenticated users to the default login page. When
# addressed directly (and not based on a redirect), users who logged
# on successfully will be redirected to the UserManagement.html page
# where they can adjust their profile.
customGwt = com.sap.sse.security.CustomFilter
customGwt.loginUrl = /security/ui/Login.html
customGwt.successUrl = /UserManagement.html
# Configuration for the default shiro HTTP form authentication filter.
# It assumes that form-based login parameters are sent to the
# /api/restsecurity/login RESTlet and forwards successful login attempts
# to the /api/restsecurity/hello service which is expected to respond
# with a JSON document containing the authenticated subject's properties.
authc.loginUrl = /api/restsecurity/login
authc.successUrl = /api/restsecurity/hello
# This authentication filter accepts a bearer access token in the HTTP
# Authorization header field, as in
# Authorization: Bearer 1029741026501365024376093245
# If no such bearer token is provided, the filter falls back to basic HTTP
# authentication ("Authentication: Basic ...") and then regular form-based
# authentication with POST parameters "username" and "password".
bearerToken = com.sap.sse.security.BearerTokenOrBasicOrFormAuthenticationFilter
# Specifying filter chains for URL patterns
[urls]
# Uncomment the following to require the permission "event:view" in order to use /api/v1/events:
# /api/v1/events = bearerToken, perms["event:view"]
@@ -23,7 +23,7 @@
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
@@ -16,14 +16,14 @@
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre1.8.0_31"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.8.0_20"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console -clean"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djetty.port=8889 -Dreplication.exchangeName=sapsailinganalytics-replica -Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dexpedition.udp.port=2011 -Xmx6000m -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -XX:+UseMembar -Djava.library.path=${project_loc:com.sap.sailing.monitoring}/../../configuration/native-libraries -Dtractrac.mtb.cache.dir=/Users/spamies/Projects/sailing/tmp/mtb -Dmongo.dbName=replica"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
@@ -22,7 +22,7 @@
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
@@ -15,14 +15,14 @@
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre1.8.0_31"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.8.0_20"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console -clean"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y -ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=2010 -Xmx6000m -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -Dpersistentcompetitors.clear=false -XX:+UseMembar -Digtimi.client.id=7fcdd217e0aa16090edb4ad55b09ec43b2021090e209541fc9b7003c2a2b70c6 -Digtimi.client.secret=aa569cf4909bdc7b0e04b11873f3c4ea20687421e010fcc25b771cca9e6f3f9a -Digtimi.client.redirecturi=http://127.0.0.1:8888/igtimi/oauth/v1/authorizationcallback -DspatialWind=true -Dmongo.host=172.31.25.253 -Dmongo.port=10200 -Dmongo.dbName=LOAD_TEST"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
@@ -29,7 +29,7 @@
<stringAttribute key="profilingTraceType-PERFORMANCE_HOTSPOT_TRACE" value="KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_IGNORE_SLEEPING_THREADS%CTX_KEY%true%CTX_ENTRY%KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%"/>
<stringAttribute key="profilingTraceType-SYNCHRONIZATION_TRACE" value="KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
@@ -23,7 +23,7 @@
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
@@ -16,13 +16,13 @@
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre1.8.0_20"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.8.0_20"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Xmx6000m -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dhttp.proxyHost=proxy.wdf.sap.corp -Dhttp.proxyPort=8080 -Dhttps.proxyHost=proxy -Dhttps.proxyPort=8080 -Dexpedition.udp.port=2010 -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -XX:+UseMembar"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="true"/>
@@ -22,7 +22,7 @@
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-DsimulateLiveMode=true -DsimulateLiveMode.delayInMillis=250 -Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dexpedition.udp.port=2010 -Xmx6000m -Dhttp.proxyHost=proxy.wdf.sap.corp -Dhttp.proxyPort=8080 -Dhttps.proxyHost=proxy -Dhttps.proxyPort=8080 -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -XX:+UseMembar"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
@@ -24,7 +24,7 @@
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
@@ -23,6 +23,7 @@ scp -r ../../com.sap.sailing.targetplatform.base/target/repository $USER@$SERVER
echo "Making readable for everyone..."
ssh $USER@$SERVER "chmod -R a+r $REPO_HOME/sailing"
ssh $USER@$SERVER "chmod -R a+x $REPO_HOME/sailing"
echo "Remote files now available:"
ssh $USER@$SERVER "ls -lah $REPO_HOME/sailing"
@@ -39,7 +39,7 @@ public class GenericGroupKey<T> extends AbstractGroupKey {
@Override
public String asString() {
return value.toString();
return value == null ? "null" : value.toString();
}
@Override
@@ -10,4 +10,6 @@ LegNumber=Anzahl der Schenkel
SailID=Segelnummer
TestCluster=Test Cluster Deutsch
ClosedBoundariesClusterGroup=Cluster-Gruppe mit geschlossenen Grenzen
OpenBoundariesClusterGroup=Cluster-Gruppe mit offenen Grenzen
OpenBoundariesClusterGroup=Cluster-Gruppe mit offenen Grenzen
increment=Inkrementieren
illegalDimension=Illegale Dimension
@@ -10,4 +10,6 @@ LegNumber=Leg Number
SailID=Sail ID
TestCluster=Test Cluster English
ClosedBoundariesClusterGroup=Cluster group with closed boundaries
OpenBoundariesClusterGroup=Cluster group with open boundaries
OpenBoundariesClusterGroup=Cluster group with open boundaries
increment=Increment
illegalDimension=Illegal Dimension
@@ -14,11 +14,13 @@ import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Test;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.DataRetrieverChainBuilder;
import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.Query;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
@@ -71,16 +73,16 @@ public class TestDimensionsValuesQuery {
protected Processor<Collection<Test_Regatta>, ?> createFirstProcessor() {
Processor<GroupedDataEntry<Object>, Map<GroupKey, Set<Object>>> resultCollector = ComponentTestsUtil.getProcessorFactory().createGroupedDataCollectingAsSetProcessor(this);
Collection<Function<?>> legDimensions = new ArrayList<>();
legDimensions.add(dimensionLegNumber);
legDimensions.add(dimensionCompetitorName);
legDimensions.add(dimensionCompetitorSailID);
Collection<Pair<Function<?>, ParameterProvider>> legDimensions = new ArrayList<>();
legDimensions.add(new Pair<>(dimensionLegNumber, ParameterProvider.NULL));
legDimensions.add(new Pair<>(dimensionCompetitorName, ParameterProvider.NULL));
legDimensions.add(new Pair<>(dimensionCompetitorSailID, ParameterProvider.NULL));
Collection<Function<?>> raceDimensions = new ArrayList<>();
raceDimensions.add(dimensionRegattaName);
raceDimensions.add(dimensionRaceName);
raceDimensions.add(dimensionBoatClassName);
raceDimensions.add(dimensionYear);
Collection<Pair<Function<?>, ParameterProvider>> raceDimensions = new ArrayList<>();
raceDimensions.add(new Pair<>(dimensionRegattaName, ParameterProvider.NULL));
raceDimensions.add(new Pair<>(dimensionRaceName, ParameterProvider.NULL));
raceDimensions.add(new Pair<>(dimensionBoatClassName, ParameterProvider.NULL));
raceDimensions.add(new Pair<>(dimensionYear, ParameterProvider.NULL));
DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getExecutor());
chainBuilder.stepFurther(); //Initialization
@@ -20,12 +20,14 @@ import java.util.concurrent.TimeoutException;
import org.junit.Before;
import org.junit.Test;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.AdditionalResultDataBuilder;
import com.sap.sse.datamining.Query;
import com.sap.sse.datamining.components.FilterCriterion;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.factories.ProcessorFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.impl.components.AbstractSimpleParallelProcessor;
import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor;
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
@@ -115,11 +117,11 @@ public class TestProcessorQuery {
Method getCrossSumMethod = FunctionTestsUtil.getMethodFromClass(Number.class, "getCrossSum");
Function<Double> getCrossSumFunction = FunctionTestsUtil.getFunctionFactory().createMethodWrappingFunction(getCrossSumMethod);
Processor<GroupedDataEntry<Number>, GroupedDataEntry<Double>> crossSumExtractor = processorFactory.createExtractionProcessor(sumAggregator, getCrossSumFunction);
Processor<GroupedDataEntry<Number>, GroupedDataEntry<Double>> crossSumExtractor = processorFactory.createExtractionProcessor(sumAggregator, getCrossSumFunction, ParameterProvider.NULL);
List<Function<?>> dimensions = new ArrayList<>();
List<Pair<Function<?>, ParameterProvider>> dimensions = new ArrayList<>();
Function<Integer> getLengthFunction = FunctionTestsUtil.getFunctionFactory().createMethodWrappingFunction(FunctionTestsUtil.getMethodFromClass(Number.class, "getLength"));
dimensions.add(getLengthFunction);
dimensions.add(new Pair<>(getLengthFunction, ParameterProvider.NULL));
Processor<Number, GroupedDataEntry<Number>> lengthGrouper = processorFactory.createGroupingProcessor(Number.class, crossSumExtractor, dimensions);
Collection<Processor<Number, ?>> filtrationResultReceivers = new ArrayList<>();
filtrationResultReceivers.add(lengthGrouper);
@@ -11,8 +11,11 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.factories.ProcessorFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.impl.functions.MethodWrappingFunction;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
@@ -25,6 +28,8 @@ import com.sap.sse.datamining.test.util.components.Number;
public class TestParallelMultiDimensionalGroupingProcessor {
private final static ProcessorFactory processorFactory = ComponentTestsUtil.getProcessorFactory();
private Processor<Number, GroupedDataEntry<Number>> processor;
private Collection<Processor<GroupedDataEntry<Number>, ?>> receivers;
@@ -43,9 +48,9 @@ public class TestParallelMultiDimensionalGroupingProcessor {
receivers = new ArrayList<>();
receivers.add(receiver);
List<Function<?>> dimensions = new ArrayList<Function<?>>();
dimensions.add(new MethodWrappingFunction<>(Number.class.getMethod("getLength", new Class<?>[0]), int.class));
dimensions.add(new MethodWrappingFunction<>(Number.class.getMethod("getCrossSum", new Class<?>[0]), int.class));
List<Pair<Function<?>, ParameterProvider>> dimensions = new ArrayList<>();
dimensions.add(new Pair<>(new MethodWrappingFunction<>(Number.class.getMethod("getLength", new Class<?>[0]), int.class), ParameterProvider.NULL));
dimensions.add(new Pair<>(new MethodWrappingFunction<>(Number.class.getMethod("getCrossSum", new Class<?>[0]), int.class), ParameterProvider.NULL));
processor = ComponentTestsUtil.getProcessorFactory().createGroupingProcessor(Number.class, receivers, dimensions);
}
@@ -57,16 +62,16 @@ public class TestParallelMultiDimensionalGroupingProcessor {
@Test(expected=IllegalArgumentException.class)
public void testConstructionWithEmptyDimensions() {
Iterable<Function<?>> dimensions = new ArrayList<>();
new ParallelMultiDimensionsValueNestingGroupingProcessor<>(Number.class, ConcurrencyTestsUtil.getExecutor(), receivers, dimensions);
List<Pair<Function<?>, ParameterProvider>> dimensions = new ArrayList<>();
processorFactory.createGroupingProcessor(Number.class, receivers, dimensions);
}
@Test(expected=IllegalArgumentException.class)
public void testConstructionWithFunctionsInsteadOfDimensions() {
Collection<Function<?>> functions = new ArrayList<>();
List<Pair<Function<?>, ParameterProvider>> functions = new ArrayList<>();
Method method = FunctionTestsUtil.getMethodFromSimpleClassWithMarkedMethod("sideEffectFreeValue");
functions.add(FunctionTestsUtil.getFunctionFactory().createMethodWrappingFunction(method));
new ParallelMultiDimensionsValueNestingGroupingProcessor<>(Number.class, ConcurrencyTestsUtil.getExecutor(), receivers, functions);
functions.add(new Pair<>(FunctionTestsUtil.getFunctionFactory().createMethodWrappingFunction(method), ParameterProvider.NULL));
processorFactory.createGroupingProcessor(Number.class, receivers, functions);
}
@Test
@@ -73,7 +73,7 @@ public class TestFilterCriteria {
public void testNullaryFunctionValuesFilterCriterion() {
Function<String> getRegattaName = FunctionTestsUtil.getFunctionFactory().createMethodWrappingFunction(FunctionTestsUtil.getMethodFromClass(DataTypeWithContext.class, "getRegattaName"));
Collection<String> valuesToMatch = Arrays.asList("Regatta", "Other Regatta");
FilterCriterion<DataTypeWithContext> nullaryFunctionFilterCriterion = new NullaryFunctionValuesFilterCriterion<>(DataTypeWithContext.class, getRegattaName, valuesToMatch);
FilterCriterion<DataTypeWithContext> nullaryFunctionFilterCriterion = new FunctionValuesFilterCriterion<>(DataTypeWithContext.class, getRegattaName, valuesToMatch);
DataTypeWithContext regatta = new DataTypeWithContextImpl("Regatta", "Race Name", 7);
assertThat(nullaryFunctionFilterCriterion.matches(regatta), is(true));
@@ -16,8 +16,6 @@ import org.junit.Test;
import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.impl.SimpleDataRetrieverChainDefinition;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.test.functions.registry.test_classes.Test_Named;
@@ -36,56 +34,53 @@ import com.sap.sse.datamining.test.util.components.TestRaceWithContextRetrievalP
import com.sap.sse.datamining.test.util.components.TestRegattaRetrievalProcessor;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public class TestFunctionProvider {
public class TestFunctionManagerAsFunctionProvider {
private static final ResourceBundleStringMessages stringMessages = TestsUtil.getTestStringMessagesWithProductiveMessages();
private ExpectedFunctionRegistryUtil functionRegistryUtil;
private FunctionRegistry functionRegistry;
private FunctionManager functionManager;
@Before
public void initializeFunctionRegistry() throws NoSuchMethodException, SecurityException {
functionRegistryUtil = new ExpectedFunctionRegistryUtil();
functionRegistry = new SimpleFunctionRegistry();
functionManager = new FunctionManager();
Collection<Class<?>> internalClassesToScan = new HashSet<>();
internalClassesToScan.add(Test_HasLegOfCompetitorContext.class);
internalClassesToScan.add(Test_HasRaceContext.class);
functionRegistry.registerAllWithInternalFunctionPolicy(internalClassesToScan);
functionManager.registerAllWithInternalFunctionPolicy(internalClassesToScan);
Collection<Class<?>> externalClassesToScan = new HashSet<>();
externalClassesToScan.add(Test_ExternalLibraryClass.class);
functionRegistry.registerAllWithExternalFunctionPolicy(externalClassesToScan);
functionManager.registerAllWithExternalFunctionPolicy(externalClassesToScan);
}
@Test
public void testGetAllStatistics() {
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
Collection<Function<?>> expectedFunctions = functionRegistryUtil.getAllExpectedStatistics();
assertThat(functionProvider.getAllStatistics(), is(expectedFunctions));
assertThat(functionManager.getAllStatistics(), is(expectedFunctions));
}
@Test
public void testGetDimensionsForType() {
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
Collection<Function<?>> expectedDimensions = functionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class);
assertThat(functionProvider.getDimensionsFor(Test_HasRaceContext.class), is(expectedDimensions));
assertThat(functionProvider.getDimensionsFor(Test_HasRaceContextImpl.class), is(expectedDimensions));
assertThat(functionManager.getDimensionsFor(Test_HasRaceContext.class), is(expectedDimensions));
assertThat(functionManager.getDimensionsFor(Test_HasRaceContextImpl.class), is(expectedDimensions));
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasLegOfCompetitorContext.class));
assertThat(functionProvider.getDimensionsFor(Test_HasLegOfCompetitorContext.class), is(expectedDimensions));
assertThat(functionProvider.getDimensionsFor(Test_HasLegOfCompetitorContextImpl.class), is(expectedDimensions));
assertThat(functionManager.getDimensionsFor(Test_HasLegOfCompetitorContext.class), is(expectedDimensions));
assertThat(functionManager.getDimensionsFor(Test_HasLegOfCompetitorContextImpl.class), is(expectedDimensions));
}
@Test
public void testGetDimensionsForDataRetrieverChainDefinition() {
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
DataRetrieverChainDefinition<Collection<Test_Regatta>, Test_HasLegOfCompetitorContext> dataRetrieverChainDefinition = createDataRetrieverChainDefinition();
Collection<Function<?>> expectedDimensions = functionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class);
expectedDimensions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasLegOfCompetitorContext.class));
assertThat(functionProvider.getDimensionsFor(dataRetrieverChainDefinition), is(expectedDimensions));
assertThat(functionManager.getDimensionsFor(dataRetrieverChainDefinition), is(expectedDimensions));
}
@SuppressWarnings("unchecked")
@@ -111,21 +106,18 @@ public class TestFunctionProvider {
@Test
public void testGetStatisticsForType() {
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
Collection<Function<?>> expectedStatistics = functionRegistryUtil.getExpectedStatisticsFor(Test_HasLegOfCompetitorContext.class);
assertThat(functionProvider.getStatisticsFor(Test_HasLegOfCompetitorContext.class), is(expectedStatistics));
assertThat(functionProvider.getStatisticsFor(Test_HasLegOfCompetitorContextImpl.class), is(expectedStatistics));
assertThat(functionManager.getStatisticsFor(Test_HasLegOfCompetitorContext.class), is(expectedStatistics));
assertThat(functionManager.getStatisticsFor(Test_HasLegOfCompetitorContextImpl.class), is(expectedStatistics));
}
@Test
public void testGetAllFunctionsForType() {
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
Collection<Function<?>> expectedFunctions = functionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class);
expectedFunctions.addAll(functionRegistryUtil.getExpectedDimensionsFor(Test_HasLegOfCompetitorContext.class));
expectedFunctions.addAll(functionRegistryUtil.getExpectedStatisticsFor(Test_HasLegOfCompetitorContext.class));
assertThat(functionProvider.getFunctionsFor(Test_HasLegOfCompetitorContext.class), is(expectedFunctions));
assertThat(functionProvider.getFunctionsFor(Test_HasLegOfCompetitorContextImpl.class), is(expectedFunctions));
assertThat(functionManager.getFunctionsFor(Test_HasLegOfCompetitorContext.class), is(expectedFunctions));
assertThat(functionManager.getFunctionsFor(Test_HasLegOfCompetitorContextImpl.class), is(expectedFunctions));
}
@Test
@@ -138,26 +130,23 @@ public class TestFunctionProvider {
FunctionDTO getRegattaNameDTO = FunctionTestsUtil.getFunctionDTOFactory().createFunctionDTO(getRegattaName, stringMessages, Locale.ENGLISH);
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
@SuppressWarnings("unchecked") // Hamcrest requires type matching of actual and expected type, so the Functions have to be specific (without <?>)
Function<Object> providedFunction = (Function<Object>) functionProvider.getFunctionForDTO(getRegattaNameDTO);
Function<Object> providedFunction = (Function<Object>) functionManager.getFunctionForDTO(getRegattaNameDTO);
assertThat(providedFunction, is(getRegattaName));
}
@Test
public void testGetFunctionForUnregisteredDTO() {
Method incrementMethod = FunctionTestsUtil.getMethodFromClass(SimpleClassWithMarkedMethods.class, "increment", int.class);
Function<Object> increment = FunctionTestsUtil.getFunctionFactory().createMethodWrappingFunction(incrementMethod);
FunctionDTO incrementDTO = FunctionTestsUtil.getFunctionDTOFactory().createFunctionDTO(increment, stringMessages, Locale.ENGLISH);
Method illegalDimensionMethod = FunctionTestsUtil.getMethodFromClass(SimpleClassWithMarkedMethods.class, "illegalDimension");
Function<Object> illegalDimension = FunctionTestsUtil.getFunctionFactory().createMethodWrappingFunction(illegalDimensionMethod);
FunctionDTO illegalDimensionDTO = FunctionTestsUtil.getFunctionDTOFactory().createFunctionDTO(illegalDimension, stringMessages, Locale.ENGLISH);
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
assertThat(functionProvider.getFunctionForDTO(incrementDTO), is(nullValue()));
assertThat(functionManager.getFunctionForDTO(illegalDimensionDTO), is(nullValue()));
}
@Test
public void testGetFunctionForNullDTO() {
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
assertThat(functionProvider.getFunctionForDTO(null), is(nullValue()));
assertThat(functionManager.getFunctionForDTO(null), is(nullValue()));
}
}
@@ -12,15 +12,15 @@ import org.junit.BeforeClass;
import org.junit.Test;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.test.functions.registry.test_contexts.Test_HasContextWithDeadConnectorEnd;
import com.sap.sse.datamining.test.functions.registry.test_contexts.Test_HasLegOfCompetitorContext;
import com.sap.sse.datamining.test.functions.registry.test_contexts.Test_HasRaceContext;
import com.sap.sse.datamining.test.functions.test_classes.Test_ExternalLibraryClass;
import com.sap.sse.datamining.test.util.ExpectedFunctionRegistryUtil;
import com.sap.sse.datamining.test.util.OpenFunctionManager;
public class TestSimpleFunctionRegistry {
public class TestFunctionManagerAsFunctionRegistry {
private static ExpectedFunctionRegistryUtil expectedFunctionRegistryUtil;
@@ -45,7 +45,7 @@ public class TestSimpleFunctionRegistry {
@Test
public void testRegistration() throws NoSuchMethodException, SecurityException {
FunctionRegistry registry = new SimpleFunctionRegistry();
OpenFunctionManager registry = new OpenFunctionManager();
registry.registerAllWithInternalFunctionPolicy(internalClassesToScan);
registry.registerAllWithExternalFunctionPolicy(externalClassesToScan);
@@ -55,7 +55,7 @@ public class TestSimpleFunctionRegistry {
assertThat(registry.getDimensions(), is(expectedDimensions));
Collection<Function<?>> expectedStatistics = expectedFunctionRegistryUtil.getExpectedStatisticsFor(Test_HasLegOfCompetitorContext.class);
assertThat(registry.getStatistics(), is(expectedStatistics));
assertThat(registry.getAllStatistics(), is(expectedStatistics));
Collection<Function<?>> expectedExternalFunctions = expectedFunctionRegistryUtil.getExpectedExternalFunctionsFor(Test_ExternalLibraryClass.class);
assertThat(registry.getExternalFunctions(), is(expectedExternalFunctions));
@@ -63,7 +63,7 @@ public class TestSimpleFunctionRegistry {
@Test
public void testUnregistration() {
FunctionRegistry registry = new SimpleFunctionRegistry();
OpenFunctionManager registry = new OpenFunctionManager();
registry.registerAllWithInternalFunctionPolicy(internalClassesToScan);
Collection<Function<?>> expectedDimensions = new HashSet<>();
@@ -33,14 +33,14 @@ public class TestMethodWrappingFunctionInvocation {
@Test
public void testInvocationWithParameters() {
SimpleClassWithMarkedMethods instance = new SimpleClassWithMarkedMethods();
int valueToIncrement = 10;
assertThat(increment.tryToInvoke(instance, valueToIncrement), is(instance.increment(valueToIncrement)));
final int valueToIncrement = 10;
assertThat(increment.tryToInvoke(instance, () -> {return new Object[] {valueToIncrement};} ), is(instance.increment(valueToIncrement)));
}
@Test
public void testInvocationWithWrongParameters() {
DataTypeWithContext dataEntry = new DataTypeWithContextImpl("Regatta Name", "Race Name", 7);
assertThat(getRegattaName.tryToInvoke(dataEntry, "Wrong Parameter"), is(nullValue()));
assertThat(getRegattaName.tryToInvoke(dataEntry, () -> {return new Object[] {"Wrong Parameter"};} ), is(nullValue()));
SimpleClassWithMarkedMethods instance = new SimpleClassWithMarkedMethods();
assertThat(increment.tryToInvoke(instance), is(nullValue()));
@@ -14,7 +14,7 @@ public class TestMethodFilterCriterias {
@Test
public void testMethodIsCorrectDimensionFilterCriteria() {
FilterCriterion<Method> filterCriteria = new MethodIsCorrectDimensionFilterCriterion();
FilterCriterion<Method> filterCriteria = new MethodIsValidDimensionFilterCriterion();
Method dimension = FunctionTestsUtil.getMethodFromSimpleClassWithMarkedMethod("dimension");
assertThat(filterCriteria.matches(dimension), is(true));
@@ -28,7 +28,7 @@ public class TestMethodFilterCriterias {
@Test
public void testMethodIsCorrectSideEffectFreeValueFilterCriteria() {
FilterCriterion<Method> filterCriteria = new MethodIsCorrectStatisticFilterCriterion();
FilterCriterion<Method> filterCriteria = new MethodIsValidStatisticFilterCriterion();
Method sideEffectFreeValue = FunctionTestsUtil.getMethodFromSimpleClassWithMarkedMethod("sideEffectFreeValue");
assertThat(filterCriteria.matches(sideEffectFreeValue), is(true));
@@ -39,7 +39,7 @@ public class TestMethodFilterCriterias {
@Test
public void testMethodIsCorrectExternalLibraryFunctionFilterCriteria() {
FilterCriterion<Method> filterCriteria = new MethodIsCorrectExternalFunctionFilterCriterion();
FilterCriterion<Method> filterCriteria = new MethodIsValidExternalFunctionFilterCriterion();
Method foo = FunctionTestsUtil.getMethodFromExternalLibraryClass("foo");
assertThat(filterCriteria.matches(foo), is(true));
@@ -4,8 +4,10 @@ import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.util.HashSet;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
@@ -67,6 +69,20 @@ public class TestI18N {
assertThat(ResourceBundleStringMessages.Util.getLocaleFor("Unsupported locale info name"), is(Locale.ENGLISH));
}
@Test
public void testGetSupportedLocales() {
Set<Locale> supportedLocales = new HashSet<>();
for (Locale locale : ResourceBundleStringMessages.Util.getSupportedLocales()) {
supportedLocales.add(locale);
}
Set<Locale> expectedSupportedLocales = new HashSet<>();
expectedSupportedLocales.add(Locale.GERMAN);
expectedSupportedLocales.add(Locale.ENGLISH);
assertThat(supportedLocales, is(expectedSupportedLocales));
}
@Test(expected=MissingResourceException.class)
public void testGettingAMessageForAMissingKeyFromSimpleStringMessages() {
testStringMessages.get(Locale.ENGLISH, "$%&MissingKey/()");
@@ -1,7 +1,10 @@
package com.sap.sse.datamining.test.functions.test_classes;
import java.util.Locale;
import com.sap.sse.datamining.shared.annotations.Dimension;
import com.sap.sse.datamining.shared.annotations.Statistic;
import com.sap.sse.i18n.ResourceBundleStringMessages;
/*
* DON'T CHANGE THE METHOD/CLASS NAMES!
@@ -30,8 +33,14 @@ public class SimpleClassWithMarkedMethods {
}
//Methods with parameters
public int increment(int i) {
return i + 1;
}
public String getLocalizedName(Locale locale, ResourceBundleStringMessages stringMessages) {
return "";
}
}
@@ -0,0 +1,18 @@
package com.sap.sse.datamining.test.util;
import java.util.Collection;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.impl.functions.FunctionManager;
public class OpenFunctionManager extends FunctionManager {
public Collection<Function<?>> getDimensions() {
return asSet(dimensions);
}
public Collection<Function<?>> getExternalFunctions() {
return asSet(externalFunctions);
}
}
@@ -19,16 +19,16 @@ public interface DataRetrieverChainDefinition<DataSourceType, DataType> {
public String getLocalizedName(Locale locale, ResourceBundleStringMessages stringMessages);
public <ResultType> void startWith(Class<Processor<DataSourceType, ResultType>> retrieverType, Class<ResultType> retrievedDataType, String retrievedDataTypeMessageKey);
public <ResultType> void startWith(Class<? extends Processor<DataSourceType, ResultType>> retrieverType, Class<ResultType> retrievedDataType, String retrievedDataTypeMessageKey);
public <NextInputType, NextResultType, PreviousInputType, PreviousResultType extends NextInputType> void
addAfter(Class<Processor<PreviousInputType, PreviousResultType>> previousRetrieverType,
Class<Processor<NextInputType, NextResultType>> nextRetrieverType,
addAfter(Class<? extends Processor<PreviousInputType, PreviousResultType>> previousRetrieverType,
Class<? extends Processor<NextInputType, NextResultType>> nextRetrieverType,
Class<NextResultType> retrievedDataType, String retrievedDataTypeMessageKey);
public <NextInputType, PreviousInputType, PreviousResultType extends NextInputType> void
endWith(Class<Processor<PreviousInputType, PreviousResultType>> previousRetrieverType,
Class<Processor<NextInputType, DataType>> lastRetrieverType,
endWith(Class<? extends Processor<PreviousInputType, PreviousResultType>> previousRetrieverType,
Class<? extends Processor<NextInputType, DataType>> lastRetrieverType,
Class<DataType> retrievedDataType, String retrievedDataTypeMessageKey);
public List<? extends DataRetrieverTypeWithInformation<?, ?>> getDataRetrieverTypesWithInformation();
@@ -8,8 +8,10 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.impl.ProcessorQuery;
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
import com.sap.sse.datamining.impl.components.ParallelByDimensionGroupingProcessor;
@@ -75,29 +77,33 @@ public class ProcessorFactory {
* Creates an extraction processor with the given aggregation processor as result receiver.
*/
public <ElementType, ResultType> Processor<GroupedDataEntry<ElementType>, GroupedDataEntry<ResultType>> createExtractionProcessor(
Processor<GroupedDataEntry<ResultType>, ?> aggregationProcessor, Function<ResultType> extractionFunction) {
Processor<GroupedDataEntry<ResultType>, ?> aggregationProcessor, Function<ResultType> extractionFunction, ParameterProvider parameterProvider) {
Collection<Processor<GroupedDataEntry<ResultType>, ?>> resultReceivers = new ArrayList<>();
resultReceivers.add(aggregationProcessor);
return createExtractionProcessor(resultReceivers, extractionFunction);
return createExtractionProcessor(resultReceivers, extractionFunction, parameterProvider);
}
public <ElementType, ResultType> Processor<GroupedDataEntry<ElementType>, GroupedDataEntry<ResultType>> createExtractionProcessor(
Collection<Processor<GroupedDataEntry<ResultType>, ?>> resultReceivers, Function<ResultType> extractionFunction) {
Collection<Processor<GroupedDataEntry<ResultType>, ?>> resultReceivers, Function<ResultType> extractionFunction, ParameterProvider parameterProvider) {
return new ParallelGroupedElementsValueExtractionProcessor<ElementType, ResultType>(executor,
resultReceivers, extractionFunction);
resultReceivers, extractionFunction, parameterProvider);
}
/**
* Creates a grouping processor with the given extraction processor as result receiver.
*/
public <DataType> Processor<DataType, GroupedDataEntry<DataType>> createGroupingProcessor(Class<DataType> dataType, Processor<GroupedDataEntry<DataType>, ?> extractionProcessor, List<Function<?>> dimensionsToGroupBy) {
public <DataType> Processor<DataType, GroupedDataEntry<DataType>> createGroupingProcessor(Class<DataType> dataType, Processor<GroupedDataEntry<DataType>, ?> extractionProcessor, Iterable<Pair<Function<?>, ParameterProvider>> dimensionsToGroupByWithParameterProvider) {
Collection<Processor<GroupedDataEntry<DataType>, ?>> resultReceivers = new ArrayList<>();
resultReceivers.add(extractionProcessor);
return createGroupingProcessor(dataType, resultReceivers, dimensionsToGroupBy);
return createGroupingProcessor(dataType, resultReceivers, dimensionsToGroupByWithParameterProvider);
}
public <DataType> Processor<DataType, GroupedDataEntry<DataType>> createGroupingProcessor(Class<DataType> dataType, Collection<Processor<GroupedDataEntry<DataType>, ?>> resultReceivers, List<Function<?>> dimensionsToGroupBy) {
return new ParallelMultiDimensionsValueNestingGroupingProcessor<>(dataType, executor, resultReceivers, dimensionsToGroupBy);
public <DataType> Processor<DataType, GroupedDataEntry<DataType>> createGroupingProcessor(Class<DataType> dataType, Collection<Processor<GroupedDataEntry<DataType>, ?>> resultReceivers, Iterable<Pair<Function<?>, ParameterProvider>> dimensionsToGroupByWithParameterProvider) {
return new ParallelMultiDimensionsValueNestingGroupingProcessor<>(dataType, executor, resultReceivers, dimensionsToGroupByWithParameterProvider);
}
public <DataType> Processor<DataType, GroupedDataEntry<DataType>> createGroupingProcessorWithParameter(Class<DataType> dataType, Collection<Processor<GroupedDataEntry<DataType>, ?>> resultReceivers, List<Pair<Function<?>, ParameterProvider>> dimensionsToGroupByWithParameterProvider) {
return new ParallelMultiDimensionsValueNestingGroupingProcessor<DataType>(dataType, executor, resultReceivers, dimensionsToGroupByWithParameterProvider);
}
/**
@@ -105,18 +111,18 @@ public class ProcessorFactory {
*/
@SuppressWarnings("unchecked")
public <DataType> Collection<Processor<DataType, GroupedDataEntry<DataType>>> createGroupingExtractorsForDimensions(Class<DataType> dataType,
Processor<GroupedDataEntry<Object>, ?> valueCollector, Iterable<Function<?>> dimensions,
Processor<GroupedDataEntry<Object>, ?> valueCollector, Iterable<Pair<Function<?>, ParameterProvider>> dimensionsToGroupByWithParameterProvider,
ResourceBundleStringMessages stringMessages, Locale locale) {
Collection<Processor<GroupedDataEntry<Object>, ?>> extractionResultReceivers = new ArrayList<>();
extractionResultReceivers.add(valueCollector);
Collection<Processor<DataType, GroupedDataEntry<DataType>>> groupingExtractors = new ArrayList<>();
for (Function<?> dimension : dimensions) {
Processor<GroupedDataEntry<DataType>, GroupedDataEntry<Object>> dimensionValueExtractor = new ParallelGroupedElementsValueExtractionProcessor<DataType, Object>(executor, extractionResultReceivers, (Function<Object>) dimension);
for (Pair<Function<?>, ParameterProvider> dimensionWithParameterProvider : dimensionsToGroupByWithParameterProvider) {
Processor<GroupedDataEntry<DataType>, GroupedDataEntry<Object>> dimensionValueExtractor = createExtractionProcessor(extractionResultReceivers, (Function<Object>) dimensionWithParameterProvider.getA(), dimensionWithParameterProvider.getB());
Collection<Processor<GroupedDataEntry<DataType>, ?>> groupingResultReceivers = new ArrayList<>();
groupingResultReceivers.add(dimensionValueExtractor);
Processor<DataType, GroupedDataEntry<DataType>> byDimensionGrouper = new ParallelByDimensionGroupingProcessor<>(dataType, executor, groupingResultReceivers, dimension, stringMessages, locale);
Processor<DataType, GroupedDataEntry<DataType>> byDimensionGrouper = new ParallelByDimensionGroupingProcessor<>(dataType, executor, groupingResultReceivers, dimensionWithParameterProvider.getA(), stringMessages, locale);
groupingExtractors.add(byDimensionGrouper);
}
return groupingExtractors;
@@ -3,12 +3,14 @@ package com.sap.sse.datamining.factories;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.DataRetrieverChainBuilder;
import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.Query;
@@ -16,11 +18,13 @@ import com.sap.sse.datamining.QueryDefinition;
import com.sap.sse.datamining.components.FilterCriterion;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.impl.ProcessorQuery;
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
import com.sap.sse.datamining.impl.criterias.AndCompoundFilterCriterion;
import com.sap.sse.datamining.impl.criterias.CompoundFilterCriterion;
import com.sap.sse.datamining.impl.criterias.NullaryFunctionValuesFilterCriterion;
import com.sap.sse.datamining.impl.criterias.FunctionValuesFilterCriterion;
import com.sap.sse.datamining.impl.functions.LocalizationParameterProvider;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.i18n.ResourceBundleStringMessages;
@@ -37,9 +41,9 @@ public class QueryFactory {
Class<DataType> dataTypeToRetrieve = queryDefinition.getDataType();
Processor<GroupedDataEntry<ResultType>, Map<GroupKey, ResultType>> aggregationProcessor = processorFactory.createAggregationProcessor(/*query*/ this, queryDefinition.getAggregatorType(), queryDefinition.getResultType());
Processor<GroupedDataEntry<DataType>, GroupedDataEntry<ResultType>> extractionProcessor = processorFactory.createExtractionProcessor(aggregationProcessor, extractionFunction);
Processor<GroupedDataEntry<DataType>, GroupedDataEntry<ResultType>> extractionProcessor = processorFactory.createExtractionProcessor(aggregationProcessor, extractionFunction, getParameterProviderFor(extractionFunction, stringMessages, queryDefinition.getLocale()));
Processor<DataType, GroupedDataEntry<DataType>> groupingProcessor = processorFactory.createGroupingProcessor(dataTypeToRetrieve, extractionProcessor, queryDefinition.getDimensionsToGroupBy());
Processor<DataType, GroupedDataEntry<DataType>> groupingProcessor = processorFactory.createGroupingProcessor(dataTypeToRetrieve, extractionProcessor, getParameterProvidersFor(queryDefinition.getDimensionsToGroupBy(), stringMessages, queryDefinition.getLocale()));
DataRetrieverChainBuilder<DataSourceType> chainBuilder = queryDefinition.getDataRetrieverChainDefinition().startBuilding(executor);
Map<Integer, FilterCriterion<?>> criteriaMappedByRetrieverLevel = createFilterCriteria(queryDefinition.getFilterSelection());
@@ -58,12 +62,45 @@ public class QueryFactory {
};
}
private Iterable<Pair<Function<?>, ParameterProvider>> getParameterProvidersFor(Iterable<Function<?>> functions, ResourceBundleStringMessages stringMessages, Locale locale) {
Collection<Pair<Function<?>, ParameterProvider>> functionsWithParameterProvider = new ArrayList<>();
for (Function<?> function : functions) {
functionsWithParameterProvider.add(new Pair<>(function, getParameterProviderFor(function, stringMessages, locale)));
}
return functionsWithParameterProvider;
}
private ParameterProvider getParameterProviderFor(Function<?> function, ResourceBundleStringMessages stringMessages, Locale locale) {
if (functionNeedsLocalizationParameters(function)) {
return new LocalizationParameterProvider(locale, stringMessages);
}
return ParameterProvider.NULL;
}
private boolean functionNeedsLocalizationParameters(Function<?> function) {
Iterator<Class<?>> parameterTypesIterator = function.getParameters().iterator();
int parameterCount = 0;
while (parameterTypesIterator.hasNext()) {
parameterCount++;
parameterTypesIterator.next();
}
if (parameterCount != 2) {
return false;
}
parameterTypesIterator = function.getParameters().iterator();
Class<?> firstParameter = parameterTypesIterator.next();
Class<?> secondParameter = parameterTypesIterator.next();
return firstParameter.isAssignableFrom(Locale.class) && secondParameter.isAssignableFrom(ResourceBundleStringMessages.class);
}
@SuppressWarnings("unchecked")
private <DataType> Map<Integer, FilterCriterion<?>> createFilterCriteria(Map<Integer, Map<Function<?>, Collection<?>>> filterSelection) {
Map<Integer, CompoundFilterCriterion<?>> criteriaMappedByRetrieverLevel = new HashMap<>();
for (Entry<Integer, Map<Function<?>, Collection<?>>> levelFilterSelection : filterSelection.entrySet()) {
for (Entry<Function<?>, Collection<?>> levelFilterSelectionEntry : levelFilterSelection.getValue().entrySet()) {
Function<?> function = levelFilterSelectionEntry.getKey();
ParameterProvider parameterProvider = ParameterProvider.NULL;
Class<DataType> dataType = (Class<DataType>) function.getDeclaringType();
if (!criteriaMappedByRetrieverLevel.containsKey(levelFilterSelection.getKey())) {
@@ -71,7 +108,7 @@ public class QueryFactory {
}
Collection<Object> filterValues = new ArrayList<>(levelFilterSelectionEntry.getValue());
((CompoundFilterCriterion<DataType>) criteriaMappedByRetrieverLevel.get(levelFilterSelection.getKey())).addCriteria(new NullaryFunctionValuesFilterCriterion<>(dataType, function, filterValues));
((CompoundFilterCriterion<DataType>) criteriaMappedByRetrieverLevel.get(levelFilterSelection.getKey())).addCriteria(new FunctionValuesFilterCriterion<>(dataType, function, parameterProvider, filterValues));
}
}
return (Map<Integer, FilterCriterion<?>>)(Map<Integer, ?>) criteriaMappedByRetrieverLevel;
@@ -94,7 +131,7 @@ public class QueryFactory {
chainBuilder.stepFurther();
}
for (Processor<?, ?> resultReceiver : processorFactory.createGroupingExtractorsForDimensions(
chainBuilder.getCurrentRetrievedDataType(), valueCollector, dimensions, stringMessages, locale)) {
chainBuilder.getCurrentRetrievedDataType(), valueCollector, getParameterProvidersFor(dimensions, stringMessages, locale), stringMessages, locale)) {
chainBuilder.addResultReceiver(resultReceiver);
}
@@ -20,7 +20,7 @@ public interface Function<ReturnType> {
* @return <code>true</code>, if the method {@link #getLocalizedName(Locale, ResourceBundleStringMessages) getLocalizedName} would return something
* other than the method {@link #getSimpleName()}.
*/
public boolean isLocatable();
public boolean isLocalizable();
public String getLocalizedName(Locale locale, ResourceBundleStringMessages stringMessages);
@@ -33,12 +33,13 @@ public interface Function<ReturnType> {
public ReturnType tryToInvoke(Object instance);
/**
* Tries to invoke the function for the given <code>instance</code> and the given <code>parameters</code>.
* Tries to invoke the function for the given <code>instance</code> and the <code>parameters</code> provided
* by the given {@link ParameterProvider}.
*
* @return The result of the function or <code>null</code>, if an {@link InvocationTargetException},
* {@link IllegalAccessException} or {@link IllegalArgumentException} was thrown.
*/
public ReturnType tryToInvoke(Object instance, Object... parameters);
public ReturnType tryToInvoke(Object instance, ParameterProvider parameterProvider);
public Unit getResultUnit();
@@ -6,9 +6,9 @@ import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public interface FunctionProvider {
public Collection<Function<?>> getAllStatistics();
public Collection<Function<?>> getAllStatistics();
public Collection<Function<?>> getFunctionsFor(Class<?> sourceType);
public Collection<Function<?>> getStatisticsFor(Class<?> sourceType);
@@ -1,7 +1,5 @@
package com.sap.sse.datamining.functions;
import java.util.Collection;
public interface FunctionRegistry {
public void registerAllWithInternalFunctionPolicy(Iterable<Class<?>> classesToScan);
@@ -9,13 +7,4 @@ public interface FunctionRegistry {
public void unregisterAllFunctionsOf(Iterable<Class<?>> classesToUnregister);
public Collection<Function<?>> getAllFunctions();
public Collection<Function<?>> getAllFunctionsOf(Class<?> declaringType);
public Collection<Function<?>> getStatistics();
public Collection<Function<?>> getStatisticsOf(Class<?> declaringType);
public Collection<Function<?>> getDimensions();
public Collection<Function<?>> getDimensionsOf(Class<?> declaringType);
public Collection<Function<?>> getExternalFunctions();
public Collection<Function<?>> getExternalFunctionsOf(Class<?> declaringType);
}
@@ -0,0 +1,12 @@
package com.sap.sse.datamining.functions;
import com.sap.sse.datamining.impl.functions.NullParameterProvider;
public interface ParameterProvider {
public static final ParameterProvider NULL = new NullParameterProvider();
public Object[] getParameters();
}
@@ -18,10 +18,7 @@ import com.sap.sse.datamining.DataMiningBundleService;
import com.sap.sse.datamining.DataMiningServer;
import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.ModifiableDataMiningServer;
import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.impl.functions.RegistryFunctionProvider;
import com.sap.sse.datamining.impl.functions.SimpleFunctionRegistry;
import com.sap.sse.datamining.impl.functions.FunctionManager;
import com.sap.sse.i18n.impl.ResourceBundleStringMessagesImpl;
public class DataMiningActivator implements BundleActivator {
@@ -40,10 +37,9 @@ public class DataMiningActivator implements BundleActivator {
ExecutorService executor = new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());
FunctionRegistry functionRegistry = new SimpleFunctionRegistry();
FunctionProvider functionProvider = new RegistryFunctionProvider(functionRegistry);
FunctionManager functionManager = new FunctionManager();
DataRetrieverChainDefinitionRegistry dataRetrieverChainDefinitionRegistry = new SimpleDataRetrieverChainDefinitionRegistry();
dataMiningServer = new DataMiningServerImpl(executor, functionRegistry, functionProvider, dataRetrieverChainDefinitionRegistry);
dataMiningServer = new DataMiningServerImpl(executor, functionManager, functionManager, dataRetrieverChainDefinitionRegistry);
dataMiningServer.addStringMessages(new ResourceBundleStringMessagesImpl(STRING_MESSAGES_BASE_NAME, DataMiningActivator.class.getClassLoader()));
serviceRegistrations = new HashSet<>();
@@ -42,7 +42,7 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
this.functionProvider = functionProvider;
this.dataRetrieverChainDefinitionRegistry = dataRetrieverChainDefinitionRegistry;
}
@Override
public ExecutorService getExecutorService() {
return executorService;
@@ -4,11 +4,11 @@ import com.sap.sse.datamining.components.Processor;
public class DataRetrieverTypeWithInformation<InputType, RetrievedDataType> {
private final Class<Processor<InputType, RetrievedDataType>> retrieverType;
private final Class<? extends Processor<InputType, RetrievedDataType>> retrieverType;
private final Class<RetrievedDataType> retrievedDataType;
private final String retrievedDataTypeMessageKey;
public DataRetrieverTypeWithInformation(Class<Processor<InputType, RetrievedDataType>> retrieverType,
public DataRetrieverTypeWithInformation(Class<? extends Processor<InputType, RetrievedDataType>> retrieverType,
Class<RetrievedDataType> retrievedDataType,
String retrievedDataTypeMessageKey) {
this.retrieverType = retrieverType;
@@ -16,7 +16,7 @@ public class DataRetrieverTypeWithInformation<InputType, RetrievedDataType> {
this.retrievedDataTypeMessageKey = retrievedDataTypeMessageKey;
}
public Class<Processor<InputType, RetrievedDataType>> getRetrieverType() {
public Class<? extends Processor<InputType, RetrievedDataType>> getRetrieverType() {
return retrieverType;
}
@@ -61,7 +61,7 @@ public class SimpleDataRetrieverChainDefinition<DataSourceType, DataType> implem
}
@Override
public <ResultType> void startWith(Class<Processor<DataSourceType, ResultType>> retrieverType,
public <ResultType> void startWith(Class<? extends Processor<DataSourceType, ResultType>> retrieverType,
Class<ResultType> retrievedDataType, String retrievedDataTypeMessageKey) {
if (isInitialized()) {
throw new UnsupportedOperationException("This retriever chain definition already has been started with '"
@@ -79,8 +79,8 @@ public class SimpleDataRetrieverChainDefinition<DataSourceType, DataType> implem
@Override
public <NextInputType, NextResultType, PreviousInputType, PreviousResultType extends NextInputType> void addAfter(
Class<Processor<PreviousInputType, PreviousResultType>> previousRetrieverType,
Class<Processor<NextInputType, NextResultType>> nextRetrieverType,
Class<? extends Processor<PreviousInputType, PreviousResultType>> previousRetrieverType,
Class<? extends Processor<NextInputType, NextResultType>> nextRetrieverType,
Class<NextResultType> retrievedDataType, String retrievedDataTypeMessageKey) {
if (!isInitialized()) {
throw new UnsupportedOperationException("This retriever chain definition hasn't been started yet");
@@ -103,7 +103,7 @@ public class SimpleDataRetrieverChainDefinition<DataSourceType, DataType> implem
}
private <InputType, ResultType> void checkThatRetrieverHasUsableConstructor(
Class<Processor<InputType, ResultType>> retrieverType) {
Class<? extends Processor<InputType, ResultType>> retrieverType) {
try {
retrieverType.getConstructor(ExecutorService.class, Collection.class);
} catch (NoSuchMethodException | SecurityException e) {
@@ -114,8 +114,8 @@ public class SimpleDataRetrieverChainDefinition<DataSourceType, DataType> implem
@Override
public <NextInputType, PreviousInputType, PreviousResultType extends NextInputType> void endWith(
Class<Processor<PreviousInputType, PreviousResultType>> previousRetrieverType,
Class<Processor<NextInputType, DataType>> lastRetrieverType, Class<DataType> retrievedDataType,
Class<? extends Processor<PreviousInputType, PreviousResultType>> previousRetrieverType,
Class<? extends Processor<NextInputType, DataType>> lastRetrieverType, Class<DataType> retrievedDataType,
String retrievedDataTypeMessageKey) {
addAfter(previousRetrieverType, lastRetrieverType, retrievedDataType, retrievedDataTypeMessageKey);
isComplete = true;
@@ -5,37 +5,39 @@ import java.util.Iterator;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.AdditionalResultDataBuilder;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.impl.NestingCompoundGroupKey;
public abstract class AbstractParallelMultiDimensionalNestingGroupingProcessor<DataType>
extends AbstractSimpleParallelProcessor<DataType, GroupedDataEntry<DataType>> {
private Iterable<Function<?>> dimensions;
private Iterable<Pair<Function<?>, ParameterProvider>> dimensionsWithParameterProvider;
@SuppressWarnings("unchecked")
public AbstractParallelMultiDimensionalNestingGroupingProcessor(Class<DataType> dataType,
ExecutorService executor,
Collection<Processor<GroupedDataEntry<DataType>, ?>> resultReceivers,
Iterable<Function<?>> dimensions) {
Iterable<Pair<Function<?>, ParameterProvider>> dimensionsWithParameterProvider) {
super(dataType, (Class<GroupedDataEntry<DataType>>)(Class<?>) GroupedDataEntry.class, executor, resultReceivers);
verifyThatDimensionsAreDimensions(dimensions);
this.dimensions = dimensions;
verifyThatDimensionsAreDimensions(dimensionsWithParameterProvider);
this.dimensionsWithParameterProvider = dimensionsWithParameterProvider;
}
private void verifyThatDimensionsAreDimensions(Iterable<Function<?>> dimensions) {
if (dimensions == null) {
private void verifyThatDimensionsAreDimensions(Iterable<Pair<Function<?>, ParameterProvider>> dimensionsWithParameterProvider) {
if (dimensionsWithParameterProvider == null) {
throw new IllegalArgumentException("The given dimensions mustn't be null.");
}
int size = 0;
for (Function<?> possibleDimension : dimensions) {
for (Pair<Function<?>, ParameterProvider> possibleDimension : dimensionsWithParameterProvider) {
size++;
if (!possibleDimension.isDimension()) {
throw new IllegalArgumentException("The given function " + possibleDimension.toString() + " is no dimension.");
if (!possibleDimension.getA().isDimension()) {
throw new IllegalArgumentException("The given function " + possibleDimension.getA().toString() + " is no dimension.");
}
}
@@ -50,21 +52,21 @@ public abstract class AbstractParallelMultiDimensionalNestingGroupingProcessor<D
@Override
public GroupedDataEntry<DataType> call() throws Exception {
return new GroupedDataEntry<DataType>(createCompoundKeyFor(element,
dimensions.iterator()), element);
dimensionsWithParameterProvider.iterator()), element);
}
};
}
private GroupKey createCompoundKeyFor(DataType input, Iterator<Function<?>> dimensionsIterator) {
Function<?> mainDimension = dimensionsIterator.next();
GroupKey key = createGroupKeyFor(input, mainDimension);
private GroupKey createCompoundKeyFor(DataType input, Iterator<Pair<Function<?>, ParameterProvider>> dimensionsIterator) {
Pair<Function<?>, ParameterProvider> mainDimension = dimensionsIterator.next();
GroupKey key = createGroupKeyFor(input, mainDimension.getA(), mainDimension.getB());
if (dimensionsIterator.hasNext()) {
key = new NestingCompoundGroupKey(key, createCompoundKeyFor(input, dimensionsIterator));
}
return key;
}
protected abstract GroupKey createGroupKeyFor(DataType input, Function<?> dimension);
protected abstract GroupKey createGroupKeyFor(DataType input, Function<?> dimension, ParameterProvider parameterProvider);
@Override
protected void setAdditionalData(AdditionalResultDataBuilder additionalDataBuilder) {
@@ -5,9 +5,11 @@ import java.util.Collection;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.factories.FunctionDTOFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
@@ -38,14 +40,14 @@ public class ParallelByDimensionGroupingProcessor<DataType> extends
functionDTOFactory = new FunctionDTOFactory();
}
private static Iterable<Function<?>> asIterable(Function<?> dimension) {
Collection<Function<?>> collection = new ArrayList<>();
collection.add(dimension);
private static Iterable<Pair<Function<?>, ParameterProvider>> asIterable(Function<?> dimension) {
Collection<Pair<Function<?>, ParameterProvider>> collection = new ArrayList<>();
collection.add(new Pair<Function<?>, ParameterProvider>(dimension, ParameterProvider.NULL));
return collection;
}
@Override
protected GroupKey createGroupKeyFor(DataType input, Function<?> dimension) {
protected GroupKey createGroupKeyFor(DataType input, Function<?> dimension, ParameterProvider parameterProvider) {
return new GenericGroupKey<FunctionDTO>(functionDTOFactory.createFunctionDTO(dimension, stringMessages, locale));
}
@@ -7,18 +7,27 @@ import java.util.concurrent.ExecutorService;
import com.sap.sse.datamining.AdditionalResultDataBuilder;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
public class ParallelGroupedElementsValueExtractionProcessor<DataType, FunctionReturnType>
extends AbstractSimpleParallelProcessor<GroupedDataEntry<DataType>, GroupedDataEntry<FunctionReturnType>> {
private final Function<FunctionReturnType> extractionFunction;
private final ParameterProvider parameterProvider;
public ParallelGroupedElementsValueExtractionProcessor(ExecutorService executor,
Collection<Processor<GroupedDataEntry<FunctionReturnType>, ?>> resultReceivers,
Function<FunctionReturnType> extractionFunction) {
this(executor, resultReceivers, extractionFunction, ParameterProvider.NULL);
}
@SuppressWarnings("unchecked")
public ParallelGroupedElementsValueExtractionProcessor(ExecutorService executor,
Collection<Processor<GroupedDataEntry<FunctionReturnType>, ?>> resultReceivers,
Function<FunctionReturnType> extractionFunction) {
Function<FunctionReturnType> extractionFunction, ParameterProvider parameterProvider) {
super((Class<GroupedDataEntry<DataType>>)(Class<?>) GroupedDataEntry.class, (Class<GroupedDataEntry<FunctionReturnType>>)(Class<?>) GroupedDataEntry.class, executor, resultReceivers);
this.extractionFunction = extractionFunction;
this.parameterProvider = parameterProvider;
}
@Override
@@ -26,7 +35,7 @@ public class ParallelGroupedElementsValueExtractionProcessor<DataType, FunctionR
return new Callable<GroupedDataEntry<FunctionReturnType>>() {
@Override
public GroupedDataEntry<FunctionReturnType> call() throws Exception {
FunctionReturnType value = extractionFunction.tryToInvoke(element.getDataEntry());
FunctionReturnType value = extractionFunction.tryToInvoke(element.getDataEntry(), parameterProvider);
return value != null ? new GroupedDataEntry<FunctionReturnType>(element.getKey(), value) :
ParallelGroupedElementsValueExtractionProcessor.super.createInvalidResult();
}
@@ -3,8 +3,10 @@ package com.sap.sse.datamining.impl.components;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
@@ -23,12 +25,12 @@ public class ParallelMultiDimensionsValueNestingGroupingProcessor<DataType>
public ParallelMultiDimensionsValueNestingGroupingProcessor(Class<DataType> dataType,
ExecutorService executor,
Collection<Processor<GroupedDataEntry<DataType>, ?>> resultReceivers,
Iterable<Function<?>> dimensions) {
super(dataType, executor, resultReceivers, dimensions);
Iterable<Pair<Function<?>, ParameterProvider>> dimensionsWithParameterProvider) {
super(dataType, executor, resultReceivers, dimensionsWithParameterProvider);
}
protected GroupKey createGroupKeyFor(DataType input, Function<?> mainDimension) {
Object keyValue = mainDimension.tryToInvoke(input);
protected GroupKey createGroupKeyFor(DataType input, Function<?> dimension, ParameterProvider parameterProvider) {
Object keyValue = dimension.tryToInvoke(input, parameterProvider);
return new GenericGroupKey<Object>(keyValue);
}
@@ -48,11 +48,11 @@ public class ParallelGroupedDoubleDataMedianAggregationProcessor
private Double getMedianOf(List<Double> values) {
Collections.sort(values);
if (listSizeIsEven(values)) {
int index1 = values.size() / 2;
int index1 = (values.size() / 2) - 1;
int index2 = index1 + 1;
return (values.get(index1) + values.get(index2)) / 2;
} else {
int index = (values.size() + 1) / 2;
int index = ((values.size() + 1) / 2) - 1;
return values.get(index);
}
}
@@ -0,0 +1,39 @@
package com.sap.sse.datamining.impl.criterias;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
public class FunctionValuesFilterCriterion<ElementType> extends AbstractFilterCriterion<ElementType> {
private final Function<?> function;
private final ParameterProvider parameterProvider;
private final Collection<?> valuesToMatch;
public FunctionValuesFilterCriterion(Class<ElementType> elementType, Function<?> function, Collection<?> valuesToMatch) {
this(elementType, function, ParameterProvider.NULL, valuesToMatch);
}
public FunctionValuesFilterCriterion(Class<ElementType> elementType, Function<?> function, ParameterProvider parameterProvider, Collection<?> valuesToMatch) {
super(elementType);
this.function = function;
this.parameterProvider = parameterProvider;
this.valuesToMatch = new HashSet<>(valuesToMatch);
}
@Override
public boolean matches(ElementType dataEntry) {
Object value = function.tryToInvoke(dataEntry, parameterProvider);
for (Object valueToMatch : valuesToMatch) {
if (Objects.equals(value, valueToMatch)) {
return true;
}
}
return false;
}
}
@@ -1,32 +0,0 @@
package com.sap.sse.datamining.impl.criterias;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import com.sap.sse.datamining.functions.Function;
public class NullaryFunctionValuesFilterCriterion<ElementType> extends AbstractFilterCriterion<ElementType> {
private Function<?> function;
private Collection<?> valuesToMatch;
public NullaryFunctionValuesFilterCriterion(Class<ElementType> elementType, Function<?> function, Collection<?> valuesToMatch) {
super(elementType);
this.function = function;
this.valuesToMatch = new HashSet<>(valuesToMatch);
}
@Override
public boolean matches(ElementType dataEntry) {
Object value = function.tryToInvoke(dataEntry);
for (Object valueToMatch : valuesToMatch) {
if (Objects.equals(value, valueToMatch)) {
return true;
}
}
return false;
}
}
@@ -6,6 +6,7 @@ import java.util.List;
import java.util.Locale;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.i18n.ResourceBundleStringMessages;
@@ -90,7 +91,7 @@ public class ConcatenatingCompoundFunction<ReturnType> extends AbstractFunction<
if (name != null && !name.isEmpty()) {
return name;
}
if (!isLocatable()) {
if (!isLocalizable()) {
return getSimpleName();
}
@@ -98,9 +99,9 @@ public class ConcatenatingCompoundFunction<ReturnType> extends AbstractFunction<
}
@Override
public boolean isLocatable() {
public boolean isLocalizable() {
for (Function<?> function : functions) {
if (function.isLocatable()) {
if (function.isLocalizable()) {
return true;
}
}
@@ -111,7 +112,7 @@ public class ConcatenatingCompoundFunction<ReturnType> extends AbstractFunction<
StringBuilder builder = new StringBuilder();
boolean first = true;
for (Function<?> function : functions) {
if (function.isLocatable()) {
if (function.isLocalizable()) {
if (!first) {
builder.append(LOCALIZED_NAME_CHAIN_CONNECTOR);
}
@@ -124,16 +125,16 @@ public class ConcatenatingCompoundFunction<ReturnType> extends AbstractFunction<
@Override
public ReturnType tryToInvoke(Object instance) {
return tryToInvoke(instance, new Object[0]);
return tryToInvoke(instance, ParameterProvider.NULL);
}
@SuppressWarnings("unchecked") // The cast has to work. The types were checked in the constructor.
@SuppressWarnings("unchecked")
@Override
public ReturnType tryToInvoke(Object instance, Object... parameters) {
public ReturnType tryToInvoke(Object instance, ParameterProvider parameterProvider) {
Iterator<Function<?>> functionsIterator = functions.iterator();
Object result = functionsIterator.next().tryToInvoke(instance, parameters);
Object result = functionsIterator.next().tryToInvoke(instance, parameterProvider);
while (functionsIterator.hasNext()) {
Function<?> function = (Function<?>) functionsIterator.next();
Function<?> function = functionsIterator.next();
result = function.tryToInvoke(result);
if (result == null) {
return null;
@@ -0,0 +1,340 @@
package com.sap.sse.datamining.impl.functions;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.components.FilterCriterion;
import com.sap.sse.datamining.factories.FunctionDTOFactory;
import com.sap.sse.datamining.factories.FunctionFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.impl.DataRetrieverTypeWithInformation;
import com.sap.sse.datamining.impl.functions.criterias.FunctionMatchesDTOFilterCriterion;
import com.sap.sse.datamining.impl.functions.criterias.MethodIsValidConnectorFilterCriterion;
import com.sap.sse.datamining.impl.functions.criterias.MethodIsValidDimensionFilterCriterion;
import com.sap.sse.datamining.impl.functions.criterias.MethodIsValidExternalFunctionFilterCriterion;
import com.sap.sse.datamining.impl.functions.criterias.MethodIsValidStatisticFilterCriterion;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public class FunctionManager implements FunctionRegistry, FunctionProvider {
private enum FunctionRetrievalStrategies {
All {
@Override
public Collection<Function<?>> retrieveFunctions(Class<?> declaringType, FunctionManager manager) {
return manager.getAllFunctionsOf(declaringType);
}
},
Dimensions {
@Override
public Collection<Function<?>> retrieveFunctions(Class<?> declaringType, FunctionManager manager) {
return manager.getDimensionsOf(declaringType);
}
},
Statistics {
@Override
public Collection<Function<?>> retrieveFunctions(Class<?> declaringType, FunctionManager manager) {
return manager.getStatisticsOf(declaringType);
}
};
public abstract Collection<Function<?>> retrieveFunctions(Class<?> declaringType, FunctionManager manager);
}
private static final Logger LOGGER = Logger.getLogger(FunctionManager.class.getName());
private final FilterCriterion<Method> isValidDimension = new MethodIsValidDimensionFilterCriterion();
private final FilterCriterion<Method> isValidStatistic = new MethodIsValidStatisticFilterCriterion();
private final FilterCriterion<Method> isValidConnector = new MethodIsValidConnectorFilterCriterion();
private final FilterCriterion<Method> isValidExternalFunction = new MethodIsValidExternalFunctionFilterCriterion();
private final FunctionFactory functionFactory;
private final FunctionDTOFactory functionDTOFactory;
protected final Map<Class<?>, Set<Function<?>>> statistics;
protected final Map<Class<?>, Set<Function<?>>> dimensions;
protected final Map<Class<?>, Set<Function<?>>> externalFunctions;
private final Collection<Map<Class<?>, Set<Function<?>>>> functionMaps;
public FunctionManager() {
functionDTOFactory = new FunctionDTOFactory();
functionFactory = new FunctionFactory();
statistics = new HashMap<>();
dimensions = new HashMap<>();
externalFunctions = new HashMap<>();
functionMaps = new ArrayList<>();
functionMaps.add(statistics);
functionMaps.add(dimensions);
functionMaps.add(externalFunctions);
}
@Override
public void registerAllWithInternalFunctionPolicy(Iterable<Class<?>> internalClassesToScan) {
for (Class<?> internalClass : internalClassesToScan) {
scanInternalClass(internalClass);
}
}
private void scanInternalClass(Class<?> internalClass) {
scanInternalClass(internalClass, new ArrayList<Function<?>>());
}
private void scanInternalClass(Class<?> internalClass, List<Function<?>> previousFunctions) {
for (Method method : internalClass.getMethods()) {
if (isValidDimension.matches(method) || isValidStatistic.matches(method)) {
registerFunction(previousFunctions, method);
continue;
}
if (isValidConnector.matches(method)) {
handleConnectorMethod(method, previousFunctions);
}
}
}
private void registerFunction(List<Function<?>> previousFunctions, Method method) {
Function<?> function = functionFactory.createMethodWrappingFunction(method);
if (!previousFunctions.isEmpty()) {
function = functionFactory.createCompoundFunction(null, previousFunctions, function);
}
if (function.isDimension()) {
addDimension(function);
} else {
addStatistic(function);
}
}
private void addDimension(Function<?> dimension) {
Class<?> declaringType = dimension.getDeclaringType();
if (!dimensions.containsKey(declaringType)) {
dimensions.put(declaringType, new HashSet<Function<?>>());
}
dimensions.get(declaringType).add(dimension);
}
private void addStatistic(Function<?> statistic) {
Class<?> declaringType = statistic.getDeclaringType();
if (!statistics.containsKey(declaringType)) {
statistics.put(declaringType, new HashSet<Function<?>>());
}
statistics.get(declaringType).add(statistic);
}
private void handleConnectorMethod(Method method, List<Function<?>> previousFunctions) {
Function<?> function = functionFactory.createMethodWrappingFunction(method);
Class<?> returnType = method.getReturnType();
List<Function<?>> previousFunctionsClone = new ArrayList<>(previousFunctions);
previousFunctionsClone.add(function);
scanInternalClass(returnType, previousFunctionsClone);
}
@Override
public void registerAllWithExternalFunctionPolicy(Iterable<Class<?>> externalClassesToScan) {
for (Class<?> externalClass : externalClassesToScan) {
for (Method method : externalClass.getMethods()) {
if (isValidExternalFunction.matches(method)) {
Function<?> function = functionFactory.createMethodWrappingFunction(method);
addExternalFunction(function);
}
}
}
}
private void addExternalFunction(Function<?> function) {
Class<?> declaringType = function.getDeclaringType();
if (!externalFunctions.containsKey(declaringType)) {
externalFunctions.put(declaringType, new HashSet<Function<?>>());
}
externalFunctions.get(declaringType).add(function);
}
@Override
public void unregisterAllFunctionsOf(Iterable<Class<?>> classesToUnregister) {
for (Class<?> classToUnregister : classesToUnregister) {
unregisterAllFunctionsOf(classToUnregister);
}
}
private void unregisterAllFunctionsOf(Class<?> classToUnregister) {
for (Map<Class<?>, Set<Function<?>>> functionMap : functionMaps) {
functionMap.remove(classToUnregister);
}
}
private Collection<Function<?>> getAllFunctionsOf(Class<?> declaringType) {
Collection<Function<?>> allFunctions = new HashSet<>();
for (Map<Class<?>, Set<Function<?>>> functionMap : functionMaps) {
Collection<Function<?>> functions = functionMap.get(declaringType);
if (functions != null) {
allFunctions.addAll(functions);
}
}
return allFunctions;
}
@Override
public Collection<Function<?>> getAllStatistics() {
return asSet(statistics);
}
private Collection<Function<?>> getStatisticsOf(Class<?> declaringType) {
return statistics.get(declaringType);
}
private Collection<Function<?>> getDimensionsOf(Class<?> declaringType) {
return dimensions.get(declaringType);
}
protected Collection<Function<?>> asSet(Map<?, Set<Function<?>>> map) {
Collection<Function<?>> set = new HashSet<>();
for (Entry<?, Set<Function<?>>> entry : map.entrySet()) {
set.addAll(entry.getValue());
}
return set;
}
@Override
public Collection<Function<?>> getFunctionsFor(Class<?> sourceType) {
return getFunctionsFor(sourceType, FunctionRetrievalStrategies.All);
}
@Override
public Collection<Function<?>> getDimensionsFor(Class<?> sourceType) {
return getFunctionsFor(sourceType, FunctionRetrievalStrategies.Dimensions);
}
@Override
public Collection<Function<?>> getDimensionsFor(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
Collection<Function<?>> dimensions = new HashSet<>();
for (DataRetrieverTypeWithInformation<?, ?> dataRetrieverTypeWithInformation : dataRetrieverChainDefinition.getDataRetrieverTypesWithInformation()) {
dimensions.addAll(getDimensionsFor(dataRetrieverTypeWithInformation.getRetrievedDataType()));
}
return dimensions;
}
@Override
public Collection<Function<?>> getStatisticsFor(Class<?> sourceType) {
return getFunctionsFor(sourceType, FunctionRetrievalStrategies.Statistics);
}
private Collection<Function<?>> getFunctionsFor(Class<?> sourceType, FunctionRetrievalStrategies retrievalStrategy) {
Collection<Class<?>> typesToRetrieve = getSupertypesOf(sourceType);
typesToRetrieve.add(sourceType);
return getFunctionsFor(typesToRetrieve, retrievalStrategy);
}
private Collection<Function<?>> getFunctionsFor(Collection<Class<?>> typesToRetrieve, FunctionRetrievalStrategies retrievalStrategy) {
Collection<Function<?>> functions = new HashSet<>();
for (Class<?> typeToRetrieve : typesToRetrieve) {
Collection<Function<?>> typeSpecificFunctions = retrievalStrategy.retrieveFunctions(typeToRetrieve, this);
if (typeSpecificFunctions != null) {
functions.addAll(typeSpecificFunctions);
}
}
return functions;
}
private Collection<Class<?>> getSupertypesOf(Class<?> type) {
Collection<Class<?>> supertypes = new HashSet<>();
supertypes.addAll(getInterfacesOf(type));
if (isSuperclassValid(type)) {
supertypes.add(type.getSuperclass());
}
supertypes.addAll(getSupertypesOf(supertypes));
return supertypes;
}
private Collection<Class<?>> getInterfacesOf(Class<?> type) {
return Arrays.asList(type.getInterfaces());
}
private boolean isSuperclassValid(Class<?> subType) {
return subType.getSuperclass() != null && !subType.getSuperclass().equals(Object.class);
}
private Collection<Class<?>> getSupertypesOf(Collection<Class<?>> types) {
Collection<Class<?>> supertypes = new HashSet<>();
boolean supertypeAdded;
do {
Collection<Class<?>> supertypesToAdd = getSupertypesToAdd(types);
supertypeAdded = supertypes.addAll(supertypesToAdd);
} while (supertypeAdded);
return supertypes;
}
private Collection<Class<?>> getSupertypesToAdd(Collection<Class<?>> types) {
Collection<Class<?>> supertypesToAdd = new HashSet<>();
for (Class<?> supertype : types) {
supertypesToAdd.addAll(getSupertypesOf(supertype));
}
return supertypesToAdd;
}
@Override
public Function<?> getFunctionForDTO(FunctionDTO functionDTO) {
if (functionDTO == null) {
return null;
}
Collection<Function<?>> functionsMatchingDTO = getFunctionsForDTO(functionDTO);
if (moreThanOneFunctionMatchedDTO(functionsMatchingDTO)) {
logThatMoreThanOneFunctionMatchedDTO(functionDTO, functionsMatchingDTO);
}
return getFunctionToReturn(functionsMatchingDTO);
}
private Collection<Function<?>> getFunctionsForDTO(FunctionDTO functionDTO) {
Collection<Function<?>> functionsMatchingDTO = new HashSet<>();
FilterCriterion<Function<?>> functionDTOFilterCriteria = new FunctionMatchesDTOFilterCriterion(functionDTOFactory, functionDTO);
for (Function<?> function : getAllFunctions()) {
if (functionDTOFilterCriteria.matches(function)) {
functionsMatchingDTO.add(function);
}
}
return functionsMatchingDTO;
}
private Collection<Function<?>> getAllFunctions() {
Collection<Function<?>> allFunctions = new HashSet<>();
for (Map<Class<?>, Set<Function<?>>> functionMap : functionMaps) {
allFunctions.addAll(asSet(functionMap));
}
return allFunctions;
}
private boolean moreThanOneFunctionMatchedDTO(Collection<Function<?>> functionsMatchingDTO) {
return functionsMatchingDTO.size() > 1;
}
private void logThatMoreThanOneFunctionMatchedDTO(FunctionDTO functionDTO, Collection<Function<?>> functionsMatchingDTO) {
LOGGER.log(Level.FINER, "More than on registered function matched the function DTO '" + functionDTO.toString() + "'");
for (Function<?> function : functionsMatchingDTO) {
LOGGER.log(Level.FINEST, "The function '" + function.toString() + "' matched the function DTO '" + functionDTO.toString() + "'");
}
}
private Function<?> getFunctionToReturn(Collection<Function<?>> functionsMatchingDTO) {
return functionsMatchingDTO.isEmpty() ? null : functionsMatchingDTO.iterator().next();
}
}
@@ -0,0 +1,13 @@
package com.sap.sse.datamining.impl.functions;
import java.util.Locale;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public class LocalizationParameterProvider extends SimpleParameterProvider {
public LocalizationParameterProvider(Locale locale, ResourceBundleStringMessages stringMessages) {
super(new Object[] {locale, stringMessages});
}
}
@@ -6,6 +6,7 @@ import java.util.Arrays;
import java.util.Locale;
import java.util.logging.Level;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.annotations.Dimension;
@@ -81,9 +82,13 @@ public class MethodWrappingFunction<ReturnType> extends AbstractFunction<ReturnT
return tryToInvoke(instance, new Object[0]);
}
@SuppressWarnings("unchecked") // The cast has to work, because the constructor checks, that the return types match
@Override
public ReturnType tryToInvoke(Object instance, Object... parameters) {
public ReturnType tryToInvoke(Object instance, ParameterProvider parameterProvider) {
return tryToInvoke(instance, parameterProvider.getParameters());
}
@SuppressWarnings("unchecked") // The cast has to work, because the constructor checks, that the return types match
private ReturnType tryToInvoke(Object instance, Object... parameters) {
if (instance != null) {
try {
return (ReturnType) method.invoke(instance, parameters);
@@ -116,14 +121,14 @@ public class MethodWrappingFunction<ReturnType> extends AbstractFunction<ReturnT
@Override
public String getLocalizedName(Locale locale, ResourceBundleStringMessages stringMessages) {
if (!isLocatable()) {
if (!isLocalizable()) {
return getSimpleName();
}
return stringMessages.get(locale, additionalData.getMessageKey());
}
@Override
public boolean isLocatable() {
public boolean isLocalizable() {
return additionalData != null && !additionalData.getMessageKey().isEmpty();
}
@@ -0,0 +1,10 @@
package com.sap.sse.datamining.impl.functions;
public class NullParameterProvider extends SimpleParameterProvider {
public NullParameterProvider() {
super(new Object[0]);
}
}
@@ -1,191 +0,0 @@
package com.sap.sse.datamining.impl.functions;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.components.FilterCriterion;
import com.sap.sse.datamining.factories.FunctionDTOFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.impl.DataRetrieverTypeWithInformation;
import com.sap.sse.datamining.impl.functions.criterias.FunctionMatchesDTOFilterCriterion;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public class RegistryFunctionProvider implements FunctionProvider {
private enum FunctionRetrievalStrategies {
All {
@Override
public Collection<Function<?>> retrieveFunctions(Class<?> declaringType, FunctionRegistry registry) {
return registry.getAllFunctionsOf(declaringType);
}
},
Dimensions {
@Override
public Collection<Function<?>> retrieveFunctions(Class<?> declaringType, FunctionRegistry registry) {
return registry.getDimensionsOf(declaringType);
}
},
Statistics {
@Override
public Collection<Function<?>> retrieveFunctions(Class<?> declaringType, FunctionRegistry registry) {
return registry.getStatisticsOf(declaringType);
}
};
public abstract Collection<Function<?>> retrieveFunctions(Class<?> declaringType, FunctionRegistry registry);
}
private static final Logger LOGGER = Logger.getLogger(RegistryFunctionProvider.class.getName());
private final FunctionDTOFactory functionDTOFactory;
private final Collection<FunctionRegistry> functionRegistries;
public RegistryFunctionProvider(FunctionRegistry... functionRegistry) {
this(Arrays.asList(functionRegistry));
}
public RegistryFunctionProvider(Collection<FunctionRegistry> functionRegistries) {
functionDTOFactory = new FunctionDTOFactory();
this.functionRegistries = new HashSet<>(functionRegistries);
}
@Override
public Collection<Function<?>> getAllStatistics() {
Collection<Function<?>> allStatistics = new HashSet<>();
for (FunctionRegistry registry : functionRegistries) {
allStatistics.addAll(registry.getStatistics());
}
return allStatistics;
}
@Override
public Collection<Function<?>> getFunctionsFor(Class<?> sourceType) {
return getFunctionsFor(sourceType, FunctionRetrievalStrategies.All);
}
@Override
public Collection<Function<?>> getDimensionsFor(Class<?> sourceType) {
return getFunctionsFor(sourceType, FunctionRetrievalStrategies.Dimensions);
}
@Override
public Collection<Function<?>> getDimensionsFor(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
Collection<Function<?>> dimensions = new HashSet<>();
for (DataRetrieverTypeWithInformation<?, ?> dataRetrieverTypeWithInformation : dataRetrieverChainDefinition.getDataRetrieverTypesWithInformation()) {
dimensions.addAll(getDimensionsFor(dataRetrieverTypeWithInformation.getRetrievedDataType()));
}
return dimensions;
}
@Override
public Collection<Function<?>> getStatisticsFor(Class<?> sourceType) {
return getFunctionsFor(sourceType, FunctionRetrievalStrategies.Statistics);
}
private Collection<Function<?>> getFunctionsFor(Class<?> sourceType, FunctionRetrievalStrategies retrievalStrategy) {
Collection<Class<?>> typesToRetrieve = getSupertypesOf(sourceType);
typesToRetrieve.add(sourceType);
return getFunctionsFor(typesToRetrieve, retrievalStrategy);
}
private Collection<Function<?>> getFunctionsFor(Collection<Class<?>> typesToRetrieve, FunctionRetrievalStrategies retrievalStrategy) {
Collection<Function<?>> functions = new HashSet<>();
for (FunctionRegistry functionRegistry : functionRegistries) {
for (Class<?> typeToRetrieve : typesToRetrieve) {
Collection<Function<?>> typeSpecificFunctions = retrievalStrategy.retrieveFunctions(typeToRetrieve, functionRegistry);
if (typeSpecificFunctions != null) {
functions.addAll(typeSpecificFunctions);
}
}
}
return functions;
}
private Collection<Class<?>> getSupertypesOf(Class<?> type) {
Collection<Class<?>> supertypes = new HashSet<>();
supertypes.addAll(getInterfacesOf(type));
if (isSuperclassValid(type)) {
supertypes.add(type.getSuperclass());
}
supertypes.addAll(getSupertypesOf(supertypes));
return supertypes;
}
private Collection<Class<?>> getInterfacesOf(Class<?> type) {
return Arrays.asList(type.getInterfaces());
}
private boolean isSuperclassValid(Class<?> subType) {
return subType.getSuperclass() != null && !subType.getSuperclass().equals(Object.class);
}
private Collection<Class<?>> getSupertypesOf(Collection<Class<?>> types) {
Collection<Class<?>> supertypes = new HashSet<>();
boolean supertypeAdded;
do {
Collection<Class<?>> supertypesToAdd = getSupertypesToAdd(types);
supertypeAdded = supertypes.addAll(supertypesToAdd);
} while (supertypeAdded);
return supertypes;
}
private Collection<Class<?>> getSupertypesToAdd(Collection<Class<?>> types) {
Collection<Class<?>> supertypesToAdd = new HashSet<>();
for (Class<?> supertype : types) {
supertypesToAdd.addAll(getSupertypesOf(supertype));
}
return supertypesToAdd;
}
@Override
public Function<?> getFunctionForDTO(FunctionDTO functionDTO) {
if (functionDTO == null) {
return null;
}
Collection<Function<?>> functionsMatchingDTO = getFunctionsForDTO(functionDTO);
if (moreThanOneFunctionMatchedDTO(functionsMatchingDTO)) {
logThatMoreThanOneFunctionMatchedDTO(functionDTO, functionsMatchingDTO);
}
return getFunctionToReturn(functionsMatchingDTO);
}
private Collection<Function<?>> getFunctionsForDTO(FunctionDTO functionDTO) {
Collection<Function<?>> functionsMatchingDTO = new HashSet<>();
FilterCriterion<Function<?>> functionDTOFilterCriteria = new FunctionMatchesDTOFilterCriterion(functionDTOFactory, functionDTO);
for (FunctionRegistry functionRegistry : functionRegistries) {
for (Function<?> function : functionRegistry.getAllFunctions()) {
if (functionDTOFilterCriteria.matches(function)) {
functionsMatchingDTO.add(function);
}
}
}
return functionsMatchingDTO;
}
private boolean moreThanOneFunctionMatchedDTO(Collection<Function<?>> functionsMatchingDTO) {
return functionsMatchingDTO.size() > 1;
}
private void logThatMoreThanOneFunctionMatchedDTO(FunctionDTO functionDTO, Collection<Function<?>> functionsMatchingDTO) {
LOGGER.log(Level.FINER, "More than on registered function matched the function DTO '" + functionDTO.toString() + "'");
for (Function<?> function : functionsMatchingDTO) {
LOGGER.log(Level.FINEST, "The function '" + function.toString() + "' matched the function DTO '" + functionDTO.toString() + "'");
}
}
private Function<?> getFunctionToReturn(Collection<Function<?>> functionsMatchingDTO) {
return functionsMatchingDTO.isEmpty() ? null : functionsMatchingDTO.iterator().next();
}
}
@@ -1,218 +0,0 @@
package com.sap.sse.datamining.impl.functions;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.sap.sse.datamining.factories.FunctionFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.annotations.Dimension;
import com.sap.sse.datamining.shared.annotations.Statistic;
public class SimpleFunctionRegistry implements FunctionRegistry {
private final FunctionFactory functionFactory;
private final Map<Class<?>, Set<Function<?>>> statistics;
private final Map<Class<?>, Set<Function<?>>> dimensions;
private final Map<Class<?>, Set<Function<?>>> externalFunctions;
private final Collection<Map<Class<?>, Set<Function<?>>>> functionMaps;
public SimpleFunctionRegistry() {
functionFactory = new FunctionFactory();
statistics = new HashMap<>();
dimensions = new HashMap<>();
externalFunctions = new HashMap<>();
functionMaps = new ArrayList<>();
functionMaps.add(statistics);
functionMaps.add(dimensions);
functionMaps.add(externalFunctions);
}
@Override
public void registerAllWithInternalFunctionPolicy(Iterable<Class<?>> internalClassesToScan) {
for (Class<?> internalClass : internalClassesToScan) {
scanInternalClass(internalClass);
}
}
private void scanInternalClass(Class<?> internalClass) {
scanInternalClass(internalClass, new ArrayList<Function<?>>());
}
private void scanInternalClass(Class<?> internalClass, List<Function<?>> previousFunctions) {
for (Method method : internalClass.getMethods()) {
if (isValidDimension(method) || isValidStatistic(method)) {
registerFunction(previousFunctions, method);
continue;
}
if (isConnector(method)) {
handleConnectorMethod(method, previousFunctions);
}
}
}
private void registerFunction(List<Function<?>> previousFunctions, Method method) {
Function<?> function = functionFactory.createMethodWrappingFunction(method);
if (!previousFunctions.isEmpty()) {
function = functionFactory.createCompoundFunction(null, previousFunctions, function);
}
if (function.isDimension()) {
addDimension(function);
} else {
addStatistic(function);
}
}
private void addDimension(Function<?> dimension) {
Class<?> declaringType = dimension.getDeclaringType();
if (!dimensions.containsKey(declaringType)) {
dimensions.put(declaringType, new HashSet<Function<?>>());
}
dimensions.get(declaringType).add(dimension);
}
private void addStatistic(Function<?> statistic) {
Class<?> declaringType = statistic.getDeclaringType();
if (!statistics.containsKey(declaringType)) {
statistics.put(declaringType, new HashSet<Function<?>>());
}
statistics.get(declaringType).add(statistic);
}
private void handleConnectorMethod(Method method, List<Function<?>> previousFunctions) {
Function<?> function = functionFactory.createMethodWrappingFunction(method);
Class<?> returnType = method.getReturnType();
List<Function<?>> previousFunctionsClone = new ArrayList<>(previousFunctions);
previousFunctionsClone.add(function);
scanInternalClass(returnType, previousFunctionsClone);
}
private boolean isValidDimension(Method method) {
return method.getAnnotation(Dimension.class) != null &&
!method.getReturnType().equals(Void.TYPE) &&
method.getParameterTypes().length == 0;
}
private boolean isValidStatistic(Method method) {
return method.getAnnotation(Statistic.class) != null &&
!method.getReturnType().equals(Void.TYPE) &&
method.getParameterTypes().length == 0;
}
private boolean isConnector(Method method) {
return method.getAnnotation(Connector.class) != null &&
!method.getReturnType().equals(Void.TYPE) &&
method.getParameterTypes().length == 0;
}
@Override
public void registerAllWithExternalFunctionPolicy(Iterable<Class<?>> externalClassesToScan) {
for (Class<?> externalClass : externalClassesToScan) {
for (Method method : externalClass.getMethods()) {
if (isValidExternalFunction(method)) {
Function<?> function = functionFactory.createMethodWrappingFunction(method);
addExternalFunction(function);
}
}
}
}
private void addExternalFunction(Function<?> function) {
Class<?> declaringType = function.getDeclaringType();
if (!externalFunctions.containsKey(declaringType)) {
externalFunctions.put(declaringType, new HashSet<Function<?>>());
}
externalFunctions.get(declaringType).add(function);
}
private boolean isValidExternalFunction(Method method) {
return !method.getReturnType().equals(Void.TYPE) && !method.getDeclaringClass().equals(Object.class);
}
@Override
public void unregisterAllFunctionsOf(Iterable<Class<?>> classesToUnregister) {
for (Class<?> classToUnregister : classesToUnregister) {
unregisterAllFunctionsOf(classToUnregister);
}
}
private void unregisterAllFunctionsOf(Class<?> classToUnregister) {
for (Map<Class<?>, Set<Function<?>>> functionMap : functionMaps) {
functionMap.remove(classToUnregister);
}
}
@Override
public Collection<Function<?>> getAllFunctions() {
Collection<Function<?>> allFunctions = new HashSet<>();
for (Map<Class<?>, Set<Function<?>>> functionMap : functionMaps) {
allFunctions.addAll(asSet(functionMap));
}
return allFunctions;
}
@Override
public Collection<Function<?>> getAllFunctionsOf(Class<?> declaringType) {
Collection<Function<?>> allFunctions = new HashSet<>();
for (Map<Class<?>, Set<Function<?>>> functionMap : functionMaps) {
Collection<Function<?>> functions = functionMap.get(declaringType);
if (functions != null) {
allFunctions.addAll(functions);
}
}
return allFunctions;
}
@Override
public Collection<Function<?>> getStatistics() {
return asSet(statistics);
}
@Override
public Collection<Function<?>> getStatisticsOf(Class<?> declaringType) {
return statistics.get(declaringType);
}
@Override
public Collection<Function<?>> getDimensions() {
return asSet(dimensions);
}
@Override
public Collection<Function<?>> getDimensionsOf(Class<?> declaringType) {
return dimensions.get(declaringType);
}
@Override
public Collection<Function<?>> getExternalFunctions() {
return asSet(externalFunctions);
}
@Override
public Collection<Function<?>> getExternalFunctionsOf(Class<?> declaringType) {
return externalFunctions.get(declaringType);
}
private Collection<Function<?>> asSet(Map<?, Set<Function<?>>> map) {
Collection<Function<?>> set = new HashSet<>();
for (Entry<?, Set<Function<?>>> entry : map.entrySet()) {
set.addAll(entry.getValue());
}
return set;
}
}
@@ -0,0 +1,18 @@
package com.sap.sse.datamining.impl.functions;
import com.sap.sse.datamining.functions.ParameterProvider;
public class SimpleParameterProvider implements ParameterProvider {
private final Object[] parameters;
public SimpleParameterProvider(Object[] parameters) {
this.parameters = parameters;
}
@Override
public Object[] getParameters() {
return parameters;
}
}
@@ -53,7 +53,7 @@ public class IsDeclaringTypeFilterCriterion extends AbstractFunctionFilterCriter
return false;
}
public boolean isDeclaringTypeMatching(Function<?> function, Class<?> expectingType) {
private boolean isDeclaringTypeMatching(Function<?> function, Class<?> expectingType) {
return function.getDeclaringType().equals(expectingType);
}
@@ -0,0 +1,16 @@
package com.sap.sse.datamining.impl.functions.criterias;
import java.lang.reflect.Method;
import com.sap.sse.datamining.shared.annotations.Connector;
public class MethodIsValidConnectorFilterCriterion extends AbstractMethodFilterCriterion {
@Override
public boolean matches(Method method) {
return method.getAnnotation(Connector.class) != null &&
!method.getReturnType().equals(Void.TYPE) &&
method.getParameterTypes().length == 0;
}
}
@@ -4,7 +4,7 @@ import java.lang.reflect.Method;
import com.sap.sse.datamining.shared.annotations.Dimension;
public class MethodIsCorrectDimensionFilterCriterion extends AbstractMethodFilterCriterion {
public class MethodIsValidDimensionFilterCriterion extends AbstractMethodFilterCriterion {
@Override
public boolean matches(Method method) {
@@ -2,7 +2,7 @@ package com.sap.sse.datamining.impl.functions.criterias;
import java.lang.reflect.Method;
public class MethodIsCorrectExternalFunctionFilterCriterion extends AbstractMethodFilterCriterion {
public class MethodIsValidExternalFunctionFilterCriterion extends AbstractMethodFilterCriterion {
@Override
public boolean matches(Method method) {
@@ -4,11 +4,12 @@ import java.lang.reflect.Method;
import com.sap.sse.datamining.shared.annotations.Statistic;
public class MethodIsCorrectStatisticFilterCriterion extends AbstractMethodFilterCriterion {
public class MethodIsValidStatisticFilterCriterion extends AbstractMethodFilterCriterion {
@Override
public boolean matches(Method method) {
return method.getAnnotation(Statistic.class) != null;
return method.getAnnotation(Statistic.class) != null &&
!method.getReturnType().equals(Void.TYPE);
}
}
@@ -9,6 +9,7 @@ Require-Bundle: com.google.gwt.osgi;bundle-version="2.7.0",
com.sap.sse.gwt,
com.sap.sse.security.ui,
com.sap.sse.security,
com.sap.sse.common
com.sap.sse.common,
com.sap.sse.security.common
Export-Package: com.sap.sse.gwt.adminconsole
Bundle-ActivationPolicy: lazy
@@ -1,27 +0,0 @@
package com.sap.sse.gwt.adminconsole;
import com.sap.sse.common.impl.NamedImpl;
/**
* Specifies a feature with a name and the role names, one of which is required in order to be allowed
* to see and use the feature.
*
* @author Axel Uhl (D043530)
*
*/
public class AdminConsoleFeatures extends NamedImpl {
private static final long serialVersionUID = 7441608351911944793L;
private String[] enabledRoles;
public AdminConsoleFeatures(String name, String... enabledRoles) {
super(name);
this.enabledRoles = enabledRoles;
}
/**
* If the user has at least one of these roles, he/she is permitted to use this feature.
*/
public String[] getEnabledRoles() {
return enabledRoles;
}
}
@@ -1,8 +1,11 @@
package com.sap.sse.gwt.adminconsole;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.SelectionEvent;
@@ -20,6 +23,9 @@ import com.sap.sse.gwt.client.AbstractEntryPoint;
import com.sap.sse.gwt.client.BuildVersionRetriever;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.panels.VerticalTabLayoutPanel;
import com.sap.sse.security.shared.Permission;
import com.sap.sse.security.shared.PermissionsForRoleProvider;
import com.sap.sse.security.shared.WildcardPermission;
import com.sap.sse.security.ui.client.UserService;
import com.sap.sse.security.ui.client.UserStatusEventHandler;
import com.sap.sse.security.ui.loginpanel.LoginPanel;
@@ -27,29 +33,35 @@ import com.sap.sse.security.ui.loginpanel.LoginPanelCss;
import com.sap.sse.security.ui.shared.UserDTO;
/**
* A panel that can be used to implement an administration console. Widgets can be arranged in vertical and horizontal tabs ("L-shape").
* The top-level element is the vertical tab panel. Widgets may either be added directly as the content of one vertical tab, or a horizontal
* tab panel can be added as the content widget of a vertical tab, in turn holding widgets in horizontal tabs.<p>
* A panel that can be used to implement an administration console. Widgets can be arranged in vertical and horizontal
* tabs ("L-shape"). The top-level element is the vertical tab panel. Widgets may either be added directly as the
* content of one vertical tab, or a horizontal tab panel can be added as the content widget of a vertical tab, in turn
* holding widgets in horizontal tabs.
* <p>
*
* After constructing an instance of this class, there are three ways for adding widgets:<ul>
* <li>{@link #addToVerticalTabPanel(RefreshableAdminConsolePanel, String, AdminConsoleFeatures)} adds a widget as a content element
* of a vertical tab</li>
* <li>{@link #addVerticalTab(String, String, AdminConsoleFeatures)} creates a horizontal tab panel and adds it as a content element of
* a vertical tab</li>
* <li>{@link #addToTabPanel(TabLayoutPanel, RefreshableAdminConsolePanel, String, AdminConsoleFeatures)} adds a widget as a content element
* of a horizontal tab</li>
* After constructing an instance of this class, there are three ways for adding widgets:
* <ul>
* <li>{@link #addToVerticalTabPanel(RefreshableAdminConsolePanel, String, Permission)} adds a widget as a content
* element of a vertical tab</li>
* <li>{@link #addVerticalTab(String, String, Permission)} creates a horizontal tab panel and adds it as a content
* element of a vertical tab</li>
* <li>{@link #addToTabPanel(TabLayoutPanel, RefreshableAdminConsolePanel, String, Permission)} adds a widget as a
* content element of a horizontal tab</li>
* </ul>
*
* Widgets to be added need to be wrapped as {@link RefreshableAdminConsolePanel} holding the widget and receiving the refresh call when
* the widget is shown because the user has selected the tab. If the component doesn't require any refresh logic, an instance of
* {@link DefaultRefreshableAdminConsolePanel} can be used to wrap the widget.<p>
* Widgets to be added need to be wrapped as {@link RefreshableAdminConsolePanel} holding the widget and receiving the
* refresh call when the widget is shown because the user has selected the tab. If the component doesn't require any
* refresh logic, an instance of {@link DefaultRefreshableAdminConsolePanel} can be used to wrap the widget.
* <p>
*
* After the widgets have been added, {@link #initUI()} must be called to assemble all tabs for the current user's roles. The {@link #initUI()}
* method must be called each time more widgets have been added dynamically.<p>
* After the widgets have been added, {@link #initUI()} must be called to assemble all tabs for the current user's
* roles. The {@link #initUI()} method must be called each time more widgets have been added dynamically.
* <p>
*
* For each widget added, a {@link AdminConsoleFeatures feature} needs to be specified. The feature tells the roles of which the logged-in user
* needs to have at least one in order to see the tab. When the user changes or has his/her roles updated the set of tabs visible will be
* adjusted according to the new roles available for the logged-in user.<p>
* For each widget added, a {@link Permission set of permissions} needs to be specified, any of which is sufficient to
* get to see the widget. When the user changes or has his/her permissions updated the set of tabs visible will be
* adjusted according to the new roles available for the logged-in user.
* <p>
*
* @author Axel Uhl (D043530)
*
@@ -59,10 +71,14 @@ public class AdminConsolePanel extends DockLayoutPanel {
/**
* The administration console's UI depends on the user's roles. When the roles change then so shall the display of
* tabs. {@link AdminConsoleFeatures} list the roles to which they are made available. This map keeps track of the
* dependencies and allows the UI to adjust to role changes.
* tabs. Required {@link Permission}s tell when they are to be made available based on the user's actual
* permissions. This map keeps track of the dependencies and allows the UI to adjust to role changes.<p>
*
* The values are the permissions, at least one of which is required from the user to be able to see the widget.
*/
private final LinkedHashMap<Triple<VerticalOrHorizontalTabLayoutPanel, Widget, String>, AdminConsoleFeatures> roleSpecificTabs;
private final LinkedHashSet<Triple<VerticalOrHorizontalTabLayoutPanel, Widget, String>> roleSpecificTabs;
private final Map<Widget, Set<Permission>> permissionsAnyOfWhichIsRequiredToSeeWidget;
private final SelectionHandler<Integer> tabSelectionHandler;
@@ -79,6 +95,8 @@ public class AdminConsolePanel extends DockLayoutPanel {
*/
private final Map<Widget, RefreshableAdminConsolePanel> panelsByWidget;
private final PermissionsForRoleProvider permissionsForRoleProvider;
/**
* Generic selection handler that forwards selected tabs to a refresher that ensures that data gets reloaded. If
* you add a new tab then make sure to have a look at #refreshDataFor(Widget widget) to ensure that upon
@@ -130,12 +148,14 @@ public class AdminConsolePanel extends DockLayoutPanel {
}
}
public AdminConsolePanel(UserService userService, BuildVersionRetriever buildVersionRetriever,
String releaseNotesAnchorLabel, String releaseNotesURL,
ErrorReporter errorReporter, LoginPanelCss loginPanelCss) {
public AdminConsolePanel(UserService userService, PermissionsForRoleProvider permissionsForRoleProvider,
BuildVersionRetriever buildVersionRetriever, String releaseNotesAnchorLabel,
String releaseNotesURL, ErrorReporter errorReporter, LoginPanelCss loginPanelCss) {
super(Unit.EM);
this.permissionsForRoleProvider = permissionsForRoleProvider;
this.permissionsAnyOfWhichIsRequiredToSeeWidget = new HashMap<>();
this.userService = userService;
roleSpecificTabs = new LinkedHashMap<>();
roleSpecificTabs = new LinkedHashSet<>();
this.panelsByWidget = new HashMap<>();
getUserService().addUserStatusEventHandler(new UserStatusEventHandler() {
@Override
@@ -158,6 +178,11 @@ public class AdminConsolePanel extends DockLayoutPanel {
public void remove(Widget child) {
topLevelTabPanel.remove(child);
}
@Override
public Widget getPanel() {
return topLevelTabPanel;
}
};
final DockPanel informationPanel = new DockPanel();
informationPanel.setSize("100%", "95%");
@@ -197,6 +222,8 @@ public class AdminConsolePanel extends DockLayoutPanel {
void add(Widget child, String text, boolean asHtml);
void remove(Widget child);
Widget getPanel();
}
/**
@@ -205,12 +232,12 @@ public class AdminConsolePanel extends DockLayoutPanel {
* @return the horizontal tab panel that was created and added to the top-level vertical tab panel; the panel returned can be specified
* as argument to {@link #addToTabPanel(TabLayoutPanel, Widget, String, AdminConsoleFeatures)}.
*/
public TabLayoutPanel addVerticalTab(String tabTitle, String tabDebugId, AdminConsoleFeatures feature) {
public TabLayoutPanel addVerticalTab(String tabTitle, String tabDebugId, Permission... requiresAnyOfThesePermissions) {
final TabLayoutPanel newTabPanel = new TabLayoutPanel(2.5, Unit.EM);
AbstractEntryPoint.setTabPanelSize(newTabPanel, "100%", "100%");
newTabPanel.addSelectionHandler(tabSelectionHandler);
newTabPanel.ensureDebugId(tabDebugId);
remeberWidgetLocationAndFeature(topLevelTabPanelWrapper, newTabPanel, tabTitle, feature);
remeberWidgetLocationAndPermissions(topLevelTabPanelWrapper, newTabPanel, tabTitle, requiresAnyOfThesePermissions);
return newTabPanel;
}
@@ -219,8 +246,8 @@ public class AdminConsolePanel extends DockLayoutPanel {
* This is useful for panels that form a top-level category of its own but don't require multiple panels to represent this
* top-level category.
*/
public void addToVerticalTabPanel(final RefreshableAdminConsolePanel panelToAdd, String tabTitle, AdminConsoleFeatures feature) {
addToTabPanel(topLevelTabPanelWrapper, panelToAdd, tabTitle, feature);
public void addToVerticalTabPanel(final RefreshableAdminConsolePanel panelToAdd, String tabTitle, Permission... requiresAnyOfThesePermissions) {
addToTabPanel(topLevelTabPanelWrapper, panelToAdd, tabTitle, requiresAnyOfThesePermissions);
}
private ScrollPanel wrapInScrollPanel(Widget panelToAdd) {
@@ -230,7 +257,7 @@ public class AdminConsolePanel extends DockLayoutPanel {
return scrollPanel;
}
public void addToTabPanel(final TabLayoutPanel tabPanel, RefreshableAdminConsolePanel panelToAdd, String tabTitle, AdminConsoleFeatures feature) {
public void addToTabPanel(final TabLayoutPanel tabPanel, RefreshableAdminConsolePanel panelToAdd, String tabTitle, Permission... requiresAnyOfThesePermissions) {
VerticalOrHorizontalTabLayoutPanel wrapper = new VerticalOrHorizontalTabLayoutPanel() {
@Override
public void add(Widget child, String text, boolean asHtml) {
@@ -242,8 +269,13 @@ public class AdminConsolePanel extends DockLayoutPanel {
public void remove(Widget child) {
tabPanel.remove(child);
}
@Override
public Widget getPanel() {
return tabPanel;
}
};
addToTabPanel(wrapper, panelToAdd, tabTitle, feature);
addToTabPanel(wrapper, panelToAdd, tabTitle, requiresAnyOfThesePermissions);
}
/**
@@ -251,18 +283,34 @@ public class AdminConsolePanel extends DockLayoutPanel {
* a hook so that when the <code>panelToAdd</code>'s widget is selected then the {@link RefreshableAdminConsolePanel#refreshAfterBecomingVisible()}
* method can be called.
*/
private void addToTabPanel(VerticalOrHorizontalTabLayoutPanel tabPanel, RefreshableAdminConsolePanel panelToAdd, String tabTitle, AdminConsoleFeatures feature) {
remeberWidgetLocationAndFeature(tabPanel, wrapInScrollPanel(panelToAdd.getWidget()), tabTitle, feature);
private void addToTabPanel(VerticalOrHorizontalTabLayoutPanel tabPanel, RefreshableAdminConsolePanel panelToAdd, String tabTitle, Permission... requiresAnyOfThesePermissions) {
remeberWidgetLocationAndPermissions(tabPanel, wrapInScrollPanel(panelToAdd.getWidget()), tabTitle, requiresAnyOfThesePermissions);
panelsByWidget.put(panelToAdd.getWidget(), panelToAdd);
}
/**
* Remembers the tab panel in which the <code>widgetToAdd</code> is to be displayed and for which feature.
* Remembers the tab panel in which the <code>widgetToAdd</code> is to be displayed and which permissions are
* sufficient to see the widget. For the <code>tabPanel</code>, all permissions provided here are added to the tab
* panel's permissions so that the user will see the tab panel as soon as the user may see any of the widgets inside
* that panel
*
* @param requiresAnyOfThesePermissions
* zero or more permissions; if no permissions are provided, the user will never be able to see the
* widget. Otherwise, if any of these permissions implies any of the permissions the user has, the user
* will be shown the widget. In particular, a "*" wildcard permission will show the widget to all users,
* regardless their actual permissions.
*/
private void remeberWidgetLocationAndFeature(VerticalOrHorizontalTabLayoutPanel tabPanel, Widget widgetToAdd,
String tabTitle, AdminConsoleFeatures feature) {
roleSpecificTabs.put(new Triple<VerticalOrHorizontalTabLayoutPanel, Widget, String>(tabPanel,
widgetToAdd, tabTitle), feature);
private void remeberWidgetLocationAndPermissions(VerticalOrHorizontalTabLayoutPanel tabPanel, Widget widgetToAdd,
String tabTitle, Permission... requiresAnyOfThesePermissions) {
roleSpecificTabs.add(new Triple<VerticalOrHorizontalTabLayoutPanel, Widget, String>(tabPanel, widgetToAdd, tabTitle));
final HashSet<Permission> permissionsAsSet = new HashSet<>(Arrays.asList(requiresAnyOfThesePermissions));
permissionsAnyOfWhichIsRequiredToSeeWidget.put(widgetToAdd, permissionsAsSet);
Set<Permission> permissionsForTabPanel = permissionsAnyOfWhichIsRequiredToSeeWidget.get(tabPanel.getPanel());
if (permissionsForTabPanel == null) {
permissionsForTabPanel = new HashSet<>();
permissionsAnyOfWhichIsRequiredToSeeWidget.put(tabPanel.getPanel(), permissionsForTabPanel);
}
permissionsForTabPanel.addAll(permissionsAsSet);
}
/**
@@ -270,26 +318,37 @@ public class AdminConsolePanel extends DockLayoutPanel {
* to see which tabs. See {@link #roleSpecificTabs}.
*/
private void updateTabDisplayForCurrentUser(UserDTO user) {
for (Map.Entry<Triple<VerticalOrHorizontalTabLayoutPanel, Widget, String>, AdminConsoleFeatures> e : roleSpecificTabs
.entrySet()) {
final Widget panelToAdd = e.getKey().getB();
if (user != null && isUserInRole(e.getValue().getEnabledRoles())) {
e.getKey().getA().add(panelToAdd, e.getKey().getC(), /* asHtml */false);
for (Triple<VerticalOrHorizontalTabLayoutPanel, Widget, String> e : roleSpecificTabs) {
final Widget widgetToAdd = e.getB();
if (user != null && userHasPermissionsToSeeWidget(user, e.getB())) {
e.getA().add(widgetToAdd, e.getC(), /* asHtml */false);
} else {
e.getKey().getA().remove(panelToAdd);
e.getA().remove(widgetToAdd);
}
}
}
private boolean isUserInRole(String... roles) {
boolean result = false;
UserDTO user = getUserService().getCurrentUser();
for (String enabledRole : roles) {
if (user.hasRole(enabledRole)) {
result = true;
break;
/**
* A user is defined to have permission to see a widget if the widget's required permissions imply any of the permissions the
* user has. This may at first seem the wrong way around. However, the problem is that a widget cannot express a general permission
* that is implied by any detailed permissions. Wildcard permissions don't work this way. Instead, a wildcard permission implies
* detailed permissions. This way, if the widget requires, say, "event:*:*" (or "event" for short), this permission implies
* all more detailed event permissions such as "event:write:9456192873". Therefore, the permissions provided for widgets
* must imply a permission the user has in order for the user to see the tab. More detailed permissions checks can then be
* applied at a more detailed level of the UI and, of course, in the back end. Additionally, if any of the user's permissions
* implies the required permission (e.g., the user having "*" as the administrator's permission), permission to see the widget
* is also implied.
*/
private boolean userHasPermissionsToSeeWidget(UserDTO user, Widget widget) {
for (Permission requiredStringPermission : permissionsAnyOfWhichIsRequiredToSeeWidget.get(widget)) {
WildcardPermission requiredPermission = new WildcardPermission(requiredStringPermission.getStringPermission());
for (String userStringPermission : user.getAllPermissions(permissionsForRoleProvider)) {
WildcardPermission userPermission = new WildcardPermission(userStringPermission);
if (requiredPermission.implies(userPermission) || userPermission.implies(requiredPermission)) {
return true;
}
}
}
return result;
return false;
}
}
@@ -1,15 +1,15 @@
package com.sap.sse.security.shared;
public enum DefaultPermissions {
public enum DefaultPermissions implements Permission {
ALL_EVENTS("event:*");
private DefaultPermissions(String permissionname) {
this.permissionname = permissionname;
private DefaultPermissions(String stringPermission) {
this.stringPermission = stringPermission;
}
public String getPermissionname() {
return permissionname;
public String getStringPermission() {
return stringPermission;
}
private final String permissionname;
private final String stringPermission;
}
@@ -1,12 +1,13 @@
package com.sap.sse.security.shared;
public enum DefaultRoles {
public enum DefaultRoles implements Role {
ADMIN("admin");
private DefaultRoles(String rolename) {
this.rolename = rolename;
}
@Override
public String getRolename() {
return rolename;
}
@@ -0,0 +1,9 @@
package com.sap.sse.security.shared;
public interface Permission {
String name();
int ordinal();
String getStringPermission();
}
@@ -0,0 +1,13 @@
package com.sap.sse.security.shared;
/**
* Roles can imply permissions. For example, an application may define that the role "admin" can do everything by
* returning a "*" permission from {@link #getPermissions(String)}.
*
* @author Axel Uhl (D043530)
*
*/
public interface PermissionsForRoleProvider {
Iterable<String> getPermissions(String role);
}
@@ -0,0 +1,9 @@
package com.sap.sse.security.shared;
public interface Role {
String getRolename();
String name();
int ordinal();
}
Loaded 100 of 135 files, more files were not shown because too many files have changed in this diff. Show more