mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-08 20:12:23 +00:00
Merge branch 'master' into bug2842
This commit is contained in:
commit
b1beb08497
169 files changed
+295
-267
No files matched your search
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -32,7 +32,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -32,7 +32,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -32,7 +32,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -32,7 +32,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
|
||||
+2
-2
@@ -56,7 +56,7 @@ public enum BoatClassMasterdata {
|
||||
GC_32 ("GC 32", false, 10.0, 6.00, BoatHullType.CATAMARAN, true, "GC32", "GC-32"),
|
||||
GP_26 ("GP 26", true, 7.90, 2.55, BoatHullType.MONOHULL, true, "GP26", "GP-26"),
|
||||
HOBIE_16 ("Hobie 16", true, 5.05, 2.41, BoatHullType.CATAMARAN, false, "H16"),
|
||||
H_BOAT ("H-Boat", true, 8.28, 2.18, BoatHullType.MONOHULL, true, "HB", "H-Boat"),
|
||||
H_BOAT ("H-Boat", true, 8.28, 2.18, BoatHullType.MONOHULL, true, "HB", "H-Boot"),
|
||||
HANSA_303 ("Hansa 303", false, 3.03, 1.35, BoatHullType.MONOHULL, false, "Hansa-303", "Hansa303"),
|
||||
HOBIE_TIGER ("Hobie Tiger", true, 5.51, 2.60, BoatHullType.CATAMARAN, true),
|
||||
HOBIE_WILD_CAT ("Hobie Wild Cat", true, 5.49, 2.59, BoatHullType.CATAMARAN, true, "Hobie Wild Cat F18"),
|
||||
@@ -108,7 +108,7 @@ public enum BoatClassMasterdata {
|
||||
SPLASH_BLUE ("Splash Blue", true, 3.50, 1.50, BoatHullType.MONOHULL, false, "Splash_Blue"),
|
||||
SPLASH_RED ("Splash Red", true, 3.50, 1.50, BoatHullType.MONOHULL, false, "Splash_Red"),
|
||||
SPLASH_GREEN ("Splash Green", true, 3.50, 1.50, BoatHullType.MONOHULL, false, "Splash_Green"),
|
||||
STAR ("Star", true, 6.92, 1.74, BoatHullType.MONOHULL, false, "STR"),
|
||||
STAR ("Star", true, 6.92, 1.74, BoatHullType.MONOHULL, false, "STR", "STARBOOT", "STARBOAT"),
|
||||
STREAMLINE ("Streamline", true, 7.15, 2.55, BoatHullType.MONOHULL, true),
|
||||
SUNBEAM_22 ("Sunbeam 22", true, 6.70, 2.15, BoatHullType.MONOHULL, true, "Sunbeam 22.1"),
|
||||
SWAN_45 ("Swan 45", true, 13.83, 3.91, BoatHullType.MONOHULL, true, "Swan", "Swan-45"),
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
+8
@@ -46,6 +46,14 @@ public class CompetitorImpl implements DynamicCompetitor {
|
||||
this.searchTag = searchTag;
|
||||
this.listeners = new HashSet<CompetitorChangeListener>();
|
||||
}
|
||||
|
||||
private Object writeReplace() {
|
||||
if (CompetitorSerializationCustomizer.getCurrentCustomizer().removalOfPersonalDataNecessary(this)) {
|
||||
return new CompetitorImpl(id, name, shortName, color, /* email */ null, flagImage, team, timeOnTimeFactor,
|
||||
timeOnDistanceAllowancePerNauticalMile, searchTag);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
ois.defaultReadObject();
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
|
||||
public interface CompetitorSerializationCustomizer {
|
||||
|
||||
boolean removalOfPersonalDataNecessary(Competitor competitor);
|
||||
|
||||
public static final ThreadLocal<CompetitorSerializationCustomizer> threadLocalCustomizer = new ThreadLocal<>();
|
||||
|
||||
public static final CompetitorSerializationCustomizer defaultCustomizer = new CompetitorSerializationCustomizer() {
|
||||
@Override
|
||||
public boolean removalOfPersonalDataNecessary(Competitor competitor) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public static CompetitorSerializationCustomizer getCurrentCustomizer() {
|
||||
CompetitorSerializationCustomizer result = threadLocalCustomizer.get();
|
||||
if (result == null) {
|
||||
result = defaultCustomizer;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void doWithCustomizer(CompetitorSerializationCustomizer customizer, Runnable action) {
|
||||
threadLocalCustomizer.set(customizer);
|
||||
try {
|
||||
action.run();
|
||||
} finally {
|
||||
threadLocalCustomizer.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T doWithCustomizer(CompetitorSerializationCustomizer customizer, Supplier<T> action) {
|
||||
threadLocalCustomizer.set(customizer);
|
||||
try {
|
||||
return action.get();
|
||||
} finally {
|
||||
threadLocalCustomizer.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+9
@@ -26,6 +26,15 @@ public class CompetitorWithBoatImpl extends CompetitorImpl implements DynamicCom
|
||||
competitor.getTimeOnDistanceAllowancePerNauticalMile(), competitor.getSearchTag(), boat);
|
||||
}
|
||||
|
||||
private Object writeReplace() {
|
||||
if (CompetitorSerializationCustomizer.getCurrentCustomizer().removalOfPersonalDataNecessary(this)) {
|
||||
return new CompetitorWithBoatImpl(getId(), getName(), getShortName(), getColor(), /* email */ null,
|
||||
getFlagImage(), getTeam(), getTimeOnTimeFactor(), getTimeOnDistanceAllowancePerNauticalMile(),
|
||||
getSearchTag(), boat);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Competitor resolve(SharedDomainFactory domainFactory) {
|
||||
final Competitor result;
|
||||
if (!hasBoat()) {
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
+20
-2
@@ -27,8 +27,10 @@ import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.InvalidatesLeaderboardCache;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
@@ -585,8 +587,24 @@ public abstract class AbstractLeaderboardWithCache implements Leaderboard {
|
||||
LeaderboardEntryDTO entryDTO = new LeaderboardEntryDTO();
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace(competitor);
|
||||
entryDTO.race = trackedRace == null ? null : trackedRace.getRaceIdentifier();
|
||||
// TODO bug2822: Should this rather come from raceColumn.getBoatOfCompetitor() ?
|
||||
entryDTO.boat = trackedRace == null ? null : baseDomainFactory.convertToBoatDTO(trackedRace.getBoatOfCompetitor(competitor));
|
||||
Boat boat;
|
||||
if (trackedRace != null) {
|
||||
boat = trackedRace.getBoatOfCompetitor(competitor);
|
||||
} else {
|
||||
// check if it's a CompetitorWithBoat:
|
||||
if (competitor.hasBoat()) {
|
||||
boat = ((CompetitorWithBoat) competitor).getBoat();
|
||||
} else {
|
||||
final Fleet fleetOfCompetitor = raceColumn.getFleetOfCompetitor(competitor);
|
||||
if (fleetOfCompetitor != null) {
|
||||
final Map<Competitor, Boat> competitorsAndTheirBoats = raceColumn.getCompetitorsRegisteredInRacelog(fleetOfCompetitor);
|
||||
boat = competitorsAndTheirBoats.get(competitor);
|
||||
} else {
|
||||
boat = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
entryDTO.boat = boat == null ? null : baseDomainFactory.convertToBoatDTO(boat);
|
||||
entryDTO.totalPoints = entry.getTotalPoints();
|
||||
if (fillTotalPointsUncorrected) {
|
||||
entryDTO.totalPointsUncorrected = entry.getTotalPointsUncorrected();
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -32,7 +32,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -32,7 +32,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
<nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
|
||||
|
||||
+1
-2
@@ -452,8 +452,7 @@ public class StructureImportManagementPanel extends SimplePanel implements Regat
|
||||
return result;
|
||||
}
|
||||
|
||||
private void createRegattas(final Iterable<RegattaDTO> selectedOriginalRegattasFromXRR,
|
||||
EventDTO newEvent) {
|
||||
private void createRegattas(final Iterable<RegattaDTO> selectedOriginalRegattasFromXRR, EventDTO newEvent) {
|
||||
eventManagementPanel.fillEvents();
|
||||
final Set<RegattaDTO> regattaConfigurationsToCreate = new HashSet<>();
|
||||
for (RegattaDTO originalRegattaFromXRR : selectedOriginalRegattasFromXRR) {
|
||||
|
||||
+6
-8
@@ -14,13 +14,11 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import com.sap.sailing.server.interfaces.RacingEventService;
|
||||
import com.sap.sse.ServerInfo;
|
||||
import com.sap.sse.common.settings.SerializableSettings;
|
||||
import com.sap.sse.datamining.DataMiningServer;
|
||||
import com.sap.sse.datamining.Query;
|
||||
@@ -51,7 +49,6 @@ import com.sap.sse.datamining.shared.impl.dto.ReducedDimensionsDTO;
|
||||
import com.sap.sse.datamining.shared.impl.dto.StoredDataMiningQueryDTOImpl;
|
||||
import com.sap.sse.datamining.ui.client.DataMiningService;
|
||||
import com.sap.sse.gwt.server.ProxiedRemoteServiceServlet;
|
||||
import com.sap.sse.gwt.client.ServerInfoDTO;
|
||||
import com.sap.sse.i18n.ResourceBundleStringMessages;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
|
||||
@@ -74,7 +71,7 @@ public class DataMiningServiceImpl extends ProxiedRemoteServiceServlet implement
|
||||
dataMiningServerTracker = createAndOpenDataMiningServerTracker(context);
|
||||
securityServiceTracker = ServiceTrackerFactory.createAndOpen(context, SecurityService.class);
|
||||
|
||||
storedDataMiningQueryPersistor = new StoredDataMiningQueryPersisterImpl(securityServiceTracker.getService());
|
||||
storedDataMiningQueryPersistor = new StoredDataMiningQueryPersisterImpl(getSecurityService());
|
||||
dtoFactory = new DataMiningDTOFactory();
|
||||
}
|
||||
|
||||
@@ -89,6 +86,10 @@ public class DataMiningServiceImpl extends ProxiedRemoteServiceServlet implement
|
||||
private DataMiningServer getDataMiningServer() {
|
||||
return dataMiningServerTracker.getService();
|
||||
}
|
||||
|
||||
private SecurityService getSecurityService() {
|
||||
return securityServiceTracker.getService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getComponentsChangedTimepoint() {
|
||||
@@ -116,10 +117,7 @@ public class DataMiningServiceImpl extends ProxiedRemoteServiceServlet implement
|
||||
* if permission does not exist
|
||||
*/
|
||||
private void checkDataMiningPermission() {
|
||||
// TODO: should be moved to one place (not the ServerInfoDTO) -> could not be moved to ServerInfo, since
|
||||
// sse.security is not available
|
||||
SecurityUtils.getSubject().checkPermission(new ServerInfoDTO(ServerInfo.getName(), ServerInfo.getBuildVersion())
|
||||
.getIdentifier().getStringPermission(ServerActions.DATA_MINING));
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.DATA_MINING);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+22
-33
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.gwt.ui.server;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -4290,9 +4291,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
|
||||
@Override
|
||||
public ReplicationStateDTO getReplicaInfo() {
|
||||
SecurityUtils.getSubject().checkPermission(
|
||||
SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(ServerActions.READ_REPLICATOR,
|
||||
new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.READ_REPLICATOR);
|
||||
ReplicationService service = getReplicationService();
|
||||
Set<ReplicaDTO> replicaDTOs = new HashSet<ReplicaDTO>();
|
||||
for (ReplicaDescriptor replicaDescriptor : service.getReplicaInfo()) {
|
||||
@@ -4333,9 +4332,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
public void startReplicatingFromMaster(String messagingHost, String masterHostName, String exchangeName,
|
||||
int servletPort, int messagingPort, String usernameOrNull, String passwordOrNull)
|
||||
throws IOException, ClassNotFoundException, InterruptedException {
|
||||
SecurityUtils.getSubject()
|
||||
.checkPermission(SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(
|
||||
ServerActions.START_REPLICATION, new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.START_REPLICATION);
|
||||
// The queue name must always be the same for this server. In order to achieve
|
||||
// this we're using the unique server identifier
|
||||
final ReplicationService replicationService = getReplicationService();
|
||||
@@ -5126,9 +5123,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
|
||||
@Override
|
||||
public void updateServerConfiguration(ServerConfigurationDTO serverConfiguration) {
|
||||
SecurityUtils.getSubject()
|
||||
.checkPermission(SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(
|
||||
ServerActions.CONFIGURE_LOCAL_SERVER, new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.CONFIGURE_LOCAL_SERVER);
|
||||
getService().apply(new UpdateServerConfiguration(
|
||||
new SailingServerConfigurationImpl(serverConfiguration.isStandaloneServer())));
|
||||
if (serverConfiguration.isSelfService() != null) {
|
||||
@@ -5427,9 +5422,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
List<RegattaDTO> regattaDTOs = new ArrayList<RegattaDTO>();
|
||||
Iterable<Regatta> regattas = structureImporter.getRegattas(parsedEvent);
|
||||
for (Regatta regatta : regattas) {
|
||||
if (getSecurityService().hasCurrentUserReadPermission(regatta)) {
|
||||
regattaDTOs.add(convertToRegattaDTO(regatta));
|
||||
}
|
||||
regattaDTOs.add(convertToRegattaDTO(regatta));
|
||||
}
|
||||
return regattaDTOs;
|
||||
}
|
||||
@@ -5623,9 +5616,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
|
||||
@Override
|
||||
public void stopReplicatingFromMaster() {
|
||||
SecurityUtils.getSubject()
|
||||
.checkPermission(SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(
|
||||
ServerActions.START_REPLICATION, new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.START_REPLICATION);
|
||||
try {
|
||||
getReplicationService().stopToReplicateFromMaster();
|
||||
} catch (IOException e) {
|
||||
@@ -5636,9 +5627,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
|
||||
@Override
|
||||
public void stopAllReplicas() {
|
||||
SecurityUtils.getSubject()
|
||||
.checkPermission(SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(
|
||||
ServerActions.REPLICATE, new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.REPLICATE);
|
||||
try {
|
||||
getReplicationService().stopAllReplicas();
|
||||
} catch (IOException e) {
|
||||
@@ -5649,9 +5638,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
|
||||
@Override
|
||||
public void stopSingleReplicaInstance(String identifier) {
|
||||
SecurityUtils.getSubject()
|
||||
.checkPermission(SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(
|
||||
ServerActions.REPLICATE, new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.REPLICATE);
|
||||
UUID uuid = UUID.fromString(identifier);
|
||||
try {
|
||||
getReplicationService().unregisterReplica(uuid);
|
||||
@@ -5767,18 +5754,12 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
public UUID importMasterData(final String urlAsString, final String[] groupNames, final boolean override,
|
||||
final boolean compress, final boolean exportWind, final boolean exportDeviceConfigurations,
|
||||
String targetServerUsername, String targetServerPassword) {
|
||||
// FIXME should the targetserver also check this?
|
||||
SecurityUtils.getSubject().isPermitted(SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(
|
||||
ServerActions.CAN_IMPORT_MASTERDATA, new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
|
||||
getSecurityService().checkCurrentUserServerPermission(ServerActions.CAN_IMPORT_MASTERDATA);
|
||||
String token = RemoteServerUtil.resolveBearerTokenForRemoteServer(urlAsString, targetServerUsername, targetServerPassword);
|
||||
|
||||
final UUID importOperationId = UUID.randomUUID();
|
||||
getService().createOrUpdateDataImportProgressWithReplication(importOperationId, 0.0, DataImportSubProgress.INIT,
|
||||
0.0);
|
||||
getService().createOrUpdateDataImportProgressWithReplication(importOperationId, 0.0, DataImportSubProgress.INIT, 0.0);
|
||||
final User user = getSecurityService().getCurrentUser();
|
||||
final UserGroup tenant = getSecurityService().getDefaultTenantForCurrentUser();
|
||||
|
||||
// Create a progress indicator for as long as the server gets data from the other server.
|
||||
// As soon as the server starts the import operation, a progress object will be built on every server
|
||||
Runnable masterDataImportTask = new Runnable() {
|
||||
@@ -5813,13 +5794,21 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
inputStream = new TimeoutExtendingInputStream(connection.getInputStream(), connection);
|
||||
}
|
||||
final MasterDataImporter importer = new MasterDataImporter(baseDomainFactory, getService(),
|
||||
user,
|
||||
tenant);
|
||||
user, tenant);
|
||||
importer.importFromStream(inputStream, importOperationId, override);
|
||||
} catch (Throwable e) {
|
||||
// do not assume that RuntimeException is logged properly
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
getService().setDataImportFailedWithReplication(importOperationId, e.getMessage()
|
||||
String message = e.getMessage();
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
// try to obtain an error message from the connection's error stream:
|
||||
try {
|
||||
message = new BufferedReader(new InputStreamReader(((HttpURLConnection) connection).getErrorStream())).readLine();
|
||||
} catch (Exception exceptionTryingToReadErrorStream) {
|
||||
// in this case we just stay with the exception's message
|
||||
}
|
||||
}
|
||||
logger.log(Level.SEVERE, message, e);
|
||||
getService().setDataImportFailedWithReplication(importOperationId, message
|
||||
+ "\n\nHave you checked if the"
|
||||
+ " versions (commit-wise) of the importing and exporting servers are compatible with each other? "
|
||||
+ "If the error still occurs, when both servers are running the same version, please report the problem.");
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -32,7 +32,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature>
|
||||
</natures>
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -23,6 +23,5 @@
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
+98
-48
@@ -23,19 +23,25 @@ import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.StreamingOutput;
|
||||
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorSerializationCustomizer;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.masterdataimport.TopLevelMasterData;
|
||||
import com.sap.sailing.server.gateway.jaxrs.AbstractSailingServerResource;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.PublicReadableActions;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
|
||||
@Path("/v1/masterdata/leaderboardgroups")
|
||||
@@ -50,9 +56,7 @@ public class MasterDataResource extends AbstractSailingServerResource {
|
||||
throws UnsupportedEncodingException {
|
||||
final SecurityService securityService = getSecurityService();
|
||||
User user = securityService.getCurrentUser();
|
||||
if (user == null) {
|
||||
return Response.status(Status.FORBIDDEN).build();
|
||||
}
|
||||
securityService.checkCurrentUserServerPermission(ServerActions.CAN_EXPORT_MASTERDATA);
|
||||
final long startTime = System.currentTimeMillis();
|
||||
logger.info("Masterdataexport has started; requesting user: "+user);
|
||||
if (compress == null) {
|
||||
@@ -66,33 +70,59 @@ public class MasterDataResource extends AbstractSailingServerResource {
|
||||
}
|
||||
logger.info(String.format("Masterdataexport gzip compression is turned %s", compress ? "on" : "off"));
|
||||
Map<String, LeaderboardGroup> allLeaderboardGroups = getService().getLeaderboardGroups();
|
||||
|
||||
Set<LeaderboardGroup> groupsToExport = new HashSet<LeaderboardGroup>();
|
||||
|
||||
if (requestedLeaderboardGroups.isEmpty()) {
|
||||
// add all visible
|
||||
// Add all visible LeaderboardGroups.
|
||||
// The request will not fail due to missing LeaderboardGroup READ permissions.
|
||||
for (LeaderboardGroup group : allLeaderboardGroups.values()) {
|
||||
if (securityService.hasCurrentUserReadPermission(group)) {
|
||||
groupsToExport.add(group);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// add all requested, that are visible
|
||||
// Add all requested LeaderboardGroups.
|
||||
// The request will fail due to missing LeaderboardGroup READ permissions.
|
||||
for (String name : requestedLeaderboardGroups) {
|
||||
LeaderboardGroup group = allLeaderboardGroups.get(name);
|
||||
if (group != null) {
|
||||
if (securityService.hasCurrentUserReadPermission(group)) {
|
||||
groupsToExport.add(group);
|
||||
if (!securityService.hasCurrentUserReadPermission(group)) {
|
||||
throw new AuthorizationException("No permission to read leaderboard group '" + name + "'");
|
||||
}
|
||||
groupsToExport.add(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
final List<Serializable> competitorIds = new ArrayList<Serializable>();
|
||||
for (LeaderboardGroup lg : groupsToExport) {
|
||||
for (Leaderboard leaderboard : lg.getLeaderboards()) {
|
||||
if (securityService.hasCurrentUserReadPermission(leaderboard)) {
|
||||
for (Competitor competitor : leaderboard.getAllCompetitors()) {
|
||||
competitorIds.add(competitor.getId());
|
||||
// All Leaderboards/Regattas contained in the LeaderboardGroup need to be visible
|
||||
// to ensure consistency during import. A partial/pruned import is not intended to take place.
|
||||
if (!securityService.hasCurrentUserReadPermission(leaderboard)
|
||||
|| ((leaderboard instanceof RegattaLeaderboard) && !securityService
|
||||
.hasCurrentUserReadPermission(((RegattaLeaderboard) leaderboard).getRegatta()))) {
|
||||
throw new AuthorizationException(
|
||||
"No permission to read all leaderboards and regattas of leaderboard group '" + lg.getName()
|
||||
+ "'");
|
||||
}
|
||||
for (Competitor competitor : leaderboard.getAllCompetitors()) {
|
||||
// All competitors reachable by Leaderboards contained in a LeaderboardGroup
|
||||
// need to be readable (READ or READ_PUBLIC) to allow the import.
|
||||
// Pruning of personal data (email) is done during serialization if the user has READ_PUBLIC but no
|
||||
// READ permission.
|
||||
if (!securityService.hasCurrentUserOneOfExplicitPermissions(competitor,
|
||||
PublicReadableActions.READ_AND_READ_PUBLIC_ACTIONS)) {
|
||||
throw new AuthorizationException("No permission to read competitor " + competitor.getId()
|
||||
+ " for leaderboard '" + leaderboard.getName() + "'");
|
||||
}
|
||||
competitorIds.add(competitor.getId());
|
||||
}
|
||||
for (Boat boat : leaderboard.getAllBoats()) {
|
||||
// All boats reachable by Leaderboards contained in a LeaderboardGroup
|
||||
// need to be readable (READ or READ_PUBLIC) to allow the import.
|
||||
if (!securityService.hasCurrentUserOneOfExplicitPermissions(boat,
|
||||
PublicReadableActions.READ_AND_READ_PUBLIC_ACTIONS)) {
|
||||
throw new AuthorizationException("No permission to read boat " + boat.getId()
|
||||
+ " for leaderboard '" + leaderboard.getName() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,43 +130,52 @@ public class MasterDataResource extends AbstractSailingServerResource {
|
||||
Set<DeviceConfiguration> raceManagerDeviceConfigurations = new HashSet<>();
|
||||
if (exportDeviceConfigs) {
|
||||
for (DeviceConfiguration deviceConfig : getAllDeviceConfigs()) {
|
||||
// FIXME here permission check?
|
||||
raceManagerDeviceConfigurations.add(deviceConfig);
|
||||
// DeviceConfiguration are explicitly filtered by their permissions
|
||||
// because no filtering based on the selected LeaderboardGroups is done.
|
||||
// This is the only way to allow importing DeviceConfigurations at all.
|
||||
if (securityService.hasCurrentUserReadPermission(deviceConfig)) {
|
||||
raceManagerDeviceConfigurations.add(deviceConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
ArrayList<Event> events = new ArrayList<>();
|
||||
for (Event event : getService().getAllEvents()) {
|
||||
if (securityService.hasCurrentUserReadPermission(event)) {
|
||||
events.add(event);
|
||||
}
|
||||
events.add(event);
|
||||
}
|
||||
|
||||
ArrayList<MediaTrack> mediaTracks = new ArrayList<>();
|
||||
for (MediaTrack mediaTrack : getService().getAllMediaTracks()) {
|
||||
if (securityService.hasCurrentUserReadPermission(mediaTrack)) {
|
||||
mediaTracks.add(mediaTrack);
|
||||
}
|
||||
mediaTracks.add(mediaTrack);
|
||||
}
|
||||
Map<String, Regatta> regattaRaceIds = new HashMap<>();
|
||||
for (Entry<String, Regatta> regattaRaceMap : getService().getPersistentRegattasForRaceIDs().entrySet()) {
|
||||
if (securityService.hasCurrentUserReadPermission(regattaRaceMap.getValue())) {
|
||||
regattaRaceIds.put(regattaRaceMap.getKey(), regattaRaceMap.getValue());
|
||||
}
|
||||
regattaRaceIds.put(regattaRaceMap.getKey(), regattaRaceMap.getValue());
|
||||
}
|
||||
final TopLevelMasterData masterData = new TopLevelMasterData(groupsToExport,
|
||||
events, regattaRaceIds, mediaTracks,
|
||||
getService().getSensorFixStore(), exportWind, raceManagerDeviceConfigurations);
|
||||
// Checking permissions after filtering of Events to be transferred.
|
||||
for (Event event: masterData.getAllEvents()) {
|
||||
if (!securityService.hasCurrentUserReadPermission(event)) {
|
||||
throw new AuthorizationException("No permission to read event " + event.getId());
|
||||
}
|
||||
}
|
||||
// Checking permissions after filtering of MediaTracks to be transferred.
|
||||
for (MediaTrack mediaTrack : masterData.getFilteredMediaTracks()) {
|
||||
if (!securityService.hasCurrentUserReadPermission(mediaTrack)) {
|
||||
throw new AuthorizationException("No permission to read media track " + mediaTrack.dbId);
|
||||
}
|
||||
}
|
||||
final StreamingOutput streamingOutput;
|
||||
if (compress) {
|
||||
streamingOutput = new CompressingStreamingOutput(masterData, competitorIds, startTime);
|
||||
streamingOutput = new CompressingStreamingOutput(masterData, competitorIds, startTime, securityService);
|
||||
} else {
|
||||
streamingOutput = new NonCompressingStreamingOutput(masterData, competitorIds, startTime);
|
||||
streamingOutput = new NonCompressingStreamingOutput(masterData, competitorIds, startTime, securityService);
|
||||
}
|
||||
final ResponseBuilder resp = Response.ok(streamingOutput);
|
||||
ResponseBuilder resp = Response.ok(streamingOutput);
|
||||
if (compress) {
|
||||
resp.header("Content-Encoding", "gzip");
|
||||
}
|
||||
Response builtResponse = resp.build();
|
||||
final Response builtResponse = resp.build();
|
||||
long timeToExport = System.currentTimeMillis() - startTime;
|
||||
logger.info(String.format("Took %s ms to start masterdataexport-streaming.", timeToExport));
|
||||
return builtResponse;
|
||||
@@ -150,39 +189,50 @@ public class MasterDataResource extends AbstractSailingServerResource {
|
||||
private final TopLevelMasterData masterData;
|
||||
private final List<Serializable> competitorIds;
|
||||
private final long startTime;
|
||||
private final SecurityService securityService;
|
||||
|
||||
protected AbstractStreamingOutput(TopLevelMasterData masterData, List<Serializable> competitorIds, long startTime) {
|
||||
protected AbstractStreamingOutput(TopLevelMasterData masterData, List<Serializable> competitorIds, long startTime, SecurityService securityService) {
|
||||
super();
|
||||
this.masterData = masterData;
|
||||
this.competitorIds = competitorIds;
|
||||
this.startTime = startTime;
|
||||
this.securityService = securityService;
|
||||
}
|
||||
|
||||
protected abstract OutputStream wrapOutputStream(OutputStream outputStream) throws IOException;
|
||||
|
||||
@Override
|
||||
public void write(OutputStream output) throws IOException, WebApplicationException {
|
||||
ObjectOutputStream objectOutputStream = null;
|
||||
try {
|
||||
OutputStream gzipOrNot = wrapOutputStream(output);
|
||||
OutputStream outputStreamWithByteCounter = new ByteCountOutputStreamDecorator(gzipOrNot);
|
||||
objectOutputStream = new ObjectOutputStream(outputStreamWithByteCounter);
|
||||
masterData.setMasterDataExportFlagOnRaceColumns(true);
|
||||
// Actual start of streaming
|
||||
writeObjects(competitorIds, masterData, objectOutputStream);
|
||||
} finally {
|
||||
objectOutputStream.close();
|
||||
masterData.setMasterDataExportFlagOnRaceColumns(false);
|
||||
}
|
||||
long timeToExport = System.currentTimeMillis() - startTime;
|
||||
logger.info(String.format("Took %s ms to finish masterdataexport", timeToExport));
|
||||
CompetitorSerializationCustomizer
|
||||
.doWithCustomizer(c -> {
|
||||
return !securityService.hasCurrentUserReadPermission(c) && c.getEmail() != null;
|
||||
}, () -> {
|
||||
try {
|
||||
ObjectOutputStream objectOutputStream = null;
|
||||
try {
|
||||
OutputStream gzipOrNot = wrapOutputStream(output);
|
||||
OutputStream outputStreamWithByteCounter = new ByteCountOutputStreamDecorator(gzipOrNot);
|
||||
objectOutputStream = new ObjectOutputStream(outputStreamWithByteCounter);
|
||||
masterData.setMasterDataExportFlagOnRaceColumns(true);
|
||||
// Actual start of streaming
|
||||
writeObjects(competitorIds, masterData, objectOutputStream);
|
||||
} finally {
|
||||
objectOutputStream.close();
|
||||
masterData.setMasterDataExportFlagOnRaceColumns(false);
|
||||
}
|
||||
long timeToExport = System.currentTimeMillis() - startTime;
|
||||
logger.info(String.format("Took %s ms to finish masterdataexport", timeToExport));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class NonCompressingStreamingOutput extends AbstractStreamingOutput {
|
||||
protected NonCompressingStreamingOutput(TopLevelMasterData masterData, List<Serializable> competitorIds,
|
||||
long startTime) {
|
||||
super(masterData, competitorIds, startTime);
|
||||
long startTime, SecurityService securityService) {
|
||||
super(masterData, competitorIds, startTime, securityService);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,8 +243,8 @@ public class MasterDataResource extends AbstractSailingServerResource {
|
||||
|
||||
private class CompressingStreamingOutput extends AbstractStreamingOutput {
|
||||
protected CompressingStreamingOutput(TopLevelMasterData masterData, List<Serializable> competitorIds,
|
||||
long startTime) {
|
||||
super(masterData, competitorIds, startTime);
|
||||
long startTime, SecurityService securityService) {
|
||||
super(masterData, competitorIds, startTime, securityService);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-7
@@ -26,7 +26,6 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.json.simple.parser.ParseException;
|
||||
@@ -96,7 +95,6 @@ import com.sap.sailing.server.operationaltransformation.CreateRegattaLeaderboard
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateEvent;
|
||||
import com.sap.sailing.server.security.PermissionAwareRaceTrackingHandler;
|
||||
import com.sap.sailing.server.util.WaitForTrackedRaceUtil;
|
||||
import com.sap.sse.ServerInfo;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
@@ -108,8 +106,6 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.i18n.ResourceBundleStringMessages;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
|
||||
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
|
||||
|
||||
/**
|
||||
@@ -287,9 +283,7 @@ public class ExpeditionAllInOneImporter {
|
||||
public ImporterResult importFiles(final String filenameWithSuffix, final FileItem fileItem,
|
||||
final String boatClassName, ImportMode importMode, String existingRegattaName, boolean importStartData)
|
||||
throws AllInOneImportException, IOException, FormatNotSupportedException {
|
||||
SecurityUtils.getSubject().checkPermission(
|
||||
SecuredSecurityTypes.SERVER.getStringPermissionForTypeRelativeIdentifier(ServerActions.CREATE_OBJECT,
|
||||
new TypeRelativeObjectIdentifier(ServerInfo.getName())));
|
||||
securityService.checkCurrentUserServerPermission(ServerActions.CREATE_OBJECT);
|
||||
final List<ErrorImportDTO> errors = new ArrayList<>();
|
||||
final String importTimeString = DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.now(ZoneOffset.UTC));
|
||||
final String filename = ExpeditionImportFilenameUtils.truncateFilenameExtentions(filenameWithSuffix);
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
+8
-3
@@ -22,7 +22,9 @@ import java.util.UUID;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.StreamingOutput;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
@@ -50,11 +52,11 @@ import com.sap.sse.mongodb.MongoDBService;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.interfaces.UserImpl;
|
||||
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.PublicReadableActions;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroupImpl;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
public class MediaReplicationTest extends AbstractServerReplicationTest {
|
||||
|
||||
private void waitSomeTime() throws InterruptedException {
|
||||
@@ -202,7 +204,10 @@ public class MediaReplicationTest extends AbstractServerReplicationTest {
|
||||
Mockito.doNothing().when(securityService).checkCurrentUserReadPermission(Mockito.any());
|
||||
Mockito.doReturn(true).when(securityService)
|
||||
.hasCurrentUserReadPermission(Mockito.any(WithQualifiedObjectIdentifier.class));
|
||||
|
||||
Mockito.doReturn(true).when(securityService)
|
||||
.hasCurrentUserServerPermission(ServerActions.CAN_EXPORT_MASTERDATA);
|
||||
Mockito.doReturn(true).when(securityService).hasCurrentUserOneOfExplicitPermissions(
|
||||
Mockito.any(WithQualifiedObjectIdentifier.class), Matchers.<PublicReadableActions> anyVararg());
|
||||
|
||||
// Setup source service
|
||||
RacingEventServiceImpl sourceService = Mockito.spy(new RacingEventServiceImpl());
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
+7
@@ -37,6 +37,7 @@ import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.mongodb.WriteConcern;
|
||||
@@ -152,6 +153,8 @@ import com.sap.sse.mongodb.MongoDBConfiguration;
|
||||
import com.sap.sse.mongodb.MongoDBService;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.PublicReadableActions;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroupImpl;
|
||||
import com.sap.sse.shared.media.ImageDescriptor;
|
||||
@@ -205,6 +208,10 @@ public class MasterDataImportTest {
|
||||
|
||||
Mockito.doReturn(true).when(securityService)
|
||||
.hasCurrentUserReadPermission(Mockito.any(WithQualifiedObjectIdentifier.class));
|
||||
Mockito.doReturn(true).when(securityService)
|
||||
.hasCurrentUserServerPermission(ServerActions.CAN_EXPORT_MASTERDATA);
|
||||
Mockito.doReturn(true).when(securityService).hasCurrentUserOneOfExplicitPermissions(
|
||||
Mockito.any(WithQualifiedObjectIdentifier.class), Matchers.<PublicReadableActions> anyVararg());
|
||||
|
||||
|
||||
Mockito.doReturn(true).when(fakeSubject).isAuthenticated();
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
Loaded 100 of 169 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user