Storage of plugin info, icon and tabs of DataExtension

This commit is contained in:
Rsl1122 2019-03-17 11:56:33 +02:00
parent 41f5ce4853
commit c5b28fe3f9
13 changed files with 593 additions and 6 deletions

View File

@ -16,6 +16,9 @@
*/
package com.djrapitops.plan.extension;
import java.util.ArrayList;
import java.util.List;
/**
* Enum representing big elements of a plugin.
* <p>
@ -36,5 +39,39 @@ public enum ElementOrder {
/**
* Represents graphs.
*/
GRAPH
GRAPH;
public static String serialize(ElementOrder[] order) {
StringBuilder builder = new StringBuilder();
int length = order.length;
for (int i = 0; i < length; i++) {
builder.append(order[i].name());
if (i < length - 1) {
builder.append(',');
}
}
return builder.toString();
}
public static ElementOrder[] deserialize(String serializedOrder) {
if (serializedOrder == null || serializedOrder.isEmpty()) {
return null;
}
String[] split = serializedOrder.split(",");
List<ElementOrder> order = new ArrayList<>();
for (String elementName : split) {
try {
ElementOrder element = valueOf(elementName);
order.add(element);
} catch (IllegalArgumentException ignore) {
/* Has been deleted */
}
}
return order.toArray(new ElementOrder[0]);
}
}

View File

