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;