Cleaning up some code:

- Some extension API implementation things refactored
- getOrDefault+put calls replaced with computeIfAbsent
  using Maps#create, Lists#create
- stream().map(mapper).collect(toList/toSet) optimized
  using Lists#map, #mapUnique
- stream().filter(by).collect(toList) optimized
  using Lists#filter
This commit is contained in:
Rsl1122 2019-12-19 00:09:29 +02:00
parent 241cdbe82e
commit a3cd3adb32
42 changed files with 423 additions and 262 deletions

2
.gitignore vendored
View File

@ -3,6 +3,8 @@ Plan.iml
PlanPluginBridge.iml
.sonar/
builds/
# Nukkit creates server.log during tests for some reason.
server.log
*.db

View File

@ -17,6 +17,7 @@
package com.djrapitops.plan.delivery.domain.mutators;
import com.djrapitops.plan.delivery.domain.DateHolder;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.*;
import java.util.concurrent.TimeUnit;
@ -41,19 +42,18 @@ public class DateHoldersMutator<T extends DateHolder> {
long date = holder.getDate();
long startOfSection = date - (date % sectionLenght);
List<T> list = map.getOrDefault(startOfSection, new ArrayList<>());
List<T> list = map.computeIfAbsent(startOfSection, Lists::create);
list.add(holder);
map.put(startOfSection, list);
}
return map;
}
public SortedMap<Long, List<T>> groupByStartOfDay(TimeZone timeZone) {
long twentyFourHours = TimeUnit.DAYS.toMillis(1L);
TreeMap<Long, List<T>> map = new TreeMap<>();
TreeMap<Long, List<T>> byStart = new TreeMap<>();
if (dateHolders.isEmpty()) {
return map;
return byStart;
}
for (T holder : dateHolders) {
@ -61,22 +61,21 @@ public class DateHoldersMutator<T extends DateHolder> {
long dateWithOffset = date + timeZone.getOffset(date);
long startOfSection = dateWithOffset - (dateWithOffset % twentyFourHours);
List<T> list = map.getOrDefault(startOfSection, new ArrayList<>());
list.add(holder);
map.put(startOfSection, list);
List<T> grouped = byStart.computeIfAbsent(startOfSection, Lists::create);
grouped.add(holder);
}
// Empty map firstKey attempt causes NPE if not checked.
if (!map.isEmpty()) {
if (!byStart.isEmpty()) {
// Add missing in-between dates
long start = map.firstKey();
long start = byStart.firstKey();
long now = System.currentTimeMillis();
long end = now - (now % twentyFourHours);
for (long date = start; date < end; date += twentyFourHours) {
map.putIfAbsent(date, new ArrayList<>());
byStart.putIfAbsent(date, new ArrayList<>());
}
}
return map;
return byStart;
}
}

View File

@ -17,17 +17,15 @@
package com.djrapitops.plan.delivery.domain.mutators;
import com.djrapitops.plan.delivery.rendering.json.graphs.line.Point;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plugin.utilities.Verify;
import java.util.*;
import java.util.stream.Collectors;
public class MutatorFunctions {
public static List<Point> toPoints(NavigableMap<Long, Integer> map) {
return map.entrySet().stream()
.map(entry -> new Point(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
return Lists.map(map.entrySet(), entry -> new Point(entry.getKey(), entry.getValue()));
}
public static NavigableMap<Long, Integer> addMissing(NavigableMap<Long, Integer> points, long accuracy, Integer replacement) {

View File

@ -22,11 +22,12 @@ import com.djrapitops.plan.delivery.domain.keys.CommonKeys;
import com.djrapitops.plan.delivery.domain.keys.SessionKeys;
import com.djrapitops.plan.gathering.domain.Ping;
import com.djrapitops.plan.gathering.domain.Session;
import com.djrapitops.plan.utilities.Predicates;
import com.djrapitops.plan.utilities.comparators.DateHolderOldestComparator;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class PingMutator {
@ -41,7 +42,7 @@ public class PingMutator {
}
public PingMutator filterBy(Predicate<Ping> predicate) {
return new PingMutator(pings.stream().filter(predicate).collect(Collectors.toList()));
return new PingMutator(Lists.filter(pings, predicate));
}
public PingMutator filterByServer(UUID serverUUID) {
@ -52,13 +53,12 @@ public class PingMutator {
DateHoldersMutator<Ping> dateMutator = new DateHoldersMutator<>(pings);
SortedMap<Long, List<Ping>> byStartOfMinute = dateMutator.groupByStartOfMinute();
return new PingMutator(byStartOfMinute.entrySet().stream()
.map(entry -> {
PingMutator mutator = new PingMutator(entry.getValue());
return new PingMutator(Lists.map(byStartOfMinute.entrySet(), entry -> {
PingMutator mutator = new PingMutator(entry.getValue());
return new Ping(entry.getKey(), null,
mutator.min(), mutator.max(), mutator.average());
}).collect(Collectors.toList()));
return new Ping(entry.getKey(), null,
mutator.min(), mutator.max(), mutator.average());
}));
}
public static Map<UUID, SortedMap<Long, Ping>> sortByServers(List<Ping> pings) {
@ -92,7 +92,7 @@ public class PingMutator {
for (Session session : sessionsOfServer) {
long start = session.getDate();
Long end = session.getValue(SessionKeys.END).orElseGet(System::currentTimeMillis);
// Calcuclate average ping for each session with a Ping submap
// Calculate average ping for each session with a Ping submap
SortedMap<Long, Ping> duringSession = pingOfServer.subMap(start, end);
for (Ping ping : duringSession.values()) {
pingCount += ping.getAverage();
@ -143,7 +143,7 @@ public class PingMutator {
public double average() {
return pings.stream().mapToDouble(Ping::getAverage)
.filter(value -> value > 0 && value <= 4000)
.filter(Predicates::pingInRange)
.average().orElse(-1);
}
}

View File

@ -18,11 +18,11 @@ package com.djrapitops.plan.delivery.domain.mutators;
import com.djrapitops.plan.delivery.formatting.Formatters;
import com.djrapitops.plan.gathering.domain.PlayerKill;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Mutator functions for {@link PlayerKill} objects.
@ -38,11 +38,11 @@ public class PlayerKillMutator {
}
public PlayerKillMutator filterNonSelfKills() {
return new PlayerKillMutator(kills.stream().filter(PlayerKill::isNotSelfKill).collect(Collectors.toList()));
return new PlayerKillMutator(Lists.filter(kills, PlayerKill::isNotSelfKill));
}
public List<Map<String, Object>> toJSONAsMap(Formatters formatters) {
return kills.stream().map(
return Lists.map(kills,
kill -> {
Map<String, Object> killMap = new HashMap<>();
killMap.put("date", formatters.secondLong().apply(kill.getDate()));
@ -51,6 +51,6 @@ public class PlayerKillMutator {
killMap.put("weapon", kill.getWeapon());
return killMap;
}
).collect(Collectors.toList());
);
}
}

View File

@ -21,6 +21,7 @@ import com.djrapitops.plan.delivery.domain.container.DataContainer;
import com.djrapitops.plan.delivery.domain.keys.PlayerKeys;
import com.djrapitops.plan.gathering.domain.PlayerKill;
import com.djrapitops.plan.utilities.Predicates;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.Collections;
import java.util.HashMap;
@ -54,8 +55,8 @@ public class PlayerVersusMutator {
return new PlayerVersusMutator(
sessionsMutator.filterSessionsBetween(after, before),
kills.stream().filter(killWithinDate).collect(Collectors.toList()),
deaths.stream().filter(killWithinDate).collect(Collectors.toList())
Lists.filter(kills, killWithinDate),
Lists.filter(deaths, killWithinDate)
);
}

View File

@ -25,9 +25,12 @@ import com.djrapitops.plan.delivery.domain.keys.SessionKeys;
import com.djrapitops.plan.gathering.domain.GeoInfo;
import com.djrapitops.plan.gathering.domain.Ping;
import com.djrapitops.plan.gathering.domain.Session;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plan.utilities.java.Maps;
import com.djrapitops.plugin.api.TimeAmount;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -53,7 +56,7 @@ public class PlayersMutator {
}
public <T extends Predicate<PlayerContainer>> PlayersMutator filterBy(T by) {
return new PlayersMutator(players.stream().filter(by).collect(Collectors.toList()));
return new PlayersMutator(Lists.filter(players, by));
}
public PlayersMutator filterPlayedBetween(long after, long before) {
@ -129,11 +132,8 @@ public class PlayersMutator {
}
List<Ping> pings = player.getValue(PlayerKeys.PING).orElse(new ArrayList<>());
String country = mostRecent.get().getGeolocation();
List<Ping> countryPings = pingPerCountry.getOrDefault(country, new ArrayList<>());
pings.stream()
.filter(ping -> ping.getServerUUID().equals(serverUUID))
.forEach(countryPings::add);
pingPerCountry.put(country, countryPings);
List<Ping> countryPings = pingPerCountry.computeIfAbsent(country, Lists::create);
countryPings.addAll(new PingMutator(pings).filterByServer(serverUUID).all());
}
return pingPerCountry;
@ -142,7 +142,7 @@ public class PlayersMutator {
public TreeMap<Long, Map<String, Set<UUID>>> toActivityDataMap(long date, long msThreshold) {
TreeMap<Long, Map<String, Set<UUID>>> activityData = new TreeMap<>();
for (long time = date; time >= date - TimeAmount.MONTH.toMillis(2L); time -= TimeAmount.WEEK.toMillis(1L)) {
Map<String, Set<UUID>> map = activityData.getOrDefault(time, new HashMap<>());
Map<String, Set<UUID>> map = activityData.computeIfAbsent(time, Maps::create);
if (!players.isEmpty()) {
for (PlayerContainer player : players) {
if (player.getValue(PlayerKeys.REGISTERED).orElse(0L) > time) {
@ -151,12 +151,10 @@ public class PlayersMutator {
ActivityIndex activityIndex = player.getActivityIndex(time, msThreshold);
String activityGroup = activityIndex.getGroup();
Set<UUID> uuids = map.getOrDefault(activityGroup, new HashSet<>());
Set<UUID> uuids = map.computeIfAbsent(activityGroup, Maps::createSet);
uuids.add(player.getUnsafe(PlayerKeys.UUID));
map.put(activityGroup, uuids);
}
}
activityData.put(time, map);
}
return activityData;
}
@ -170,14 +168,12 @@ public class PlayersMutator {
}
public TreeMap<Long, Integer> newPerDay(TimeZone timeZone) {
List<DateObj> registerDates = registerDates().stream()
.map(value -> new DateObj<>(value, value))
.collect(Collectors.toList());
List<DateObj<?>> registerDates = Lists.map(registerDates(), value -> new DateObj<>(value, value));
// Adds timezone offset
SortedMap<Long, List<DateObj>> byDay = new DateHoldersMutator<>(registerDates).groupByStartOfDay(timeZone);
SortedMap<Long, List<DateObj<?>>> byDay = new DateHoldersMutator<>(registerDates).groupByStartOfDay(timeZone);
TreeMap<Long, Integer> byDayCounts = new TreeMap<>();
for (Map.Entry<Long, List<DateObj>> entry : byDay.entrySet()) {
for (Map.Entry<Long, List<DateObj<?>>> entry : byDay.entrySet()) {
byDayCounts.put(
entry.getKey(),
entry.getValue().size()
@ -225,12 +221,9 @@ public class PlayersMutator {
throw new IllegalStateException("No players to compare to after rejecting with dateLimit");
}
List<RetentionData> retained = retainedAfterMonth.stream()
.map(player -> new RetentionData(player, onlineResolver, activityMsThreshold))
.collect(Collectors.toList());
List<RetentionData> notRetained = notRetainedAfterMonth.stream()
.map(player -> new RetentionData(player, onlineResolver, activityMsThreshold))
.collect(Collectors.toList());
Function<PlayerContainer, RetentionData> mapper = player -> new RetentionData(player, onlineResolver, activityMsThreshold);
List<RetentionData> retained = Lists.map(retainedAfterMonth, mapper);
List<RetentionData> notRetained = Lists.map(notRetainedAfterMonth, mapper);
RetentionData avgRetained = RetentionData.average(retained);
RetentionData avgNotRetained = RetentionData.average(notRetained);
@ -260,8 +253,7 @@ public class PlayersMutator {
}
public List<PlayerContainer> operators() {
return players.stream()
.filter(player -> player.getValue(PlayerKeys.OPERATOR).orElse(false)).collect(Collectors.toList());
return Lists.filter(players, player -> player.getValue(PlayerKeys.OPERATOR).orElse(false));
}
public List<Ping> pings() {

View File

@ -28,6 +28,7 @@ import com.djrapitops.plan.gathering.domain.Session;
import com.djrapitops.plan.gathering.domain.WorldTimes;
import com.djrapitops.plan.settings.config.WorldAliasSettings;
import com.djrapitops.plan.utilities.analysis.Median;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.*;
import java.util.function.Function;
@ -62,10 +63,15 @@ public class SessionsMutator {
return this;
}
public SessionsMutator filterBy(Predicate<Session> predicate) {
return new SessionsMutator(sessions.stream()
.filter(predicate)
.collect(Collectors.toList()));
public static Map<UUID, List<Session>> sortByPlayers(List<Session> sessions) {
Map<UUID, List<Session>> sorted = new HashMap<>();
for (Session session : sessions) {
UUID playerUUID = session.getUnsafe(SessionKeys.UUID);
List<Session> playerSessions = sorted.computeIfAbsent(playerUUID, Lists::create);
playerSessions.add(session);
sorted.put(playerUUID, playerSessions);
}
return sorted;
}
public SessionsMutator filterSessionsBetween(long after, long before) {
@ -157,9 +163,14 @@ public class SessionsMutator {
return 0L;
}
public long toMedianSessionLength() {
List<Long> sessionLengths = sessions.stream().map(Session::getLength).collect(Collectors.toList());
return (long) Median.forList(sessionLengths).calculate();
public static Map<UUID, List<Session>> sortByServers(List<Session> sessions) {
Map<UUID, List<Session>> sorted = new HashMap<>();
for (Session session : sessions) {
UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID);
List<Session> serverSessions = sorted.computeIfAbsent(serverUUID, Lists::create);
serverSessions.add(session);
}
return sorted;
}
public int toUniquePlayers() {
@ -189,26 +200,13 @@ public class SessionsMutator {
};
}
public static Map<UUID, List<Session>> sortByPlayers(List<Session> sessions) {
Map<UUID, List<Session>> sorted = new HashMap<>();
for (Session session : sessions) {
UUID playerUUID = session.getUnsafe(SessionKeys.UUID);
List<Session> playerSessions = sorted.getOrDefault(playerUUID, new ArrayList<>());
playerSessions.add(session);
sorted.put(playerUUID, playerSessions);
}
return sorted;
public SessionsMutator filterBy(Predicate<Session> predicate) {
return new SessionsMutator(Lists.filter(sessions, predicate));
}
public static Map<UUID, List<Session>> sortByServers(List<Session> sessions) {
Map<UUID, List<Session>> sorted = new HashMap<>();
for (Session session : sessions) {
UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID);
List<Session> serverSessions = sorted.getOrDefault(serverUUID, new ArrayList<>());
serverSessions.add(session);
sorted.put(serverUUID, serverSessions);
}
return sorted;
public long toMedianSessionLength() {
List<Long> sessionLengths = Lists.map(sessions, Session::getLength);
return (long) Median.forList(sessionLengths).calculate();
}
public static Map<UUID, TreeMap<Long, Session>> sortByServersToMaps(List<Session> sessions) {
@ -264,7 +262,7 @@ public class SessionsMutator {
Formatters formatters,
Function<Map<String, Object>, Object> nameFunction
) {
return sessions.stream().map(session -> {
return Lists.map(sessions, session -> {
Map<String, Object> sessionMap = new HashMap<>();
sessionMap.put("player_name", session.getValue(SessionKeys.NAME).orElse(session.getUnsafe(SessionKeys.UUID).toString()));
sessionMap.put("player_uuid", session.getUnsafe(SessionKeys.UUID).toString());
@ -298,6 +296,6 @@ public class SessionsMutator {
sessionMap.put("avg_ping", formatters.decimals().apply(averagePing) + " ms")
);
return sessionMap;
}).collect(Collectors.toList());
});
}
}

View File

@ -21,6 +21,7 @@ import com.djrapitops.plan.delivery.domain.keys.ServerKeys;
import com.djrapitops.plan.delivery.rendering.json.graphs.line.Point;
import com.djrapitops.plan.gathering.domain.TPS;
import com.djrapitops.plan.utilities.comparators.TPSComparator;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.ArrayList;
import java.util.List;
@ -53,9 +54,7 @@ public class TPSMutator {
}
public TPSMutator filterBy(Predicate<TPS> filter) {
return new TPSMutator(tpsData.stream()
.filter(filter)
.collect(Collectors.toList()));
return new TPSMutator(Lists.filter(tpsData, filter));
}
public TPSMutator filterDataBetween(long after, long before) {
@ -71,15 +70,11 @@ public class TPSMutator {
}
public List<Point> playersOnlinePoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getPlayers()))
.collect(Collectors.toList());
return Lists.map(tpsData, tps -> new Point(tps.getDate(), tps.getPlayers()));
}
public List<Point> tpsPoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getTicksPerSecond()))
.collect(Collectors.toList());
return Lists.map(tpsData, tps -> new Point(tps.getDate(), tps.getTicksPerSecond()));
}
public List<Point> cpuPoints() {
@ -90,21 +85,15 @@ public class TPSMutator {
}
public List<Point> ramUsagePoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getUsedMemory()))
.collect(Collectors.toList());
return Lists.map(tpsData, tps -> new Point(tps.getDate(), tps.getUsedMemory()));
}
public List<Point> entityPoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getEntityCount()))
.collect(Collectors.toList());
return Lists.map(tpsData, tps -> new Point(tps.getDate(), tps.getEntityCount()));
}
public List<Point> chunkPoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getChunksLoaded()))
.collect(Collectors.toList());
return Lists.map(tpsData, tps -> new Point(tps.getDate(), tps.getChunksLoaded()));
}
public List<Point> freeDiskPoints() {

View File

@ -40,13 +40,13 @@ import com.djrapitops.plan.storage.database.Database;
import com.djrapitops.plan.storage.database.queries.containers.PlayerContainerQuery;
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
import com.djrapitops.plan.utilities.java.Lists;
import org.apache.commons.text.StringEscapeUtils;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Singleton
public class PlayerJSONCreator {
@ -304,9 +304,7 @@ public class PlayerJSONCreator {
}
public static List<ConnectionInfo> fromGeoInfo(List<GeoInfo> geoInfo, Formatter<Long> dateFormatter) {
return geoInfo.stream()
.map(i -> new ConnectionInfo(i.getGeolocation(), dateFormatter.apply(i.getDate())))
.collect(Collectors.toList());
return Lists.map(geoInfo, i -> new ConnectionInfo(i.getGeolocation(), dateFormatter.apply(i.getDate())));
}
}

View File

@ -41,13 +41,13 @@ import com.djrapitops.plan.storage.database.queries.analysis.ActivityIndexQuerie
import com.djrapitops.plan.storage.database.queries.analysis.NetworkActivityIndexQueries;
import com.djrapitops.plan.storage.database.queries.analysis.PlayerCountQueries;
import com.djrapitops.plan.storage.database.queries.objects.*;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plugin.api.TimeAmount;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* Perses Graph related Data JSON.
@ -98,9 +98,9 @@ public class GraphJSONCreator {
long now = System.currentTimeMillis();
long halfYearAgo = now - TimeUnit.DAYS.toMillis(180L);
List<Point> points = db.query(TPSQueries.fetchPlayersOnlineOfServer(halfYearAgo, now, serverUUID)).stream()
.map(point -> new Point(point.getDate(), point.getValue()))
.collect(Collectors.toList());
List<Point> points = Lists.map(db.query(TPSQueries.fetchPlayersOnlineOfServer(halfYearAgo, now, serverUUID)),
point -> new Point(point.getDate(), point.getValue())
);
return "{\"playersOnline\":" + graphs.line().lineGraph(points).toHighChartsSeries() + '}';
}

View File

@ -26,6 +26,7 @@ import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.lang.HtmlLang;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.settings.theme.ThemeVal;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.*;
import java.util.concurrent.TimeUnit;
@ -124,9 +125,8 @@ public class PlayerCalendar {
for (Session session : allSessions) {
String day = iso8601Formatter.apply(session.getDate());
List<Session> sessionsOfDay = sessionsByDay.getOrDefault(day, new ArrayList<>());
List<Session> sessionsOfDay = sessionsByDay.computeIfAbsent(day, Lists::create);
sessionsOfDay.add(session);
sessionsByDay.put(day, sessionsOfDay);
}
return sessionsByDay;
}

View File

@ -25,10 +25,10 @@ import com.djrapitops.plan.extension.ElementOrder;
import com.djrapitops.plan.extension.FormatType;
import com.djrapitops.plan.extension.implementation.TabInformation;
import com.djrapitops.plan.extension.implementation.results.*;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plugin.utilities.Format;
import java.util.*;
import java.util.stream.Collectors;
/**
* Responsible for generating /server page plugin tabs based on DataExtension API data.
@ -61,9 +61,7 @@ public class ServerPluginTabs {
Formatters formatters
) {
this.serverData = serverData;
this.extraTabServerData = serverData.stream()
.filter(ExtensionData::doesNeedWiderSpace)
.collect(Collectors.toList());
this.extraTabServerData = Lists.filter(serverData, ExtensionData::doesNeedWiderSpace);
this.serverData.removeAll(extraTabServerData);
numberFormatters = new EnumMap<>(FormatType.class);

View File

@ -18,11 +18,11 @@ package com.djrapitops.plan.delivery.webserver.response.pages;
import com.djrapitops.plan.delivery.domain.container.DataContainer;
import com.djrapitops.plan.delivery.webserver.response.data.JSONResponse;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Response for sending raw data as JSON when it is inside a DataContainer.
@ -46,10 +46,10 @@ public class RawDataResponse extends JSONResponse {
value = mapToNormalMap((DataContainer) value);
}
if (value instanceof Map) {
value = handleMap((Map) value);
value = handleMap((Map<?, ?>) value);
}
if (value instanceof List) {
value = handleList((List) value);
value = handleList((List<?>) value);
}
values.put(key.getKeyName(), value);
}
@ -57,14 +57,14 @@ public class RawDataResponse extends JSONResponse {
return values;
}
private static List handleList(List list) {
private static List<?> handleList(List<?> list) {
if (list.stream().findAny().orElse(null) instanceof DataContainer) {
return (List) list.stream().map(obj -> mapToNormalMap((DataContainer) obj)).collect(Collectors.toList());
return Lists.map(list, obj -> mapToNormalMap((DataContainer) obj));
}
return list;
}
private static Map handleMap(Map map) {
private static Map<?, ?> handleMap(Map<?, ?> map) {
if (map.values().stream().findAny().orElse(null) instanceof DataContainer) {
Map<Object, Object> newMap = new HashMap<>();
map.forEach((key, value) -> newMap.put(key, mapToNormalMap((DataContainer) value)));

View File

@ -32,26 +32,26 @@ import java.util.UUID;
public class CallerImplementation implements Caller {
private final ProviderValueGatherer gatherer;
private final ExtensionServiceImplementation extensionServiceImplementation;
private final ExtensionServiceImplementation extensionService;
private final Processing processing;
public CallerImplementation(
ProviderValueGatherer gatherer,
ExtensionServiceImplementation extensionServiceImplementation,
ExtensionServiceImplementation extensionService,
Processing processing
) {
this.gatherer = gatherer;
this.extensionServiceImplementation = extensionServiceImplementation;
this.extensionService = extensionService;
this.processing = processing;
}
@Override
public void updatePlayerData(UUID playerUUID, String playerName) {
processing.submitNonCritical(() -> extensionServiceImplementation.updatePlayerValues(gatherer, playerUUID, playerName, CallEvents.MANUAL));
processing.submitNonCritical(() -> extensionService.updatePlayerValues(gatherer, playerUUID, playerName, CallEvents.MANUAL));
}
@Override
public void updateServerData() {
processing.submitNonCritical(() -> extensionServiceImplementation.updateServerValues(gatherer, CallEvents.MANUAL));
processing.submitNonCritical(() -> extensionService.updateServerValues(gatherer, CallEvents.MANUAL));
}
}

View File

@ -23,6 +23,7 @@ import com.djrapitops.plan.extension.extractor.MethodAnnotations;
import com.djrapitops.plan.extension.icon.Color;
import com.djrapitops.plan.extension.icon.Icon;
import com.djrapitops.plan.extension.implementation.providers.*;
import com.djrapitops.plan.utilities.java.Lists;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
@ -42,8 +43,8 @@ import java.util.stream.Collectors;
*/
public class DataProviderExtractor {
private final ExtensionExtractor extensionExtractor;
private final DataProviders dataProviders;
private final ExtensionExtractor extractor;
private final DataProviders providers;
/**
* Create a DataProviderExtractor.
@ -52,31 +53,31 @@ public class DataProviderExtractor {
* @throws IllegalArgumentException If something is badly wrong with the specified extension class annotations.
*/
public DataProviderExtractor(DataExtension extension) {
extensionExtractor = new ExtensionExtractor(extension);
extractor = new ExtensionExtractor(extension);
extensionExtractor.extractAnnotationInformation();
extractor.extractAnnotationInformation();
dataProviders = new DataProviders();
extractAllDataProviders();
providers = new DataProviders();
extractProviders();
}
public String getPluginName() {
return extensionExtractor.getPluginInfo().name();
return extractor.getPluginInfo().name();
}
public Icon getPluginIcon() {
PluginInfo pluginInfo = extensionExtractor.getPluginInfo();
PluginInfo pluginInfo = extractor.getPluginInfo();
return new Icon(pluginInfo.iconFamily(), pluginInfo.iconName(), pluginInfo.color());
}
public Collection<TabInformation> getPluginTabs() {
Map<String, TabInfo> tabInformation = extensionExtractor.getTabInformation()
Map<String, TabInfo> tabInformation = extractor.getTabInformation()
.stream().collect(Collectors.toMap(TabInfo::tab, Function.identity(), (one, two) -> one));
Map<String, Integer> order = getTabOrder().map(this::orderToMap).orElse(new HashMap<>());
// Extracts PluginTabs
return extensionExtractor.getMethodAnnotations().getAnnotations(Tab.class).stream()
return extractor.getMethodAnnotations().getAnnotations(Tab.class).stream()
.map(Tab::value)
.distinct()
.map(tabName -> {
@ -99,44 +100,42 @@ public class DataProviderExtractor {
}
public Optional<String[]> getTabOrder() {
return extensionExtractor.getTabOrder().map(TabOrder::value);
return extractor.getTabOrder().map(TabOrder::value);
}
public Collection<String> getInvalidatedMethods() {
return extensionExtractor.getInvalidateMethodAnnotations().stream()
.map(InvalidateMethod::value)
.collect(Collectors.toSet());
return Lists.mapUnique(extractor.getInvalidateMethodAnnotations(), InvalidateMethod::value);
}
public DataProviders getDataProviders() {
return dataProviders;
public DataProviders getProviders() {
return providers;
}
private void extractAllDataProviders() {
PluginInfo pluginInfo = extensionExtractor.getPluginInfo();
private void extractProviders() {
PluginInfo pluginInfo = extractor.getPluginInfo();
MethodAnnotations methodAnnotations = extensionExtractor.getMethodAnnotations();
MethodAnnotations methodAnnotations = extractor.getMethodAnnotations();
Map<Method, Tab> tabs = methodAnnotations.getMethodAnnotations(Tab.class);
Map<Method, Conditional> conditions = methodAnnotations.getMethodAnnotations(Conditional.class);
extractDataProviders(pluginInfo, tabs, conditions, BooleanProvider.class, BooleanDataProvider::placeToDataProviders);
extractDataProviders(pluginInfo, tabs, conditions, DoubleProvider.class, DoubleDataProvider::placeToDataProviders);
extractDataProviders(pluginInfo, tabs, conditions, PercentageProvider.class, PercentageDataProvider::placeToDataProviders);
extractDataProviders(pluginInfo, tabs, conditions, NumberProvider.class, NumberDataProvider::placeToDataProviders);
extractDataProviders(pluginInfo, tabs, conditions, StringProvider.class, StringDataProvider::placeToDataProviders);
extractDataProviders(pluginInfo, tabs, conditions, TableProvider.class, TableDataProvider::placeToDataProviders);
extractDataProviders(pluginInfo, tabs, conditions, GroupProvider.class, GroupDataProvider::placeToDataProviders);
extractProviders(pluginInfo, tabs, conditions, BooleanProvider.class, BooleanDataProvider::placeToDataProviders);
extractProviders(pluginInfo, tabs, conditions, DoubleProvider.class, DoubleDataProvider::placeToDataProviders);
extractProviders(pluginInfo, tabs, conditions, PercentageProvider.class, PercentageDataProvider::placeToDataProviders);
extractProviders(pluginInfo, tabs, conditions, NumberProvider.class, NumberDataProvider::placeToDataProviders);
extractProviders(pluginInfo, tabs, conditions, StringProvider.class, StringDataProvider::placeToDataProviders);
extractProviders(pluginInfo, tabs, conditions, TableProvider.class, TableDataProvider::placeToDataProviders);
extractProviders(pluginInfo, tabs, conditions, GroupProvider.class, GroupDataProvider::placeToDataProviders);
}
private <T extends Annotation> void extractDataProviders(PluginInfo pluginInfo, Map<Method, Tab> tabs, Map<Method, Conditional> conditions, Class<T> ofKind, DataProviderFactory<T> factory) {
for (Map.Entry<Method, T> entry : extensionExtractor.getMethodAnnotations().getMethodAnnotations(ofKind).entrySet()) {
private <T extends Annotation> void extractProviders(PluginInfo pluginInfo, Map<Method, Tab> tabs, Map<Method, Conditional> conditions, Class<T> ofKind, DataProviderFactory<T> factory) {
for (Map.Entry<Method, T> entry : extractor.getMethodAnnotations().getMethodAnnotations(ofKind).entrySet()) {
Method method = entry.getKey();
T annotation = entry.getValue();
Optional<Conditional> conditional = Optional.ofNullable(conditions.get(method));
Optional<Tab> tab = Optional.ofNullable(tabs.get(method));
factory.placeToDataProviders(
dataProviders, method, annotation,
providers, method, annotation,
conditional.orElse(null),
tab.map(Tab::value).orElse(null),
pluginInfo.name()
@ -145,7 +144,7 @@ public class DataProviderExtractor {
}
public Collection<String> getWarnings() {
return extensionExtractor.getWarnings();
return extractor.getWarnings();
}
/**

View File

@ -18,6 +18,8 @@ package com.djrapitops.plan.extension.implementation.providers;
import com.djrapitops.plan.extension.implementation.ProviderInformation;
import java.util.Objects;
/**
* Abstract representation of all values a Provider annotation provides.
*
@ -40,4 +42,18 @@ public abstract class DataProvider<T> {
public ProviderInformation getProviderInformation() {
return providerInformation;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DataProvider)) return false;
DataProvider<?> that = (DataProvider<?>) o;
return Objects.equals(providerInformation, that.providerInformation) &&
Objects.equals(method, that.method);
}
@Override
public int hashCode() {
return Objects.hash(providerInformation, method);
}
}

View File

@ -17,9 +17,10 @@
package com.djrapitops.plan.extension.implementation.providers;
import com.djrapitops.plan.extension.implementation.MethodType;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plan.utilities.java.Maps;
import java.util.*;
import java.util.stream.Collectors;
/**
* Group class for handling multiple different types of {@link DataProvider}s.
@ -28,74 +29,73 @@ import java.util.stream.Collectors;
*/
public class DataProviders {
private final Map<MethodType, Map<Class, List<DataProvider>>> byMethodType;
private final Map<MethodType, Map<Class<?>, List<DataProvider<?>>>> byMethodType;
public DataProviders() {
byMethodType = new EnumMap<>(MethodType.class);
}
public <T> void put(DataProvider<T> provider) {
MethodWrapper<T> method = provider.getMethod();
public void put(DataProvider<?> provider) {
MethodWrapper<?> method = provider.getMethod();
MethodType methodType = method.getMethodType();
Class<T> resultType = method.getResultType();
Class<?> returnType = method.getReturnType();
Map<Class, List<DataProvider>> byParameterType = byMethodType.getOrDefault(methodType, new HashMap<>());
List<DataProvider> dataProviders = byParameterType.getOrDefault(resultType, new ArrayList<>());
computeIfAbsent(methodType, returnType).add(provider);
}
dataProviders.add(provider);
private List<DataProvider<?>> computeIfAbsent(MethodType methodType, Class<?> returnType) {
return byMethodType.computeIfAbsent(methodType, Maps::create).computeIfAbsent(returnType, Lists::create);
}
byParameterType.put(resultType, dataProviders);
byMethodType.put(methodType, byParameterType);
private List<DataProvider<?>> getProvidersByTypes(MethodType methodType, Class<?> returnType) {
Map<Class<?>, List<DataProvider<?>>> byReturnType = byMethodType.getOrDefault(methodType, Collections.emptyMap());
return byReturnType.getOrDefault(returnType, Collections.emptyList());
}
public <T> List<DataProvider<T>> getPlayerMethodsByType(Class<T> returnType) {
Map<Class, List<DataProvider>> providersAcceptingUUID = byMethodType.getOrDefault(MethodType.PLAYER_UUID, new HashMap<>());
Map<Class, List<DataProvider>> providersAcceptingName = byMethodType.getOrDefault(MethodType.PLAYER_NAME, new HashMap<>());
List<DataProvider<T>> byReturnType = new ArrayList<>();
for (DataProvider dataProvider : providersAcceptingUUID.getOrDefault(returnType, Collections.emptyList())) {
for (DataProvider<?> dataProvider : getProvidersByTypes(MethodType.PLAYER_UUID, returnType)) {
byReturnType.add((DataProvider<T>) dataProvider);
}
for (DataProvider dataProvider : providersAcceptingName.getOrDefault(returnType, Collections.emptyList())) {
for (DataProvider<?> dataProvider : getProvidersByTypes(MethodType.PLAYER_NAME, returnType)) {
byReturnType.add((DataProvider<T>) dataProvider);
}
return byReturnType;
}
public <T> List<DataProvider<T>> getServerMethodsByType(Class<T> returnType) {
List<DataProvider<T>> byReturnType = new ArrayList<>();
for (DataProvider dataProvider : byMethodType.getOrDefault(MethodType.SERVER, new HashMap<>()).getOrDefault(returnType, Collections.emptyList())) {
byReturnType.add((DataProvider<T>) dataProvider);
List<DataProvider<T>> providers = new ArrayList<>();
for (DataProvider<?> dataProvider : getProvidersByTypes(MethodType.SERVER, returnType)) {
providers.add((DataProvider<T>) dataProvider);
}
return byReturnType;
return providers;
}
public <T> List<DataProvider<T>> getGroupMethodsByType(Class<T> returnType) {
List<DataProvider<T>> byReturnType = new ArrayList<>();
for (DataProvider dataProvider : byMethodType.getOrDefault(MethodType.GROUP, new HashMap<>()).getOrDefault(returnType, Collections.emptyList())) {
for (DataProvider<?> dataProvider : getProvidersByTypes(MethodType.GROUP, returnType)) {
byReturnType.add((DataProvider<T>) dataProvider);
}
return byReturnType;
}
public void removeProviderWithMethod(MethodWrapper toRemove) {
public void removeProviderWithMethod(MethodWrapper<?> toRemove) {
MethodType methodType = toRemove.getMethodType();
Map<Class, List<DataProvider>> byResultType = byMethodType.getOrDefault(methodType, Collections.emptyMap());
Map<Class<?>, List<DataProvider<?>>> byResultType = byMethodType.getOrDefault(methodType, Collections.emptyMap());
if (byResultType.isEmpty()) {
return;
}
Class resultType = toRemove.getResultType();
List<DataProvider> providers = byResultType.getOrDefault(resultType, Collections.emptyList());
if (providers.isEmpty()) {
return;
}
Class<?> returnType = toRemove.getReturnType();
List<DataProvider<?>> providers = getProvidersByTypes(methodType, returnType);
byResultType.put(resultType, providers.stream()
.filter(provider -> !provider.getMethod().equals(toRemove))
.collect(Collectors.toList())
);
byMethodType.put(methodType, byResultType);
DataProvider<?> providerToRemove = null;
for (DataProvider<?> provider : providers) {
if (provider.getMethod().equals(toRemove)) {
providerToRemove = provider;
break;
}
}
providers.remove(providerToRemove);
}
}

View File

@ -34,18 +34,18 @@ import java.util.UUID;
public class MethodWrapper<T> {
private final Method method;
private final Class<T> resultType;
private final Class<T> returnType;
private final MethodType methodType;
public MethodWrapper(Method method, Class<T> resultType) {
public MethodWrapper(Method method, Class<T> returnType) {
this.method = method;
this.resultType = resultType;
this.returnType = returnType;
methodType = MethodType.forMethod(this.method);
}
public T callMethod(DataExtension extension, UUID playerUUID, String playerName) {
if (methodType != MethodType.PLAYER_NAME && methodType != MethodType.PLAYER_UUID) {
throw new IllegalStateException(method.getDeclaringClass() + " method " + method.getName() + " is not GROUP method.");
throw new IllegalStateException(method.getDeclaringClass() + " method " + method.getName() + " is not PLAYER method.");
}
return callMethod(extension, playerUUID, playerName, null);
}
@ -68,13 +68,13 @@ public class MethodWrapper<T> {
try {
switch (methodType) {
case SERVER:
return resultType.cast(method.invoke(extension));
return returnType.cast(method.invoke(extension));
case PLAYER_UUID:
return resultType.cast(method.invoke(extension, playerUUID));
return returnType.cast(method.invoke(extension, playerUUID));
case PLAYER_NAME:
return resultType.cast(method.invoke(extension, playerName));
return returnType.cast(method.invoke(extension, playerName));
case GROUP:
return resultType.cast(method.invoke(extension, group));
return returnType.cast(method.invoke(extension, group));
default:
throw new IllegalArgumentException(method.getDeclaringClass() + " method " + method.getName() + " had invalid parameters.");
}
@ -97,8 +97,8 @@ public class MethodWrapper<T> {
return methodType;
}
public Class<T> getResultType() {
return resultType;
public Class<T> getReturnType() {
return returnType;
}
@Override
@ -107,12 +107,12 @@ public class MethodWrapper<T> {
if (!(o instanceof MethodWrapper)) return false;
MethodWrapper<?> that = (MethodWrapper<?>) o;
return method.equals(that.method) &&
resultType.equals(that.resultType) &&
returnType.equals(that.returnType) &&
methodType == that.methodType;
}
@Override
public int hashCode() {
return Objects.hash(method, resultType, methodType);
return Objects.hash(method, returnType, methodType);
}
}

View File

@ -68,7 +68,7 @@ public class ProviderValueGatherer {
String pluginName = extractor.getPluginName();
UUID serverUUID = serverInfo.getServerUUID();
Database database = dbSystem.getDatabase();
dataProviders = extractor.getDataProviders();
dataProviders = extractor.getProviders();
booleanGatherer = new BooleanProviderValueGatherer(
pluginName, extension, serverUUID, database, dataProviders
);

View File

@ -17,6 +17,7 @@
package com.djrapitops.plan.extension.implementation.results;
import com.djrapitops.plan.extension.implementation.TabInformation;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.*;
import java.util.stream.Collectors;
@ -131,11 +132,11 @@ public class ExtensionTabData implements Comparable<ExtensionTabData> {
}
private void createOrderingList() {
booleanData.values().stream().map(DescribedExtensionData::getDescriptive).forEach(descriptives::add);
doubleData.values().stream().map(DescribedExtensionData::getDescriptive).forEach(descriptives::add);
percentageData.values().stream().map(DescribedExtensionData::getDescriptive).forEach(descriptives::add);
numberData.values().stream().map(DescribedExtensionData::getDescriptive).forEach(descriptives::add);
stringData.values().stream().map(DescribedExtensionData::getDescriptive).forEach(descriptives::add);
descriptives.addAll(Lists.map(booleanData.values(), DescribedExtensionData::getDescriptive));
descriptives.addAll(Lists.map(doubleData.values(), DescribedExtensionData::getDescriptive));
descriptives.addAll(Lists.map(percentageData.values(), DescribedExtensionData::getDescriptive));
descriptives.addAll(Lists.map(numberData.values(), DescribedExtensionData::getDescriptive));
descriptives.addAll(Lists.map(stringData.values(), DescribedExtensionData::getDescriptive));
order = descriptives.stream().sorted()
.map(ExtensionDescriptive::getName)

View File

@ -25,6 +25,7 @@ import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPluginTable;
import com.djrapitops.plan.utilities.java.Lists;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -103,9 +104,8 @@ public class ExtensionInformationQueries {
Map<UUID, List<ExtensionInformation>> byServerUUID = new HashMap<>();
while (set.next()) {
UUID serverUUID = UUID.fromString(set.getString(ExtensionPluginTable.SERVER_UUID));
List<ExtensionInformation> information = byServerUUID.getOrDefault(serverUUID, new ArrayList<>());
List<ExtensionInformation> information = byServerUUID.computeIfAbsent(serverUUID, Lists::create);
information.add(extractExtensionInformationFromQuery(set));
byServerUUID.put(serverUUID, information);
}
return byServerUUID;
}

View File

@ -30,6 +30,7 @@ import com.djrapitops.plan.storage.database.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPlayerValueTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionProviderTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionTabTable;
import com.djrapitops.plan.utilities.java.Lists;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -100,9 +101,8 @@ public class ExtensionPlayerDataQuery implements Query<Map<UUID, List<ExtensionD
if (data == null) {
continue;
}
List<ExtensionData> list = extensionDataByServerUUID.getOrDefault(serverUUID, new ArrayList<>());
List<ExtensionData> list = extensionDataByServerUUID.computeIfAbsent(serverUUID, Lists::create);
list.add(data.setInformation(extensionInformation).build());
extensionDataByServerUUID.put(serverUUID, list);
}
}
return extensionDataByServerUUID;

View File

@ -19,6 +19,7 @@ package com.djrapitops.plan.extension.implementation.storage.queries;
import com.djrapitops.plan.extension.implementation.TabInformation;
import com.djrapitops.plan.extension.implementation.results.ExtensionData;
import com.djrapitops.plan.extension.implementation.results.ExtensionTabData;
import com.djrapitops.plan.utilities.java.Maps;
import com.djrapitops.plan.utilities.java.ThrowingSupplier;
import java.util.HashMap;
@ -38,7 +39,7 @@ public class QueriedTabData {
}
public <K extends Throwable> ExtensionTabData.Builder getTab(int pluginID, String tabName, ThrowingSupplier<TabInformation, K> newDefault) throws K {
Map<String, ExtensionTabData.Builder> byTabName = byPluginID.getOrDefault(pluginID, new HashMap<>());
Map<String, ExtensionTabData.Builder> byTabName = byPluginID.computeIfAbsent(pluginID, Maps::create);
ExtensionTabData.Builder tab = byTabName.get(tabName);
if (tab == null) {
@ -46,7 +47,6 @@ public class QueriedTabData {
}
byTabName.put(tabName, tab);
byPluginID.put(pluginID, byTabName);
return tab;
}

View File

@ -24,6 +24,7 @@ import com.djrapitops.plan.extension.implementation.results.ExtensionTabData;
import com.djrapitops.plan.extension.implementation.results.ExtensionTableData;
import com.djrapitops.plan.extension.table.Table;
import com.djrapitops.plan.extension.table.TableAccessor;
import com.djrapitops.plan.utilities.java.Maps;
import java.util.HashMap;
import java.util.Map;
@ -48,9 +49,8 @@ public class QueriedTables {
}
public void put(int pluginID, int tableID, Table.Factory table) {
Map<Integer, Table.Factory> byTableID = byPluginID.getOrDefault(pluginID, new HashMap<>());
Map<Integer, Table.Factory> byTableID = byPluginID.computeIfAbsent(pluginID, Maps::create);
byTableID.put(tableID, table);
byPluginID.put(pluginID, byTableID);
}
public void addRow(int pluginID, int tableID, Object... row) {

View File

@ -21,6 +21,8 @@ import com.djrapitops.plan.gathering.domain.builders.TPSBuilder;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.TPSTable;
import com.djrapitops.plan.storage.database.sql.tables.WorldTable;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plan.utilities.java.Maps;
import java.sql.ResultSet;
import java.sql.SQLException;
@ -67,7 +69,7 @@ public class LargeFetchQueries {
while (set.next()) {
UUID serverUUID = UUID.fromString(set.getString("s_uuid"));
List<TPS> tpsList = serverMap.getOrDefault(serverUUID, new ArrayList<>());
List<TPS> tpsList = serverMap.computeIfAbsent(serverUUID, Lists::create);
TPS tps = TPSBuilder.get()
.date(set.getLong(TPSTable.DATE))
@ -81,7 +83,6 @@ public class LargeFetchQueries {
.toTPS();
tpsList.add(tps);
serverMap.put(serverUUID, tpsList);
}
return serverMap;
}
@ -102,9 +103,8 @@ public class LargeFetchQueries {
Map<UUID, Collection<String>> worldMap = new HashMap<>();
while (set.next()) {
UUID serverUUID = UUID.fromString(set.getString(WorldTable.SERVER_UUID));
Collection<String> worlds = worldMap.getOrDefault(serverUUID, new HashSet<>());
Collection<String> worlds = worldMap.computeIfAbsent(serverUUID, Maps::createSet);
worlds.add(set.getString(WorldTable.NAME));
worldMap.put(serverUUID, worlds);
}
return worldMap;
}

View File

@ -79,7 +79,7 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
container.putRawData(PlayerKeys.KICK_COUNT, user.getTimesKicked());
// GeoInfo
container.putRawData(PlayerKeys.GEO_INFO, geoInformation.getOrDefault(uuid, new ArrayList<>()));
container.putRawData(PlayerKeys.GEO_INFO, geoInformation.getOrDefault(uuid, Collections.emptyList()));
// Ping
container.putRawData(PlayerKeys.PING, pingData.get(uuid));

View File

@ -22,6 +22,7 @@ import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.utilities.java.Lists;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -66,13 +67,9 @@ public class GeoInfoQueries {
while (set.next()) {
UUID uuid = UUID.fromString(set.getString(GeoInfoTable.USER_UUID));
List<GeoInfo> userGeoInfo = geoInformation.getOrDefault(uuid, new ArrayList<>());
String geolocation = set.getString(GeoInfoTable.GEOLOCATION);
long lastUsed = set.getLong(GeoInfoTable.LAST_USED);
userGeoInfo.add(new GeoInfo(geolocation, lastUsed));
geoInformation.put(uuid, userGeoInfo);
List<GeoInfo> userGeoInfo = geoInformation.computeIfAbsent(uuid, Lists::create);
GeoInfo geoInfo = new GeoInfo(set.getString(GeoInfoTable.GEOLOCATION), set.getLong(GeoInfoTable.LAST_USED));
userGeoInfo.add(geoInfo);
}
return geoInformation;
}

View File

@ -21,6 +21,8 @@ import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.NicknamesTable;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plan.utilities.java.Maps;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -61,17 +63,14 @@ public class NicknameQueries {
UUID serverUUID = UUID.fromString(set.getString(NicknamesTable.SERVER_UUID));
UUID uuid = UUID.fromString(set.getString(NicknamesTable.USER_UUID));
Map<UUID, List<Nickname>> serverMap = map.getOrDefault(serverUUID, new HashMap<>());
List<Nickname> nicknames = serverMap.getOrDefault(uuid, new ArrayList<>());
Map<UUID, List<Nickname>> serverMap = map.computeIfAbsent(serverUUID, Maps::create);
List<Nickname> nicknames = serverMap.computeIfAbsent(uuid, Lists::create);
nicknames.add(new Nickname(
set.getString(NicknamesTable.NICKNAME),
set.getLong(NicknamesTable.LAST_USED),
serverUUID
));
serverMap.put(uuid, nicknames);
map.put(serverUUID, serverMap);
}
return map;
}
@ -168,15 +167,13 @@ public class NicknameQueries {
UUID serverUUID = UUID.fromString(set.getString(NicknamesTable.SERVER_UUID));
UUID uuid = UUID.fromString(set.getString(NicknamesTable.USER_UUID));
List<Nickname> nicknames = serverMap.getOrDefault(uuid, new ArrayList<>());
List<Nickname> nicknames = serverMap.computeIfAbsent(uuid, Lists::create);
nicknames.add(new Nickname(
set.getString(NicknamesTable.NICKNAME),
set.getLong(NicknamesTable.LAST_USED),
serverUUID
));
serverMap.put(uuid, nicknames);
}
return serverMap;
}

View File

@ -23,6 +23,7 @@ import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.PingTable;
import com.djrapitops.plan.utilities.java.Lists;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -75,12 +76,11 @@ public class PingQueries {
int minPing = set.getInt(PingTable.MIN_PING);
int maxPing = set.getInt(PingTable.MAX_PING);
List<Ping> pings = userPings.getOrDefault(uuid, new ArrayList<>());
List<Ping> pings = userPings.computeIfAbsent(uuid, Lists::create);
pings.add(new Ping(date, serverUUID,
minPing,
maxPing,
avgPing));
userPings.put(uuid, pings);
}
return userPings;

View File

@ -29,6 +29,7 @@ import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.building.Sql;
import com.djrapitops.plan.storage.database.sql.tables.*;
import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
import com.djrapitops.plan.utilities.java.Maps;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -159,10 +160,10 @@ public class SessionQueries {
while (set.next()) {
UUID serverUUID = UUID.fromString(set.getString(SessionsTable.SERVER_UUID));
Map<UUID, SortedMap<Long, Session>> serverSessions = tempSessionMap.getOrDefault(serverUUID, new HashMap<>());
Map<UUID, SortedMap<Long, Session>> serverSessions = tempSessionMap.computeIfAbsent(serverUUID, Maps::create);
UUID playerUUID = UUID.fromString(set.getString(SessionsTable.USER_UUID));
SortedMap<Long, Session> playerSessions = serverSessions.getOrDefault(playerUUID, new TreeMap<>(longRecentComparator));
SortedMap<Long, Session> playerSessions = serverSessions.computeIfAbsent(playerUUID, key -> new TreeMap<>(longRecentComparator));
long sessionStart = set.getLong(SessionsTable.SESSION_START);
// id, uuid, serverUUID, sessionStart, sessionEnd, mobKills, deaths, afkTime
@ -206,8 +207,6 @@ public class SessionQueries {
session.setAsFirstSessionIfMatches(set.getLong("registered"));
playerSessions.put(sessionStart, session);
serverSessions.put(playerUUID, playerSessions);
tempSessionMap.put(serverUUID, serverSessions);
}
return tempSessionMap.values().stream()

View File

@ -23,6 +23,7 @@ import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.building.Select;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.utilities.java.Lists;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -157,11 +158,8 @@ public class TPSQueries {
Map<UUID, List<TPS>> byServer = new HashMap<>();
while (set.next()) {
UUID serverUUID = UUID.fromString(set.getString(ServerTable.SERVER_UUID));
List<TPS> ofServer = byServer.getOrDefault(serverUUID, new ArrayList<>());
List<TPS> ofServer = byServer.computeIfAbsent(serverUUID, Lists::create);
ofServer.add(extractTPS(set));
byServer.put(serverUUID, ofServer);
}
return byServer;
}

View File

@ -21,6 +21,7 @@ import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.utilities.java.Lists;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -64,14 +65,13 @@ public class UserInfoQueries {
UUID serverUUID = UUID.fromString(set.getString(UserInfoTable.SERVER_UUID));
UUID uuid = UUID.fromString(set.getString(UserInfoTable.USER_UUID));
List<UserInfo> userInfos = serverMap.getOrDefault(serverUUID, new ArrayList<>());
List<UserInfo> userInfos = serverMap.computeIfAbsent(serverUUID, Lists::create);
long registered = set.getLong(UserInfoTable.REGISTERED);
boolean banned = set.getBoolean(UserInfoTable.BANNED);
boolean op = set.getBoolean(UserInfoTable.OP);
userInfos.add(new UserInfo(uuid, serverUUID, registered, op, banned));
serverMap.put(serverUUID, userInfos);
}
return serverMap;
}

View File

@ -22,10 +22,10 @@ import com.djrapitops.plan.storage.database.queries.DataStoreQueries;
import com.djrapitops.plan.storage.database.transactions.Transaction;
import com.djrapitops.plan.utilities.Predicates;
import com.djrapitops.plan.utilities.analysis.Median;
import com.djrapitops.plan.utilities.java.Lists;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* Transaction to store player's Ping value on a server.
@ -76,6 +76,7 @@ public class PingStoreTransaction extends Transaction {
// VisibleForTesting
int getMeanValue() {
return (int) Median.forList(pingList.stream().map(DateObj::getValue).collect(Collectors.toList())).calculate();
List<Integer> values = Lists.map(pingList, DateObj::getValue);
return (int) Median.forList(values).calculate();
}
}

View File

@ -22,11 +22,15 @@ import com.djrapitops.plan.storage.database.sql.building.Select;
import com.djrapitops.plan.storage.database.sql.tables.NicknamesTable;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.transactions.ExecBatchStatement;
import com.djrapitops.plan.utilities.java.Maps;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import static com.djrapitops.plan.storage.database.sql.building.Sql.AND;
import static com.djrapitops.plan.storage.database.sql.building.Sql.WHERE;
@ -96,12 +100,11 @@ public class NicknameLastSeenPatch extends Patch {
int serverID = set.getInt("server_id");
UUID serverUUID = serverUUIDsByID.get(serverID);
Nickname nick = new Nickname(set.getString("additional_info"), date, serverUUID);
Set<Nickname> nicknames1 = map.getOrDefault(userID, new HashSet<>());
if (serverUUID == null || nicknames1.contains(nick)) {
Set<Nickname> foundNicknames = map.computeIfAbsent(userID, Maps::createSet);
if (serverUUID == null || foundNicknames.contains(nick)) {
continue;
}
nicknames1.add(nick);
map.put(userID, nicknames1);
foundNicknames.add(nick);
}
return map;

View File

@ -38,8 +38,7 @@ public class Predicates {
};
}
public static boolean pingInRange(int value) {
return value > 0 && value < 4000;
public static boolean pingInRange(double value) {
return value > 0 && value <= 4000;
}
}

View File

@ -0,0 +1,88 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.utilities.java;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* Methods that can be used as functional interfaces when dealing with Maps.
*
* @author Rsl1122
*/
public class Lists {
private Lists() {
// Static method class
}
public static <V, K> List<V> create(K key) {
return new ArrayList<>();
}
/**
* Efficient replacement for List#stream().filter(keep).collect(Collectors.toList()).
*
* @param original Original list
* @param keep Condition for keeping on the list
* @param <T> Type of the list objects
* @param <V> Supertype for T if exists, T if not
* @return List with elements in original that keep returned true for.
*/
public static <T extends V, V> List<T> filter(Collection<T> original, Predicate<V> keep) {
List<T> filtered = new ArrayList<>();
for (T value : original) {
if (keep.test(value)) filtered.add(value);
}
return filtered;
}
/**
* Efficient replacement for List#stream().map(mapper).collect(Collectors.toList()).
*
* @param original Original list
* @param mapper Function to change object of type A to type B
* @param <A> Type of the old list objects
* @param <B> Type of the new list objects
* @return List with elements in original that keep returned true for.
*/
public static <A, B> List<B> map(Collection<A> original, Function<A, B> mapper) {
List<B> mapped = new ArrayList<>();
for (A element : original) {
mapped.add(mapper.apply(element));
}
return mapped;
}
/**
* Efficient replacement for List#stream().map(mapper).collect(Collectors.toSet()).
*
* @param original Original list
* @param mapper Function to change object of type A to type B
* @param <A> Type of the old list objects
* @param <B> Type of the new list objects
* @return List with elements in original that keep returned true for.
*/
public static <A, B> Set<B> mapUnique(Collection<A> original, Function<A, B> mapper) {
Set<B> mapped = new HashSet<>();
for (A element : original) {
mapped.add(mapper.apply(element));
}
return mapped;
}
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.utilities.java;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Methods that can be used as functional interfaces when dealing with Maps.
*
* @author Rsl1122
*/
public class Maps {
private Maps() {
// Static method class
}
public static <V, T, K> Map<V, T> create(K key) {
return new HashMap<>();
}
public static <V, K> Set<V> createSet(K key) {
return new HashSet<>();
}
}

View File

@ -21,6 +21,7 @@ import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.PluginSettings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.lang.PluginLang;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plugin.api.utility.Version;
import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.console.PluginLogger;
@ -31,7 +32,6 @@ import javax.inject.Singleton;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* System for checking if new Version is available when the System initializes.
@ -73,7 +73,7 @@ public class VersionCheckSystem implements SubSystem {
try {
List<VersionInfo> versions = VersionInfoLoader.load();
if (config.isFalse(PluginSettings.NOTIFY_ABOUT_DEV_RELEASES)) {
versions = versions.stream().filter(VersionInfo::isRelease).collect(Collectors.toList());
versions = Lists.filter(versions, VersionInfo::isRelease);
}
VersionInfo newestVersion = versions.get(0);
if (Version.isNewVersionAvailable(new Version(currentVersion), newestVersion.getVersion())) {

View File

@ -67,6 +67,7 @@ import com.djrapitops.plan.storage.database.transactions.patches.Patch;
import com.djrapitops.plan.storage.database.transactions.patches.RegisterDateMinimizationPatch;
import com.djrapitops.plan.storage.upkeep.DBCleanTask;
import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plugin.logging.console.TestPluginLogger;
import com.djrapitops.plugin.logging.error.ConsoleErrorLogger;
import com.google.common.util.concurrent.MoreExecutors;
@ -188,7 +189,7 @@ public interface DatabaseTest {
saveGeoInfo(playerUUID, expected);
commitTest();
List<GeoInfo> result = db().query(GeoInfoQueries.fetchAllGeoInformation()).getOrDefault(playerUUID, new ArrayList<>());
List<GeoInfo> result = db().query(GeoInfoQueries.fetchAllGeoInformation()).get(playerUUID);
assertEquals(Collections.singletonList(expected), result);
}
@ -237,7 +238,7 @@ public interface DatabaseTest {
commitTest();
Collection<String> result = db().query(LargeFetchQueries.fetchAllWorldNames()).getOrDefault(serverUUID(), new HashSet<>());
Collection<String> result = db().query(LargeFetchQueries.fetchAllWorldNames()).get(serverUUID());
assertEquals(new HashSet<>(Arrays.asList(expected)), result);
}
@ -968,7 +969,7 @@ public interface DatabaseTest {
tpsData.sort(Comparator.comparingInt(TPS::getPlayers));
int expected = tpsData.get(tpsData.size() - 1).getPlayers();
int actual = db().query(TPSQueries.fetchAllTimePeakPlayerCount(serverUUID())).map(DateObj::getValue).orElse(-1);
assertEquals(expected, actual, () -> "Wrong return value. " + tpsData.stream().map(TPS::getPlayers).collect(Collectors.toList()).toString());
assertEquals(expected, actual, () -> "Wrong return value. " + Lists.map(tpsData, TPS::getPlayers).toString());
}
@Test

View File

@ -26,6 +26,7 @@ import com.djrapitops.plan.settings.locale.Message;
import com.djrapitops.plan.settings.locale.lang.CmdHelpLang;
import com.djrapitops.plan.settings.locale.lang.Lang;
import com.djrapitops.plan.utilities.PassEncryptUtil;
import com.djrapitops.plan.utilities.java.Lists;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
@ -62,7 +63,7 @@ class ComparatorTest {
Collections.reverse(expected);
sessions.sort(new SessionStartComparator());
List<Long> result = sessions.stream().map(s -> s.getUnsafe(SessionKeys.START)).collect(Collectors.toList());
List<Long> result = Lists.map(sessions, s -> s.getUnsafe(SessionKeys.START));
assertEquals(expected, result);
}
@ -89,7 +90,7 @@ class ComparatorTest {
Collections.reverse(expected);
webUsers.sort(new WebUserComparator());
List<Integer> result = webUsers.stream().map(WebUser::getPermLevel).collect(Collectors.toList());
List<Integer> result = Lists.map(webUsers, WebUser::getPermLevel);
assertEquals(expected, result);
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.utilities.java;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Tests for Java Map shenanigans.
*
* @author Rsl1122
*/
@RunWith(JUnitPlatform.class)
class MapsSanityTest {
@Test
void mapComputeIfAbsentPutSideEffect() {
Map<String, String> t = new HashMap<>();
t.computeIfAbsent("Test", key -> "Confirmed");
assertEquals("Confirmed", t.get("Test"));
}
}