@ -52,7 +52,7 @@ public class Icon {
return new Builder().of(color);
}
public Family getType() {
public Family getFamily() {
return type;
}

View File

@ -0,0 +1,55 @@
/*
* 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.db.sql.tables;
import com.djrapitops.plan.extension.icon.Icon;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
/**
* Table information about 'plan_extension_icons'.
*
* @author Rsl1122
*/
public class ExtensionIconTable {
public static final String TABLE_NAME = "plan_extension_icons";
public static final String ID = "id";
public static final String ICON_NAME = "name";
public static final String FAMILY = "family";
public static final String COLOR = "color";
public static final String STATEMENT_SELECT_ICON_ID = "(" + SELECT + ID +
FROM + TABLE_NAME +
WHERE + ICON_NAME + "=?" +
AND + FAMILY + "=?" +
AND + COLOR + "=?)";
public static void setIconValuesToStatement(PreparedStatement statement, Icon icon) throws SQLException {
setIconValuesToStatement(statement, 1, icon);
}
public static void setIconValuesToStatement(PreparedStatement statement, int parameterIndex, Icon icon) throws SQLException {
statement.setString(parameterIndex, icon.getName());
statement.setString(parameterIndex + 1, icon.getFamily().name());
statement.setString(parameterIndex + 2, icon.getColor().name());
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.db.sql.tables;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.UUID;
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
/**
* Table information about 'plan_extension_plugins'.
*
* @author Rsl1122
*/
public class ExtensionPluginTable {
public static final String TABLE_NAME = "plan_extension_plugins";
public static final String ID = "id";
public static final String PLUGIN_NAME = "name";
public static final String LAST_UPDATED = "last_updated";
public static final String SERVER_UUID = "server_uuid";
public static final String ICON_ID = "icon_id";
public static final String STATEMENT_SELECT_PLUGIN_ID = "(" + SELECT + ID +
FROM + TABLE_NAME +
WHERE + PLUGIN_NAME + "=?" +
AND + SERVER_UUID + "=?)";
public static void setPluginValuesToStatement(PreparedStatement statement, int parameterIndex, String pluginName, UUID serverUUID) throws SQLException {
statement.setString(parameterIndex, pluginName);
statement.setString(parameterIndex + 1, serverUUID.toString());
}
}

View File

@ -0,0 +1,19 @@
package com.djrapitops.plan.db.sql.tables;
/**
* Table information about 'plan_extension_tabs'.
*
* @author Rsl1122
*/
public class ExtensionTabTable {
public static final String TABLE_NAME = "plan_extension_tabs";
public static final String ID = "id";
public static final String TAB_NAME = "name";
public static final String ELEMENT_ORDER = "element_order";
public static final String TAB_PRIORITY = "tab_priority";
public static final String PLUGIN_ID = "plugin_id";
public static final String ICON_ID = "icon_id";
}

View File

@ -27,6 +27,7 @@ import com.djrapitops.plan.extension.implementation.providers.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
@ -72,6 +73,8 @@ public class DataProviderExtractor {
Map<String, TabInfo> tabInformation = extensionExtractor.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()
.map(Tab::value)
@ -81,11 +84,20 @@ public class DataProviderExtractor {
return new PluginTab(
tabName,
tabInfo.map(info -> new Icon(info.iconFamily(), info.iconName(), Color.NONE)).orElse(null),
tabInfo.map(TabInfo::elementOrder).orElse(null)
tabInfo.map(TabInfo::elementOrder).orElse(null),
order.getOrDefault(tabName, 100)
);
}).collect(Collectors.toList());
}
private Map<String, Integer> orderToMap(String[] order) {
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < order.length; i++) {
map.put(order[i], i);
}
return map;
}
public Optional<String[]> getTabOrder() {
return extensionExtractor.getTabOrder().map(TabOrder::value);
}

View File

@ -17,6 +17,8 @@
package com.djrapitops.plan.extension.implementation;
import com.djrapitops.plan.extension.ElementOrder;
import com.djrapitops.plan.extension.icon.Color;
import com.djrapitops.plan.extension.icon.Family;
import com.djrapitops.plan.extension.icon.Icon;
import com.djrapitops.plugin.utilities.ArrayUtil;
@ -34,19 +36,25 @@ public class PluginTab {
private final String tabName;
private final Icon icon; // can be null
private ElementOrder[] elementOrder; // can be null / miss values
private int tabPriority;
public PluginTab(String tabName, Icon icon, ElementOrder[] elementOrder) {
public PluginTab(String tabName, Icon icon, ElementOrder[] elementOrder, int tabPriority) {
this.tabName = tabName;
this.icon = icon;
this.elementOrder = elementOrder;
this.tabPriority = tabPriority;
}
public String getTabName() {
return tabName;
}
public Optional<Icon> getTabIcon() {
return Optional.ofNullable(icon);
public Icon getTabIcon() {
return icon != null ? icon : new Icon(Family.SOLID, "circle", Color.NONE);
}
public int getTabPriority() {
return tabPriority;
}
public Optional<ElementOrder[]> getTabElementOrder() {

View File

@ -0,0 +1,81 @@
/*
* 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.extension.implementation;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.extension.DataExtension;
import com.djrapitops.plan.extension.icon.Icon;
import com.djrapitops.plan.extension.implementation.storage.transactions.RemoveInvalidResultsTransaction;
import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIconTransaction;
import com.djrapitops.plan.extension.implementation.storage.transactions.StorePluginTabTransaction;
import com.djrapitops.plan.extension.implementation.storage.transactions.StorePluginTransaction;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plugin.logging.console.PluginLogger;
import java.util.UUID;
/**
* Object that can be called to place data about players to the database.
*
* @author Rsl1122
*/
public class ProviderValueGatherer {
private final DataExtension extension;
private final DataProviderExtractor extractor;
private final DBSystem dbSystem;
private final ServerInfo serverInfo;
private final PluginLogger logger;
public ProviderValueGatherer(
DataExtension extension,
DataProviderExtractor extractor,
DBSystem dbSystem,
ServerInfo serverInfo,
PluginLogger logger
) {
this.extension = extension;
this.extractor = extractor;
this.dbSystem = dbSystem;
this.serverInfo = serverInfo;
this.logger = logger;
}
public void storeProviderInformation() {
String pluginName = extractor.getPluginName();
Icon pluginIcon = extractor.getPluginIcon();
long time = System.currentTimeMillis();
UUID serverUUID = serverInfo.getServerUUID();
Database database = dbSystem.getDatabase();
database.executeTransaction(new StoreIconTransaction(pluginIcon));
database.executeTransaction(new StorePluginTransaction(pluginName, time, serverUUID, pluginIcon));
for (PluginTab tab : extractor.getPluginTabs()) {
database.executeTransaction(new StoreIconTransaction(tab.getTabIcon()));
database.executeTransaction(new StorePluginTabTransaction(pluginName, serverUUID, tab));
}
// TODO implement after storage
database.executeTransaction(new RemoveInvalidResultsTransaction(pluginName, serverUUID, extractor.getInvalidatedMethods()));
}
public void updateValues(UUID playerUUID) {
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.extension.implementation.storage.transactions;
import com.djrapitops.plan.db.access.transactions.Transaction;
import java.util.Collection;
import java.util.UUID;
/**
* Transaction to remove method results that correspond to {@link com.djrapitops.plan.extension.annotation.InvalidateMethod} annotations.
*
* @author Rsl1122
*/
public class RemoveInvalidResultsTransaction extends Transaction {
private final String pluginName;
private final UUID serverUUID;
private final Collection<String> invalidatedMethods;
public RemoveInvalidResultsTransaction(String pluginName, UUID serverUUID, Collection<String> invalidatedMethods) {
this.pluginName = pluginName;
this.serverUUID = serverUUID;
this.invalidatedMethods = invalidatedMethods;
}
@Override
protected void performOperations() {
// TODO implement after storage
}
}

View File

@ -0,0 +1,79 @@
/*
* 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.extension.implementation.storage.transactions;
import com.djrapitops.plan.db.access.ExecStatement;
import com.djrapitops.plan.db.access.Executable;
import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement;
import com.djrapitops.plan.db.access.Query;
import com.djrapitops.plan.db.access.transactions.Transaction;
import com.djrapitops.plan.db.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.extension.icon.Icon;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
/**
* Transaction to store an Icon to the database.
*
* @author Rsl1122
*/
public class StoreIconTransaction extends Transaction {
private final Icon icon;
public StoreIconTransaction(Icon icon) {
this.icon = icon;
}
@Override
protected void performOperations() {
if (!query(isIconStored())) {
execute(insertIcon());
}
}
private Executable insertIcon() {
String sql = "INSERT INTO " + ExtensionIconTable.TABLE_NAME + "(" +
ExtensionIconTable.ICON_NAME + "," +
ExtensionIconTable.FAMILY + "," +
ExtensionIconTable.COLOR +
") VALUES (?,?,?)";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
ExtensionIconTable.setIconValuesToStatement(statement, icon);
}
};
}
private Query<Boolean> isIconStored() {
String sql = SELECT + "COUNT(1) as c" +
FROM + ExtensionIconTable.TABLE_NAME +
WHERE + ExtensionIconTable.ICON_NAME + "=?" +
AND + ExtensionIconTable.FAMILY + "=?" +
AND + ExtensionIconTable.COLOR + "=?";
return new HasMoreThanZeroQueryStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
ExtensionIconTable.setIconValuesToStatement(statement, icon);
}
};
}
}

View File

@ -0,0 +1,89 @@
package com.djrapitops.plan.extension.implementation.storage.transactions;
import com.djrapitops.plan.db.access.ExecStatement;
import com.djrapitops.plan.db.access.Executable;
import com.djrapitops.plan.db.access.transactions.Transaction;
import com.djrapitops.plan.db.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable;
import com.djrapitops.plan.db.sql.tables.ExtensionTabTable;
import com.djrapitops.plan.extension.ElementOrder;
import com.djrapitops.plan.extension.implementation.PluginTab;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.UUID;
import static com.djrapitops.plan.db.sql.parsing.Sql.AND;
import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE;
/**
* Transaction for storing {@link com.djrapitops.plan.extension.implementation.PluginTab}s.
*
* @author Rsl1122
*/
public class StorePluginTabTransaction extends Transaction {
private final String pluginName;
private final UUID serverUUID;
private final PluginTab pluginTab;
public StorePluginTabTransaction(String pluginName, UUID serverUUID, PluginTab pluginTab) {
this.pluginName = pluginName;
this.serverUUID = serverUUID;
this.pluginTab = pluginTab;
}
@Override
protected void performOperations() {
execute(storeTab());
}
private Executable storeTab() {
return connection -> {
if (!updateTab().execute(connection)) {
return insertTab().execute(connection);
}
return false;
};
}
private Executable updateTab() {
String sql = "UPDATE " + ExtensionTabTable.TABLE_NAME +
" SET (" +
ExtensionTabTable.TAB_PRIORITY + "=?," +
ExtensionTabTable.ELEMENT_ORDER + "=?," +
ExtensionTabTable.ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + "," +
")" + WHERE + ExtensionTabTable.PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID +
AND + ExtensionTabTable.TAB_NAME + "=?";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setInt(1, pluginTab.getTabPriority());
statement.setString(2, pluginTab.getTabElementOrder().map(ElementOrder::serialize).orElse(null));
ExtensionIconTable.setIconValuesToStatement(statement, 3, pluginTab.getTabIcon());
ExtensionPluginTable.setPluginValuesToStatement(statement, 6, pluginName, serverUUID);
statement.setString(8, pluginTab.getTabName());
}
};
}
private Executable insertTab() {
String sql = "INSERT INFO " + ExtensionTabTable.TABLE_NAME + "(" +
ExtensionTabTable.TAB_NAME + "," +
ExtensionTabTable.ELEMENT_ORDER + "," +
ExtensionTabTable.TAB_PRIORITY + "," +
ExtensionTabTable.ICON_ID +
ExtensionTabTable.PLUGIN_ID +
") VALUES (?,?,?," + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + "," + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, pluginTab.getTabName());
statement.setString(2, pluginTab.getTabElementOrder().map(ElementOrder::serialize).orElse(null));
statement.setInt(3, pluginTab.getTabPriority());
ExtensionIconTable.setIconValuesToStatement(statement, 4, pluginTab.getTabIcon());
ExtensionPluginTable.setPluginValuesToStatement(statement, 7, pluginName, serverUUID);
}
};
}
}

