Commits vergleichen
1 Commits
master
...
schemnode_
Autor | SHA1 | Datum | |
---|---|---|---|
|
662c3cdd9b |
@ -22,6 +22,7 @@ package de.steamwar.sql;
|
||||
import de.steamwar.sql.internal.Field;
|
||||
import de.steamwar.sql.internal.SelectStatement;
|
||||
import de.steamwar.sql.internal.Table;
|
||||
import de.steamwar.sql.v2.SchematicNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
|
@ -19,134 +19,43 @@
|
||||
|
||||
package de.steamwar.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Deprecated
|
||||
public class SchematicNode {
|
||||
|
||||
static {
|
||||
new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> { throw new SecurityException("SchematicNode cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.nodeId));
|
||||
private static int nullableInt(Integer i) {
|
||||
return i == null ? 0 : i;
|
||||
}
|
||||
|
||||
private static final Map<Integer, Map<String, List<String>>> TAB_CACHE = new HashMap<>();
|
||||
public static void clear() {
|
||||
TAB_CACHE.clear();
|
||||
}
|
||||
|
||||
private static final String[] fields = {"NodeId", "NodeOwner", "NodeName", "ParentNode", "LastUpdate", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay", "NodeFormat"};
|
||||
private static String nodeSelectCreator(String itemPrefix) {
|
||||
return "SELECT " + Arrays.stream(fields).map(s -> itemPrefix + s).collect(Collectors.joining(", ")) + " FROM SchematicNode ";
|
||||
}
|
||||
|
||||
private static final Table<SchematicNode> table = new Table<>(SchematicNode.class);
|
||||
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType");
|
||||
private static final Statement update = table.insertAll();
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
private static final SelectStatement<SchematicNode> byId = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<SchematicNode> byOwnerNameParent = table.select("OwnerNameParent");
|
||||
private static final SelectStatement<SchematicNode> byOwnerNameParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode is NULL");
|
||||
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? AND NodeType is NULL ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> dirsByParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL AND NodeType is NULL ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byParentName = table.selectFields("NodeName", "ParentNode");
|
||||
private static final SelectStatement<SchematicNode> byParentName_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeName = ? AND ParentNode is NULL");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserTypeParent = new SelectStatement<>(table, "WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? UNION " + nodeSelectCreator("SN.") + "AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserTypeParent_Null = new SelectStatement<>(table, "WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? UNION " + nodeSelectCreator("SN.") + "AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode is null ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table, "WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUser = new SelectStatement<>(table, nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) AND ((s.NodeOwner = ? AND s.ParentNode IS NULL) OR NOT s.NodeOwner = ?) GROUP BY s.NodeId ORDER BY s.NodeName");
|
||||
private static final Statement schematicAccessibleForUser = new Statement("WITH RECURSIVE RSN AS (" + nodeSelectCreator("") + "WHERE NodeId = ? UNION " + nodeSelectCreator("SN.") + "SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT COUNT(RSN.NodeId) AS `Accessible` FROM RSN LEFT Join NodeMember NM On NM.NodeId = RSN.NodeId WHERE NodeOwner = ? OR UserId = ? LIMIT 1");
|
||||
private static final SelectStatement<SchematicNode> allAccessibleByUser = new SelectStatement<>(table, "WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (" + nodeSelectCreator("") + "WHERE NodeId = ? UNION " + nodeSelectCreator("SN.") + "SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
|
||||
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
private final int nodeId;
|
||||
@Field(keys = {"OwnerNameParent"})
|
||||
private final int nodeOwner;
|
||||
@Field(keys = {"OwnerNameParent"})
|
||||
private String nodeName;
|
||||
@Field(keys = {"OwnerNameParent"}, nullable = true)
|
||||
private Integer parentNode;
|
||||
@Field(def = "CURRENT_TIMESTAMP")
|
||||
private Timestamp lastUpdate;
|
||||
@Field(def = "''")
|
||||
private String nodeItem;
|
||||
@Field(def = "'normal'", nullable = true)
|
||||
private SchematicType nodeType;
|
||||
@Field(def = "0")
|
||||
private int nodeRank;
|
||||
@Field(def = "1")
|
||||
private boolean replaceColor;
|
||||
@Field(def = "1")
|
||||
private boolean allowReplay;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Field(def = "1")
|
||||
private boolean nodeFormat;
|
||||
private final de.steamwar.sql.v2.SchematicNode node;
|
||||
|
||||
private final Map<Integer, String> brCache = new HashMap<>();
|
||||
|
||||
public SchematicNode(
|
||||
int nodeId,
|
||||
int nodeOwner,
|
||||
String nodeName,
|
||||
Integer parentNode,
|
||||
Timestamp lastUpdate,
|
||||
String nodeItem,
|
||||
SchematicType nodeType,
|
||||
int nodeRank,
|
||||
boolean replaceColor,
|
||||
boolean allowReplay,
|
||||
boolean nodeFormat
|
||||
) {
|
||||
this.nodeId = nodeId;
|
||||
this.nodeOwner = nodeOwner;
|
||||
this.nodeName = nodeName;
|
||||
this.parentNode = parentNode;
|
||||
this.nodeItem = nodeItem;
|
||||
this.nodeType = nodeType;
|
||||
this.lastUpdate = lastUpdate;
|
||||
this.nodeRank = nodeRank;
|
||||
this.replaceColor = replaceColor;
|
||||
this.allowReplay = allowReplay;
|
||||
this.nodeFormat = nodeFormat;
|
||||
public SchematicNode(de.steamwar.sql.v2.SchematicNode node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public static SchematicNode createSchematic(int owner, String name, Integer parent) {
|
||||
return createSchematicNode(owner, name, parent, SchematicType.Normal.toDB(), "");
|
||||
return new SchematicNode(de.steamwar.sql.v2.SchematicNode.createSchematic(SteamwarUser.get(owner), name, nullableInt(parent)));
|
||||
}
|
||||
|
||||
public static SchematicNode createSchematicDirectory(int owner, String name, Integer parent) {
|
||||
return createSchematicNode(owner, name, parent, null, "");
|
||||
return new SchematicNode(de.steamwar.sql.v2.SchematicNode.createSchematicNode(SteamwarUser.get(owner), name, nullableInt(parent), null, ""));
|
||||
}
|
||||
|
||||
public static SchematicNode createSchematicNode(int owner, String name, Integer parent, String type, String item) {
|
||||
if (parent != null && parent == 0)
|
||||
parent = null;
|
||||
int nodeId = create.insertGetKey(owner, name, parent, type, item);
|
||||
return getSchematicNode(nodeId);
|
||||
return new SchematicNode(de.steamwar.sql.v2.SchematicNode.createSchematicNode(SteamwarUser.get(owner), name, nullableInt(parent), type, item));
|
||||
}
|
||||
|
||||
public static SchematicNode getSchematicNode(int owner, String name, SchematicNode parent) {
|
||||
return getSchematicNode(owner, name, parent.getId());
|
||||
return de.steamwar.sql.v2.SchematicNode.getSchematicNode(SteamwarUser.get(owner), name, parent.node).map(SchematicNode::new).orElse(null);
|
||||
}
|
||||
|
||||
public static SchematicNode getSchematicNode(int owner, String name, Integer parent) {
|
||||
if (parent == null || parent == 0)
|
||||
return byOwnerNameParent_null.select(owner, name);
|
||||
return byOwnerNameParent.select(owner, name, parent);
|
||||
return de.steamwar.sql.v2.SchematicNode.getSchematicNode(SteamwarUser.get(owner), name, de.steamwar.sql.v2.SchematicNode.getSchematicNode(nullableInt(parent))).map(SchematicNode::new).orElse(null);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getSchematicNodeInNode(SchematicNode parent) {
|
||||
@ -154,20 +63,11 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getSchematicNodeInNode(Integer parent) {
|
||||
if(parent == null || parent == 0) {
|
||||
rootWarning();
|
||||
return byParent_null.listSelect();
|
||||
}
|
||||
|
||||
return byParent.listSelect(parent);
|
||||
return de.steamwar.sql.v2.SchematicNode.getSchematicNodeInNode(de.steamwar.sql.v2.SchematicNode.getSchematicNode(nullableInt(parent))).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getSchematicDirectoryInNode(Integer parent) {
|
||||
if(parent == null || parent == 0) {
|
||||
rootWarning();
|
||||
return dirsByParent_null.listSelect();
|
||||
}
|
||||
return dirsByParent.listSelect(parent);
|
||||
return de.steamwar.sql.v2.SchematicNode.getSchematicDirectoryInNode(de.steamwar.sql.v2.SchematicNode.getSchematicNode(nullableInt(parent))).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ -181,69 +81,44 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public static SchematicNode getSchematicNode(String name, Integer parent) {
|
||||
if(parent == null || parent == 0) {
|
||||
rootWarning();
|
||||
return byParentName_null.select(name);
|
||||
}
|
||||
return byParentName.select(name, parent);
|
||||
return de.steamwar.sql.v2.SchematicNode.getSchematicNode(name, de.steamwar.sql.v2.SchematicNode.getSchematicNode(nullableInt(parent))).map(SchematicNode::new).orElse(null);
|
||||
}
|
||||
|
||||
public static SchematicNode getSchematicNode(int id) {
|
||||
return byId.select(id);
|
||||
return new SchematicNode(de.steamwar.sql.v2.SchematicNode.getSchematicNode(id));
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) {
|
||||
if(parent == null || parent == 0)
|
||||
return accessibleByUserTypeParent_Null.listSelect(owner, owner, schemType);
|
||||
return accessibleByUserTypeParent.listSelect(owner, owner, schemType, parent);
|
||||
return de.steamwar.sql.v2.SchematicNode.getAccessibleSchematicsOfTypeInParent(SteamwarUser.get(owner), schemType, de.steamwar.sql.v2.SchematicNode.getSchematicNode(nullableInt(parent))).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllAccessibleSchematicsOfType(int user, String schemType) {
|
||||
return accessibleByUserType.listSelect(user, user, schemType);
|
||||
return de.steamwar.sql.v2.SchematicNode.getAllAccessibleSchematicsOfType(SteamwarUser.get(user), SchematicType.fromDB(schemType)).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllSchematicsOfType(int owner, String schemType) {
|
||||
return byOwnerType.listSelect(owner, schemType);
|
||||
return de.steamwar.sql.v2.SchematicNode.getAllSchematicsOfType(SteamwarUser.get(owner), SchematicType.fromDB(schemType)).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static List<SchematicNode> getAllSchematicsOfType(String schemType) {
|
||||
return byType.listSelect(schemType);
|
||||
return de.steamwar.sql.v2.SchematicNode.getAllSchematicsOfType(SchematicType.fromDB(schemType)).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllSchematicsOfType(SchematicType schemType) {
|
||||
return byType.listSelect(schemType);
|
||||
return de.steamwar.sql.v2.SchematicNode.getAllSchematicsOfType(schemType).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<SchematicNode> deepGet(Integer parent, Predicate<SchematicNode> filter) {
|
||||
List<SchematicNode> finalList = new ArrayList<>();
|
||||
List<SchematicNode> nodes = SchematicNode.getSchematicNodeInNode(parent);
|
||||
nodes.forEach(node -> {
|
||||
if (node.isDir()) {
|
||||
finalList.addAll(deepGet(node.getId(), filter));
|
||||
} else {
|
||||
if (filter.test(node))
|
||||
finalList.add(node);
|
||||
}
|
||||
});
|
||||
return finalList;
|
||||
return de.steamwar.sql.v2.SchematicNode.deepGet(de.steamwar.sql.v2.SchematicNode.getSchematicNode(nullableInt(parent)), schematicNode -> filter.test(new SchematicNode(schematicNode))).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getSchematicsAccessibleByUser(int user, Integer parent) {
|
||||
if (parent == null || parent == 0)
|
||||
return accessibleByUser.listSelect(user, user, user, user);
|
||||
|
||||
if(schematicAccessibleForUser.select(rs -> {
|
||||
rs.next();
|
||||
return rs.getInt("Accessible") > 0;
|
||||
}, parent, user, user))
|
||||
return getSchematicNodeInNode(parent);
|
||||
|
||||
return Collections.emptyList();
|
||||
return de.steamwar.sql.v2.SchematicNode.getSchematicsAccessibleByUser(SteamwarUser.get(user), de.steamwar.sql.v2.SchematicNode.getSchematicNode(nullableInt(parent))).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllSchematicsAccessibleByUser(int user) {
|
||||
return allAccessibleByUser.listSelect(user, user);
|
||||
return de.steamwar.sql.v2.SchematicNode.getAllSchematicsAccessibleByUser(SteamwarUser.get(user)).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllParentsOfNode(SchematicNode node) {
|
||||
@ -251,55 +126,15 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllParentsOfNode(int node) {
|
||||
return allParentsOfNode.listSelect(node);
|
||||
return de.steamwar.sql.v2.SchematicNode.getAllParentsOfNode(de.steamwar.sql.v2.SchematicNode.getSchematicNode(node)).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static SchematicNode getNodeFromPath(SteamwarUser user, String s) {
|
||||
if (s.startsWith("/")) {
|
||||
s = s.substring(1);
|
||||
}
|
||||
if (s.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (s.contains("/")) {
|
||||
String[] layers = s.split("/");
|
||||
SchematicNode currentNode = null;
|
||||
for (int i = 0; i < layers.length; i++) {
|
||||
int finalI = i;
|
||||
Optional<SchematicNode> node;
|
||||
if (currentNode == null) {
|
||||
node = SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0).stream().filter(node1 -> node1.getName().equals(layers[finalI])).findAny();
|
||||
} else {
|
||||
node = Optional.ofNullable(SchematicNode.getSchematicNode(layers[i], currentNode.getId()));
|
||||
}
|
||||
if (!node.isPresent()) {
|
||||
return null;
|
||||
} else {
|
||||
currentNode = node.get();
|
||||
if (!currentNode.isDir() && i != layers.length - 1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return currentNode;
|
||||
} else {
|
||||
String finalS = s;
|
||||
return SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0).stream().filter(node1 -> node1.getName().equals(finalS)).findAny().orElse(null);
|
||||
}
|
||||
return de.steamwar.sql.v2.SchematicNode.getNodeFromPath(user, s).map(SchematicNode::new).orElse(null);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> filterSchems(int user, Predicate<SchematicNode> filter) {
|
||||
List<SchematicNode> finalList = new ArrayList<>();
|
||||
List<SchematicNode> nodes = getSchematicsAccessibleByUser(user, null);
|
||||
nodes.forEach(node -> {
|
||||
if (node.isDir()) {
|
||||
finalList.addAll(deepGet(node.getId(), filter));
|
||||
} else {
|
||||
if (filter.test(node))
|
||||
finalList.add(node);
|
||||
}
|
||||
});
|
||||
return finalList;
|
||||
return de.steamwar.sql.v2.SchematicNode.filterSchems(SteamwarUser.get(user), schematicNode -> filter.test(new SchematicNode(schematicNode))).stream().map(SchematicNode::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ -308,236 +143,139 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return nodeId;
|
||||
return node.getId();
|
||||
}
|
||||
|
||||
public int getOwner() {
|
||||
return nodeOwner;
|
||||
return node.getOwner().getId();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return nodeName;
|
||||
return node.getName();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.nodeName = name;
|
||||
updateDB();
|
||||
node.setName(name);
|
||||
}
|
||||
|
||||
public Integer getParent() {
|
||||
return parentNode;
|
||||
return node.getParent() == null ? null : node.getParent().getId();
|
||||
}
|
||||
|
||||
public void setParent(Integer parent) {
|
||||
this.parentNode = parent;
|
||||
updateDB();
|
||||
node.setParent(de.steamwar.sql.v2.SchematicNode.getSchematicNode(nullableInt(parent)));
|
||||
}
|
||||
|
||||
public String getItem() {
|
||||
if (nodeItem.isEmpty()) {
|
||||
return isDir() ? "CHEST" : "CAULDRON_ITEM";
|
||||
}
|
||||
return nodeItem;
|
||||
return node.getItem();
|
||||
}
|
||||
|
||||
public void setItem(String item) {
|
||||
this.nodeItem = item;
|
||||
updateDB();
|
||||
node.setItem(item);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getType() {
|
||||
return nodeType.name();
|
||||
return node.getSchemtype().toDB();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setType(String type) {
|
||||
if(isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
this.nodeType = SchematicType.fromDB(type);
|
||||
updateDB();
|
||||
node.setSchemtype(SchematicType.fromDB(type));
|
||||
}
|
||||
|
||||
public boolean isDir() {
|
||||
return nodeType == null;
|
||||
return node.isDir();
|
||||
}
|
||||
|
||||
public boolean getSchemFormat() {
|
||||
if(isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
return nodeFormat;
|
||||
return node.getSchemFormat();
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
if(isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
return nodeRank;
|
||||
return node.getRank();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getRankUnsafe() {
|
||||
return nodeRank;
|
||||
return node.getRank();
|
||||
}
|
||||
|
||||
public void setRank(int rank) {
|
||||
if(isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
this.nodeRank = rank;
|
||||
node.setRank(rank);
|
||||
}
|
||||
|
||||
public SchematicType getSchemtype() {
|
||||
if(isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
return nodeType;
|
||||
return node.getSchemtype();
|
||||
}
|
||||
|
||||
public void setSchemtype(SchematicType type) {
|
||||
if(isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
this.nodeType = type;
|
||||
updateDB();
|
||||
node.setSchemtype(type);
|
||||
}
|
||||
|
||||
public boolean replaceColor() {
|
||||
return replaceColor;
|
||||
return node.replaceColor();
|
||||
}
|
||||
|
||||
public void setReplaceColor(boolean replaceColor) {
|
||||
if(isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
this.replaceColor = replaceColor;
|
||||
updateDB();
|
||||
node.setReplaceColor(replaceColor);
|
||||
}
|
||||
|
||||
public boolean allowReplay() {
|
||||
return allowReplay;
|
||||
return node.allowReplay();
|
||||
}
|
||||
|
||||
public void setAllowReplay(boolean allowReplay) {
|
||||
if(isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
this.allowReplay = allowReplay;
|
||||
updateDB();
|
||||
node.setAllowReplay(allowReplay);
|
||||
}
|
||||
|
||||
public SchematicNode getParentNode() {
|
||||
if(parentNode == null) return null;
|
||||
return SchematicNode.getSchematicNode(parentNode);
|
||||
return node.getParent() == de.steamwar.sql.v2.SchematicNode.ROOT ? null : new SchematicNode(node.getParent());
|
||||
}
|
||||
|
||||
public int getElo(int season) {
|
||||
return SchemElo.getElo(this, season);
|
||||
return node.getElo(season);
|
||||
}
|
||||
|
||||
public boolean accessibleByUser(int user) {
|
||||
return NodeMember.getNodeMember(nodeId, user) != null;
|
||||
return node.accessibleByUser(user);
|
||||
}
|
||||
|
||||
public Set<NodeMember> getMembers() {
|
||||
return NodeMember.getNodeMembers(nodeId);
|
||||
return node.getMembers();
|
||||
}
|
||||
|
||||
public Timestamp getLastUpdate() {
|
||||
return lastUpdate;
|
||||
}
|
||||
|
||||
private void updateDB() {
|
||||
this.lastUpdate = Timestamp.from(Instant.now());
|
||||
update.update(nodeId, nodeOwner, nodeName, parentNode, nodeItem, nodeType, lastUpdate, nodeRank, replaceColor, allowReplay, nodeFormat);
|
||||
this.brCache.clear();
|
||||
TAB_CACHE.clear();
|
||||
return node.getLastUpdate();
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(nodeId);
|
||||
node.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return nodeId;
|
||||
return node.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof SchematicNode))
|
||||
return false;
|
||||
|
||||
return ((SchematicNode) obj).getId() == nodeId;
|
||||
return node.equals(obj);
|
||||
}
|
||||
|
||||
public String generateBreadcrumbs(SteamwarUser user) {
|
||||
return brCache.computeIfAbsent(user.getId(), integer -> generateBreadcrumbs("/", user));
|
||||
return node.generateBreadcrumbs(user);
|
||||
}
|
||||
|
||||
public String generateBreadcrumbs(String split, SteamwarUser user) {
|
||||
StringBuilder builder = new StringBuilder(getName());
|
||||
SchematicNode currentNode = this;
|
||||
if (currentNode.isDir()) builder.append("/");
|
||||
final Set<NodeMember> nodeMembers = NodeMember.getSchematics(user.getId());
|
||||
AtomicInteger i = new AtomicInteger();
|
||||
i.set(currentNode.getId());
|
||||
while (currentNode.getParentNode() != null && nodeMembers.stream().noneMatch(nodeMember -> nodeMember.getNode() == i.get())) {
|
||||
currentNode = currentNode.getParentNode();
|
||||
i.set(currentNode.getId());
|
||||
builder.insert(0, split)
|
||||
.insert(0, currentNode.getName());
|
||||
}
|
||||
return builder.toString();
|
||||
return node.generateBreadcrumbs(split, user);
|
||||
}
|
||||
|
||||
private static final List<String> FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
|
||||
public static boolean invalidSchemName(String[] layers) {
|
||||
for (String layer : layers) {
|
||||
if (layer.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (layer.contains("/") ||
|
||||
layer.contains("\\") ||
|
||||
layer.contains("<") ||
|
||||
layer.contains(">") ||
|
||||
layer.contains("^") ||
|
||||
layer.contains("°") ||
|
||||
layer.contains("'") ||
|
||||
layer.contains("\"") ||
|
||||
layer.contains(" ")) {
|
||||
return true;
|
||||
}
|
||||
if(FORBIDDEN_NAMES.contains(layer.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return de.steamwar.sql.v2.SchematicNode.invalidSchemName(layers);
|
||||
}
|
||||
|
||||
public static List<String> getNodeTabcomplete(SteamwarUser user, String s) {
|
||||
boolean sws = s.startsWith("/");
|
||||
if (sws) {
|
||||
s = s.substring(1);
|
||||
}
|
||||
int index = s.lastIndexOf("/");
|
||||
String cacheKey = index == -1 ? "" : s.substring(0, index);
|
||||
if(TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) {
|
||||
return new ArrayList<>(TAB_CACHE.get(user.getId()).get(cacheKey));
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
if (s.contains("/")) {
|
||||
String preTab = s.substring(0, s.lastIndexOf("/") + 1);
|
||||
SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab);
|
||||
if (pa == null) return Collections.emptyList();
|
||||
List<SchematicNode> nodes = SchematicNode.getSchematicNodeInNode(pa);
|
||||
nodes.forEach(node -> list.add((sws ? "/" : "") + node.generateBreadcrumbs(user)));
|
||||
} else {
|
||||
List<SchematicNode> nodes = SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0);
|
||||
nodes.forEach(node -> list.add((sws ? "/" : "") + node.getName() + (node.isDir() ? "/" : "")));
|
||||
}
|
||||
list.remove("//copy");
|
||||
TAB_CACHE.computeIfAbsent(user.getId(), integer -> new HashMap<>()).putIfAbsent(cacheKey, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void rootWarning() {
|
||||
ByteArrayOutputStream stacktraceOutput = new ByteArrayOutputStream();
|
||||
new Throwable().printStackTrace(new PrintStream(stacktraceOutput));
|
||||
SWException.log("PERFORMANCE!!! Getting all/weird subset of schematic nodes with parent NULL", stacktraceOutput.toString());
|
||||
return de.steamwar.sql.v2.SchematicNode.getNodeTabcomplete(user, s);
|
||||
}
|
||||
}
|
||||
|
482
src/de/steamwar/sql/v2/SchematicNode.java
Normale Datei
482
src/de/steamwar/sql/v2/SchematicNode.java
Normale Datei
@ -0,0 +1,482 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.sql.v2;
|
||||
|
||||
import de.steamwar.sql.*;
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SchematicNode {
|
||||
|
||||
static {
|
||||
new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> { throw new SecurityException("SchematicNode cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.nodeId));
|
||||
}
|
||||
|
||||
private static final Map<Integer, Map<String, List<String>>> TAB_CACHE = new HashMap<>();
|
||||
public static void clear() {
|
||||
TAB_CACHE.clear();
|
||||
}
|
||||
|
||||
private static final String[] fields = {"NodeId", "NodeOwner", "NodeName", "ParentNode", "LastUpdate", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay", "NodeFormat"};
|
||||
private static String nodeSelectCreator(String itemPrefix) {
|
||||
return "SELECT " + Arrays.stream(fields).map(s -> itemPrefix + s).collect(Collectors.joining(", ")) + " FROM SchematicNode ";
|
||||
}
|
||||
|
||||
public static final SchematicNode ROOT = new SchematicNode(0, 0, "ROOT", 0, Timestamp.from(Instant.now()), "", SchematicType.Normal, 0, false, false, false);
|
||||
|
||||
private static final Table<SchematicNode> table = new Table<>(SchematicNode.class);
|
||||
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType");
|
||||
private static final Statement update = table.insertAll();
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
private static final SelectStatement<SchematicNode> byId = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<SchematicNode> byOwnerNameParent = table.select("OwnerNameParent");
|
||||
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? AND NodeType is NULL ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byParentName = table.selectFields("NodeName", "ParentNode");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserTypeParent = new SelectStatement<>(table, "WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? UNION " + nodeSelectCreator("SN.") + "AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table, "WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUser = new SelectStatement<>(table, nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) AND ((s.NodeOwner = ? AND s.ParentNode IS NULL) OR NOT s.NodeOwner = ?) GROUP BY s.NodeId ORDER BY s.NodeName");
|
||||
private static final Statement schematicAccessibleForUser = new Statement("WITH RECURSIVE RSN AS (" + nodeSelectCreator("") + "WHERE NodeId = ? UNION " + nodeSelectCreator("SN.") + "SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT COUNT(RSN.NodeId) AS `Accessible` FROM RSN LEFT Join NodeMember NM On NM.NodeId = RSN.NodeId WHERE NodeOwner = ? OR UserId = ? LIMIT 1");
|
||||
private static final SelectStatement<SchematicNode> allAccessibleByUser = new SelectStatement<>(table, "WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (" + nodeSelectCreator("") + "WHERE NodeId = ? UNION " + nodeSelectCreator("SN.") + "SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
|
||||
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
private final int nodeId;
|
||||
@Field(keys = {"OwnerNameParent"})
|
||||
private final int nodeOwner;
|
||||
@Field(keys = {"OwnerNameParent"})
|
||||
private String nodeName;
|
||||
@Field(keys = {"OwnerNameParent"})
|
||||
private int parentNode;
|
||||
@Field(def = "CURRENT_TIMESTAMP")
|
||||
private Timestamp lastUpdate;
|
||||
@Field(def = "''")
|
||||
private String nodeItem;
|
||||
@Field(def = "'normal'", nullable = true)
|
||||
private SchematicType nodeType;
|
||||
@Field(def = "0")
|
||||
private int nodeRank;
|
||||
@Field(def = "1")
|
||||
private boolean replaceColor;
|
||||
@Field(def = "1")
|
||||
private boolean allowReplay;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Field(def = "1")
|
||||
private boolean nodeFormat;
|
||||
|
||||
private final Map<Integer, String> brCache = new HashMap<>();
|
||||
|
||||
public SchematicNode(
|
||||
int nodeId,
|
||||
int nodeOwner,
|
||||
String nodeName,
|
||||
int parentNode,
|
||||
Timestamp lastUpdate,
|
||||
String nodeItem,
|
||||
SchematicType nodeType,
|
||||
int nodeRank,
|
||||
boolean replaceColor,
|
||||
boolean allowReplay,
|
||||
boolean nodeFormat
|
||||
) {
|
||||
this.nodeId = nodeId;
|
||||
this.nodeOwner = nodeOwner;
|
||||
this.nodeName = nodeName;
|
||||
this.parentNode = parentNode;
|
||||
this.nodeItem = nodeItem;
|
||||
this.nodeType = nodeType;
|
||||
this.lastUpdate = lastUpdate;
|
||||
this.nodeRank = nodeRank;
|
||||
this.replaceColor = replaceColor;
|
||||
this.allowReplay = allowReplay;
|
||||
this.nodeFormat = nodeFormat;
|
||||
}
|
||||
|
||||
public static SchematicNode createSchematic(SteamwarUser owner, String name, int parent) {
|
||||
return createSchematicNode(owner, name, parent, SchematicType.Normal.toDB(), "");
|
||||
}
|
||||
|
||||
public static SchematicNode createSchematicDirectory(SteamwarUser owner, String name, int parent) {
|
||||
return createSchematicNode(owner, name, parent, null, "");
|
||||
}
|
||||
|
||||
public static SchematicNode createSchematicNode(SteamwarUser owner, String name, int parent, String type, String item) {
|
||||
int nodeId = create.insertGetKey(owner, name, parent, type, item);
|
||||
return getSchematicNode(nodeId);
|
||||
}
|
||||
|
||||
public static Optional<SchematicNode> getSchematicNode(SteamwarUser owner, String name, SchematicNode parent) {
|
||||
return getSchematicNode(owner, name, parent.getId());
|
||||
}
|
||||
|
||||
public static Optional<SchematicNode> getSchematicNode(SteamwarUser owner, String name, int parent) {
|
||||
return Optional.ofNullable(byOwnerNameParent.select(owner, name, parent));
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getSchematicNodeInNode(SchematicNode parent) {
|
||||
if(parent.equals(ROOT)) {
|
||||
rootWarning();
|
||||
}
|
||||
|
||||
return byParent.listSelect(parent);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getSchematicDirectoryInNode(SchematicNode parent) {
|
||||
if(parent.equals(ROOT)) {
|
||||
rootWarning();
|
||||
}
|
||||
return dirsByParent.listSelect(parent);
|
||||
}
|
||||
|
||||
public static Optional<SchematicNode> getSchematicNode(String name, SchematicNode parent) {
|
||||
if(parent.equals(ROOT)) {
|
||||
rootWarning();
|
||||
}
|
||||
return Optional.ofNullable(byParentName.select(name, parent));
|
||||
}
|
||||
|
||||
public static SchematicNode getSchematicNode(int id) {
|
||||
if(id == 0) return ROOT;
|
||||
return Optional.ofNullable(byId.select(id)).orElseThrow(() -> new IllegalStateException("Schematic node " + id + " does not exist"));
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(SteamwarUser owner, String schemType, SchematicNode parent) {
|
||||
return accessibleByUserTypeParent.listSelect(owner, owner, schemType, parent);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllAccessibleSchematicsOfType(SteamwarUser user, SchematicType schemType) {
|
||||
return accessibleByUserType.listSelect(user, user, schemType);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllSchematicsOfType(SteamwarUser owner, SchematicType schemType) {
|
||||
return byOwnerType.listSelect(owner, schemType);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllSchematicsOfType(SchematicType schemType) {
|
||||
return byType.listSelect(schemType);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> deepGet(SchematicNode parent, Predicate<SchematicNode> filter) {
|
||||
List<SchematicNode> finalList = new ArrayList<>();
|
||||
List<SchematicNode> nodes = SchematicNode.getSchematicNodeInNode(parent);
|
||||
nodes.forEach(node -> {
|
||||
if (node.isDir()) {
|
||||
finalList.addAll(deepGet(node, filter));
|
||||
} else {
|
||||
if (filter.test(node))
|
||||
finalList.add(node);
|
||||
}
|
||||
});
|
||||
return finalList;
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getSchematicsAccessibleByUser(SteamwarUser user, SchematicNode parent) {
|
||||
if (parent.equals(ROOT)) {
|
||||
return accessibleByUser.listSelect(user, user, user, user);
|
||||
}
|
||||
|
||||
if(Boolean.TRUE.equals(schematicAccessibleForUser.select(rs -> {
|
||||
rs.next();
|
||||
return rs.getBoolean("Accessible");
|
||||
}, parent, user, user)))
|
||||
return getSchematicNodeInNode(parent);
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllSchematicsAccessibleByUser(SteamwarUser user) {
|
||||
return allAccessibleByUser.listSelect(user, user);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAllParentsOfNode(SchematicNode node) {
|
||||
return allParentsOfNode.listSelect(node);
|
||||
}
|
||||
|
||||
public static Optional<SchematicNode> getNodeFromPath(SteamwarUser user, String s) {
|
||||
if (s.startsWith("/")) {
|
||||
s = s.substring(1);
|
||||
}
|
||||
if (s.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
if (s.contains("/")) {
|
||||
String[] layers = s.split("/");
|
||||
SchematicNode currentNode = null;
|
||||
for (int i = 0; i < layers.length; i++) {
|
||||
int finalI = i;
|
||||
Optional<SchematicNode> node;
|
||||
if (currentNode == null) {
|
||||
node = SchematicNode.getSchematicsAccessibleByUser(user, ROOT).stream().filter(node1 -> node1.getName().equals(layers[finalI])).findAny();
|
||||
} else {
|
||||
node = SchematicNode.getSchematicNode(layers[i], currentNode);
|
||||
}
|
||||
if (!node.isPresent()) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
currentNode = node.get();
|
||||
if (!currentNode.isDir() && i != layers.length - 1) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.ofNullable(currentNode);
|
||||
} else {
|
||||
String finalS = s;
|
||||
return SchematicNode.getSchematicsAccessibleByUser(user, ROOT).stream().filter(node1 -> node1.getName().equals(finalS)).findAny();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<SchematicNode> filterSchems(SteamwarUser user, Predicate<SchematicNode> filter) {
|
||||
List<SchematicNode> finalList = new ArrayList<>();
|
||||
List<SchematicNode> nodes = getSchematicsAccessibleByUser(user, ROOT);
|
||||
nodes.forEach(node -> {
|
||||
if (node.isDir()) {
|
||||
finalList.addAll(deepGet(node, filter));
|
||||
} else {
|
||||
if (filter.test(node))
|
||||
finalList.add(node);
|
||||
}
|
||||
});
|
||||
return finalList;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
public SteamwarUser getOwner() {
|
||||
return SteamwarUser.get(nodeOwner);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return nodeName;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.nodeName = name;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public SchematicNode getParent() {
|
||||
return SchematicNode.getSchematicNode(parentNode);
|
||||
}
|
||||
|
||||
public void setParent(SchematicNode parent) {
|
||||
this.parentNode = parent.nodeId;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public String getItem() {
|
||||
if (nodeItem.isEmpty()) {
|
||||
return isDir() ? "CHEST" : "CAULDRON_ITEM";
|
||||
}
|
||||
return nodeItem;
|
||||
}
|
||||
|
||||
public void setItem(String item) {
|
||||
this.nodeItem = item;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public boolean isDir() {
|
||||
return nodeType == null;
|
||||
}
|
||||
|
||||
public boolean getSchemFormat() {
|
||||
throwIfDir();
|
||||
return nodeFormat;
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
throwIfDir();
|
||||
return nodeRank;
|
||||
}
|
||||
|
||||
public void setRank(int rank) {
|
||||
throwIfDir();
|
||||
this.nodeRank = rank;
|
||||
}
|
||||
|
||||
public SchematicType getSchemtype() {
|
||||
throwIfDir();
|
||||
return nodeType;
|
||||
}
|
||||
|
||||
public void setSchemtype(SchematicType type) {
|
||||
throwIfDir();
|
||||
this.nodeType = type;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public boolean replaceColor() {
|
||||
return replaceColor;
|
||||
}
|
||||
|
||||
public void setReplaceColor(boolean replaceColor) {
|
||||
throwIfDir();
|
||||
this.replaceColor = replaceColor;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public boolean allowReplay() {
|
||||
return allowReplay;
|
||||
}
|
||||
|
||||
public void setAllowReplay(boolean allowReplay) {
|
||||
throwIfDir();
|
||||
this.allowReplay = allowReplay;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public int getElo(int season) {
|
||||
return SchemElo.getElo(this, season);
|
||||
}
|
||||
|
||||
public boolean accessibleByUser(int user) {
|
||||
return NodeMember.getNodeMember(nodeId, user) != null;
|
||||
}
|
||||
|
||||
public Set<NodeMember> getMembers() {
|
||||
return NodeMember.getNodeMembers(nodeId);
|
||||
}
|
||||
|
||||
public Timestamp getLastUpdate() {
|
||||
return lastUpdate;
|
||||
}
|
||||
|
||||
private void updateDB() {
|
||||
this.lastUpdate = Timestamp.from(Instant.now());
|
||||
update.update(nodeId, nodeOwner, nodeName, parentNode, nodeItem, nodeType, lastUpdate, nodeRank, replaceColor, allowReplay, nodeFormat);
|
||||
this.brCache.clear();
|
||||
TAB_CACHE.clear();
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(nodeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof SchematicNode))
|
||||
return false;
|
||||
|
||||
return ((SchematicNode) obj).getId() == nodeId;
|
||||
}
|
||||
|
||||
public String generateBreadcrumbs(SteamwarUser user) {
|
||||
return brCache.computeIfAbsent(user.getId(), integer -> generateBreadcrumbs("/", user));
|
||||
}
|
||||
|
||||
public String generateBreadcrumbs(String split, SteamwarUser user) {
|
||||
StringBuilder builder = new StringBuilder(getName());
|
||||
SchematicNode currentNode = this;
|
||||
if (currentNode.isDir()) builder.append("/");
|
||||
final Set<NodeMember> nodeMembers = NodeMember.getSchematics(user.getId());
|
||||
AtomicInteger i = new AtomicInteger();
|
||||
i.set(currentNode.getId());
|
||||
while (!currentNode.getParent().equals(ROOT) && nodeMembers.stream().noneMatch(nodeMember -> nodeMember.getNode() == i.get())) {
|
||||
currentNode = currentNode.getParent();
|
||||
i.set(currentNode.getId());
|
||||
builder.insert(0, split)
|
||||
.insert(0, currentNode.getName());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static final List<String> FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
|
||||
public static boolean invalidSchemName(String[] layers) {
|
||||
for (String layer : layers) {
|
||||
if (layer.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (layer.contains("/") ||
|
||||
layer.contains("\\") ||
|
||||
layer.contains("<") ||
|
||||
layer.contains(">") ||
|
||||
layer.contains("^") ||
|
||||
layer.contains("°") ||
|
||||
layer.contains("'") ||
|
||||
layer.contains("\"") ||
|
||||
layer.contains(" ")) {
|
||||
return true;
|
||||
}
|
||||
if(FORBIDDEN_NAMES.contains(layer.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<String> getNodeTabcomplete(SteamwarUser user, String s) {
|
||||
boolean sws = s.startsWith("/");
|
||||
if (sws) {
|
||||
s = s.substring(1);
|
||||
}
|
||||
int index = s.lastIndexOf("/");
|
||||
String cacheKey = index == -1 ? "" : s.substring(0, index);
|
||||
if(TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) {
|
||||
return new ArrayList<>(TAB_CACHE.get(user.getId()).get(cacheKey));
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
if (s.contains("/")) {
|
||||
String preTab = s.substring(0, s.lastIndexOf("/") + 1);
|
||||
Optional<SchematicNode> pa = SchematicNode.getNodeFromPath(user, preTab);
|
||||
if (!pa.isPresent()) return Collections.emptyList();
|
||||
List<SchematicNode> nodes = pa.map(SchematicNode::getSchematicNodeInNode).orElseGet(Collections::emptyList);
|
||||
nodes.forEach(node -> list.add((sws ? "/" : "") + node.generateBreadcrumbs(user)));
|
||||
} else {
|
||||
List<SchematicNode> nodes = SchematicNode.getSchematicsAccessibleByUser(user, ROOT);
|
||||
nodes.forEach(node -> list.add((sws ? "/" : "") + node.getName() + (node.isDir() ? "/" : "")));
|
||||
}
|
||||
list.remove("//copy");
|
||||
TAB_CACHE.computeIfAbsent(user.getId(), integer -> new HashMap<>()).putIfAbsent(cacheKey, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void rootWarning() {
|
||||
ByteArrayOutputStream stacktraceOutput = new ByteArrayOutputStream();
|
||||
new Throwable().printStackTrace(new PrintStream(stacktraceOutput));
|
||||
SWException.log("PERFORMANCE!!! Getting all/weird subset of schematic nodes with parent NULL", stacktraceOutput.toString());
|
||||
}
|
||||
|
||||
private void throwIfDir() {
|
||||
if (isDir()) {
|
||||
throw new SecurityException("Is Directory");
|
||||
}
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren