From 2fbc22af0d030558f700fb30b787a392fa68e239 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Thu, 5 May 2022 22:21:43 +0200 Subject: [PATCH] Added new model. --- pom.xml | 2 +- .../railsignalapi/dao/BranchRepository.java | 18 ------ .../dao/ComponentRepository.java | 11 ++++ .../railsignalapi/dao/SegmentRepository.java | 11 ++++ .../dao/SignalBranchConnectionRepository.java | 9 --- .../railsignalapi/dao/SignalRepository.java | 26 -------- .../railsignalapi/dao/TrainRepository.java | 9 --- .../andrewl/railsignalapi/model/Branch.java | 38 ------------ .../railsignalapi/model/BranchStatus.java | 6 -- .../railsignalapi/model/Direction.java | 3 + .../railsignalapi/model/RailSystem.java | 6 ++ .../andrewl/railsignalapi/model/Segment.java | 50 +++++++++++++++ .../andrewl/railsignalapi/model/Signal.java | 40 ------------ .../model/SignalBranchConnection.java | 57 ----------------- .../andrewl/railsignalapi/model/Switch.java | 30 --------- .../nl/andrewl/railsignalapi/model/Train.java | 20 ------ .../model/component/Component.java | 62 +++++++++++++++++++ .../model/component/PathNode.java | 33 ++++++++++ .../model/{ => component}/Position.java | 5 +- .../model/component/SegmentBoundaryNode.java | 32 ++++++++++ .../railsignalapi/model/component/Signal.java | 43 +++++++++++++ .../railsignalapi/model/component/Switch.java | 29 +++++++++ .../model/component/SwitchConfiguration.java | 31 ++++++++++ .../rest/BranchesController.java | 38 ------------ .../rest/RailSystemsApiController.java | 2 +- .../rest/SignalsApiController.java | 44 ------------- .../rest/dto/BranchResponse.java | 13 ---- .../dto/SignalConnectionsUpdatePayload.java | 9 --- .../rest/dto/SignalCreationPayload.java | 13 ---- .../rest/dto/SignalResponse.java | 61 ------------------ .../service/RailSystemService.java | 14 ++--- .../railsignalapi/service/SignalService.java | 1 + 32 files changed, 324 insertions(+), 442 deletions(-) delete mode 100644 src/main/java/nl/andrewl/railsignalapi/dao/BranchRepository.java create mode 100644 src/main/java/nl/andrewl/railsignalapi/dao/ComponentRepository.java create mode 100644 src/main/java/nl/andrewl/railsignalapi/dao/SegmentRepository.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/dao/SignalBranchConnectionRepository.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/dao/SignalRepository.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/dao/TrainRepository.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/model/Branch.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/model/BranchStatus.java create mode 100644 src/main/java/nl/andrewl/railsignalapi/model/Segment.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/model/Signal.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/model/SignalBranchConnection.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/model/Switch.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/model/Train.java create mode 100644 src/main/java/nl/andrewl/railsignalapi/model/component/Component.java create mode 100644 src/main/java/nl/andrewl/railsignalapi/model/component/PathNode.java rename src/main/java/nl/andrewl/railsignalapi/model/{ => component}/Position.java (68%) create mode 100644 src/main/java/nl/andrewl/railsignalapi/model/component/SegmentBoundaryNode.java create mode 100644 src/main/java/nl/andrewl/railsignalapi/model/component/Signal.java create mode 100644 src/main/java/nl/andrewl/railsignalapi/model/component/Switch.java create mode 100644 src/main/java/nl/andrewl/railsignalapi/model/component/SwitchConfiguration.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/rest/BranchesController.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/rest/SignalsApiController.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/rest/dto/BranchResponse.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalConnectionsUpdatePayload.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalCreationPayload.java delete mode 100644 src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalResponse.java diff --git a/pom.xml b/pom.xml index 9ee5fa8..7c63610 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.6.0 + 2.6.6 nl.andrewl diff --git a/src/main/java/nl/andrewl/railsignalapi/dao/BranchRepository.java b/src/main/java/nl/andrewl/railsignalapi/dao/BranchRepository.java deleted file mode 100644 index ef475fc..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/dao/BranchRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package nl.andrewl.railsignalapi.dao; - -import nl.andrewl.railsignalapi.model.Branch; -import nl.andrewl.railsignalapi.model.RailSystem; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -@Repository -public interface BranchRepository extends JpaRepository { - Optional findByIdAndRailSystem(long id, RailSystem railSystem); - Optional findByIdAndRailSystemId(long id, long railSystemId); - Optional findByNameAndRailSystem(String name, RailSystem railSystem); - List findAllByRailSystemOrderByName(RailSystem railSystem); - List findAllByNameAndRailSystem(String name, RailSystem railSystem); -} diff --git a/src/main/java/nl/andrewl/railsignalapi/dao/ComponentRepository.java b/src/main/java/nl/andrewl/railsignalapi/dao/ComponentRepository.java new file mode 100644 index 0000000..3e5e0c9 --- /dev/null +++ b/src/main/java/nl/andrewl/railsignalapi/dao/ComponentRepository.java @@ -0,0 +1,11 @@ +package nl.andrewl.railsignalapi.dao; + +import nl.andrewl.railsignalapi.model.RailSystem; +import nl.andrewl.railsignalapi.model.component.Component; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ComponentRepository extends JpaRepository { + void deleteAllByRailSystem(RailSystem rs); +} diff --git a/src/main/java/nl/andrewl/railsignalapi/dao/SegmentRepository.java b/src/main/java/nl/andrewl/railsignalapi/dao/SegmentRepository.java new file mode 100644 index 0000000..3cde24a --- /dev/null +++ b/src/main/java/nl/andrewl/railsignalapi/dao/SegmentRepository.java @@ -0,0 +1,11 @@ +package nl.andrewl.railsignalapi.dao; + +import nl.andrewl.railsignalapi.model.RailSystem; +import nl.andrewl.railsignalapi.model.Segment; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SegmentRepository extends JpaRepository { + void deleteAllByRailSystem(RailSystem rs); +} diff --git a/src/main/java/nl/andrewl/railsignalapi/dao/SignalBranchConnectionRepository.java b/src/main/java/nl/andrewl/railsignalapi/dao/SignalBranchConnectionRepository.java deleted file mode 100644 index 2e1efa7..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/dao/SignalBranchConnectionRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package nl.andrewl.railsignalapi.dao; - -import nl.andrewl.railsignalapi.model.SignalBranchConnection; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface SignalBranchConnectionRepository extends JpaRepository { -} diff --git a/src/main/java/nl/andrewl/railsignalapi/dao/SignalRepository.java b/src/main/java/nl/andrewl/railsignalapi/dao/SignalRepository.java deleted file mode 100644 index 414cb9e..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/dao/SignalRepository.java +++ /dev/null @@ -1,26 +0,0 @@ -package nl.andrewl.railsignalapi.dao; - -import nl.andrewl.railsignalapi.model.Branch; -import nl.andrewl.railsignalapi.model.RailSystem; -import nl.andrewl.railsignalapi.model.Signal; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -@Repository -public interface SignalRepository extends JpaRepository { - Optional findByIdAndRailSystem(long id, RailSystem railSystem); - Optional findByIdAndRailSystemId(long id, long railSystemId); - boolean existsByNameAndRailSystem(String name, RailSystem railSystem); - - @Query("SELECT DISTINCT s FROM Signal s " + - "LEFT JOIN s.branchConnections bc " + - "WHERE bc.branch = :branch " + - "ORDER BY s.name") - List findAllConnectedToBranch(Branch branch); - - List findAllByRailSystemOrderByName(RailSystem railSystem); -} diff --git a/src/main/java/nl/andrewl/railsignalapi/dao/TrainRepository.java b/src/main/java/nl/andrewl/railsignalapi/dao/TrainRepository.java deleted file mode 100644 index 621136f..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/dao/TrainRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package nl.andrewl.railsignalapi.dao; - -import nl.andrewl.railsignalapi.model.Train; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface TrainRepository extends JpaRepository { -} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/Branch.java b/src/main/java/nl/andrewl/railsignalapi/model/Branch.java deleted file mode 100644 index 68af2c3..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/model/Branch.java +++ /dev/null @@ -1,38 +0,0 @@ -package nl.andrewl.railsignalapi.model; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.*; -import java.util.HashSet; -import java.util.Set; - -@Entity -@NoArgsConstructor -@Getter -public class Branch { - @Id - @GeneratedValue - private Long id; - - @ManyToOne(optional = false, fetch = FetchType.LAZY) - private RailSystem railSystem; - - @Column(nullable = false) - private String name; - - @Enumerated(EnumType.STRING) - @Setter - private BranchStatus status; - - @OneToMany(mappedBy = "branch", orphanRemoval = true) - private Set signalConnections; - - public Branch(RailSystem railSystem, String name, BranchStatus status) { - this.railSystem = railSystem; - this.name = name; - this.status = status; - this.signalConnections = new HashSet<>(); - } -} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/BranchStatus.java b/src/main/java/nl/andrewl/railsignalapi/model/BranchStatus.java deleted file mode 100644 index cbca38b..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/model/BranchStatus.java +++ /dev/null @@ -1,6 +0,0 @@ -package nl.andrewl.railsignalapi.model; - -public enum BranchStatus { - FREE, - OCCUPIED -} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/Direction.java b/src/main/java/nl/andrewl/railsignalapi/model/Direction.java index 8a12331..f73363b 100644 --- a/src/main/java/nl/andrewl/railsignalapi/model/Direction.java +++ b/src/main/java/nl/andrewl/railsignalapi/model/Direction.java @@ -1,5 +1,8 @@ package nl.andrewl.railsignalapi.model; +/** + * A cardinal direction, useful for some components. + */ public enum Direction { NORTH, SOUTH, diff --git a/src/main/java/nl/andrewl/railsignalapi/model/RailSystem.java b/src/main/java/nl/andrewl/railsignalapi/model/RailSystem.java index 6401810..92afd4d 100644 --- a/src/main/java/nl/andrewl/railsignalapi/model/RailSystem.java +++ b/src/main/java/nl/andrewl/railsignalapi/model/RailSystem.java @@ -8,6 +8,9 @@ import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; +/** + * Represents a closed system that contains a collection of components. + */ @Entity @Getter @NoArgsConstructor @@ -16,6 +19,9 @@ public class RailSystem { @GeneratedValue private Long id; + /** + * The name of this system. + */ @Column(nullable = false, unique = true) private String name; diff --git a/src/main/java/nl/andrewl/railsignalapi/model/Segment.java b/src/main/java/nl/andrewl/railsignalapi/model/Segment.java new file mode 100644 index 0000000..efe0b8f --- /dev/null +++ b/src/main/java/nl/andrewl/railsignalapi/model/Segment.java @@ -0,0 +1,50 @@ +package nl.andrewl.railsignalapi.model; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import nl.andrewl.railsignalapi.model.component.SegmentBoundaryNode; +import nl.andrewl.railsignalapi.model.component.Signal; + +import javax.persistence.*; +import java.util.Set; + +/** + * Represents a traversable segment of a rail system that components can + * connect to. + */ +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class Segment { + @Id + @GeneratedValue + private Long id; + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + private RailSystem railSystem; + + /** + * A unique name for this segment. + */ + @Column(unique = true) + private String name; + + /** + * The signals that are connected to this branch. + */ + @OneToMany(mappedBy = "segment") + private Set signals; + + /** + * The set of nodes from which trains can enter and exit this segment. + */ + @ManyToMany(mappedBy = "segments", cascade = CascadeType.ALL) + private Set boundaryNodes; + + @Override + public boolean equals(Object o) { + if (o == this) return true; + return o instanceof Segment s && this.id != null && this.id.equals(s.id); + } +} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/Signal.java b/src/main/java/nl/andrewl/railsignalapi/model/Signal.java deleted file mode 100644 index 9847f9a..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/model/Signal.java +++ /dev/null @@ -1,40 +0,0 @@ -package nl.andrewl.railsignalapi.model; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.*; -import java.util.Set; - -@Entity -@Getter -@NoArgsConstructor -public class Signal { - @Id - @GeneratedValue - private Long id; - - @ManyToOne(optional = false, fetch = FetchType.LAZY) - private RailSystem railSystem; - - @Column(nullable = false) - private String name; - - @OneToMany(mappedBy = "signal", orphanRemoval = true, cascade = CascadeType.ALL) - private Set branchConnections; - - @Embedded - private Position position; - - @Column(nullable = false) - @Setter - private boolean online = false; - - public Signal(RailSystem railSystem, String name, Position position, Set branchConnections) { - this.railSystem = railSystem; - this.name = name; - this.position = position; - this.branchConnections = branchConnections; - } -} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/SignalBranchConnection.java b/src/main/java/nl/andrewl/railsignalapi/model/SignalBranchConnection.java deleted file mode 100644 index e4eabc6..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/model/SignalBranchConnection.java +++ /dev/null @@ -1,57 +0,0 @@ -package nl.andrewl.railsignalapi.model; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -@Entity -@NoArgsConstructor -@Getter -public class SignalBranchConnection implements Comparable { - @Id - @GeneratedValue - private Long id; - - @ManyToOne(optional = false) - private Signal signal; - - @ManyToOne(optional = false, cascade = CascadeType.PERSIST) - private Branch branch; - - @Enumerated(EnumType.STRING) - private Direction direction; - - @ManyToMany - private Set reachableSignalConnections; - - public SignalBranchConnection(Signal signal, Branch branch, Direction direction) { - this.signal = signal; - this.branch = branch; - this.direction = direction; - reachableSignalConnections = new HashSet<>(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - return this.id != null && - o instanceof SignalBranchConnection sbc && sbc.getId() != null && - this.id.equals(sbc.getId()); - } - - @Override - public int hashCode() { - return Objects.hashCode(id); - } - - @Override - public int compareTo(SignalBranchConnection o) { - int c = Long.compare(this.getSignal().getId(), o.getSignal().getId()); - if (c != 0) return c; - return this.direction.compareTo(o.getDirection()); - } -} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/Switch.java b/src/main/java/nl/andrewl/railsignalapi/model/Switch.java deleted file mode 100644 index 720e85e..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/model/Switch.java +++ /dev/null @@ -1,30 +0,0 @@ -package nl.andrewl.railsignalapi.model; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -@Entity -@Getter -@NoArgsConstructor -public class Switch { - @Id - @GeneratedValue - private Long id; - - @ManyToOne(optional = false, fetch = FetchType.LAZY) - private RailSystem railSystem; - - @Column(nullable = false) - private String name; - - @Embedded - private Position position; - - @Column(nullable = false) - private int state; - - @Column(nullable = false) - private int maxStates; -} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/Train.java b/src/main/java/nl/andrewl/railsignalapi/model/Train.java deleted file mode 100644 index 09a05b8..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/model/Train.java +++ /dev/null @@ -1,20 +0,0 @@ -package nl.andrewl.railsignalapi.model; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -@Entity -@NoArgsConstructor -@Getter -public class Train { - @Id - @GeneratedValue - private Long id; - - private String name; - - @ManyToOne(fetch = FetchType.LAZY) - private Branch currentBranch; -} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/component/Component.java b/src/main/java/nl/andrewl/railsignalapi/model/component/Component.java new file mode 100644 index 0000000..a0ff76c --- /dev/null +++ b/src/main/java/nl/andrewl/railsignalapi/model/component/Component.java @@ -0,0 +1,62 @@ +package nl.andrewl.railsignalapi.model.component; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import nl.andrewl.railsignalapi.model.RailSystem; + +import javax.persistence.*; + +/** + * Represents a physical component of the rail system that the API can interact + * with, and send or receive data from. For example, a signal, switch, or + * detector. + */ +@Entity +@Inheritance(strategy = InheritanceType.JOINED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public abstract class Component { + @Id + @GeneratedValue + private Long id; + + /** + * The rail system that this component belongs to. + */ + @ManyToOne(optional = false, fetch = FetchType.LAZY) + private RailSystem railSystem; + + /** + * The position of this component in the system. + */ + @Embedded + private Position position; + + /** + * A human-readable name for the component. + */ + @Column(unique = true) + private String name; + + /** + * Whether this component is online, meaning that an in-world device is + * currently connected to relay information regarding this component. + */ + @Column(nullable = false) + @Setter + private boolean online = false; + + public Component(RailSystem railSystem, Position position, String name) { + this.railSystem = railSystem; + this.position = position; + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + return o instanceof Component c && this.id != null && this.id.equals(c.id); + } +} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/component/PathNode.java b/src/main/java/nl/andrewl/railsignalapi/model/component/PathNode.java new file mode 100644 index 0000000..6d82422 --- /dev/null +++ b/src/main/java/nl/andrewl/railsignalapi/model/component/PathNode.java @@ -0,0 +1,33 @@ +package nl.andrewl.railsignalapi.model.component; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import nl.andrewl.railsignalapi.model.RailSystem; + +import javax.persistence.Entity; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.ManyToMany; +import java.util.Set; + +/** + * A node that, together with other nodes, forms a path that trains can follow + * to traverse through segments in the rail system. + */ +@Entity +@Inheritance(strategy = InheritanceType.JOINED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class PathNode extends Component { + /** + * The set of nodes that this one is connected to. + */ + @ManyToMany + private Set connectedNodes; + + public PathNode(RailSystem railSystem, Position position, String name, Set connectedNodes) { + super(railSystem, position, name); + this.connectedNodes = connectedNodes; + } +} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/Position.java b/src/main/java/nl/andrewl/railsignalapi/model/component/Position.java similarity index 68% rename from src/main/java/nl/andrewl/railsignalapi/model/Position.java rename to src/main/java/nl/andrewl/railsignalapi/model/component/Position.java index 9060feb..f7bb43f 100644 --- a/src/main/java/nl/andrewl/railsignalapi/model/Position.java +++ b/src/main/java/nl/andrewl/railsignalapi/model/component/Position.java @@ -1,4 +1,4 @@ -package nl.andrewl.railsignalapi.model; +package nl.andrewl.railsignalapi.model.component; import lombok.AllArgsConstructor; import lombok.Data; @@ -6,6 +6,9 @@ import lombok.NoArgsConstructor; import javax.persistence.Embeddable; +/** + * A three-dimensional position for a component within a system. + */ @Embeddable @Data @AllArgsConstructor diff --git a/src/main/java/nl/andrewl/railsignalapi/model/component/SegmentBoundaryNode.java b/src/main/java/nl/andrewl/railsignalapi/model/component/SegmentBoundaryNode.java new file mode 100644 index 0000000..0b9923d --- /dev/null +++ b/src/main/java/nl/andrewl/railsignalapi/model/component/SegmentBoundaryNode.java @@ -0,0 +1,32 @@ +package nl.andrewl.railsignalapi.model.component; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import nl.andrewl.railsignalapi.model.RailSystem; +import nl.andrewl.railsignalapi.model.Segment; + +import javax.persistence.Entity; +import javax.persistence.ManyToMany; +import java.util.Set; + +/** + * Component that relays information about trains traversing from one segment + * to another. It links exactly two segments together at a specific point. + */ +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class SegmentBoundaryNode extends PathNode { + /** + * The set of segments that this boundary node connects. This should + * generally always have exactly two segments. + */ + @ManyToMany + private Set segments; + + public SegmentBoundaryNode(RailSystem railSystem, Position position, String name, Set connectedNodes, Set segments) { + super(railSystem, position, name, connectedNodes); + this.segments = segments; + } +} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/component/Signal.java b/src/main/java/nl/andrewl/railsignalapi/model/component/Signal.java new file mode 100644 index 0000000..591542d --- /dev/null +++ b/src/main/java/nl/andrewl/railsignalapi/model/component/Signal.java @@ -0,0 +1,43 @@ +package nl.andrewl.railsignalapi.model.component; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import nl.andrewl.railsignalapi.model.Direction; +import nl.andrewl.railsignalapi.model.RailSystem; +import nl.andrewl.railsignalapi.model.Segment; + +import javax.persistence.*; + +/** + * A signal is a component that relays the status of a connected segment to + * some sort of in-world representation, whether that be a certain light + * color, or electrical signal. + */ +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Signal extends Component { + /** + * The direction this signal is facing. This is the direction in which the + * signal connects to a branch. + *
+	 *     |-segment A-|-segment B-|
+	 *     ===================== <- Rail
+	 *                ]+  --->      Signal is facing East, and shows status on
+	 *                              its western side. It is connected to segment B.
+	 * 
+ */ + @Enumerated(EnumType.STRING) + private Direction direction; + + /** + * The segment that this signal connects to. + */ + @ManyToOne(optional = false, fetch = FetchType.LAZY) + private Segment segment; + + public Signal(RailSystem railSystem, Position position, String name, Segment segment, Direction direction) { + super(railSystem, position, name); + this.segment = segment; + this.direction = direction; + } +} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/component/Switch.java b/src/main/java/nl/andrewl/railsignalapi/model/component/Switch.java new file mode 100644 index 0000000..afa8c80 --- /dev/null +++ b/src/main/java/nl/andrewl/railsignalapi/model/component/Switch.java @@ -0,0 +1,29 @@ +package nl.andrewl.railsignalapi.model.component; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.util.Set; + +/** + * A switch is a component that directs traffic between several connected + * segments. + */ +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class Switch extends PathNode { + /** + * The set of all possible configurations that this switch can be in. + */ + @OneToMany(mappedBy = "switchComponent", orphanRemoval = true, cascade = CascadeType.ALL) + private Set possibleConfigurations; + + /** + * The switch configuration that this switch is currently in. + */ + @OneToOne(optional = false, fetch = FetchType.LAZY) + private SwitchConfiguration activeConfiguration; +} diff --git a/src/main/java/nl/andrewl/railsignalapi/model/component/SwitchConfiguration.java b/src/main/java/nl/andrewl/railsignalapi/model/component/SwitchConfiguration.java new file mode 100644 index 0000000..261f81c --- /dev/null +++ b/src/main/java/nl/andrewl/railsignalapi/model/component/SwitchConfiguration.java @@ -0,0 +1,31 @@ +package nl.andrewl.railsignalapi.model.component; + +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.util.Set; + +/** + * A possible connection that can be made between path nodes, if this is set + * as an active configuration in the linked switch component. + */ +@Entity +@NoArgsConstructor +public class SwitchConfiguration { + @Id + @GeneratedValue + private Long id; + + /** + * The switch component that this configuration belongs to. + */ + @ManyToOne(optional = false, fetch = FetchType.LAZY) + private Switch switchComponent; + + /** + * The set of nodes that this switch configuration connects. This should + * be almost always a set of two nodes. + */ + @ManyToMany(fetch = FetchType.EAGER) + private Set nodes; +} diff --git a/src/main/java/nl/andrewl/railsignalapi/rest/BranchesController.java b/src/main/java/nl/andrewl/railsignalapi/rest/BranchesController.java deleted file mode 100644 index e4df17c..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/rest/BranchesController.java +++ /dev/null @@ -1,38 +0,0 @@ -package nl.andrewl.railsignalapi.rest; - -import lombok.RequiredArgsConstructor; -import nl.andrewl.railsignalapi.rest.dto.BranchResponse; -import nl.andrewl.railsignalapi.rest.dto.SignalResponse; -import nl.andrewl.railsignalapi.service.BranchService; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@RestController -@RequestMapping(path = "/api/railSystems/{rsId}/branches") -@RequiredArgsConstructor -public class BranchesController { - private final BranchService branchService; - - @GetMapping - public List getAllBranches(@PathVariable long rsId) { - return branchService.getAllBranches(rsId); - } - - @GetMapping(path = "/{branchId}") - public BranchResponse getBranch(@PathVariable long rsId, @PathVariable long branchId) { - return branchService.getBranch(rsId, branchId); - } - - @GetMapping(path = "/{branchId}/signals") - public List getBranchSignals(@PathVariable long rsId, @PathVariable long branchId) { - return branchService.getConnectedSignals(rsId, branchId); - } - - @DeleteMapping(path = "/{branchId}") - public ResponseEntity deleteBranch(@PathVariable long rsId, @PathVariable long branchId) { - branchService.deleteBranch(rsId, branchId); - return ResponseEntity.noContent().build(); - } -} diff --git a/src/main/java/nl/andrewl/railsignalapi/rest/RailSystemsApiController.java b/src/main/java/nl/andrewl/railsignalapi/rest/RailSystemsApiController.java index 160c2dc..cbe1362 100644 --- a/src/main/java/nl/andrewl/railsignalapi/rest/RailSystemsApiController.java +++ b/src/main/java/nl/andrewl/railsignalapi/rest/RailSystemsApiController.java @@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping(path = "/api/railSystems") +@RequestMapping(path = "/api/rs") @RequiredArgsConstructor public class RailSystemsApiController { private final RailSystemService railSystemService; diff --git a/src/main/java/nl/andrewl/railsignalapi/rest/SignalsApiController.java b/src/main/java/nl/andrewl/railsignalapi/rest/SignalsApiController.java deleted file mode 100644 index e44ca0f..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/rest/SignalsApiController.java +++ /dev/null @@ -1,44 +0,0 @@ -package nl.andrewl.railsignalapi.rest; - -import lombok.RequiredArgsConstructor; -import nl.andrewl.railsignalapi.rest.dto.SignalConnectionsUpdatePayload; -import nl.andrewl.railsignalapi.rest.dto.SignalCreationPayload; -import nl.andrewl.railsignalapi.rest.dto.SignalResponse; -import nl.andrewl.railsignalapi.service.SignalService; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@RestController -@RequestMapping(path = "/api/railSystems/{rsId}/signals") -@RequiredArgsConstructor -public class SignalsApiController { - private final SignalService signalService; - - @PostMapping - public SignalResponse createSignal(@PathVariable long rsId, @RequestBody SignalCreationPayload payload) { - return signalService.createSignal(rsId, payload); - } - - @GetMapping - public List getSignals(@PathVariable long rsId) { - return signalService.getAllSignals(rsId); - } - - @GetMapping(path = "/{sigId}") - public SignalResponse getSignal(@PathVariable long rsId, @PathVariable long sigId) { - return signalService.getSignal(rsId, sigId); - } - - @PostMapping(path = "/{sigId}/signalConnections") - public SignalResponse updateSignalConnections(@PathVariable long rsId, @PathVariable long sigId, @RequestBody SignalConnectionsUpdatePayload payload) { - return signalService.updateSignalBranchConnections(rsId, sigId, payload); - } - - @DeleteMapping(path = "/{sigId}") - public ResponseEntity deleteSignal(@PathVariable long rsId, @PathVariable long sigId) { - signalService.deleteSignal(rsId, sigId); - return ResponseEntity.noContent().build(); - } -} diff --git a/src/main/java/nl/andrewl/railsignalapi/rest/dto/BranchResponse.java b/src/main/java/nl/andrewl/railsignalapi/rest/dto/BranchResponse.java deleted file mode 100644 index 413fa7c..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/rest/dto/BranchResponse.java +++ /dev/null @@ -1,13 +0,0 @@ -package nl.andrewl.railsignalapi.rest.dto; - -import nl.andrewl.railsignalapi.model.Branch; - -public record BranchResponse( - long id, - String name, - String status -) { - public BranchResponse(Branch branch) { - this(branch.getId(), branch.getName(), branch.getStatus().name()); - } -} diff --git a/src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalConnectionsUpdatePayload.java b/src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalConnectionsUpdatePayload.java deleted file mode 100644 index 321f931..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalConnectionsUpdatePayload.java +++ /dev/null @@ -1,9 +0,0 @@ -package nl.andrewl.railsignalapi.rest.dto; - -import java.util.List; - -public record SignalConnectionsUpdatePayload( - List connections -) { - public static record ConnectionData(long from, long to) {} -} diff --git a/src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalCreationPayload.java b/src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalCreationPayload.java deleted file mode 100644 index b0ace7b..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalCreationPayload.java +++ /dev/null @@ -1,13 +0,0 @@ -package nl.andrewl.railsignalapi.rest.dto; - -import nl.andrewl.railsignalapi.model.Position; - -import java.util.List; - -public record SignalCreationPayload( - String name, - Position position, - List branchConnections -) { - public static record BranchData(String direction, String name, Long id) {} -} diff --git a/src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalResponse.java b/src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalResponse.java deleted file mode 100644 index b71a040..0000000 --- a/src/main/java/nl/andrewl/railsignalapi/rest/dto/SignalResponse.java +++ /dev/null @@ -1,61 +0,0 @@ -package nl.andrewl.railsignalapi.rest.dto; - -import nl.andrewl.railsignalapi.model.Position; -import nl.andrewl.railsignalapi.model.Signal; -import nl.andrewl.railsignalapi.model.SignalBranchConnection; - -import java.util.Comparator; -import java.util.List; - -public record SignalResponse( - long id, - String name, - Position position, - List branchConnections, - boolean online -) { - public SignalResponse(Signal signal) { - this( - signal.getId(), - signal.getName(), - signal.getPosition(), - signal.getBranchConnections().stream() - .sorted(Comparator.comparing(SignalBranchConnection::getDirection)) - .map(ConnectionData::new) - .toList(), - signal.isOnline() - ); - } - - public static record ConnectionData( - long id, - String direction, - BranchResponse branch, - List reachableSignalConnections - ) { - public ConnectionData(SignalBranchConnection c) { - this( - c.getId(), - c.getDirection().name(), - new BranchResponse(c.getBranch()), - c.getReachableSignalConnections().stream() - .map(cc -> new ReachableConnectionData( - cc.getId(), - cc.getDirection().name(), - cc.getSignal().getId(), - cc.getSignal().getName(), - cc.getSignal().getPosition() - )) - .toList() - ); - } - - public static record ReachableConnectionData( - long connectionId, - String direction, - long signalId, - String signalName, - Position signalPosition - ) {} - } -} diff --git a/src/main/java/nl/andrewl/railsignalapi/service/RailSystemService.java b/src/main/java/nl/andrewl/railsignalapi/service/RailSystemService.java index fafbb73..2e9e1f1 100644 --- a/src/main/java/nl/andrewl/railsignalapi/service/RailSystemService.java +++ b/src/main/java/nl/andrewl/railsignalapi/service/RailSystemService.java @@ -1,9 +1,9 @@ package nl.andrewl.railsignalapi.service; import lombok.RequiredArgsConstructor; -import nl.andrewl.railsignalapi.dao.BranchRepository; +import nl.andrewl.railsignalapi.dao.ComponentRepository; import nl.andrewl.railsignalapi.dao.RailSystemRepository; -import nl.andrewl.railsignalapi.dao.SignalRepository; +import nl.andrewl.railsignalapi.dao.SegmentRepository; import nl.andrewl.railsignalapi.model.RailSystem; import nl.andrewl.railsignalapi.rest.dto.RailSystemCreationPayload; import nl.andrewl.railsignalapi.rest.dto.RailSystemResponse; @@ -19,8 +19,8 @@ import java.util.List; @RequiredArgsConstructor public class RailSystemService { private final RailSystemRepository railSystemRepository; - private final SignalRepository signalRepository; - private final BranchRepository branchRepository; + private final SegmentRepository segmentRepository; + private final ComponentRepository componentRepository; @Transactional public List getRailSystems() { @@ -40,10 +40,8 @@ public class RailSystemService { public void delete(long rsId) { var rs = railSystemRepository.findById(rsId) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); - var signals = signalRepository.findAllByRailSystemOrderByName(rs); - signalRepository.deleteAll(signals); - var branches = branchRepository.findAllByRailSystemOrderByName(rs); - branchRepository.deleteAll(branches); + componentRepository.deleteAllByRailSystem(rs); + segmentRepository.deleteAllByRailSystem(rs); railSystemRepository.delete(rs); } diff --git a/src/main/java/nl/andrewl/railsignalapi/service/SignalService.java b/src/main/java/nl/andrewl/railsignalapi/service/SignalService.java index 43e2d61..570bae2 100644 --- a/src/main/java/nl/andrewl/railsignalapi/service/SignalService.java +++ b/src/main/java/nl/andrewl/railsignalapi/service/SignalService.java @@ -9,6 +9,7 @@ import nl.andrewl.railsignalapi.dao.RailSystemRepository; import nl.andrewl.railsignalapi.dao.SignalBranchConnectionRepository; import nl.andrewl.railsignalapi.dao.SignalRepository; import nl.andrewl.railsignalapi.model.*; +import nl.andrewl.railsignalapi.model.component.SignalBranchConnection; import nl.andrewl.railsignalapi.rest.dto.SignalConnectionsUpdatePayload; import nl.andrewl.railsignalapi.rest.dto.SignalCreationPayload; import nl.andrewl.railsignalapi.rest.dto.SignalResponse;