View File

@ -0,0 +1,101 @@
/*
* 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.extension.implementation.storage.transactions;
import com.djrapitops.plan.db.access.ExecStatement;
import com.djrapitops.plan.db.access.Executable;
import com.djrapitops.plan.db.access.transactions.Transaction;
import com.djrapitops.plan.db.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable;
import com.djrapitops.plan.extension.icon.Icon;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.UUID;
import static com.djrapitops.plan.db.sql.parsing.Sql.AND;
import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE;
/**
* Transaction to update command usage information in the database.
*
* @author Rsl1122
*/
public class StorePluginTransaction extends Transaction {
private final String pluginName;
private final long time;
private final UUID serverUUID;
private final Icon icon;
public StorePluginTransaction(String pluginName, long time, UUID serverUUID, Icon icon) {
this.pluginName = pluginName;
this.time = time;
this.serverUUID = serverUUID;
this.icon = icon;
}
@Override
protected void performOperations() {
execute(storePlugin());
}
private Executable storePlugin() {
return connection -> {
if (!updatePlugin().execute(connection)) {
return insertPlugin().execute(connection);
}
return false;
};
}
private Executable updatePlugin() {
String sql = "UPDATE " + ExtensionPluginTable.TABLE_NAME +
" SET (" +
ExtensionPluginTable.LAST_UPDATED + "=?," +
ExtensionPluginTable.ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID +
")" + WHERE + ExtensionPluginTable.PLUGIN_NAME + "=?" +
AND + ExtensionPluginTable.SERVER_UUID + "=?";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setLong(1, time);
ExtensionIconTable.setIconValuesToStatement(statement, 2, icon);
statement.setString(5, pluginName);
statement.setString(6, serverUUID.toString());
}
};
}
private Executable insertPlugin() {
String sql = "INSERT INFO " + ExtensionPluginTable.TABLE_NAME + "(" +
ExtensionPluginTable.PLUGIN_NAME + "," +
ExtensionPluginTable.LAST_UPDATED + "," +
ExtensionPluginTable.SERVER_UUID + "," +
ExtensionPluginTable.ICON_ID +
") VALUES (?,?,?," + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ")";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, pluginName);
statement.setLong(2, time);
statement.setString(3, serverUUID.toString());
ExtensionIconTable.setIconValuesToStatement(statement, 4, icon);
}
};
}
}

View File

@ -35,6 +35,18 @@ public class Icon {
this.color = color;
}
public Family getFamily() {
return type;
}
public String getName() {
return name;
}
public Color getColor() {
return color;
}
public static Builder called(String name) {
return new Builder().called(name);
}