mirror of
https://bitbucket.org/projectswg/lightspeed.git
synced 2026-07-28 22:15:50 -04:00
290 lines
9.7 KiB
Java
290 lines
9.7 KiB
Java
/***********************************************************************************
|
|
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
|
* *
|
|
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
|
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
|
* Our goal is to create an emulator which will provide a server for players to *
|
|
* continue playing a game similar to the one they used to play. We are basing *
|
|
* it on the final publish of the game prior to end-game events. *
|
|
* *
|
|
* This file is part of Holocore. *
|
|
* *
|
|
* -------------------------------------------------------------------------------- *
|
|
* *
|
|
* Holocore is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU Affero General Public License as *
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
* License, or (at your option) any later version. *
|
|
* *
|
|
* Holocore 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 Affero General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Affero General Public License *
|
|
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
|
* *
|
|
***********************************************************************************/
|
|
package com.projectswg.common.data;
|
|
|
|
import java.lang.ref.WeakReference;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.Set;
|
|
|
|
import com.projectswg.common.info.RelationalDatabase;
|
|
import com.projectswg.common.info.RelationalServerFactory;
|
|
import com.projectswg.lightspeed_frontend.data.SharedBuildData;
|
|
import com.projectswg.lightspeed_frontend.data.SharedDeploymentData;
|
|
import com.projectswg.lightspeed_frontend.data.SharedServerData;
|
|
|
|
public class BackendData {
|
|
|
|
private final WeakMap<String, SharedServerData> serverMap;
|
|
private final WeakMap<Long, SharedBuildData> buildMap;
|
|
private final WeakMap<Long, SharedDeploymentData> deploymentMap;
|
|
|
|
public BackendData() {
|
|
serverMap = new WeakMap<>();
|
|
buildMap = new WeakMap<>();
|
|
deploymentMap = new WeakMap<>();
|
|
loadServers();
|
|
}
|
|
|
|
public void insertServer(SharedServerData server) {
|
|
synchronized (serverMap) {
|
|
if (serverMap.put(server.getName(), server) != null)
|
|
return;
|
|
}
|
|
try (ServerTable serverTable = new ServerTable()) {
|
|
serverTable.insertServer(new SQLServerData(server.getName(), server.getDirectory(), server.getJvmArguments()));
|
|
}
|
|
}
|
|
|
|
public void insertBuild(SharedBuildData build) {
|
|
synchronized (buildMap) {
|
|
if (buildMap.put(build.getId(), build) != null)
|
|
return;
|
|
}
|
|
try (BuildHistoryTable buildTable = new BuildHistoryTable()) {
|
|
buildTable.insertBuildHistory(new SQLBuildData(build));
|
|
}
|
|
}
|
|
|
|
public void insertDeployment(SharedDeploymentData deployment) {
|
|
synchronized (deploymentMap) {
|
|
if (deploymentMap.put(deployment.getId(), deployment) != null)
|
|
return;
|
|
}
|
|
try (DeploymentTable deploymentTable = new DeploymentTable()) {
|
|
deploymentTable.insertDeployment(new SQLDeploymentData(deployment));
|
|
}
|
|
}
|
|
|
|
public void removeServer(String serverId) {
|
|
synchronized (serverMap) {
|
|
serverMap.remove(serverId);
|
|
}
|
|
try (ServerTable serverTable = new ServerTable()) {
|
|
serverTable.deleteServer(serverId);
|
|
}
|
|
}
|
|
|
|
public List<SharedServerData> getServerList() {
|
|
List<SharedServerData> servers = new ArrayList<>(serverMap.size());
|
|
synchronized (serverMap) {
|
|
for (Entry<String, SharedServerData> e : serverMap.entrySet()) {
|
|
servers.add(e.getValue());
|
|
}
|
|
}
|
|
return servers;
|
|
}
|
|
|
|
public SharedServerData getServer(String serverId) {
|
|
synchronized (serverMap) {
|
|
SharedServerData server = serverMap.get(serverId);
|
|
if (server != null)
|
|
return server;
|
|
server = fetchServer(serverId);
|
|
serverMap.put(serverId, server);
|
|
return server;
|
|
}
|
|
}
|
|
|
|
public SharedBuildData getBuild(long buildId) {
|
|
synchronized (buildMap) {
|
|
SharedBuildData build = buildMap.get(buildId);
|
|
if (build != null)
|
|
return build;
|
|
build = fetchBuild(buildId);
|
|
buildMap.put(buildId, build);
|
|
return build;
|
|
}
|
|
}
|
|
|
|
private void loadServers() {
|
|
synchronized (serverMap) {
|
|
try (RelationalDatabase db = RelationalServerFactory.getServerDatabase("lightspeed.db")) {
|
|
try (ServerTable serverTable = new ServerTable(db)) {
|
|
for (String serverId : serverTable.getServerStrings()) {
|
|
SharedServerData server = fetchServer(serverId);
|
|
serverMap.put(server.getName(), server);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private SharedServerData fetchServer(String serverId) {
|
|
try (RelationalDatabase db = RelationalServerFactory.getServerDatabase("lightspeed.db")) {
|
|
try (ServerTable serverTable = new ServerTable(db)) {
|
|
SharedServerData server = createServerFromInfo(serverTable.getServerById(serverId));
|
|
fetchBuildHistory(db, server);
|
|
return server;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void fetchBuildHistory(RelationalDatabase db, SharedServerData server) {
|
|
try (BuildHistoryTable buildTable = new BuildHistoryTable(db)) {
|
|
for (SQLBuildData info : buildTable.getBuildHistory(server.getName())) {
|
|
SharedBuildData build = createBuildFromInfo(server, info);
|
|
synchronized (buildMap) {
|
|
buildMap.put(build.getId(), build);
|
|
}
|
|
fetchDeploymentHistory(db, build);
|
|
server.addBuild(build);
|
|
}
|
|
}
|
|
}
|
|
|
|
private SharedBuildData fetchBuild(long buildId) {
|
|
try (RelationalDatabase db = RelationalServerFactory.getServerDatabase("lightspeed.db")) {
|
|
try (BuildHistoryTable buildTable = new BuildHistoryTable(db)) {
|
|
SQLBuildData info = buildTable.getBuildById(buildId);
|
|
SharedServerData server = getServer(info.getServerId());
|
|
SharedBuildData build = createBuildFromInfo(server, info);
|
|
fetchDeploymentHistory(db, build);
|
|
return build;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void fetchDeploymentHistory(RelationalDatabase db, SharedBuildData build) {
|
|
try (DeploymentTable deploymentTable = new DeploymentTable(db)) {
|
|
for (SQLDeploymentData info : deploymentTable.getDeployments(build.getId())) {
|
|
SharedDeploymentData deployment = createDeploymentFromInfo(build, info);
|
|
build.addDeployment(deployment);
|
|
synchronized (deploymentMap) {
|
|
deploymentMap.put(deployment.getId(), deployment);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private SharedServerData createServerFromInfo(SQLServerData info) {
|
|
SharedServerData server = new SharedServerData(info.getId());
|
|
server.setDirectory(info.getDir());
|
|
server.setJvmArguments(info.getJvmArgs());
|
|
return server;
|
|
}
|
|
|
|
private SharedBuildData createBuildFromInfo(SharedServerData server, SQLBuildData info) {
|
|
SharedBuildData build = new SharedBuildData(info.getId(), server);
|
|
build.setTime(info.getCompletedTime());
|
|
build.setBuildString(info.getBuildString());
|
|
build.setTestString(info.getTestString());
|
|
build.setCompileTime(info.getCompileTime());
|
|
build.setOffline(info.isOffline());
|
|
build.setBuildSuccess(info.isBuildSuccess());
|
|
build.setTestSuccess(info.isTestSuccess());
|
|
build.setCancelled(info.isCancelled());
|
|
build.setTestDetails(info.getTestDetails());
|
|
build.setJar(info.getJar());
|
|
return build;
|
|
}
|
|
|
|
private SharedDeploymentData createDeploymentFromInfo(SharedBuildData build, SQLDeploymentData info) {
|
|
SharedDeploymentData deployment = new SharedDeploymentData(info.getId(), build);
|
|
deployment.setStartTime(info.getStartTime());
|
|
deployment.setEndTime(info.getEndTime());
|
|
return deployment;
|
|
}
|
|
|
|
private static class WeakMap<K, V> {
|
|
|
|
private final Map<K, WeakReference<V>> map;
|
|
|
|
public WeakMap() {
|
|
map = new HashMap<>();
|
|
}
|
|
|
|
public V get(K key) {
|
|
WeakReference<V> ref = map.get(key);
|
|
return (ref == null) ? null : ref.get();
|
|
}
|
|
|
|
public V put(K key, V val) {
|
|
WeakReference<V> ref = map.put(key, new WeakReference<>(val));
|
|
if (ref == null)
|
|
return null;
|
|
return ref.get();
|
|
}
|
|
|
|
public boolean remove(K key) {
|
|
return map.remove(key) != null;
|
|
}
|
|
|
|
public Set<Entry<K, V>> entrySet() {
|
|
Set<Entry<K, WeakReference<V>>> entries = map.entrySet();
|
|
Set<Entry<K, V>> ret = new HashSet<>();
|
|
for (Entry<K, WeakReference<V>> entry : entries) {
|
|
if (entry.getValue() != null) {
|
|
V val = entry.getValue().get();
|
|
if (val != null)
|
|
ret.add(new WeakEntry<>(entry.getKey(), val));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
public int size() {
|
|
return map.size();
|
|
}
|
|
|
|
}
|
|
|
|
private static class WeakEntry<K, V> implements Map.Entry<K, V> {
|
|
|
|
private final K key;
|
|
private V value;
|
|
|
|
public WeakEntry(K key, V value) {
|
|
this.key = key;
|
|
this.value = value;
|
|
}
|
|
|
|
@Override
|
|
public K getKey() {
|
|
return key;
|
|
}
|
|
|
|
@Override
|
|
public V getValue() {
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public V setValue(V value) {
|
|
V old = this.value;
|
|
this.value = value;
|
|
return old;
|
|
}
|
|
}
|
|
|
|
}
|