This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Thrown when there are insufficient user permissions to perform an operation.
|
||||
*/
|
||||
public class CredentialsException
|
||||
extends
|
||||
KernelRuntimeException
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* Constructs a CredentialsException with no detail message.
|
||||
*/
|
||||
public CredentialsException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CredentialsException with the specified detail message.
|
||||
*
|
||||
* @param message The detail message.
|
||||
*/
|
||||
public CredentialsException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CredentialsException with the specified detail message and
|
||||
* cause.
|
||||
*
|
||||
* @param message The detail message.
|
||||
* @param cause The exception's cause.
|
||||
*/
|
||||
public CredentialsException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CredentialsException with the specified cause and a detail
|
||||
* message of <code>(cause == null ? null : cause.toString())</code> (which
|
||||
* typically contains the class and detail message of <code>cause</code>).
|
||||
*
|
||||
* @param cause The exception's cause.
|
||||
*/
|
||||
public CredentialsException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
/**
|
||||
* Declares the methods an openTCS kernel implements.
|
||||
*/
|
||||
public interface Kernel {
|
||||
|
||||
/**
|
||||
* The default name used for the empty model created on startup.
|
||||
*/
|
||||
String DEFAULT_MODEL_NAME = "unnamed";
|
||||
|
||||
/**
|
||||
* Returns the current state of the kernel.
|
||||
*
|
||||
* @return The current state of the kernel.
|
||||
* @throws CredentialsException If the calling client is not allowed to
|
||||
* execute this method.
|
||||
*/
|
||||
State getState()
|
||||
throws CredentialsException;
|
||||
|
||||
/**
|
||||
* Sets the current state of the kernel.
|
||||
* <p>
|
||||
* Note: This method should only be used internally by the Kernel application.
|
||||
* </p>
|
||||
*
|
||||
* @param newState The state the kernel is to be set to.
|
||||
* @throws IllegalArgumentException If setting the new state is not possible,
|
||||
* e.g. because a transition from the current to the new state is not allowed.
|
||||
* @throws CredentialsException If the calling client is not allowed to
|
||||
* execute this method.
|
||||
*/
|
||||
void setState(State newState)
|
||||
throws IllegalArgumentException,
|
||||
CredentialsException;
|
||||
|
||||
/**
|
||||
* The various states a kernel instance may be running in.
|
||||
*/
|
||||
enum State {
|
||||
|
||||
/**
|
||||
* The state in which the model/topology is created and parameters are set.
|
||||
*/
|
||||
MODELLING,
|
||||
/**
|
||||
* The normal mode of operation in which transport orders may be accepted
|
||||
* and dispatched to vehicles.
|
||||
*/
|
||||
OPERATING,
|
||||
/**
|
||||
* A transitional state the kernel is in while shutting down.
|
||||
*/
|
||||
SHUTDOWN
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* An exception thrown by the openTCS kernel.
|
||||
*/
|
||||
public class KernelException
|
||||
extends
|
||||
Exception
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* Constructs a new instance with no detail message.
|
||||
*/
|
||||
public KernelException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified detail message.
|
||||
*
|
||||
* @param message The detail message.
|
||||
*/
|
||||
public KernelException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified detail message and cause.
|
||||
*
|
||||
* @param message The detail message.
|
||||
* @param cause The exception's cause.
|
||||
*/
|
||||
public KernelException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified cause and a detail
|
||||
* message of <code>(cause == null ? null : cause.toString())</code> (which
|
||||
* typically contains the class and detail message of <code>cause</code>).
|
||||
*
|
||||
* @param cause The exception's cause.
|
||||
*/
|
||||
public KernelException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A runtime exception thrown by the openTCS kernel.
|
||||
*/
|
||||
public class KernelRuntimeException
|
||||
extends
|
||||
RuntimeException
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* Constructs a new instance with no detail message.
|
||||
*/
|
||||
public KernelRuntimeException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified detail message.
|
||||
*
|
||||
* @param message The detail message.
|
||||
*/
|
||||
public KernelRuntimeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified detail message and cause.
|
||||
*
|
||||
* @param message The detail message.
|
||||
* @param cause The exception's cause.
|
||||
*/
|
||||
public KernelRuntimeException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified cause and a detail
|
||||
* message of <code>(cause == null ? null : cause.toString())</code> (which
|
||||
* typically contains the class and detail message of <code>cause</code>).
|
||||
*
|
||||
* @param cause The exception's cause.
|
||||
*/
|
||||
public KernelRuntimeException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import org.opentcs.components.kernel.services.DispatcherService;
|
||||
import org.opentcs.components.kernel.services.NotificationService;
|
||||
import org.opentcs.components.kernel.services.PeripheralDispatcherService;
|
||||
import org.opentcs.components.kernel.services.PeripheralJobService;
|
||||
import org.opentcs.components.kernel.services.PeripheralService;
|
||||
import org.opentcs.components.kernel.services.PlantModelService;
|
||||
import org.opentcs.components.kernel.services.QueryService;
|
||||
import org.opentcs.components.kernel.services.RouterService;
|
||||
import org.opentcs.components.kernel.services.TransportOrderService;
|
||||
import org.opentcs.components.kernel.services.VehicleService;
|
||||
|
||||
/**
|
||||
* Provides clients access to kernel services.
|
||||
*/
|
||||
public interface KernelServicePortal {
|
||||
|
||||
/**
|
||||
* Logs in with/establishes a connection to the remote kernel service portal.
|
||||
*
|
||||
* @param hostName The host on which the remote portal is running.
|
||||
* @param port The port at which we can reach the remote RMI registry.
|
||||
* @throws KernelRuntimeException If there was a problem logging in with the remote portal.
|
||||
*/
|
||||
void login(
|
||||
@Nonnull
|
||||
String hostName,
|
||||
int port
|
||||
)
|
||||
throws KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Logs out from/clears the connection to the remote kernel service portal.
|
||||
*
|
||||
* @throws KernelRuntimeException If there was a problem logging out from the remote portal, i.e.
|
||||
* it is no longer available.
|
||||
*/
|
||||
void logout()
|
||||
throws KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Returns the current state of the kernel.
|
||||
*
|
||||
* @return The current state of the kernel.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
Kernel.State getState()
|
||||
throws KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Fetches events buffered for the client.
|
||||
*
|
||||
* @param timeout A timeout (in ms) for which to wait for events to arrive.
|
||||
* @return A list of events (in the order they arrived).
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
List<Object> fetchEvents(long timeout)
|
||||
throws KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Publishes an event.
|
||||
*
|
||||
* @param event The event to be published.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void publishEvent(Object event)
|
||||
throws KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods regarding the plant model.
|
||||
*
|
||||
* @return The service a client can use to access methods regarding the plant model.
|
||||
*/
|
||||
@Nonnull
|
||||
PlantModelService getPlantModelService();
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods regarding transport orders and order
|
||||
* sequences.
|
||||
*
|
||||
* @return The service a client can use to access methods regarding transport orders and order
|
||||
* sequences.
|
||||
*/
|
||||
@Nonnull
|
||||
TransportOrderService getTransportOrderService();
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods regarding vehicles.
|
||||
*
|
||||
* @return The service a client can use to access methods regarding vehicles.
|
||||
*/
|
||||
@Nonnull
|
||||
VehicleService getVehicleService();
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods regarding user notifications.
|
||||
*
|
||||
* @return The service a client can use to access methods regarding user notifications.
|
||||
*/
|
||||
@Nonnull
|
||||
NotificationService getNotificationService();
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods regarding the dispatcher.
|
||||
*
|
||||
* @return The service a client can use to access methods regarding the dispatcher.
|
||||
*/
|
||||
@Nonnull
|
||||
DispatcherService getDispatcherService();
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods regarding the router.
|
||||
*
|
||||
* @return The service a client can use to access methods regarding the router.
|
||||
*/
|
||||
@Nonnull
|
||||
RouterService getRouterService();
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods for generic queries.
|
||||
*
|
||||
* @return The service a client can use to access methods for generic queries.
|
||||
*/
|
||||
@Nonnull
|
||||
QueryService getQueryService();
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods regarding peripherals.
|
||||
*
|
||||
* @return The service a client can use to access methods regarding peripherals.
|
||||
*/
|
||||
@Nonnull
|
||||
PeripheralService getPeripheralService();
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods regarding peripheral jobs.
|
||||
*
|
||||
* @return The service a client can use to access methods regarding peripheral jobs.
|
||||
*/
|
||||
@Nonnull
|
||||
PeripheralJobService getPeripheralJobService();
|
||||
|
||||
/**
|
||||
* Returns the service a client can use to access methods regarding the peripheral dispatcher.
|
||||
*
|
||||
* @return The service a client can use to access methods regarding the peripheral dispatcher.
|
||||
*/
|
||||
@Nonnull
|
||||
PeripheralDispatcherService getPeripheralDispatcherService();
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Emitted by/for kernel state changes.
|
||||
*/
|
||||
public class KernelStateTransitionEvent
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The old state the kernel is leaving.
|
||||
*/
|
||||
private final Kernel.State leftState;
|
||||
/**
|
||||
* The new state the kernel is in transition to.
|
||||
*/
|
||||
private final Kernel.State enteredState;
|
||||
/**
|
||||
* Whether the transition to the entered state is finished or not.
|
||||
*/
|
||||
private final boolean transitionFinished;
|
||||
|
||||
/**
|
||||
* Creates a new TCSKernelStateEvent.
|
||||
*
|
||||
* @param leftState The previous state of the kernel.
|
||||
* @param enteredState The new state of the kernel.
|
||||
* @param transitionFinished Whether the transistion is finished, yet.
|
||||
*/
|
||||
public KernelStateTransitionEvent(
|
||||
Kernel.State leftState,
|
||||
Kernel.State enteredState,
|
||||
boolean transitionFinished
|
||||
) {
|
||||
this.leftState = leftState;
|
||||
this.enteredState = enteredState;
|
||||
this.transitionFinished = transitionFinished;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state the kernel is leaving.
|
||||
*
|
||||
* @return The state the kernel is leaving.
|
||||
*/
|
||||
public Kernel.State getLeftState() {
|
||||
return leftState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state for which this event was generated.
|
||||
*
|
||||
* @return The state for which this event was generated.
|
||||
*/
|
||||
public Kernel.State getEnteredState() {
|
||||
return enteredState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if, and only if, the transition to the new kernel
|
||||
* state is finished.
|
||||
*
|
||||
* @return <code>true</code> if, and only if, the transition to the new kernel
|
||||
* state is finished.
|
||||
*/
|
||||
public boolean isTransitionFinished() {
|
||||
return transitionFinished;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName()
|
||||
+ '{'
|
||||
+ "leftState=" + leftState
|
||||
+ ", enteredState=" + enteredState
|
||||
+ ", transitionFinished=" + transitionFinished
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import org.opentcs.components.Lifecycle;
|
||||
import org.opentcs.components.kernel.KernelExtension;
|
||||
|
||||
/**
|
||||
* Declares the methods the openTCS kernel must provide which are not accessible
|
||||
* to remote peers.
|
||||
*/
|
||||
public interface LocalKernel
|
||||
extends
|
||||
Kernel,
|
||||
Lifecycle {
|
||||
|
||||
/**
|
||||
* Adds a <code>KernelExtension</code> to this kernel.
|
||||
*
|
||||
* @param newExtension The extension to be added.
|
||||
*/
|
||||
void addKernelExtension(KernelExtension newExtension);
|
||||
|
||||
/**
|
||||
* Removes a <code>KernelExtension</code> from this kernel.
|
||||
*
|
||||
* @param rmExtension The extension to be removed.
|
||||
*/
|
||||
void removeKernelExtension(KernelExtension rmExtension);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Emitted when the kernel loads a model.
|
||||
*/
|
||||
public class ModelTransitionEvent
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The old model the kernel is leaving.
|
||||
*/
|
||||
private final String oldModelName;
|
||||
/**
|
||||
* The new model the kernel is in transition to.
|
||||
*/
|
||||
private final String newModelName;
|
||||
/**
|
||||
* Whether the content of the model actually changed with the transition.
|
||||
*/
|
||||
private final boolean modelContentChanged;
|
||||
/**
|
||||
* Whether the transition to the entered state is finished or not.
|
||||
*/
|
||||
private final boolean transitionFinished;
|
||||
|
||||
/**
|
||||
* Creates a new TCSModelTransitionEvent.
|
||||
*
|
||||
* @param oldModelName The name of the previously loaded model.
|
||||
* @param newModelName The name of the new model.
|
||||
* @param modelContentChanged Whether the content of the model actually
|
||||
* changed with the transition.
|
||||
* @param transitionFinished Whether the transition to the new model is
|
||||
* finished, yet.
|
||||
*/
|
||||
public ModelTransitionEvent(
|
||||
String oldModelName,
|
||||
String newModelName,
|
||||
boolean modelContentChanged,
|
||||
boolean transitionFinished
|
||||
) {
|
||||
this.oldModelName = oldModelName;
|
||||
this.newModelName = newModelName;
|
||||
this.modelContentChanged = modelContentChanged;
|
||||
this.transitionFinished = transitionFinished;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the model name the kernel is leaving.
|
||||
*
|
||||
* @return The model the kernel is leaving.
|
||||
*/
|
||||
public String getOldModelName() {
|
||||
return oldModelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the model for which this event was generated.
|
||||
*
|
||||
* @return The model for which this event was generated.
|
||||
*/
|
||||
public String getNewModelName() {
|
||||
return newModelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if, and only if, the content of the model
|
||||
* actually changed with the transition.
|
||||
*
|
||||
* @return <code>true</code> if, and only if, the content of the model
|
||||
* actually changed with the transition.
|
||||
*/
|
||||
public boolean hasModelContentChanged() {
|
||||
return modelContentChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if, and only if, the transition to the new kernel
|
||||
* state is finished.
|
||||
*
|
||||
* @return <code>true</code> if, and only if, the transition to the new kernel
|
||||
* state is finished.
|
||||
*/
|
||||
public boolean isTransitionFinished() {
|
||||
return transitionFinished;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName()
|
||||
+ '{'
|
||||
+ "oldModelName=" + oldModelName
|
||||
+ ", newModelName=" + newModelName
|
||||
+ ", modelContentChanged=" + modelContentChanged
|
||||
+ ", transitionFinished=" + transitionFinished
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.opentcs.data.notification.UserNotification;
|
||||
|
||||
/**
|
||||
* Instances of this class represent events emitted by/for notifications being published.
|
||||
*/
|
||||
public class NotificationPublicationEvent
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The published message.
|
||||
*/
|
||||
private final UserNotification notification;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param message The message being published.
|
||||
*/
|
||||
public NotificationPublicationEvent(UserNotification message) {
|
||||
this.notification = requireNonNull(message, "notification");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message being published.
|
||||
*
|
||||
* @return The message being published.
|
||||
*/
|
||||
public UserNotification getNotification() {
|
||||
return notification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName()
|
||||
+ '{'
|
||||
+ "notification=" + notification
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
/**
|
||||
* Provides access to a shared {@link KernelServicePortal} instance.
|
||||
*/
|
||||
public interface SharedKernelServicePortal
|
||||
extends
|
||||
AutoCloseable {
|
||||
|
||||
@Override
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Indicates whether this instance is closed/unregistered from the shared portal pool.
|
||||
*
|
||||
* @return {@code true} if, and only if, this instance is closed.
|
||||
*/
|
||||
boolean isClosed();
|
||||
|
||||
/**
|
||||
* Returns the {@link KernelServicePortal} instance being shared.
|
||||
*
|
||||
* @return The portal instance being shared.
|
||||
* @throws IllegalStateException If this instance is closed.
|
||||
*/
|
||||
KernelServicePortal getPortal()
|
||||
throws IllegalStateException;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import org.opentcs.components.kernel.services.ServiceUnavailableException;
|
||||
|
||||
/**
|
||||
* Pools access to a {@link KernelServicePortal} instance for multiple clients.
|
||||
*/
|
||||
public interface SharedKernelServicePortalProvider {
|
||||
|
||||
/**
|
||||
* Creates and registers a new client with this access pool.
|
||||
* This is a convenience method that supports try-with-ressources and does not require a
|
||||
* preexisting client.
|
||||
*
|
||||
* @return The {@link SharedKernelServicePortal}.
|
||||
* @throws ServiceUnavailableException in case of connection falure with the portal.
|
||||
*/
|
||||
SharedKernelServicePortal register()
|
||||
throws ServiceUnavailableException;
|
||||
|
||||
/**
|
||||
* Checks whether a kernel reference is currently being shared.
|
||||
*
|
||||
* @return {@code true} if, and only if, a portal reference is currently being shared, meaning
|
||||
* that at least one client is registered and a usable portal reference exists.
|
||||
*/
|
||||
boolean portalShared();
|
||||
|
||||
/**
|
||||
* Returns a description for the portal currently being shared.
|
||||
*
|
||||
* @return A description for the portal currently being shared, or the empty string, if none is
|
||||
* currently being shared.
|
||||
*/
|
||||
String getPortalDescription();
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A set of parameters to be used for SSL-encrypted socket connections.
|
||||
*/
|
||||
public class SslParameterSet
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The default type used for truststore and keystore files.
|
||||
*/
|
||||
public static final String DEFAULT_KEYSTORE_TYPE = "PKCS12";
|
||||
|
||||
/**
|
||||
* The type used for keystore and truststore.
|
||||
*/
|
||||
private final String keystoreType;
|
||||
/**
|
||||
* The file path of the keystore.
|
||||
*/
|
||||
private final File keystoreFile;
|
||||
/**
|
||||
* The password for the keystore file.
|
||||
*/
|
||||
private final String keystorePassword;
|
||||
/**
|
||||
* The file path of the truststore.
|
||||
*/
|
||||
private final File truststoreFile;
|
||||
/**
|
||||
* The password for the truststore file.
|
||||
*/
|
||||
private final String truststorePassword;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param keystoreType The type used for keystore and truststore
|
||||
* @param keystoreFile The keystore file
|
||||
* @param truststoreFile The truststore file
|
||||
* @param keystorePassword The keystore file password
|
||||
* @param truststorePassword The truststore file password
|
||||
*/
|
||||
public SslParameterSet(
|
||||
@Nonnull
|
||||
String keystoreType,
|
||||
@Nullable
|
||||
File keystoreFile,
|
||||
@Nullable
|
||||
String keystorePassword,
|
||||
@Nullable
|
||||
File truststoreFile,
|
||||
@Nullable
|
||||
String truststorePassword
|
||||
) {
|
||||
this.keystoreType = requireNonNull(keystoreType, "keystoreType");
|
||||
this.keystoreFile = keystoreFile;
|
||||
this.keystorePassword = keystorePassword;
|
||||
this.truststoreFile = truststoreFile;
|
||||
this.truststorePassword = truststorePassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the keystoreType used to decrypt the keystore and truststore.
|
||||
*
|
||||
* @return The keystoreType used to decrypt the keystore and truststore
|
||||
*/
|
||||
@Nonnull
|
||||
public String getKeystoreType() {
|
||||
return keystoreType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file path of the keystore file.
|
||||
*
|
||||
* @return The file path of the keystore file
|
||||
*/
|
||||
@Nullable
|
||||
public File getKeystoreFile() {
|
||||
return keystoreFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password for the keystore file.
|
||||
*
|
||||
* @return The password for the keystore file
|
||||
*/
|
||||
@Nullable
|
||||
public String getKeystorePassword() {
|
||||
return keystorePassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file path of the truststore file.
|
||||
*
|
||||
* @return The file path of the truststore file
|
||||
*/
|
||||
@Nullable
|
||||
public File getTruststoreFile() {
|
||||
return truststoreFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password for the truststore file.
|
||||
*
|
||||
* @return The password for the truststore file
|
||||
*/
|
||||
@Nullable
|
||||
public String getTruststorePassword() {
|
||||
return truststorePassword;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
/**
|
||||
* Interfaces and classes for accessing the kernel from outside, for instance
|
||||
* from a remote client or a communication adapter.
|
||||
*/
|
||||
package org.opentcs.access;
|
||||
@@ -0,0 +1,77 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Identifies a remote client unambiguously.
|
||||
*/
|
||||
public class ClientID
|
||||
implements
|
||||
Serializable {
|
||||
/**
|
||||
* The client's name.
|
||||
*/
|
||||
private final String clientName;
|
||||
/**
|
||||
* The client's UUID.
|
||||
*/
|
||||
private final UUID uuid;
|
||||
|
||||
/**
|
||||
* Creates a new ClientID.
|
||||
*
|
||||
* @param clientName The client's name.
|
||||
*/
|
||||
public ClientID(
|
||||
@Nonnull
|
||||
String clientName
|
||||
) {
|
||||
this.clientName = requireNonNull(clientName, "clientName");
|
||||
uuid = UUID.randomUUID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the client's name.
|
||||
*
|
||||
* @return The client's name.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getClientName() {
|
||||
return clientName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this object equals another one.
|
||||
*
|
||||
* @param otherObject The other object to be compared with this object.
|
||||
* @return <code>true</code> if, and only if, the given object is also a
|
||||
* <code>ClientID</code> and contains the same name and the same UUID as this
|
||||
* one.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object otherObject) {
|
||||
if (otherObject instanceof ClientID) {
|
||||
ClientID otherID = (ClientID) otherObject;
|
||||
return clientName.equals(otherID.clientName) && uuid.equals(otherID.uuid);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return uuid.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return clientName + ":" + uuid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.access.CredentialsException;
|
||||
import org.opentcs.access.KernelServicePortal;
|
||||
import org.opentcs.access.rmi.factories.NullSocketFactoryProvider;
|
||||
import org.opentcs.access.rmi.factories.SocketFactoryProvider;
|
||||
import org.opentcs.access.rmi.services.RemoteKernelServicePortalProxy;
|
||||
import org.opentcs.components.kernel.services.ServiceUnavailableException;
|
||||
import org.opentcs.util.ClassMatcher;
|
||||
|
||||
/**
|
||||
* Builds {@link KernelServicePortal} instances for connections to remote portals.
|
||||
*/
|
||||
public class KernelServicePortalBuilder {
|
||||
|
||||
/**
|
||||
* Provides socket factories used for RMI.
|
||||
*/
|
||||
private SocketFactoryProvider socketFactoryProvider = new NullSocketFactoryProvider();
|
||||
/**
|
||||
* The user name for logging in.
|
||||
*/
|
||||
private final String userName;
|
||||
/**
|
||||
* The password for logging in.
|
||||
*/
|
||||
private final String password;
|
||||
/**
|
||||
* The event filter to be applied for the built portal.
|
||||
*/
|
||||
private Predicate<Object> eventFilter = new ClassMatcher(Object.class);
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param userName The user name to use for logging in.
|
||||
* @param password The password to use for logging in.
|
||||
*/
|
||||
public KernelServicePortalBuilder(String userName, String password) {
|
||||
this.userName = requireNonNull(userName, "userName");
|
||||
this.password = requireNonNull(password, "password");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the socket factory provider used for RMI.
|
||||
*
|
||||
* @return The socket factory provider used for RMI.
|
||||
*/
|
||||
public SocketFactoryProvider getSocketFactoryProvider() {
|
||||
return socketFactoryProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the socket factory provider used for RMI.
|
||||
*
|
||||
* @param socketFactoryProvider The socket factory provider.
|
||||
* @return This instance.
|
||||
*/
|
||||
public KernelServicePortalBuilder setSocketFactoryProvider(
|
||||
@Nonnull
|
||||
SocketFactoryProvider socketFactoryProvider
|
||||
) {
|
||||
this.socketFactoryProvider = requireNonNull(socketFactoryProvider, "socketFactoryProvider");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user name used for logging in.
|
||||
*
|
||||
* @return The user name used for logging in.
|
||||
*/
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password used for logging in.
|
||||
*
|
||||
* @return The password used for logging in.
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the event filter to be applied for the built portal.
|
||||
*
|
||||
* @return The event filter to be applied for the built portal.
|
||||
*/
|
||||
public Predicate<Object> getEventFilter() {
|
||||
return eventFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event filter to be applied for the built portal.
|
||||
*
|
||||
* @param eventFilter The event filter.
|
||||
* @return This instance.
|
||||
*/
|
||||
public KernelServicePortalBuilder setEventFilter(
|
||||
@Nonnull
|
||||
Predicate<Object> eventFilter
|
||||
) {
|
||||
this.eventFilter = requireNonNull(eventFilter, "eventFilter");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and returns a {@link KernelServicePortal} with the configured parameters.
|
||||
*
|
||||
* @return A {@link KernelServicePortal} instance.
|
||||
* @throws ServiceUnavailableException If the remote portal is not reachable for some reason.
|
||||
* @throws CredentialsException If the client login with the remote portal failed, e.g. because of
|
||||
* incorrect login data.
|
||||
*/
|
||||
public KernelServicePortal build()
|
||||
throws ServiceUnavailableException,
|
||||
CredentialsException {
|
||||
return new RemoteKernelServicePortalProxy(
|
||||
userName,
|
||||
password,
|
||||
socketFactoryProvider,
|
||||
eventFilter
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.factories;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.Socket;
|
||||
import java.rmi.server.RMIClientSocketFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.rmi.ssl.SslRMIClientSocketFactory;
|
||||
|
||||
/**
|
||||
* This implementation is similar to {@link SslRMIClientSocketFactory} but allows the use of a
|
||||
* custom SSLConext.
|
||||
*/
|
||||
class CustomSslRMIClientSocketFactory
|
||||
implements
|
||||
RMIClientSocketFactory,
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* Provides an instance of {@link SSLContext} used to get the actual socket factory.
|
||||
*/
|
||||
private final SecureSslContextFactory secureSslContextFactory;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param secureSslContextFactory Provides an instance of {@link SSLContext} used to get the
|
||||
* actual socket factory.
|
||||
*/
|
||||
CustomSslRMIClientSocketFactory(SecureSslContextFactory secureSslContextFactory) {
|
||||
this.secureSslContextFactory = requireNonNull(
|
||||
secureSslContextFactory,
|
||||
"secureSslContextFactory"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port)
|
||||
throws IOException {
|
||||
SSLContext context = secureSslContextFactory.createClientContext();
|
||||
SSLSocketFactory sf = context.getSocketFactory();
|
||||
SSLSocket socket = (SSLSocket) sf.createSocket(host, port);
|
||||
SSLParameters param = context.getSupportedSSLParameters();
|
||||
socket.setEnabledCipherSuites(param.getCipherSuites());
|
||||
socket.setEnabledProtocols(param.getProtocols());
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.factories;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.RMIClientSocketFactory;
|
||||
import java.rmi.server.RMIServerSocketFactory;
|
||||
|
||||
/**
|
||||
* Provides {@code null} for both client and server socket factories.
|
||||
* By using this provider, the default client-side/server-side socket factory will be used in
|
||||
* {@link Registry} stubs.
|
||||
*/
|
||||
public class NullSocketFactoryProvider
|
||||
implements
|
||||
SocketFactoryProvider {
|
||||
|
||||
@Inject
|
||||
public NullSocketFactoryProvider() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RMIClientSocketFactory getClientSocketFactory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RMIServerSocketFactory getServerSocketFactory() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.factories;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import java.rmi.server.RMIClientSocketFactory;
|
||||
import java.rmi.server.RMIServerSocketFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.rmi.ssl.SslRMIServerSocketFactory;
|
||||
import org.opentcs.access.SslParameterSet;
|
||||
|
||||
/**
|
||||
* Provides instances of {@link RMIClientSocketFactory} and {@link RMIServerSocketFactory} that are
|
||||
* implemented over the SSL or TLS protocols.
|
||||
* Since these factories don't support anonymous cipher suites a keystore on the server-side and a
|
||||
* truststore on the client-side is necessary.
|
||||
*/
|
||||
public class SecureSocketFactoryProvider
|
||||
implements
|
||||
SocketFactoryProvider {
|
||||
|
||||
/**
|
||||
* Provides methods for creating client-side and server-side {@link SSLContext} instances.
|
||||
*/
|
||||
private final SecureSslContextFactory secureSslContextFactory;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param sslParameterSet The SSL parameters to be used for creating socket factories.
|
||||
*/
|
||||
@Inject
|
||||
public SecureSocketFactoryProvider(SslParameterSet sslParameterSet) {
|
||||
requireNonNull(sslParameterSet, "sslParameterSet");
|
||||
this.secureSslContextFactory = new SecureSslContextFactory(sslParameterSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RMIClientSocketFactory getClientSocketFactory() {
|
||||
return new CustomSslRMIClientSocketFactory(secureSslContextFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RMIServerSocketFactory getServerSocketFactory() {
|
||||
SSLContext context = secureSslContextFactory.createServerContext();
|
||||
SSLParameters param = context.getSupportedSSLParameters();
|
||||
return new SslRMIServerSocketFactory(
|
||||
context,
|
||||
param.getCipherSuites(),
|
||||
param.getProtocols(),
|
||||
param.getWantClientAuth()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.factories;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import org.opentcs.access.SslParameterSet;
|
||||
|
||||
/**
|
||||
* Provides methods for creating client-side and server-side {@link SSLContext} instances.
|
||||
*/
|
||||
class SecureSslContextFactory
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The name of the algorithm to use for the {@link KeyManagerFactory} and
|
||||
* {@link TrustManagerFactory}.
|
||||
*/
|
||||
private static final String KEY_TRUST_MANAGEMENT_ALGORITHM = "SunX509";
|
||||
/**
|
||||
* The protocol to use with the ssl context.
|
||||
*/
|
||||
private static final String SSL_CONTEXT_PROTOCOL = "TLSv1.2";
|
||||
/**
|
||||
* The ssl parameters to be used for creating the ssl context.
|
||||
*/
|
||||
private final SslParameterSet sslParameterSet;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param sslParameterSet The ssl parameters to be used for creating the ssl context.
|
||||
*/
|
||||
SecureSslContextFactory(SslParameterSet sslParameterSet) {
|
||||
this.sslParameterSet = requireNonNull(sslParameterSet, "sslParameterSet");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link SSLContext} for the client.
|
||||
*
|
||||
* @return The ssl context.
|
||||
* @throws IllegalStateException If the creation of the ssl context fails.
|
||||
*/
|
||||
public SSLContext createClientContext()
|
||||
throws IllegalStateException {
|
||||
SSLContext context = null;
|
||||
|
||||
try {
|
||||
KeyStore ts = KeyStore.getInstance(sslParameterSet.getKeystoreType());
|
||||
ts.load(
|
||||
new FileInputStream(sslParameterSet.getTruststoreFile()),
|
||||
sslParameterSet.getTruststorePassword().toCharArray()
|
||||
);
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(KEY_TRUST_MANAGEMENT_ALGORITHM);
|
||||
tmf.init(ts);
|
||||
|
||||
context = SSLContext.getInstance(SSL_CONTEXT_PROTOCOL);
|
||||
context.init(null, tmf.getTrustManagers(), null);
|
||||
}
|
||||
catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException
|
||||
| KeyManagementException ex) {
|
||||
throw new IllegalStateException("Error creating the client's ssl context", ex);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link SSLContext} for the server.
|
||||
*
|
||||
* @return The ssl context.
|
||||
* @throws IllegalStateException If the creation of the ssl context fails.
|
||||
*/
|
||||
public SSLContext createServerContext()
|
||||
throws IllegalStateException {
|
||||
SSLContext context = null;
|
||||
|
||||
try {
|
||||
KeyStore ks = KeyStore.getInstance(sslParameterSet.getKeystoreType());
|
||||
ks.load(
|
||||
new FileInputStream(sslParameterSet.getKeystoreFile()),
|
||||
sslParameterSet.getKeystorePassword().toCharArray()
|
||||
);
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEY_TRUST_MANAGEMENT_ALGORITHM);
|
||||
kmf.init(ks, sslParameterSet.getKeystorePassword().toCharArray());
|
||||
|
||||
context = SSLContext.getInstance(SSL_CONTEXT_PROTOCOL);
|
||||
context.init(kmf.getKeyManagers(), null, null);
|
||||
|
||||
}
|
||||
catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException
|
||||
| KeyManagementException | UnrecoverableKeyException ex) {
|
||||
throw new IllegalStateException("Error creating the server's ssl context", ex);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.factories;
|
||||
|
||||
import jakarta.annotation.Nullable;
|
||||
import java.rmi.server.RMIClientSocketFactory;
|
||||
import java.rmi.server.RMIServerSocketFactory;
|
||||
|
||||
/**
|
||||
* A provider for instances of {@link RMIClientSocketFactory} and {@link RMIServerSocketFactory}.
|
||||
* Generally one provider should provide compatible factories for clients and servers.
|
||||
*/
|
||||
public interface SocketFactoryProvider {
|
||||
|
||||
/**
|
||||
* Returns a {@link RMIClientSocketFactory}.
|
||||
*
|
||||
* @return A {@link RMIClientSocketFactory}.
|
||||
* May be <code>null</code> to indicate that a default factory implementation is to be used.
|
||||
*/
|
||||
@Nullable
|
||||
RMIClientSocketFactory getClientSocketFactory();
|
||||
|
||||
/**
|
||||
* Returns a {@link RMIServerSocketFactory}.
|
||||
*
|
||||
* @return A {@link RMIServerSocketFactory}.
|
||||
* May be <code>null</code> to indicate that a default factory implementation is to be used.
|
||||
*/
|
||||
@Nullable
|
||||
RMIServerSocketFactory getServerSocketFactory();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
/**
|
||||
* Interfaces and classes for configuration of the RMI runtime used by openTCS kernel and clients.
|
||||
*/
|
||||
package org.opentcs.access.rmi.factories;
|
||||
@@ -0,0 +1,7 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
/**
|
||||
* Interfaces and classes for transparently providing an openTCS kernel's
|
||||
* functionality via RMI.
|
||||
*/
|
||||
package org.opentcs.access.rmi;
|
||||
@@ -0,0 +1,141 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.components.kernel.services.ServiceUnavailableException;
|
||||
import org.opentcs.data.ObjectExistsException;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* A base class for remote service proxy implementations.
|
||||
*
|
||||
* @param <R> The remote service's type.
|
||||
*/
|
||||
abstract class AbstractRemoteServiceProxy<R extends Remote> {
|
||||
|
||||
/**
|
||||
* The message to log when a service is unavailable.
|
||||
*/
|
||||
private static final String SERVICE_UNAVAILABLE_MESSAGE = "Remote service unreachable";
|
||||
/**
|
||||
* The client using this service.
|
||||
*/
|
||||
private ClientID clientId;
|
||||
/**
|
||||
* The corresponding remote service.
|
||||
*/
|
||||
private R remoteService;
|
||||
/**
|
||||
* The listener that is interested in updates of this service.
|
||||
*/
|
||||
private ServiceListener serviceListener;
|
||||
|
||||
/**
|
||||
* Returns the client id using this service.
|
||||
*
|
||||
* @return The client id using this service.
|
||||
*/
|
||||
ClientID getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client id using this service.
|
||||
*
|
||||
* @param clientId The client id.
|
||||
* @return This remote service proxy.
|
||||
*/
|
||||
AbstractRemoteServiceProxy<R> setClientId(ClientID clientId) {
|
||||
this.clientId = clientId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remote service to delegate method invocations to.
|
||||
*
|
||||
* @return The remote service to delegate method invocations to.
|
||||
*/
|
||||
R getRemoteService() {
|
||||
return remoteService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the remote service to delegate method invocations to.
|
||||
*
|
||||
* @param remoteService The remote service.
|
||||
* @return This remote service proxy.
|
||||
*/
|
||||
AbstractRemoteServiceProxy<R> setRemoteService(R remoteService) {
|
||||
this.remoteService = remoteService;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the listener that is interested in updates of this service.
|
||||
*
|
||||
* @return The listener that is interested in updates of this service.
|
||||
*/
|
||||
ServiceListener getServiceListener() {
|
||||
return serviceListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the listener that is interested in updates of this service.
|
||||
*
|
||||
* @param serviceListener The service listener.
|
||||
* @return This remote service proxy.
|
||||
*/
|
||||
public AbstractRemoteServiceProxy<R> setServiceListener(ServiceListener serviceListener) {
|
||||
this.serviceListener = serviceListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this service is logged in or not.
|
||||
*
|
||||
* @return {@code true} if, and only if, this service has both a client id and a remote service
|
||||
* associated to it.
|
||||
*/
|
||||
boolean isLoggedIn() {
|
||||
return getClientId() != null && getRemoteService() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that this service is available to be used.
|
||||
*
|
||||
* @throws ServiceUnavailableException If the service is not available.
|
||||
*/
|
||||
void checkServiceAvailability()
|
||||
throws ServiceUnavailableException {
|
||||
if (!isLoggedIn()) {
|
||||
throw new ServiceUnavailableException(SERVICE_UNAVAILABLE_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a suitable {@link RuntimeException} for the given {@link RemoteException}.
|
||||
*
|
||||
* @param ex The exception to find a runtime exception for.
|
||||
* @return The runtime exception.
|
||||
*/
|
||||
RuntimeException findSuitableExceptionFor(RemoteException ex) {
|
||||
if (ex.getCause() instanceof ObjectUnknownException) {
|
||||
return (ObjectUnknownException) ex.getCause();
|
||||
}
|
||||
if (ex.getCause() instanceof ObjectExistsException) {
|
||||
return (ObjectExistsException) ex.getCause();
|
||||
}
|
||||
if (ex.getCause() instanceof IllegalArgumentException) {
|
||||
return (IllegalArgumentException) ex.getCause();
|
||||
}
|
||||
|
||||
if (getServiceListener() != null) {
|
||||
getServiceListener().onServiceUnavailable();
|
||||
}
|
||||
|
||||
return new ServiceUnavailableException(SERVICE_UNAVAILABLE_MESSAGE, ex);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import org.opentcs.access.Kernel;
|
||||
|
||||
/**
|
||||
* A listener for events concerning kernel state changes.
|
||||
*/
|
||||
interface KernelStateEventListener {
|
||||
|
||||
/**
|
||||
* Called when the kernel state changes to {@link Kernel.State#SHUTDOWN}.
|
||||
*/
|
||||
void onKernelShutdown();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
/**
|
||||
* Defines the names used for binding the remote services in the RMI registry.
|
||||
*/
|
||||
public interface RegistrationName {
|
||||
|
||||
/**
|
||||
* The name the {@link RemoteKernelServicePortal} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_KERNEL_CLIENT_PORTAL = RemoteKernelServicePortal.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemotePlantModelService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_PLANT_MODEL_SERVICE = RemotePlantModelService.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemoteTransportOrderService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_TRANSPORT_ORDER_SERVICE = RemoteTransportOrderService.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemoteVehicleService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_VEHICLE_SERVICE = RemoteVehicleService.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemoteNotificationService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_NOTIFICATION_SERVICE = RemoteNotificationService.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemoteRouterService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_ROUTER_SERVICE = RemoteRouterService.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemoteDispatcherService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_DISPATCHER_SERVICE = RemoteDispatcherService.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemoteQueryService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_QUERY_SERVICE = RemoteQueryService.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemotePeripheralService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_PERIPHERAL_SERVICE = RemotePeripheralService.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemotePeripheralJobService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_PERIPHERAL_JOB_SERVICE = RemotePeripheralJobService.class.getCanonicalName();
|
||||
/**
|
||||
* The name the {@link RemotePeripheralDispatcherService} registers itself with a RMI registry.
|
||||
*/
|
||||
String REMOTE_PERIPHERAL_DISPATCHER_SERVICE
|
||||
= RemotePeripheralDispatcherService.class.getCanonicalName();
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.components.kernel.services.DispatcherService;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.ReroutingType;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link DispatcherService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link DispatcherService}, with an additional {@link ClientID} parameter which serves the purpose
|
||||
* of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link DispatcherService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemoteDispatcherService
|
||||
extends
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
void dispatch(ClientID clientId)
|
||||
throws RemoteException;
|
||||
|
||||
void withdrawByVehicle(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
boolean immediateAbort
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void withdrawByTransportOrder(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<TransportOrder> ref,
|
||||
boolean immediateAbort
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void reroute(ClientID clientId, TCSObjectReference<Vehicle> ref, ReroutingType reroutingType)
|
||||
throws RemoteException;
|
||||
|
||||
void rerouteAll(ClientID clientId, ReroutingType reroutingType)
|
||||
throws RemoteException;
|
||||
|
||||
void assignNow(ClientID clientId, TCSObjectReference<TransportOrder> ref)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.components.kernel.services.DispatcherService;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.ReroutingType;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
|
||||
/**
|
||||
* The default implementation of the dispatcher service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemoteDispatcherServiceProxy
|
||||
extends
|
||||
AbstractRemoteServiceProxy<RemoteDispatcherService>
|
||||
implements
|
||||
DispatcherService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemoteDispatcherServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch()
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().dispatch(getClientId());
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void withdrawByVehicle(
|
||||
TCSObjectReference<Vehicle> vehicleRef,
|
||||
boolean immediateAbort
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().withdrawByVehicle(
|
||||
getClientId(),
|
||||
vehicleRef,
|
||||
immediateAbort
|
||||
);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void withdrawByTransportOrder(
|
||||
TCSObjectReference<TransportOrder> ref,
|
||||
boolean immediateAbort
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().withdrawByTransportOrder(
|
||||
getClientId(),
|
||||
ref,
|
||||
immediateAbort
|
||||
);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reroute(TCSObjectReference<Vehicle> ref, ReroutingType reroutingType)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().reroute(getClientId(), ref, reroutingType);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rerouteAll(ReroutingType reroutingType) {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().rerouteAll(getClientId(), reroutingType);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignNow(TCSObjectReference<TransportOrder> ref)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
try {
|
||||
getRemoteService().assignNow(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.access.CredentialsException;
|
||||
import org.opentcs.access.Kernel;
|
||||
import org.opentcs.access.KernelServicePortal;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link KernelServicePortal} via RMI.
|
||||
*/
|
||||
public interface RemoteKernelServicePortal
|
||||
extends
|
||||
Remote {
|
||||
|
||||
/**
|
||||
* Introduce the calling client to the server and authenticate for operations.
|
||||
*
|
||||
* @param userName The user's name.
|
||||
* @param password The user's password.
|
||||
* @param eventFilter The event filter to be applied to events on the server side.
|
||||
* @return An identification object that is required for subsequent method calls.
|
||||
* @throws CredentialsException If authentication with the given username and password failed.
|
||||
* @throws RemoteException If there was an RMI-related problem.
|
||||
*/
|
||||
ClientID login(String userName, String password, Predicate<Object> eventFilter)
|
||||
throws CredentialsException,
|
||||
RemoteException;
|
||||
|
||||
void logout(ClientID clientId)
|
||||
throws RemoteException;
|
||||
|
||||
Kernel.State getState(ClientID clientId)
|
||||
throws RemoteException;
|
||||
|
||||
List<Object> fetchEvents(ClientID clientId, long timeout)
|
||||
throws RemoteException;
|
||||
|
||||
void publishEvent(ClientID clientId, Object event)
|
||||
throws RemoteException;
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_DISPATCHER_SERVICE;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_KERNEL_CLIENT_PORTAL;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_NOTIFICATION_SERVICE;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_PERIPHERAL_DISPATCHER_SERVICE;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_PERIPHERAL_JOB_SERVICE;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_PERIPHERAL_SERVICE;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_PLANT_MODEL_SERVICE;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_QUERY_SERVICE;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_ROUTER_SERVICE;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_TRANSPORT_ORDER_SERVICE;
|
||||
import static org.opentcs.access.rmi.services.RegistrationName.REMOTE_VEHICLE_SERVICE;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.rmi.NotBoundException;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.access.CredentialsException;
|
||||
import org.opentcs.access.Kernel;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.access.KernelServicePortal;
|
||||
import org.opentcs.access.rmi.factories.SocketFactoryProvider;
|
||||
import org.opentcs.components.kernel.services.DispatcherService;
|
||||
import org.opentcs.components.kernel.services.NotificationService;
|
||||
import org.opentcs.components.kernel.services.PeripheralDispatcherService;
|
||||
import org.opentcs.components.kernel.services.PeripheralJobService;
|
||||
import org.opentcs.components.kernel.services.PeripheralService;
|
||||
import org.opentcs.components.kernel.services.PlantModelService;
|
||||
import org.opentcs.components.kernel.services.QueryService;
|
||||
import org.opentcs.components.kernel.services.RouterService;
|
||||
import org.opentcs.components.kernel.services.ServiceUnavailableException;
|
||||
import org.opentcs.components.kernel.services.TransportOrderService;
|
||||
import org.opentcs.components.kernel.services.VehicleService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The default implementation for the {@link KernelServicePortal}.
|
||||
*/
|
||||
public class RemoteKernelServicePortalProxy
|
||||
extends
|
||||
AbstractRemoteServiceProxy<RemoteKernelServicePortal>
|
||||
implements
|
||||
KernelServicePortal,
|
||||
ServiceListener {
|
||||
|
||||
/**
|
||||
* This class' logger.
|
||||
*/
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RemoteKernelServicePortalProxy.class);
|
||||
/**
|
||||
* The user name used with the remote portal.
|
||||
*/
|
||||
private final String userName;
|
||||
/**
|
||||
* The password used with the remote portal.
|
||||
*/
|
||||
private final String password;
|
||||
/**
|
||||
* Provides socket factories used for RMI.
|
||||
*/
|
||||
private final SocketFactoryProvider socketFactoryProvider;
|
||||
/**
|
||||
* The event filter to be applied to events on the server side (before polling).
|
||||
*/
|
||||
private final Predicate<Object> eventFilter;
|
||||
/**
|
||||
* The plant model service.
|
||||
*/
|
||||
private final RemotePlantModelServiceProxy plantModelService
|
||||
= new RemotePlantModelServiceProxy();
|
||||
/**
|
||||
* The transport order service.
|
||||
*/
|
||||
private final RemoteTransportOrderServiceProxy transportOrderService
|
||||
= new RemoteTransportOrderServiceProxy();
|
||||
/**
|
||||
* The vehicle service.
|
||||
*/
|
||||
private final RemoteVehicleServiceProxy vehicleService = new RemoteVehicleServiceProxy();
|
||||
/**
|
||||
* The notification service.
|
||||
*/
|
||||
private final RemoteNotificationServiceProxy notificationService
|
||||
= new RemoteNotificationServiceProxy();
|
||||
/**
|
||||
* The dispatcher service.
|
||||
*/
|
||||
private final RemoteDispatcherServiceProxy dispatcherService
|
||||
= new RemoteDispatcherServiceProxy();
|
||||
/**
|
||||
* The router service.
|
||||
*/
|
||||
private final RemoteRouterServiceProxy routerService = new RemoteRouterServiceProxy();
|
||||
/**
|
||||
* The query service.
|
||||
*/
|
||||
private final RemoteQueryServiceProxy queryService = new RemoteQueryServiceProxy();
|
||||
/**
|
||||
* The peripheral service.
|
||||
*/
|
||||
private final RemotePeripheralServiceProxy peripheralService = new RemotePeripheralServiceProxy();
|
||||
/**
|
||||
* The peripheral job service.
|
||||
*/
|
||||
private final RemotePeripheralJobServiceProxy peripheralJobService
|
||||
= new RemotePeripheralJobServiceProxy();
|
||||
/**
|
||||
* The peripheral dispatcher service.
|
||||
*/
|
||||
private final RemotePeripheralDispatcherServiceProxy peripheralDispatcherService
|
||||
= new RemotePeripheralDispatcherServiceProxy();
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param userName The user name used with the remote portal.
|
||||
* @param password The password used with the remote portal.
|
||||
* @param socketFactoryProvider Provides socket factories used for RMI.
|
||||
* @param eventFilter The event filter to be applied to events on the server side.
|
||||
*/
|
||||
public RemoteKernelServicePortalProxy(
|
||||
@Nonnull
|
||||
String userName,
|
||||
@Nonnull
|
||||
String password,
|
||||
@Nonnull
|
||||
SocketFactoryProvider socketFactoryProvider,
|
||||
@Nonnull
|
||||
Predicate<Object> eventFilter
|
||||
) {
|
||||
this.userName = requireNonNull(userName, "userName");
|
||||
this.password = requireNonNull(password, "password");
|
||||
this.socketFactoryProvider = requireNonNull(socketFactoryProvider, "socketFactoryProvider");
|
||||
this.eventFilter = requireNonNull(eventFilter, "eventFilter");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceListener getServiceListener() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceUnavailable() {
|
||||
resetServiceLogins();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void login(
|
||||
@Nonnull
|
||||
String hostName,
|
||||
int port
|
||||
)
|
||||
throws CredentialsException,
|
||||
ServiceUnavailableException {
|
||||
requireNonNull(hostName, "hostName");
|
||||
|
||||
if (isLoggedIn()) {
|
||||
LOG.warn("Already logged in, doing nothing.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Look up the remote portal with the RMI registry.
|
||||
Registry registry
|
||||
= LocateRegistry.getRegistry(
|
||||
hostName,
|
||||
port,
|
||||
socketFactoryProvider.getClientSocketFactory()
|
||||
);
|
||||
|
||||
setRemoteService((RemoteKernelServicePortal) registry.lookup(REMOTE_KERNEL_CLIENT_PORTAL));
|
||||
// Login and save the client ID.
|
||||
setClientId(getRemoteService().login(userName, password, eventFilter));
|
||||
// Get notified when a service call on us fails.
|
||||
setServiceListener(this);
|
||||
|
||||
// Look up the remote services with the RMI registry and update the other service logins.
|
||||
updateServiceLogins(registry);
|
||||
}
|
||||
catch (RemoteException | NotBoundException exc) {
|
||||
resetServiceLogins();
|
||||
throw new ServiceUnavailableException(
|
||||
"Exception logging in with remote kernel client portal",
|
||||
exc
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
if (!isLoggedIn()) {
|
||||
LOG.warn("Not logged in, doing nothing.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
getRemoteService().logout(getClientId());
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw new ServiceUnavailableException("Remote kernel client portal unavailable", ex);
|
||||
}
|
||||
|
||||
resetServiceLogins();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kernel.State getState()
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().getState(getClientId());
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> fetchEvents(long timeout)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchEvents(getClientId(), timeout);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishEvent(Object event)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().publishEvent(getClientId(), event);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public PlantModelService getPlantModelService() {
|
||||
return plantModelService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public TransportOrderService getTransportOrderService() {
|
||||
return transportOrderService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public VehicleService getVehicleService() {
|
||||
return vehicleService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public NotificationService getNotificationService() {
|
||||
return notificationService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public DispatcherService getDispatcherService() {
|
||||
return dispatcherService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public RouterService getRouterService() {
|
||||
return routerService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public QueryService getQueryService() {
|
||||
return queryService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public PeripheralService getPeripheralService() {
|
||||
return peripheralService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public PeripheralJobService getPeripheralJobService() {
|
||||
return peripheralJobService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public PeripheralDispatcherService getPeripheralDispatcherService() {
|
||||
return peripheralDispatcherService;
|
||||
}
|
||||
|
||||
private void updateServiceLogins(Registry registry)
|
||||
throws RemoteException,
|
||||
NotBoundException {
|
||||
plantModelService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService((RemotePlantModelService) registry.lookup(REMOTE_PLANT_MODEL_SERVICE))
|
||||
.setServiceListener(this);
|
||||
|
||||
transportOrderService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService(
|
||||
(RemoteTransportOrderService) registry.lookup(REMOTE_TRANSPORT_ORDER_SERVICE)
|
||||
)
|
||||
.setServiceListener(this);
|
||||
|
||||
vehicleService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService((RemoteVehicleService) registry.lookup(REMOTE_VEHICLE_SERVICE))
|
||||
.setServiceListener(this);
|
||||
|
||||
notificationService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService((RemoteNotificationService) registry.lookup(REMOTE_NOTIFICATION_SERVICE))
|
||||
.setServiceListener(this);
|
||||
|
||||
dispatcherService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService((RemoteDispatcherService) registry.lookup(REMOTE_DISPATCHER_SERVICE))
|
||||
.setServiceListener(this);
|
||||
|
||||
routerService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService((RemoteRouterService) registry.lookup(REMOTE_ROUTER_SERVICE))
|
||||
.setServiceListener(this);
|
||||
|
||||
queryService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService((RemoteQueryService) registry.lookup(REMOTE_QUERY_SERVICE))
|
||||
.setServiceListener(this);
|
||||
|
||||
peripheralService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService((RemotePeripheralService) registry.lookup(REMOTE_PERIPHERAL_SERVICE))
|
||||
.setServiceListener(this);
|
||||
|
||||
peripheralJobService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService(
|
||||
(RemotePeripheralJobService) registry.lookup(REMOTE_PERIPHERAL_JOB_SERVICE)
|
||||
)
|
||||
.setServiceListener(this);
|
||||
|
||||
peripheralDispatcherService
|
||||
.setClientId(getClientId())
|
||||
.setRemoteService(
|
||||
(RemotePeripheralDispatcherService) registry.lookup(
|
||||
REMOTE_PERIPHERAL_DISPATCHER_SERVICE
|
||||
)
|
||||
)
|
||||
.setServiceListener(this);
|
||||
}
|
||||
|
||||
private void resetServiceLogins() {
|
||||
this.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
plantModelService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
transportOrderService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
vehicleService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
notificationService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
dispatcherService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
routerService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
queryService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
peripheralService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
peripheralJobService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
peripheralDispatcherService.setClientId(null).setRemoteService(null).setServiceListener(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.components.kernel.services.NotificationService;
|
||||
import org.opentcs.data.notification.UserNotification;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link NotificationService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link NotificationService}, with an additional {@link ClientID} parameter which serves the
|
||||
* purpose of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link NotificationService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemoteNotificationService
|
||||
extends
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
List<UserNotification> fetchUserNotifications(
|
||||
ClientID clientId,
|
||||
Predicate<UserNotification> predicate
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void publishUserNotification(ClientID clientId, UserNotification notification)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.components.kernel.services.NotificationService;
|
||||
import org.opentcs.data.notification.UserNotification;
|
||||
|
||||
/**
|
||||
* The default implementation of the notification service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemoteNotificationServiceProxy
|
||||
extends
|
||||
AbstractRemoteServiceProxy<RemoteNotificationService>
|
||||
implements
|
||||
NotificationService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemoteNotificationServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserNotification> fetchUserNotifications(Predicate<UserNotification> predicate)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchUserNotifications(getClientId(), predicate);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishUserNotification(UserNotification notification)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().publishUserNotification(getClientId(), notification);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.components.kernel.services.PeripheralDispatcherService;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link PeripheralDispatcherService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link PeripheralDispatcherService}, with an additional {@link ClientID} parameter which serves
|
||||
* the purpose of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link PeripheralDispatcherService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemotePeripheralDispatcherService
|
||||
extends
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
void dispatch(ClientID clientId)
|
||||
throws RemoteException;
|
||||
|
||||
void withdrawByLocation(ClientID clientId, TCSResourceReference<Location> ref)
|
||||
throws RemoteException;
|
||||
|
||||
void withdrawByPeripheralJob(ClientID clientId, TCSObjectReference<PeripheralJob> ref)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.components.kernel.services.PeripheralDispatcherService;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* The default implementation of the peripheral dispatcher service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemotePeripheralDispatcherServiceProxy
|
||||
extends
|
||||
AbstractRemoteServiceProxy<RemotePeripheralDispatcherService>
|
||||
implements
|
||||
PeripheralDispatcherService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemotePeripheralDispatcherServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch()
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().dispatch(getClientId());
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void withdrawByLocation(TCSResourceReference<Location> locationRef)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().withdrawByLocation(getClientId(), locationRef);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void withdrawByPeripheralJob(TCSObjectReference<PeripheralJob> jobRef)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().withdrawByPeripheralJob(getClientId(), jobRef);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.access.to.peripherals.PeripheralJobCreationTO;
|
||||
import org.opentcs.components.kernel.services.PeripheralJobService;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link PeripheralJobService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link PeripheralJobService}, with an additional {@link ClientID} parameter which serves the
|
||||
* purpose of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link PeripheralJobService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemotePeripheralJobService
|
||||
extends
|
||||
RemoteTCSObjectService,
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
PeripheralJob createPeripheralJob(ClientID clientId, PeripheralJobCreationTO to)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.access.to.peripherals.PeripheralJobCreationTO;
|
||||
import org.opentcs.components.kernel.services.PeripheralJobService;
|
||||
import org.opentcs.data.ObjectExistsException;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* The default implementation of the peripheral job service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemotePeripheralJobServiceProxy
|
||||
extends
|
||||
RemoteTCSObjectServiceProxy<RemotePeripheralJobService>
|
||||
implements
|
||||
PeripheralJobService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemotePeripheralJobServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralJob createPeripheralJob(PeripheralJobCreationTO to)
|
||||
throws ObjectUnknownException,
|
||||
ObjectExistsException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().createPeripheralJob(getClientId(), to);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.components.kernel.services.PeripheralService;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.drivers.peripherals.PeripheralAdapterCommand;
|
||||
import org.opentcs.drivers.peripherals.PeripheralCommAdapterDescription;
|
||||
import org.opentcs.drivers.peripherals.PeripheralProcessModel;
|
||||
import org.opentcs.drivers.peripherals.management.PeripheralAttachmentInformation;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link PeripheralService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link PeripheralService}, with an additional {@link ClientID} parameter which serves the purpose
|
||||
* of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link PeripheralService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemotePeripheralService
|
||||
extends
|
||||
RemoteTCSObjectService,
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
void attachCommAdapter(
|
||||
ClientID clientId,
|
||||
TCSResourceReference<Location> ref,
|
||||
PeripheralCommAdapterDescription description
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void disableCommAdapter(ClientID clientId, TCSResourceReference<Location> ref)
|
||||
throws RemoteException;
|
||||
|
||||
void enableCommAdapter(ClientID clientId, TCSResourceReference<Location> ref)
|
||||
throws RemoteException;
|
||||
|
||||
PeripheralAttachmentInformation fetchAttachmentInformation(
|
||||
ClientID clientId,
|
||||
TCSResourceReference<Location> ref
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
PeripheralProcessModel fetchProcessModel(ClientID clientId, TCSResourceReference<Location> ref)
|
||||
throws RemoteException;
|
||||
|
||||
void sendCommAdapterCommand(
|
||||
ClientID clientId,
|
||||
TCSResourceReference<Location> ref,
|
||||
PeripheralAdapterCommand command
|
||||
)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.components.kernel.services.PeripheralService;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.drivers.peripherals.PeripheralAdapterCommand;
|
||||
import org.opentcs.drivers.peripherals.PeripheralCommAdapterDescription;
|
||||
import org.opentcs.drivers.peripherals.PeripheralProcessModel;
|
||||
import org.opentcs.drivers.peripherals.management.PeripheralAttachmentInformation;
|
||||
|
||||
/**
|
||||
* The default implementation of the vehicle service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemotePeripheralServiceProxy
|
||||
extends
|
||||
RemoteTCSObjectServiceProxy<RemotePeripheralService>
|
||||
implements
|
||||
PeripheralService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemotePeripheralServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachCommAdapter(
|
||||
TCSResourceReference<Location> ref,
|
||||
PeripheralCommAdapterDescription description
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().attachCommAdapter(getClientId(), ref, description);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableCommAdapter(TCSResourceReference<Location> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().disableCommAdapter(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableCommAdapter(TCSResourceReference<Location> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().enableCommAdapter(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralAttachmentInformation fetchAttachmentInformation(
|
||||
TCSResourceReference<Location> ref
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchAttachmentInformation(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralProcessModel fetchProcessModel(TCSResourceReference<Location> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchProcessModel(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCommAdapterCommand(
|
||||
TCSResourceReference<Location> ref,
|
||||
PeripheralAdapterCommand command
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().sendCommAdapterCommand(getClientId(), ref, command);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.access.to.model.PlantModelCreationTO;
|
||||
import org.opentcs.components.kernel.services.PlantModelService;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.model.Path;
|
||||
import org.opentcs.data.model.PlantModel;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link PlantModelService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link PlantModelService}, with an additional {@link ClientID} parameter which serves the purpose
|
||||
* of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link PlantModelService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemotePlantModelService
|
||||
extends
|
||||
RemoteTCSObjectService,
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
PlantModel getPlantModel(ClientID clientId)
|
||||
throws RemoteException;
|
||||
|
||||
void createPlantModel(ClientID clientId, PlantModelCreationTO to)
|
||||
throws RemoteException;
|
||||
|
||||
String getModelName(ClientID clientId)
|
||||
throws RemoteException;
|
||||
|
||||
Map<String, String> getModelProperties(ClientID clientId)
|
||||
throws RemoteException;
|
||||
|
||||
void updateLocationLock(ClientID clientId, TCSObjectReference<Location> ref, boolean locked)
|
||||
throws RemoteException;
|
||||
|
||||
void updatePathLock(ClientID clientId, TCSObjectReference<Path> ref, boolean locked)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.access.to.model.PlantModelCreationTO;
|
||||
import org.opentcs.components.kernel.services.PlantModelService;
|
||||
import org.opentcs.data.ObjectExistsException;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.model.Path;
|
||||
import org.opentcs.data.model.PlantModel;
|
||||
|
||||
/**
|
||||
* The default implementation of the plant model service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemotePlantModelServiceProxy
|
||||
extends
|
||||
RemoteTCSObjectServiceProxy<RemotePlantModelService>
|
||||
implements
|
||||
PlantModelService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemotePlantModelServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlantModel getPlantModel()
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().getPlantModel(getClientId());
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPlantModel(PlantModelCreationTO to)
|
||||
throws ObjectUnknownException,
|
||||
ObjectExistsException,
|
||||
KernelRuntimeException,
|
||||
IllegalStateException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().createPlantModel(getClientId(), to);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModelName()
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().getModelName(getClientId());
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getModelProperties()
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().getModelProperties(getClientId());
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLocationLock(TCSObjectReference<Location> ref, boolean locked)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updateLocationLock(getClientId(), ref, locked);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePathLock(TCSObjectReference<Path> ref, boolean locked)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updatePathLock(getClientId(), ref, locked);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.components.kernel.Query;
|
||||
import org.opentcs.components.kernel.services.QueryService;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link QueryService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link QueryService}, with an additional {@link ClientID} parameter which serves the purpose
|
||||
* of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link QueryService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemoteQueryService
|
||||
extends
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
<T> T query(ClientID clientId, Query<T> query)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.components.kernel.Query;
|
||||
import org.opentcs.components.kernel.services.QueryService;
|
||||
|
||||
/**
|
||||
* The default implementation of the query service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemoteQueryServiceProxy
|
||||
extends
|
||||
AbstractRemoteServiceProxy<RemoteQueryService>
|
||||
implements
|
||||
QueryService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemoteQueryServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T query(Query<T> query) {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().query(getClientId(), query);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.components.kernel.services.RouterService;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Path;
|
||||
import org.opentcs.data.model.Point;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.Route;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link RouterService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link RouterService}, with an additional {@link ClientID} parameter which serves the purpose
|
||||
* of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link RouterService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemoteRouterService
|
||||
extends
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
public void updateRoutingTopology(ClientID clientId, Set<TCSObjectReference<Path>> refs)
|
||||
throws RemoteException;
|
||||
|
||||
public Map<TCSObjectReference<Point>, Route> computeRoutes(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> vehicleRef,
|
||||
TCSObjectReference<Point> sourcePointRef,
|
||||
Set<TCSObjectReference<Point>> destinationPointRefs,
|
||||
Set<TCSResourceReference<?>> resourcesToAvoid
|
||||
)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.components.kernel.services.RouterService;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Path;
|
||||
import org.opentcs.data.model.Point;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.Route;
|
||||
|
||||
/**
|
||||
* The default implementation of the router service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemoteRouterServiceProxy
|
||||
extends
|
||||
AbstractRemoteServiceProxy<RemoteRouterService>
|
||||
implements
|
||||
RouterService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemoteRouterServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRoutingTopology(Set<TCSObjectReference<Path>> refs)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updateRoutingTopology(getClientId(), refs);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<TCSObjectReference<Point>, Route> computeRoutes(
|
||||
TCSObjectReference<Vehicle> vehicleRef,
|
||||
TCSObjectReference<Point> sourcePointRef,
|
||||
Set<TCSObjectReference<Point>> destinationPointRefs,
|
||||
Set<TCSResourceReference<?>> resourcesToAvoid
|
||||
)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().computeRoutes(
|
||||
getClientId(),
|
||||
vehicleRef,
|
||||
sourcePointRef,
|
||||
destinationPointRefs,
|
||||
resourcesToAvoid
|
||||
);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.components.kernel.services.TCSObjectService;
|
||||
import org.opentcs.data.ObjectHistory;
|
||||
import org.opentcs.data.TCSObject;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link TCSObjectService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link TCSObjectService}, with an additional {@link ClientID} parameter which serves the purpose
|
||||
* of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link TCSObjectService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemoteTCSObjectService
|
||||
extends
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
<T extends TCSObject<T>> T fetchObject(
|
||||
ClientID clientId,
|
||||
Class<T> clazz,
|
||||
TCSObjectReference<T> ref
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
<T extends TCSObject<T>> T fetchObject(ClientID clientId, Class<T> clazz, String name)
|
||||
throws RemoteException;
|
||||
|
||||
<T extends TCSObject<T>> Set<T> fetchObjects(ClientID clientId, Class<T> clazz)
|
||||
throws RemoteException;
|
||||
|
||||
<T extends TCSObject<T>> Set<T> fetchObjects(
|
||||
ClientID clientId,
|
||||
Class<T> clazz,
|
||||
Predicate<? super T> predicate
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void updateObjectProperty(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<?> ref,
|
||||
String key,
|
||||
String value
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void appendObjectHistoryEntry(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<?> ref,
|
||||
ObjectHistory.Entry entry
|
||||
)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.components.kernel.services.TCSObjectService;
|
||||
import org.opentcs.data.ObjectHistory;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObject;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
|
||||
/**
|
||||
* The default implementation of the tcs object service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*
|
||||
* @param <R> The remote service's type.
|
||||
*/
|
||||
abstract class RemoteTCSObjectServiceProxy<R extends RemoteTCSObjectService>
|
||||
extends
|
||||
AbstractRemoteServiceProxy<R>
|
||||
implements
|
||||
TCSObjectService {
|
||||
|
||||
@Override
|
||||
public <T extends TCSObject<T>> T fetchObject(Class<T> clazz, TCSObjectReference<T> ref)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchObject(getClientId(), clazz, ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends TCSObject<T>> T fetchObject(Class<T> clazz, String name)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchObject(getClientId(), clazz, name);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends TCSObject<T>> Set<T> fetchObjects(Class<T> clazz)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchObjects(getClientId(), clazz);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends TCSObject<T>> Set<T> fetchObjects(
|
||||
Class<T> clazz,
|
||||
Predicate<? super T> predicate
|
||||
)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchObjects(getClientId(), clazz, predicate);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateObjectProperty(TCSObjectReference<?> ref, String key, String value)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updateObjectProperty(getClientId(), ref, key, value);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendObjectHistoryEntry(TCSObjectReference<?> ref, ObjectHistory.Entry entry)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().appendObjectHistoryEntry(getClientId(), ref, entry);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.access.to.order.OrderSequenceCreationTO;
|
||||
import org.opentcs.access.to.order.TransportOrderCreationTO;
|
||||
import org.opentcs.components.kernel.services.TransportOrderService;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.OrderSequence;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link TransportOrderService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link TransportOrderService}, with an additional {@link ClientID} parameter which serves the
|
||||
* purpose of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link TransportOrderService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemoteTransportOrderService
|
||||
extends
|
||||
RemoteTCSObjectService,
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
OrderSequence createOrderSequence(ClientID clientId, OrderSequenceCreationTO to)
|
||||
throws RemoteException;
|
||||
|
||||
TransportOrder createTransportOrder(ClientID clientId, TransportOrderCreationTO to)
|
||||
throws RemoteException;
|
||||
|
||||
void markOrderSequenceComplete(ClientID clientId, TCSObjectReference<OrderSequence> ref)
|
||||
throws RemoteException;
|
||||
|
||||
void updateTransportOrderIntendedVehicle(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<TransportOrder> orderRef,
|
||||
TCSObjectReference<Vehicle> vehicleRef
|
||||
)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.access.to.order.OrderSequenceCreationTO;
|
||||
import org.opentcs.access.to.order.TransportOrderCreationTO;
|
||||
import org.opentcs.components.kernel.services.TransportOrderService;
|
||||
import org.opentcs.data.ObjectExistsException;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.OrderSequence;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
|
||||
/**
|
||||
* The default implementation of the transport order service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemoteTransportOrderServiceProxy
|
||||
extends
|
||||
RemoteTCSObjectServiceProxy<RemoteTransportOrderService>
|
||||
implements
|
||||
TransportOrderService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemoteTransportOrderServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderSequence createOrderSequence(OrderSequenceCreationTO to)
|
||||
throws KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().createOrderSequence(getClientId(), to);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportOrder createTransportOrder(TransportOrderCreationTO to)
|
||||
throws ObjectUnknownException,
|
||||
ObjectExistsException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().createTransportOrder(getClientId(), to);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markOrderSequenceComplete(TCSObjectReference<OrderSequence> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().markOrderSequenceComplete(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTransportOrderIntendedVehicle(
|
||||
TCSObjectReference<TransportOrder> orderRef,
|
||||
TCSObjectReference<Vehicle> vehicleRef
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
IllegalArgumentException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updateTransportOrderIntendedVehicle(getClientId(), orderRef, vehicleRef);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Set;
|
||||
import org.opentcs.access.rmi.ClientID;
|
||||
import org.opentcs.components.kernel.services.VehicleService;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.model.Vehicle.EnergyLevelThresholdSet;
|
||||
import org.opentcs.drivers.vehicle.AdapterCommand;
|
||||
import org.opentcs.drivers.vehicle.VehicleCommAdapterDescription;
|
||||
import org.opentcs.drivers.vehicle.management.VehicleAttachmentInformation;
|
||||
import org.opentcs.drivers.vehicle.management.VehicleProcessModelTO;
|
||||
import org.opentcs.util.annotations.ScheduledApiChange;
|
||||
|
||||
/**
|
||||
* Declares the methods provided by the {@link VehicleService} via RMI.
|
||||
*
|
||||
* <p>
|
||||
* The majority of the methods declared here have signatures analogous to their counterparts in
|
||||
* {@link VehicleService}, with an additional {@link ClientID} parameter which serves the purpose
|
||||
* of identifying the calling client and determining its permissions.
|
||||
* </p>
|
||||
* <p>
|
||||
* To avoid redundancy, the semantics of methods that only pass through their arguments are not
|
||||
* explicitly documented here again. See the corresponding API documentation in
|
||||
* {@link VehicleService} for these, instead.
|
||||
* </p>
|
||||
*/
|
||||
public interface RemoteVehicleService
|
||||
extends
|
||||
RemoteTCSObjectService,
|
||||
Remote {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
void attachCommAdapter(
|
||||
ClientID clientId, TCSObjectReference<Vehicle> ref,
|
||||
VehicleCommAdapterDescription description
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void disableCommAdapter(ClientID clientId, TCSObjectReference<Vehicle> ref)
|
||||
throws RemoteException;
|
||||
|
||||
void enableCommAdapter(ClientID clientId, TCSObjectReference<Vehicle> ref)
|
||||
throws RemoteException;
|
||||
|
||||
VehicleAttachmentInformation fetchAttachmentInformation(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> ref
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
VehicleProcessModelTO fetchProcessModel(ClientID clientId, TCSObjectReference<Vehicle> ref)
|
||||
throws RemoteException;
|
||||
|
||||
void sendCommAdapterCommand(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
AdapterCommand command
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void sendCommAdapterMessage(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> vehicleRef,
|
||||
Object message
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void updateVehicleIntegrationLevel(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
Vehicle.IntegrationLevel integrationLevel
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void updateVehiclePaused(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
boolean paused
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
@ScheduledApiChange(when = "7.0", details = "Default implementation will be removed.")
|
||||
default void updateVehicleEnergyLevelThresholdSet(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
EnergyLevelThresholdSet energyLevelThresholdSet
|
||||
)
|
||||
throws RemoteException {
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
void updateVehicleAllowedOrderTypes(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
Set<String> allowedOrderTypes
|
||||
)
|
||||
throws RemoteException;
|
||||
|
||||
void updateVehicleEnvelopeKey(
|
||||
ClientID clientId,
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
String envelopeKey
|
||||
)
|
||||
throws RemoteException;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Set;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.components.kernel.services.VehicleService;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.model.Vehicle.EnergyLevelThresholdSet;
|
||||
import org.opentcs.drivers.vehicle.AdapterCommand;
|
||||
import org.opentcs.drivers.vehicle.VehicleCommAdapterDescription;
|
||||
import org.opentcs.drivers.vehicle.management.VehicleAttachmentInformation;
|
||||
import org.opentcs.drivers.vehicle.management.VehicleProcessModelTO;
|
||||
|
||||
/**
|
||||
* The default implementation of the vehicle service.
|
||||
* Delegates method invocations to the corresponding remote service.
|
||||
*/
|
||||
class RemoteVehicleServiceProxy
|
||||
extends
|
||||
RemoteTCSObjectServiceProxy<RemoteVehicleService>
|
||||
implements
|
||||
VehicleService {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
RemoteVehicleServiceProxy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachCommAdapter(
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
VehicleCommAdapterDescription description
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().attachCommAdapter(getClientId(), ref, description);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableCommAdapter(TCSObjectReference<Vehicle> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().disableCommAdapter(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableCommAdapter(TCSObjectReference<Vehicle> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().enableCommAdapter(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VehicleAttachmentInformation fetchAttachmentInformation(TCSObjectReference<Vehicle> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchAttachmentInformation(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VehicleProcessModelTO fetchProcessModel(TCSObjectReference<Vehicle> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
return getRemoteService().fetchProcessModel(getClientId(), ref);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCommAdapterCommand(TCSObjectReference<Vehicle> ref, AdapterCommand command)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().sendCommAdapterCommand(getClientId(), ref, command);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCommAdapterMessage(TCSObjectReference<Vehicle> ref, Object message)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().sendCommAdapterMessage(getClientId(), ref, message);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVehicleIntegrationLevel(
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
Vehicle.IntegrationLevel integrationLevel
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updateVehicleIntegrationLevel(getClientId(), ref, integrationLevel);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVehiclePaused(TCSObjectReference<Vehicle> ref, boolean paused)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updateVehiclePaused(getClientId(), ref, paused);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVehicleEnergyLevelThresholdSet(
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
EnergyLevelThresholdSet energyLevelThresholdSet
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updateVehicleEnergyLevelThresholdSet(
|
||||
getClientId(),
|
||||
ref,
|
||||
energyLevelThresholdSet
|
||||
);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVehicleAllowedOrderTypes(
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
Set<String> allowedOrderTypes
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updateVehicleAllowedOrderTypes(
|
||||
getClientId(),
|
||||
ref,
|
||||
allowedOrderTypes
|
||||
);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVehicleEnvelopeKey(TCSObjectReference<Vehicle> ref, String envelopeKey)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
checkServiceAvailability();
|
||||
|
||||
try {
|
||||
getRemoteService().updateVehicleEnvelopeKey(getClientId(), ref, envelopeKey);
|
||||
}
|
||||
catch (RemoteException ex) {
|
||||
throw findSuitableExceptionFor(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.rmi.services;
|
||||
|
||||
/**
|
||||
* Provides callback methods for instances interested in service updates.
|
||||
*/
|
||||
public interface ServiceListener {
|
||||
|
||||
/**
|
||||
* Notifies a listener that the service is unavailable, i.e. is not in a usable state.
|
||||
*/
|
||||
void onServiceUnavailable();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
/**
|
||||
* Interfaces and classes for transparently providing an openTCS kernel's service functionality via
|
||||
* RMI.
|
||||
*/
|
||||
package org.opentcs.access.rmi.services;
|
||||
@@ -0,0 +1,180 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The base class for all creation transfer objects.
|
||||
*/
|
||||
public class CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The name of this transfer object.
|
||||
*/
|
||||
@Nonnull
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The properties of this transfer object.
|
||||
*/
|
||||
@Nonnull
|
||||
private final Map<String, String> properties;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this transfer object.
|
||||
*/
|
||||
public CreationTO(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
this.name = requireNonNull(name, "name");
|
||||
this.properties = Map.of();
|
||||
}
|
||||
|
||||
protected CreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
this.name = requireNonNull(name, "name");
|
||||
this.properties = requireNonNull(properties, "properties");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this transfer object.
|
||||
*
|
||||
* @return The name of this transfer object.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name the new name
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public CreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new CreationTO(
|
||||
name,
|
||||
properties
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the properties of this transfer object in an unmodifiable map.
|
||||
*
|
||||
* @return The properties of this transfer object in an unmodifiable map.
|
||||
*/
|
||||
@Nonnull
|
||||
public Map<String, String> getProperties() {
|
||||
return Collections.unmodifiableMap(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the properties of this transfer object.
|
||||
*
|
||||
* @return The properties of this transfer object.
|
||||
*/
|
||||
protected Map<String, String> getModifiableProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The properties.
|
||||
* @return A copy of this object with the given properties.
|
||||
*/
|
||||
public CreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new CreationTO(name, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given property.
|
||||
* If value == null is true then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that includes the given property or
|
||||
* removes the entry, if value == null.
|
||||
*/
|
||||
public CreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new CreationTO(
|
||||
name,
|
||||
propertiesWith(key, value)
|
||||
);
|
||||
}
|
||||
|
||||
protected final Map<String, String> propertiesWith(String key, String value) {
|
||||
return mapWithMapping(properties, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new map, with the mappings of the given map and the given mapping added to it.
|
||||
*
|
||||
* @param <K> The type of the map's keys.
|
||||
* @param <V> The type of the map's values.
|
||||
* @param map The map to be extended.
|
||||
* @param key The key.
|
||||
* @param value The value. May be <code>null</code> to remove the mapping from the given map.
|
||||
* @return a new map, with the mappings of the given map and the given mapping added to it.
|
||||
*/
|
||||
protected static final <K, V> Map<K, V> mapWithMapping(Map<K, V> map, K key, V value) {
|
||||
requireNonNull(map, "map");
|
||||
requireNonNull(key, "key");
|
||||
|
||||
Map<K, V> result = new HashMap<>(map);
|
||||
|
||||
if (value == null) {
|
||||
result.remove(key);
|
||||
}
|
||||
else {
|
||||
result.put(key, value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new list, with the elements of the given list and the given element added to it.
|
||||
*
|
||||
* @param <T> The element type of the list.
|
||||
* @param list The list to be extended.
|
||||
* @param newElement The element to be added to the list.
|
||||
* @return A new list, consisting of the given list and the given element added to it.
|
||||
*/
|
||||
protected static final <T> List<T> listWithAppendix(List<T> list, T newElement) {
|
||||
List<T> result = new ArrayList<>(list.size() + 1);
|
||||
result.addAll(list);
|
||||
result.add(newElement);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.awt.Color;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.data.model.Block;
|
||||
|
||||
/**
|
||||
* A transfer object describing a block in the plant model.
|
||||
*/
|
||||
public class BlockCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* This block's type.
|
||||
*/
|
||||
@Nonnull
|
||||
private final Block.Type type;
|
||||
/**
|
||||
* This block's member names.
|
||||
*/
|
||||
@Nonnull
|
||||
private final Set<String> memberNames;
|
||||
/**
|
||||
* The information regarding the grahical representation of this block.
|
||||
*/
|
||||
private final Layout layout;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this block.
|
||||
*/
|
||||
public BlockCreationTO(String name) {
|
||||
super(name);
|
||||
this.type = Block.Type.SINGLE_VEHICLE_ONLY;
|
||||
this.memberNames = Set.of();
|
||||
this.layout = new Layout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new block.
|
||||
*
|
||||
* @param name the name of the new block.
|
||||
* @param memberNames the names of the block's members.
|
||||
* @param properties the properties.
|
||||
*/
|
||||
private BlockCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
@Nonnull
|
||||
Block.Type type,
|
||||
@Nonnull
|
||||
Set<String> memberNames,
|
||||
@Nonnull
|
||||
Layout layout
|
||||
) {
|
||||
super(name, properties);
|
||||
this.type = requireNonNull(type, "type");
|
||||
this.memberNames = requireNonNull(memberNames, "memberNames");
|
||||
this.layout = requireNonNull(layout, "layout");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name The new name.
|
||||
* @return A copy of this object, differing in the given name.
|
||||
*/
|
||||
@Override
|
||||
public BlockCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new BlockCreationTO(
|
||||
name,
|
||||
getModifiableProperties(),
|
||||
type,
|
||||
memberNames,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given properties.
|
||||
*/
|
||||
@Override
|
||||
public BlockCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new BlockCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
type,
|
||||
memberNames,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in it's current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public BlockCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new BlockCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
type,
|
||||
memberNames,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of this block.
|
||||
*
|
||||
* @return The type of this block.
|
||||
*/
|
||||
@Nonnull
|
||||
public Block.Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given type.
|
||||
*
|
||||
* @param type The new type.
|
||||
* @return A copy of this object, differing in the given type.
|
||||
*/
|
||||
public BlockCreationTO withType(
|
||||
@Nonnull
|
||||
Block.Type type
|
||||
) {
|
||||
return new BlockCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
type,
|
||||
memberNames,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of this block's members.
|
||||
*
|
||||
* @return The names of this block's members.
|
||||
*/
|
||||
@Nonnull
|
||||
public Set<String> getMemberNames() {
|
||||
return Collections.unmodifiableSet(memberNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given members.
|
||||
*
|
||||
* @param memberNames The names of the block's members.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public BlockCreationTO withMemberNames(
|
||||
@Nonnull
|
||||
Set<String> memberNames
|
||||
) {
|
||||
return new BlockCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
type,
|
||||
memberNames,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information regarding the grahical representation of this block.
|
||||
*
|
||||
* @return The information regarding the grahical representation of this block.
|
||||
*/
|
||||
public Layout getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layout.
|
||||
*
|
||||
* @param layout The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public BlockCreationTO withLayout(Layout layout) {
|
||||
return new BlockCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
type,
|
||||
memberNames,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BlockCreationTO{"
|
||||
+ "name=" + getName()
|
||||
+ ", type=" + type
|
||||
+ ", memberNames=" + memberNames
|
||||
+ ", layout=" + layout
|
||||
+ ", properties=" + getProperties()
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains information regarding the grahical representation of a block.
|
||||
*/
|
||||
public static class Layout
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The color in which block elements are to be emphasized.
|
||||
*/
|
||||
private final Color color;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
public Layout() {
|
||||
this(Color.RED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param color The color in which block elements are to be emphasized.
|
||||
*/
|
||||
public Layout(Color color) {
|
||||
this.color = requireNonNull(color, "color");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color in which block elements are to be emphasized.
|
||||
*
|
||||
* @return The color in which block elements are to be emphasized.
|
||||
*/
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given color.
|
||||
*
|
||||
* @param color The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withColor(Color color) {
|
||||
return new Layout(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Layout{"
|
||||
+ "color=" + color
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.opentcs.util.Assertions.checkInRange;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A transfer object describing a bounding box.
|
||||
*/
|
||||
public class BoundingBoxCreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
private final long length;
|
||||
private final long width;
|
||||
private final long height;
|
||||
private final CoupleCreationTO referenceOffset;
|
||||
|
||||
/**
|
||||
* Creates a new instance with a (0, 0) reference offset.
|
||||
*
|
||||
* @param length The bounding box's length.
|
||||
* @param width The bounding box's width.
|
||||
* @param height The bounding box's height.
|
||||
*/
|
||||
public BoundingBoxCreationTO(long length, long width, long height) {
|
||||
this(length, width, height, new CoupleCreationTO(0, 0));
|
||||
}
|
||||
|
||||
private BoundingBoxCreationTO(
|
||||
long length,
|
||||
long width,
|
||||
long height,
|
||||
CoupleCreationTO referenceOffset
|
||||
) {
|
||||
this.length = checkInRange(length, 1, Long.MAX_VALUE, "length");
|
||||
this.width = checkInRange(width, 1, Long.MAX_VALUE, "width");
|
||||
this.height = checkInRange(height, 1, Long.MAX_VALUE, "height");
|
||||
this.referenceOffset = requireNonNull(referenceOffset, "referenceOffset");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box's length.
|
||||
*
|
||||
* @return The bounding box's length.
|
||||
*/
|
||||
public long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given length.
|
||||
*
|
||||
* @param length The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public BoundingBoxCreationTO withLength(long length) {
|
||||
return new BoundingBoxCreationTO(length, width, height, referenceOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box's width.
|
||||
*
|
||||
* @return The bounding box's width.
|
||||
*/
|
||||
public long getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given width.
|
||||
*
|
||||
* @param width The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public BoundingBoxCreationTO withWidth(long width) {
|
||||
return new BoundingBoxCreationTO(length, width, height, referenceOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box's height.
|
||||
*
|
||||
* @return The bounding box's height.
|
||||
*/
|
||||
public long getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given height.
|
||||
*
|
||||
* @param height The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public BoundingBoxCreationTO withHeight(long height) {
|
||||
return new BoundingBoxCreationTO(length, width, height, referenceOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box's reference offset.
|
||||
*
|
||||
* @return The bounding box's reference offset.
|
||||
*/
|
||||
public CoupleCreationTO getReferenceOffset() {
|
||||
return referenceOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given reference offset.
|
||||
*
|
||||
* @param referenceOffset The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public BoundingBoxCreationTO withReferenceOffset(CoupleCreationTO referenceOffset) {
|
||||
return new BoundingBoxCreationTO(length, width, height, referenceOffset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A transfer object describing generic 2-tuple of long integer values.
|
||||
*/
|
||||
public class CoupleCreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
private final long x;
|
||||
private final long y;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param x The X coordinate.
|
||||
* @param y The Y coordinate.
|
||||
*/
|
||||
public CoupleCreationTO(long x, long y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the x coordinate.
|
||||
*
|
||||
* @return The x coordinate.
|
||||
*/
|
||||
public long getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given x coordinate.
|
||||
*
|
||||
* @param x The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public CoupleCreationTO withX(long x) {
|
||||
return new CoupleCreationTO(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the y coordinate.
|
||||
*
|
||||
* @return The y coordinate.
|
||||
*/
|
||||
public long getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given y coordinate.
|
||||
*
|
||||
* @param y The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public CoupleCreationTO withY(long y) {
|
||||
return new CoupleCreationTO(x, y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,515 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.data.model.Couple;
|
||||
import org.opentcs.data.model.Triple;
|
||||
import org.opentcs.data.model.visualization.LocationRepresentation;
|
||||
|
||||
/**
|
||||
* A transfer object describing a location in a plant model.
|
||||
*/
|
||||
public class LocationCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The name of this location's type.
|
||||
*/
|
||||
@Nonnull
|
||||
private final String typeName;
|
||||
/**
|
||||
* This location's position (in mm).
|
||||
*/
|
||||
@Nonnull
|
||||
private final Triple position;
|
||||
/**
|
||||
* The links attaching points to this location.
|
||||
* This is a map of point names to allowed operations.
|
||||
*/
|
||||
@Nonnull
|
||||
private final Map<String, Set<String>> links;
|
||||
/**
|
||||
* A flag for marking this location as locked (i.e. to prevent vehicles from using it).
|
||||
*/
|
||||
private final boolean locked;
|
||||
/**
|
||||
* The information regarding the grahical representation of this location.
|
||||
*/
|
||||
private final Layout layout;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this location.
|
||||
* @param typeName The name of this location's type.
|
||||
* @param position The position of this location.
|
||||
*/
|
||||
public LocationCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
String typeName,
|
||||
@Nonnull
|
||||
Triple position
|
||||
) {
|
||||
super(name);
|
||||
this.typeName = requireNonNull(typeName, "typeName");
|
||||
this.position = position;
|
||||
this.links = Map.of();
|
||||
this.locked = false;
|
||||
this.layout = new Layout();
|
||||
}
|
||||
|
||||
private LocationCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
@Nonnull
|
||||
String typeName,
|
||||
@Nonnull
|
||||
Triple position,
|
||||
@Nonnull
|
||||
Map<String, Set<String>> links,
|
||||
boolean locked,
|
||||
@Nonnull
|
||||
Layout layout
|
||||
) {
|
||||
super(name, properties);
|
||||
this.typeName = requireNonNull(typeName, "typeName");
|
||||
this.position = requireNonNull(position, "position");
|
||||
this.links = requireNonNull(links, "links");
|
||||
this.locked = locked;
|
||||
this.layout = requireNonNull(layout, "layout");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name The new name.
|
||||
* @return A copy of this object, differing in the given name.
|
||||
*/
|
||||
@Override
|
||||
public LocationCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new LocationCreationTO(
|
||||
name,
|
||||
getModifiableProperties(),
|
||||
typeName,
|
||||
position,
|
||||
links,
|
||||
locked,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this location's type.
|
||||
*
|
||||
* @return The name of this location's type.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the location's type.
|
||||
*
|
||||
* @param typeName The location type.
|
||||
* @return A copy of this object, differing in the given type.
|
||||
*/
|
||||
public LocationCreationTO withTypeName(
|
||||
@Nonnull
|
||||
String typeName
|
||||
) {
|
||||
return new LocationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
typeName,
|
||||
position,
|
||||
links,
|
||||
locked,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of this location (in mm).
|
||||
*
|
||||
* @return The position of this location (in mm).
|
||||
*/
|
||||
@Nonnull
|
||||
public Triple getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given position (in mm).
|
||||
*
|
||||
* @param position the new position of this location (in mm).
|
||||
* @return A copy of this object, differing in the given position.
|
||||
*/
|
||||
public LocationCreationTO withPosition(
|
||||
@Nonnull
|
||||
Triple position
|
||||
) {
|
||||
return new LocationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
typeName,
|
||||
position,
|
||||
links,
|
||||
locked,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the links attaching points to this location.
|
||||
* This is a map of point names to allowed operations.
|
||||
*
|
||||
* @return The links attaching points to this location.
|
||||
*/
|
||||
@Nonnull
|
||||
public Map<String, Set<String>> getLinks() {
|
||||
return Collections.unmodifiableMap(links);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given links that attach points to this location.
|
||||
*
|
||||
* @param links the new links. This is supposed to be a map of point names to allowed operations.
|
||||
* @return A copy of this object, differing in the given links.
|
||||
*/
|
||||
public LocationCreationTO withLinks(
|
||||
@Nonnull
|
||||
Map<String, Set<String>> links
|
||||
) {
|
||||
return new LocationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
typeName,
|
||||
position,
|
||||
links,
|
||||
locked,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given links that attach points to this location.
|
||||
*
|
||||
* @param pointName The name of the point linked to.
|
||||
* @param allowedOperations The operations allowed at the point.
|
||||
* @return A copy of this object, differing in the given link.
|
||||
*/
|
||||
public LocationCreationTO withLink(
|
||||
@Nonnull
|
||||
String pointName,
|
||||
@Nonnull
|
||||
Set<String> allowedOperations
|
||||
) {
|
||||
return new LocationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
typeName,
|
||||
position,
|
||||
mapWithMapping(links, pointName, allowedOperations),
|
||||
locked,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lock status of this location (i.e. whether it my be used by vehicles or not).
|
||||
*
|
||||
* @return {@code true} if this location is currently locked (i.e. it may not be used
|
||||
* by vehicles), else {@code false}.
|
||||
*/
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given locked flag.
|
||||
*
|
||||
* @param locked The new locked attribute.
|
||||
* @return A copy of this object, differing in the locked attribute.
|
||||
*/
|
||||
public LocationCreationTO withLocked(boolean locked) {
|
||||
return new LocationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
typeName,
|
||||
position,
|
||||
links,
|
||||
locked,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given properties.
|
||||
*/
|
||||
@Override
|
||||
public LocationCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new LocationCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
typeName,
|
||||
position,
|
||||
links,
|
||||
locked,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in it's current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public LocationCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new LocationCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
typeName,
|
||||
position,
|
||||
links,
|
||||
locked,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information regarding the grahical representation of this location.
|
||||
*
|
||||
* @return The information regarding the grahical representation of this location.
|
||||
*/
|
||||
public Layout getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layout.
|
||||
*
|
||||
* @param layout The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public LocationCreationTO withLayout(Layout layout) {
|
||||
return new LocationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
typeName,
|
||||
position,
|
||||
links,
|
||||
locked,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocationCreationTO{"
|
||||
+ "name=" + getName()
|
||||
+ ", typeName=" + typeName
|
||||
+ ", position=" + position
|
||||
+ ", links=" + links
|
||||
+ ", locked=" + locked
|
||||
+ ", layout=" + layout
|
||||
+ ", properties=" + getProperties()
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains information regarding the grahical representation of a location.
|
||||
*/
|
||||
public static class Layout
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The coordinates at which the location is to be drawn (in mm).
|
||||
*/
|
||||
private final Couple position;
|
||||
/**
|
||||
* The offset of the label's position to the location's position (in lu).
|
||||
*/
|
||||
private final Couple labelOffset;
|
||||
/**
|
||||
* The location representation to use.
|
||||
*/
|
||||
private final LocationRepresentation locationRepresentation;
|
||||
/**
|
||||
* The ID of the layer on which the location is to be drawn.
|
||||
*/
|
||||
private final int layerId;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
public Layout() {
|
||||
this(new Couple(0, 0), new Couple(0, 0), LocationRepresentation.DEFAULT, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param position The coordinates at which the location is to be drawn (in mm).
|
||||
* @param labelOffset The offset of the label's location to the point's position (in lu).
|
||||
* @param locationRepresentation The location representation to use.
|
||||
* @param layerId The ID of the layer on which the location is to be drawn.
|
||||
*/
|
||||
public Layout(
|
||||
Couple position,
|
||||
Couple labelOffset,
|
||||
LocationRepresentation locationRepresentation,
|
||||
int layerId
|
||||
) {
|
||||
this.position = requireNonNull(position, "position");
|
||||
this.labelOffset = requireNonNull(labelOffset, "labelOffset");
|
||||
this.locationRepresentation = requireNonNull(
|
||||
locationRepresentation,
|
||||
"locationRepresentation"
|
||||
);
|
||||
this.layerId = layerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the coordinates at which the location is to be drawn (in mm).
|
||||
*
|
||||
* @return The coordinates at which the location is to be drawn (in mm).
|
||||
*/
|
||||
public Couple getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given position.
|
||||
*
|
||||
* @param position The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withPosition(Couple position) {
|
||||
return new Layout(
|
||||
position,
|
||||
labelOffset,
|
||||
locationRepresentation,
|
||||
layerId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset of the label's position to the location's position (in lu).
|
||||
*
|
||||
* @return The offset of the label's position to the location's position (in lu).
|
||||
*/
|
||||
public Couple getLabelOffset() {
|
||||
return labelOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given X label offset.
|
||||
*
|
||||
* @param labelOffset The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withLabelOffset(Couple labelOffset) {
|
||||
return new Layout(
|
||||
position,
|
||||
labelOffset,
|
||||
locationRepresentation,
|
||||
layerId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location representation to use.
|
||||
*
|
||||
* @return The location representation to use.
|
||||
*/
|
||||
public LocationRepresentation getLocationRepresentation() {
|
||||
return locationRepresentation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given location representation.
|
||||
*
|
||||
* @param locationRepresentation The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withLocationRepresentation(LocationRepresentation locationRepresentation) {
|
||||
return new Layout(
|
||||
position,
|
||||
labelOffset,
|
||||
locationRepresentation,
|
||||
layerId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the layer on which the location is to be drawn.
|
||||
*
|
||||
* @return The layer ID.
|
||||
*/
|
||||
public int getLayerId() {
|
||||
return layerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layer ID.
|
||||
*
|
||||
* @param layerId The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withLayerId(int layerId) {
|
||||
return new Layout(
|
||||
position,
|
||||
labelOffset,
|
||||
locationRepresentation,
|
||||
layerId
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Layout{"
|
||||
+ "position=" + position
|
||||
+ ", labelOffset=" + labelOffset
|
||||
+ ", locationRepresentation=" + locationRepresentation
|
||||
+ ", layerId=" + layerId
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.data.model.visualization.LocationRepresentation;
|
||||
|
||||
/**
|
||||
* A transfer object describing a location type in the plant model.
|
||||
*/
|
||||
public class LocationTypeCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The allowed operations for this location type.
|
||||
*/
|
||||
private final List<String> allowedOperations;
|
||||
/**
|
||||
* The allowed peripheral operations for this location type.
|
||||
*/
|
||||
private final List<String> allowedPeripheralOperations;
|
||||
/**
|
||||
* The information regarding the grahical representation of this location type.
|
||||
*/
|
||||
private final Layout layout;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this location type.
|
||||
*/
|
||||
public LocationTypeCreationTO(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
super(name);
|
||||
this.allowedOperations = List.of();
|
||||
this.allowedPeripheralOperations = List.of();
|
||||
this.layout = new Layout();
|
||||
}
|
||||
|
||||
private LocationTypeCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
@Nonnull
|
||||
List<String> allowedOperations,
|
||||
@Nonnull
|
||||
List<String> allowedPeripheralOperations,
|
||||
@Nonnull
|
||||
Layout layout
|
||||
) {
|
||||
super(name, properties);
|
||||
this.allowedOperations = requireNonNull(allowedOperations, "allowedOperations");
|
||||
this.allowedPeripheralOperations = requireNonNull(
|
||||
allowedPeripheralOperations,
|
||||
"allowedPeripheralOperations"
|
||||
);
|
||||
this.layout = requireNonNull(layout, "layout");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the allowed operations for this location type.
|
||||
*
|
||||
* @return The allowed operations for this location type.
|
||||
*/
|
||||
@Nonnull
|
||||
public List<String> getAllowedOperations() {
|
||||
return Collections.unmodifiableList(allowedOperations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given allowed operations.
|
||||
*
|
||||
* @param allowedOperations the new allowed operations.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public LocationTypeCreationTO withAllowedOperations(
|
||||
@Nonnull
|
||||
List<String> allowedOperations
|
||||
) {
|
||||
return new LocationTypeCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
allowedOperations,
|
||||
allowedPeripheralOperations,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the allowed peripheral operations for this location type.
|
||||
*
|
||||
* @return The allowed peripheral operations for this location type.
|
||||
*/
|
||||
@Nonnull
|
||||
public List<String> getAllowedPeripheralOperations() {
|
||||
return Collections.unmodifiableList(allowedPeripheralOperations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given allowed peripheral operations.
|
||||
*
|
||||
* @param allowedPeripheralOperations the new allowed peripheral operations.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public LocationTypeCreationTO withAllowedPeripheralOperations(
|
||||
@Nonnull
|
||||
List<String> allowedPeripheralOperations
|
||||
) {
|
||||
return new LocationTypeCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
allowedOperations,
|
||||
allowedPeripheralOperations,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name The new name.
|
||||
* @return A copy of this object, differing in the given name.
|
||||
*/
|
||||
@Override
|
||||
public LocationTypeCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new LocationTypeCreationTO(
|
||||
name,
|
||||
getProperties(),
|
||||
allowedOperations,
|
||||
allowedPeripheralOperations,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given properties.
|
||||
*/
|
||||
@Override
|
||||
public LocationTypeCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new LocationTypeCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
allowedOperations,
|
||||
allowedPeripheralOperations,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in it's current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public LocationTypeCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new LocationTypeCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
allowedOperations,
|
||||
allowedPeripheralOperations,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information regarding the grahical representation of this location type.
|
||||
*
|
||||
* @return The information regarding the grahical representation of this location type.
|
||||
*/
|
||||
public Layout getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layout.
|
||||
*
|
||||
* @param layout The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public LocationTypeCreationTO withLayout(Layout layout) {
|
||||
return new LocationTypeCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
allowedOperations,
|
||||
allowedPeripheralOperations,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocationTypeCreationTO{"
|
||||
+ "name=" + getName()
|
||||
+ ", allowedOperations=" + allowedOperations
|
||||
+ ", allowedPeripheralOperations" + allowedPeripheralOperations
|
||||
+ ", layout=" + layout
|
||||
+ ", properties=" + getProperties()
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains information regarding the grahical representation of a location type.
|
||||
*/
|
||||
public static class Layout
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The location representation to use for locations with this location type.
|
||||
*/
|
||||
private final LocationRepresentation locationRepresentation;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
public Layout() {
|
||||
this(LocationRepresentation.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param locationRepresentation The location representation to use for locations with this
|
||||
* location type.
|
||||
*/
|
||||
public Layout(LocationRepresentation locationRepresentation) {
|
||||
this.locationRepresentation = requireNonNull(
|
||||
locationRepresentation,
|
||||
"locationRepresentation"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location representation to use for locations with this location type.
|
||||
*
|
||||
* @return The location representation to use for locations with this location type.
|
||||
*/
|
||||
public LocationRepresentation getLocationRepresentation() {
|
||||
return locationRepresentation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given location representation.
|
||||
*
|
||||
* @param locationRepresentation The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withLocationRepresentation(LocationRepresentation locationRepresentation) {
|
||||
return new Layout(locationRepresentation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Layout{"
|
||||
+ "locationRepresentation=" + locationRepresentation
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,651 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.opentcs.util.Assertions.checkArgument;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.access.to.peripherals.PeripheralOperationCreationTO;
|
||||
import org.opentcs.data.model.Couple;
|
||||
import org.opentcs.data.model.Envelope;
|
||||
import org.opentcs.data.model.Path.Layout.ConnectionType;
|
||||
|
||||
/**
|
||||
* A transfer object describing a path in the plant model.
|
||||
*/
|
||||
public class PathCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The point name this path originates in.
|
||||
*/
|
||||
@Nonnull
|
||||
private final String srcPointName;
|
||||
/**
|
||||
* The point name this path ends in.
|
||||
*/
|
||||
@Nonnull
|
||||
private final String destPointName;
|
||||
/**
|
||||
* This path's length (in mm).
|
||||
*/
|
||||
private final long length;
|
||||
/**
|
||||
* The absolute maximum allowed forward velocity on this path (in mm/s).
|
||||
* A value of 0 (default) means forward movement is not allowed on this path.
|
||||
*/
|
||||
private final int maxVelocity;
|
||||
/**
|
||||
* The absolute maximum allowed reverse velocity on this path (in mm/s).
|
||||
* A value of 0 (default) means reverse movement is not allowed on this path.
|
||||
*/
|
||||
private final int maxReverseVelocity;
|
||||
/**
|
||||
* The peripheral operations to be performed when a vehicle travels along this path.
|
||||
*/
|
||||
private final List<PeripheralOperationCreationTO> peripheralOperations;
|
||||
/**
|
||||
* A flag for marking this path as locked (i.e. to prevent vehicles from using it).
|
||||
*/
|
||||
private final boolean locked;
|
||||
/**
|
||||
* A map of envelope keys to envelopes that vehicles traversing this path may occupy.
|
||||
*/
|
||||
private final Map<String, Envelope> vehicleEnvelopes;
|
||||
/**
|
||||
* The information regarding the grahical representation of this path.
|
||||
*/
|
||||
private final Layout layout;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this path.
|
||||
* @param srcPointName The point name this path originates in.
|
||||
* @param destPointName The point name this path ends in.
|
||||
*/
|
||||
public PathCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
String srcPointName,
|
||||
@Nonnull
|
||||
String destPointName
|
||||
) {
|
||||
super(name);
|
||||
this.srcPointName = requireNonNull(srcPointName, "srcPointName");
|
||||
this.destPointName = requireNonNull(destPointName, "destPointName");
|
||||
this.length = 1;
|
||||
this.maxVelocity = 0;
|
||||
this.maxReverseVelocity = 0;
|
||||
this.peripheralOperations = List.of();
|
||||
this.locked = false;
|
||||
this.vehicleEnvelopes = Map.of();
|
||||
this.layout = new Layout();
|
||||
}
|
||||
|
||||
private PathCreationTO(
|
||||
String name,
|
||||
@Nonnull
|
||||
String srcPointName,
|
||||
@Nonnull
|
||||
String destPointName,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
long length,
|
||||
int maxVelocity,
|
||||
int maxReverseVelocity,
|
||||
List<PeripheralOperationCreationTO> peripheralOperations,
|
||||
boolean locked,
|
||||
@Nonnull
|
||||
Map<String, Envelope> vehicleEnvelopes,
|
||||
@Nonnull
|
||||
Layout layout
|
||||
) {
|
||||
super(name, properties);
|
||||
this.srcPointName = requireNonNull(srcPointName, "srcPointName");
|
||||
this.destPointName = requireNonNull(destPointName, "destPointName");
|
||||
this.length = length;
|
||||
this.maxVelocity = maxVelocity;
|
||||
this.maxReverseVelocity = maxReverseVelocity;
|
||||
this.peripheralOperations = new ArrayList<>(
|
||||
requireNonNull(
|
||||
peripheralOperations,
|
||||
"peripheralOperations"
|
||||
)
|
||||
);
|
||||
this.locked = locked;
|
||||
this.vehicleEnvelopes = requireNonNull(vehicleEnvelopes, "vehicleEnvelopes");
|
||||
this.layout = requireNonNull(layout, "layout");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name The new name.
|
||||
* @return A copy of this object, differing in the given name.
|
||||
*/
|
||||
@Override
|
||||
public PathCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new PathCreationTO(
|
||||
name,
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the point name this path originates in.
|
||||
*
|
||||
* @return The point name this path originates in.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getSrcPointName() {
|
||||
return srcPointName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given point name this path originates in.
|
||||
*
|
||||
* @param srcPointName The new source point name.
|
||||
* @return A copy of this object, differing in the given source point.
|
||||
*/
|
||||
public PathCreationTO withSrcPointName(
|
||||
@Nonnull
|
||||
String srcPointName
|
||||
) {
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the point name this path ends in.
|
||||
*
|
||||
* @return The point name this path ends in.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getDestPointName() {
|
||||
return destPointName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given destination point.
|
||||
*
|
||||
* @param destPointName The new source point.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PathCreationTO withDestPointName(
|
||||
@Nonnull
|
||||
String destPointName
|
||||
) {
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of this path (in mm).
|
||||
*
|
||||
* @return The length of this path (in mm).
|
||||
*/
|
||||
public long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given path length (in mm).
|
||||
*
|
||||
* @param length the new length (in mm). Must be a positive value.
|
||||
* @return A copy of this object, differing in the given length.
|
||||
*/
|
||||
public PathCreationTO withLength(long length) {
|
||||
checkArgument(length > 0, "length must be a positive value: " + length);
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum allowed forward velocity (in mm/s) for this path.
|
||||
*
|
||||
* @return The maximum allowed forward velocity (in mm/s). A value of 0 means forward movement is
|
||||
* not allowed on this path.
|
||||
*/
|
||||
public int getMaxVelocity() {
|
||||
return maxVelocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the maximum allowed forward velocity (in mm/s) for this
|
||||
* path.
|
||||
*
|
||||
* @param maxVelocity The new maximum allowed velocity (in mm/s). May not be a negative value.
|
||||
* @return A copy of this object, differing in the given maximum velocity.
|
||||
*/
|
||||
public PathCreationTO withMaxVelocity(int maxVelocity) {
|
||||
checkArgument(
|
||||
maxVelocity >= 0,
|
||||
"maxVelocity may not be a negative value: " + maxVelocity
|
||||
);
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum allowed reverse velocity (in mm/s) for this path.
|
||||
*
|
||||
* @return The maximum allowed reverse velocity (in mm/s). A value of 0 means reverse movement is
|
||||
* not allowed on this path.
|
||||
*/
|
||||
public int getMaxReverseVelocity() {
|
||||
return maxReverseVelocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the allowed maximum reverse velocity (in mm/s).
|
||||
*
|
||||
* @param maxReverseVelocity The new maximum allowed reverse velocity (in mm/s). Must not be a
|
||||
* negative value.
|
||||
* @return A copy of this object, differing in the given maximum reverse velocity.
|
||||
*/
|
||||
public PathCreationTO withMaxReverseVelocity(int maxReverseVelocity) {
|
||||
checkArgument(
|
||||
maxReverseVelocity >= 0,
|
||||
"maxReverseVelocity may not be a negative value: " + maxReverseVelocity
|
||||
);
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the peripheral operations to be performed when a vehicle travels along this path.
|
||||
*
|
||||
* @return The peripheral operations to be performed when a vehicle travels along this path.
|
||||
*/
|
||||
public List<PeripheralOperationCreationTO> getPeripheralOperations() {
|
||||
return Collections.unmodifiableList(peripheralOperations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given peripheral operations.
|
||||
*
|
||||
* @param peripheralOperations The peripheral operations.
|
||||
* @return A copy of this object, differing in the given peripheral operations.
|
||||
*/
|
||||
public PathCreationTO withPeripheralOperations(
|
||||
@Nonnull
|
||||
List<PeripheralOperationCreationTO> peripheralOperations
|
||||
) {
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lock status of this path (i.e. whether this path my be used by vehicles or not).
|
||||
*
|
||||
* @return {@code true} if this path is currently locked (i.e. it may not be used by vehicles),
|
||||
* else {@code false}.
|
||||
*/
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object that is locked if {@code locked==true} and unlocked otherwise.
|
||||
*
|
||||
* @param locked If {@code true}, this path will be locked when the method call returns; if
|
||||
* {@code false}, this path will be unlocked.
|
||||
* @return a copy of this object, differing in the locked attribute.
|
||||
*/
|
||||
public PathCreationTO withLocked(boolean locked) {
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given properties.
|
||||
*/
|
||||
@Override
|
||||
public PathCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
properties,
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in it's current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public PathCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
propertiesWith(key, value),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of envelope keys to envelopes that vehicles traversing this path may occupy.
|
||||
*
|
||||
* @return A map of envelope keys to envelopes that vehicles traversing this path may occupy.
|
||||
*/
|
||||
public Map<String, Envelope> getVehicleEnvelopes() {
|
||||
return vehicleEnvelopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given vehicle envelopes.
|
||||
*
|
||||
* @param vehicleEnvelopes The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PathCreationTO withVehicleEnvelopes(
|
||||
@Nonnull
|
||||
Map<String, Envelope> vehicleEnvelopes
|
||||
) {
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information regarding the grahical representation of this path.
|
||||
*
|
||||
* @return The information regarding the grahical representation of this path.
|
||||
*/
|
||||
public Layout getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layout.
|
||||
*
|
||||
* @param layout The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PathCreationTO withLayout(Layout layout) {
|
||||
return new PathCreationTO(
|
||||
getName(),
|
||||
srcPointName,
|
||||
destPointName,
|
||||
getModifiableProperties(),
|
||||
length,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
peripheralOperations,
|
||||
locked,
|
||||
vehicleEnvelopes,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PathCreationTO{"
|
||||
+ "name=" + getName()
|
||||
+ ", srcPointName=" + srcPointName
|
||||
+ ", destPointName=" + destPointName
|
||||
+ ", length=" + length
|
||||
+ ", maxVelocity=" + maxVelocity
|
||||
+ ", maxReverseVelocity=" + maxReverseVelocity
|
||||
+ ", peripheralOperations=" + peripheralOperations
|
||||
+ ", locked=" + locked
|
||||
+ ", layout=" + layout
|
||||
+ ", vehicleEnvelopes=" + vehicleEnvelopes
|
||||
+ ", properties=" + getProperties()
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains information regarding the grahical representation of a path.
|
||||
*/
|
||||
public static class Layout
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The connection type the path is represented as.
|
||||
*/
|
||||
private final ConnectionType connectionType;
|
||||
/**
|
||||
* Control points describing the way the path is drawn (if the connection type
|
||||
* is {@link ConnectionType#BEZIER}, {@link ConnectionType#BEZIER_3}
|
||||
* or {@link ConnectionType#POLYPATH}).
|
||||
*/
|
||||
private final List<Couple> controlPoints;
|
||||
/**
|
||||
* The ID of the layer on which the path is to be drawn.
|
||||
*/
|
||||
private final int layerId;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
public Layout() {
|
||||
this(ConnectionType.DIRECT, new ArrayList<>(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param connectionType The connection type a path is represented as.
|
||||
* @param controlPoints Control points describing the way the path is drawn.
|
||||
* @param layerId The ID of the layer on which the path is to be drawn.
|
||||
*/
|
||||
public Layout(ConnectionType connectionType, List<Couple> controlPoints, int layerId) {
|
||||
this.connectionType = connectionType;
|
||||
this.controlPoints = requireNonNull(controlPoints, "controlPoints");
|
||||
this.layerId = layerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the connection type the path is represented as.
|
||||
*
|
||||
* @return The connection type the path is represented as.
|
||||
*/
|
||||
public ConnectionType getConnectionType() {
|
||||
return connectionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given connection type.
|
||||
*
|
||||
* @param connectionType The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withConnectionType(ConnectionType connectionType) {
|
||||
return new Layout(connectionType, controlPoints, layerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the control points describing the way the path is drawn.
|
||||
* Returns an empty list if connection type is not {@link ConnectionType#BEZIER},
|
||||
* {@link ConnectionType#BEZIER_3} or {@link ConnectionType#POLYPATH}.
|
||||
*
|
||||
* @return The control points describing the way the path is drawn.
|
||||
*/
|
||||
public List<Couple> getControlPoints() {
|
||||
return Collections.unmodifiableList(controlPoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given control points.
|
||||
*
|
||||
* @param controlPoints The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withControlPoints(List<Couple> controlPoints) {
|
||||
return new Layout(connectionType, controlPoints, layerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the layer on which the path is to be drawn.
|
||||
*
|
||||
* @return The layer ID.
|
||||
*/
|
||||
public int getLayerId() {
|
||||
return layerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layer ID.
|
||||
*
|
||||
* @param layerId The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withLayer(int layerId) {
|
||||
return new Layout(connectionType, controlPoints, layerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Layout{"
|
||||
+ "connectionType=" + connectionType
|
||||
+ ", controlPoints=" + controlPoints
|
||||
+ ", layerId=" + layerId
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,598 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.data.model.ModelConstants;
|
||||
import org.opentcs.data.model.visualization.Layer;
|
||||
import org.opentcs.data.model.visualization.LayerGroup;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A transfer object describing a plant model.
|
||||
*/
|
||||
public class PlantModelCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* This class's logger.
|
||||
*/
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PlantModelCreationTO.class);
|
||||
|
||||
/**
|
||||
* The plant model's points.
|
||||
*/
|
||||
private final List<PointCreationTO> points;
|
||||
/**
|
||||
* The plant model's paths.
|
||||
*/
|
||||
private final List<PathCreationTO> paths;
|
||||
/**
|
||||
* The plant model's location types.
|
||||
*/
|
||||
private final List<LocationTypeCreationTO> locationTypes;
|
||||
/**
|
||||
* The plant model's locations.
|
||||
*/
|
||||
private final List<LocationCreationTO> locations;
|
||||
/**
|
||||
* The plant model's blocks.
|
||||
*/
|
||||
private final List<BlockCreationTO> blocks;
|
||||
/**
|
||||
* The plant model's vehicles.
|
||||
*/
|
||||
private final List<VehicleCreationTO> vehicles;
|
||||
/**
|
||||
* The plant model's visual layout.
|
||||
*/
|
||||
private final VisualLayoutCreationTO visualLayout;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this plant model.
|
||||
*/
|
||||
public PlantModelCreationTO(String name) {
|
||||
super(name);
|
||||
this.points = List.of();
|
||||
this.paths = List.of();
|
||||
this.locationTypes = List.of();
|
||||
this.locations = List.of();
|
||||
this.blocks = List.of();
|
||||
this.vehicles = List.of();
|
||||
this.visualLayout = defaultVisualLayout();
|
||||
}
|
||||
|
||||
private PlantModelCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
@Nonnull
|
||||
List<PointCreationTO> points,
|
||||
@Nonnull
|
||||
List<PathCreationTO> paths,
|
||||
@Nonnull
|
||||
List<LocationTypeCreationTO> locationTypes,
|
||||
@Nonnull
|
||||
List<LocationCreationTO> locations,
|
||||
@Nonnull
|
||||
List<BlockCreationTO> blocks,
|
||||
@Nonnull
|
||||
List<VehicleCreationTO> vehicles,
|
||||
@Nonnull
|
||||
VisualLayoutCreationTO visualLayout
|
||||
) {
|
||||
super(name, properties);
|
||||
this.points = requireNonNull(points, "points");
|
||||
this.paths = requireNonNull(paths, "paths");
|
||||
this.locationTypes = requireNonNull(locationTypes, "locationTypes");
|
||||
this.locations = requireNonNull(locations, "locations");
|
||||
this.blocks = requireNonNull(blocks, "blocks");
|
||||
this.vehicles = requireNonNull(vehicles, "vehicles");
|
||||
this.visualLayout = requireNonNull(visualLayout, "visualLayout");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this plant model's points.
|
||||
*
|
||||
* @return This plant model's points.
|
||||
*/
|
||||
public List<PointCreationTO> getPoints() {
|
||||
return Collections.unmodifiableList(points);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given points.
|
||||
*
|
||||
* @param points The new points.
|
||||
* @return A copy of this model, differing in the given points.
|
||||
*/
|
||||
public PlantModelCreationTO withPoints(
|
||||
@Nonnull
|
||||
List<PointCreationTO> points
|
||||
) {
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object that includes the given point in the list of points.
|
||||
*
|
||||
* @param point the new point.
|
||||
* @return A copy of this model that also includes the given point.
|
||||
*/
|
||||
public PlantModelCreationTO withPoint(
|
||||
@Nonnull
|
||||
PointCreationTO point
|
||||
) {
|
||||
requireNonNull(point, "point");
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
listWithAppendix(points, point),
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this plant model's paths.
|
||||
*
|
||||
* @return This plant model's paths.
|
||||
*/
|
||||
public List<PathCreationTO> getPaths() {
|
||||
return Collections.unmodifiableList(paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given paths.
|
||||
*
|
||||
* @param paths The new paths.
|
||||
* @return A copy of this model, differing in the given paths.
|
||||
*/
|
||||
public PlantModelCreationTO withPaths(
|
||||
@Nonnull
|
||||
List<PathCreationTO> paths
|
||||
) {
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object that includes the given path in the list of paths.
|
||||
*
|
||||
* @param path the new path.
|
||||
* @return A copy of this model that also includes the given path.
|
||||
*/
|
||||
public PlantModelCreationTO withPath(
|
||||
@Nonnull
|
||||
PathCreationTO path
|
||||
) {
|
||||
requireNonNull(path, "path");
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
listWithAppendix(paths, path),
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this plant model's location types.
|
||||
*
|
||||
* @return This plant model's location types.
|
||||
*/
|
||||
public List<LocationTypeCreationTO> getLocationTypes() {
|
||||
return Collections.unmodifiableList(locationTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given location type.
|
||||
*
|
||||
* @param locationTypes The new location types.
|
||||
* @return A copy of this model, differing in the given location types.
|
||||
*/
|
||||
public PlantModelCreationTO withLocationTypes(
|
||||
@Nonnull
|
||||
List<LocationTypeCreationTO> locationTypes
|
||||
) {
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object that includes the given path in the list of location types.
|
||||
*
|
||||
* @param locationType the new location type.
|
||||
* @return A copy of this model that also includes the given location type.
|
||||
*/
|
||||
public PlantModelCreationTO withLocationType(
|
||||
@Nonnull
|
||||
LocationTypeCreationTO locationType
|
||||
) {
|
||||
requireNonNull(locationType, "locationType");
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
listWithAppendix(locationTypes, locationType),
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this plant model's locations.
|
||||
*
|
||||
* @return This plant model's locations.
|
||||
*/
|
||||
public List<LocationCreationTO> getLocations() {
|
||||
return Collections.unmodifiableList(locations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given locations.
|
||||
*
|
||||
* @param locations The new locations.
|
||||
* @return A copy of this model, differing in the given locations.
|
||||
*/
|
||||
public PlantModelCreationTO withLocations(
|
||||
@Nonnull
|
||||
List<LocationCreationTO> locations
|
||||
) {
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object that includes the given block in the list of locations.
|
||||
*
|
||||
* @param location the new location.
|
||||
* @return A copy of this model that also includes the given location.
|
||||
*/
|
||||
public PlantModelCreationTO withLocation(
|
||||
@Nonnull
|
||||
LocationCreationTO location
|
||||
) {
|
||||
requireNonNull(location, "location");
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
listWithAppendix(locations, location),
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this plant model's blocks.
|
||||
*
|
||||
* @return This plant model's blocks.
|
||||
*/
|
||||
public List<BlockCreationTO> getBlocks() {
|
||||
return Collections.unmodifiableList(blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given blocks.
|
||||
*
|
||||
* @param blocks The new blocks.
|
||||
* @return A copy of this model, differing in the given blocks.
|
||||
*/
|
||||
public PlantModelCreationTO withBlocks(
|
||||
@Nonnull
|
||||
List<BlockCreationTO> blocks
|
||||
) {
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object that includes the given block in the list of blocks.
|
||||
*
|
||||
* @param block the new block.
|
||||
* @return A copy of this model that also includes the given block.
|
||||
*/
|
||||
public PlantModelCreationTO withBlock(
|
||||
@Nonnull
|
||||
BlockCreationTO block
|
||||
) {
|
||||
requireNonNull(block, "block");
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
CreationTO.listWithAppendix(blocks, block),
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this plant model's vehicles.
|
||||
*
|
||||
* @return This plant model's vehicles.
|
||||
*/
|
||||
public List<VehicleCreationTO> getVehicles() {
|
||||
return Collections.unmodifiableList(vehicles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given vehicles.
|
||||
*
|
||||
* @param vehicles The new vehicles.
|
||||
* @return A copy of this model, differing in the given vehicles.
|
||||
*/
|
||||
public PlantModelCreationTO withVehicles(
|
||||
@Nonnull
|
||||
List<VehicleCreationTO> vehicles
|
||||
) {
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object that includes the given vehicle in the list of vehicles.
|
||||
*
|
||||
* @param vehicle the new vehicle.
|
||||
* @return A copy of this model that also includes the given vehicle.
|
||||
*/
|
||||
public PlantModelCreationTO withVehicle(
|
||||
@Nonnull
|
||||
VehicleCreationTO vehicle
|
||||
) {
|
||||
requireNonNull(vehicle, "vehicle");
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
listWithAppendix(vehicles, vehicle),
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this plant model's visual layout.
|
||||
*
|
||||
* @return This plant model's visual layout.
|
||||
*/
|
||||
public VisualLayoutCreationTO getVisualLayout() {
|
||||
return visualLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given visual layout.
|
||||
*
|
||||
* @param visualLayout the new visual layout.
|
||||
* @return A copy of this model with the given visual layout.
|
||||
*/
|
||||
public PlantModelCreationTO withVisualLayout(
|
||||
@Nonnull
|
||||
VisualLayoutCreationTO visualLayout
|
||||
) {
|
||||
requireNonNull(visualLayout, "visualLayout");
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
ensureValidity(visualLayout)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given properties.
|
||||
*/
|
||||
@Override
|
||||
public PlantModelCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in it's current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public PlantModelCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new PlantModelCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
points,
|
||||
paths,
|
||||
locationTypes,
|
||||
locations,
|
||||
blocks,
|
||||
vehicles,
|
||||
visualLayout
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PlantModelCreationTO{"
|
||||
+ "name=" + getName()
|
||||
+ ", points=" + points
|
||||
+ ", paths=" + paths
|
||||
+ ", locationTypes=" + locationTypes
|
||||
+ ", locations=" + locations
|
||||
+ ", blocks=" + blocks
|
||||
+ ", vehicles=" + vehicles
|
||||
+ ", visualLayout=" + visualLayout
|
||||
+ ", properties=" + getProperties()
|
||||
+ '}';
|
||||
}
|
||||
|
||||
private VisualLayoutCreationTO defaultVisualLayout() {
|
||||
return new VisualLayoutCreationTO(ModelConstants.DEFAULT_VISUAL_LAYOUT_NAME)
|
||||
.withLayer(
|
||||
new Layer(
|
||||
ModelConstants.DEFAULT_LAYER_ID,
|
||||
ModelConstants.DEFAULT_LAYER_ORDINAL,
|
||||
true,
|
||||
ModelConstants.DEFAULT_LAYER_NAME,
|
||||
ModelConstants.DEFAULT_LAYER_GROUP_ID
|
||||
)
|
||||
)
|
||||
.withLayerGroup(
|
||||
new LayerGroup(
|
||||
ModelConstants.DEFAULT_LAYER_GROUP_ID,
|
||||
ModelConstants.DEFAULT_LAYER_GROUP_NAME,
|
||||
true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private VisualLayoutCreationTO ensureValidity(
|
||||
@Nonnull
|
||||
VisualLayoutCreationTO visualLayout
|
||||
) {
|
||||
VisualLayoutCreationTO vLayout = visualLayout;
|
||||
|
||||
if (visualLayout.getLayers().isEmpty()) {
|
||||
LOG.warn("Adding default layer to visual layout with no layers...");
|
||||
vLayout = visualLayout.withLayer(
|
||||
new Layer(
|
||||
ModelConstants.DEFAULT_LAYER_ID,
|
||||
ModelConstants.DEFAULT_LAYER_ORDINAL,
|
||||
true,
|
||||
ModelConstants.DEFAULT_LAYER_NAME,
|
||||
ModelConstants.DEFAULT_LAYER_GROUP_ID
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (visualLayout.getLayerGroups().isEmpty()) {
|
||||
LOG.warn("Adding default layer group to visual layout with no layer groups...");
|
||||
vLayout = vLayout.withLayerGroup(
|
||||
new LayerGroup(
|
||||
ModelConstants.DEFAULT_LAYER_GROUP_ID,
|
||||
ModelConstants.DEFAULT_LAYER_GROUP_NAME,
|
||||
true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return vLayout;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.data.model.Couple;
|
||||
import org.opentcs.data.model.Envelope;
|
||||
import org.opentcs.data.model.Point;
|
||||
import org.opentcs.data.model.Pose;
|
||||
import org.opentcs.data.model.Triple;
|
||||
|
||||
/**
|
||||
* A transfer object describing a point in the plant model.
|
||||
*/
|
||||
public class PointCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The pose of the vehicle at this point.
|
||||
*/
|
||||
private final Pose pose;
|
||||
/**
|
||||
* This point's type.
|
||||
*/
|
||||
@Nonnull
|
||||
private final Point.Type type;
|
||||
/**
|
||||
* A map of envelope keys to envelopes that vehicles located at this point may occupy.
|
||||
*/
|
||||
private final Map<String, Envelope> vehicleEnvelopes;
|
||||
/**
|
||||
* The maximum bounding box (in mm) that a vehicle at this point is allowed to have.
|
||||
*/
|
||||
private final BoundingBoxCreationTO maxVehicleBoundingBox;
|
||||
/**
|
||||
* The information regarding the graphical representation of this point.
|
||||
*/
|
||||
private final Layout layout;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this point.
|
||||
*/
|
||||
public PointCreationTO(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
super(name);
|
||||
this.pose = new Pose(new Triple(0, 0, 0), Double.NaN);
|
||||
this.type = Point.Type.HALT_POSITION;
|
||||
this.vehicleEnvelopes = Map.of();
|
||||
this.maxVehicleBoundingBox
|
||||
= new BoundingBoxCreationTO(1000, 1000, 1000);
|
||||
this.layout = new Layout();
|
||||
}
|
||||
|
||||
private PointCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
@Nonnull
|
||||
Pose pose,
|
||||
@Nonnull
|
||||
Point.Type type,
|
||||
@Nonnull
|
||||
Map<String, Envelope> vehicleEnvelopes,
|
||||
@Nonnull
|
||||
BoundingBoxCreationTO maxVehicleBoundingBox,
|
||||
@Nonnull
|
||||
Layout layout
|
||||
) {
|
||||
super(name, properties);
|
||||
this.pose = requireNonNull(pose, "pose");
|
||||
requireNonNull(pose.getPosition(), "A point requires a pose with a position.");
|
||||
this.type = requireNonNull(type, "type");
|
||||
this.vehicleEnvelopes = requireNonNull(vehicleEnvelopes, "vehicleEnvelopes");
|
||||
this.maxVehicleBoundingBox = requireNonNull(maxVehicleBoundingBox, "maxVehicleBoundingBox");
|
||||
this.layout = requireNonNull(layout, "layout");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name The new name.
|
||||
* @return A copy of this object, differing in the given name.
|
||||
*/
|
||||
@Override
|
||||
public PointCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new PointCreationTO(
|
||||
name,
|
||||
getModifiableProperties(),
|
||||
pose,
|
||||
type,
|
||||
vehicleEnvelopes,
|
||||
maxVehicleBoundingBox,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pose of the vehicle at this point.
|
||||
*
|
||||
* @return The pose of the vehicle at this point.
|
||||
*/
|
||||
@Nonnull
|
||||
public Pose getPose() {
|
||||
return pose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given pose.
|
||||
*
|
||||
* @param pose The new pose.
|
||||
* @return A copy of this object, differing in the given position.
|
||||
*/
|
||||
public PointCreationTO withPose(
|
||||
@Nonnull
|
||||
Pose pose
|
||||
) {
|
||||
return new PointCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
pose,
|
||||
type,
|
||||
vehicleEnvelopes,
|
||||
maxVehicleBoundingBox,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of this point.
|
||||
*
|
||||
* @return The type of this point.
|
||||
*/
|
||||
@Nonnull
|
||||
public Point.Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given type.
|
||||
*
|
||||
* @param type The new type.
|
||||
* @return A copy of this object, differing in the given type.
|
||||
*/
|
||||
public PointCreationTO withType(
|
||||
@Nonnull
|
||||
Point.Type type
|
||||
) {
|
||||
return new PointCreationTO(
|
||||
getName(),
|
||||
getProperties(),
|
||||
pose,
|
||||
type,
|
||||
vehicleEnvelopes,
|
||||
maxVehicleBoundingBox,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given properties.
|
||||
*/
|
||||
@Override
|
||||
public PointCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new PointCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
pose,
|
||||
type,
|
||||
vehicleEnvelopes,
|
||||
maxVehicleBoundingBox,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in its current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public PointCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new PointCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
pose,
|
||||
type,
|
||||
vehicleEnvelopes,
|
||||
maxVehicleBoundingBox,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of envelope keys to envelopes that vehicles located at this point may occupy.
|
||||
*
|
||||
* @return A map of envelope keys to envelopes that vehicles located at this point may occupy.
|
||||
*/
|
||||
public Map<String, Envelope> getVehicleEnvelopes() {
|
||||
return vehicleEnvelopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given vehicle envelopes.
|
||||
*
|
||||
* @param vehicleEnvelopes The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PointCreationTO withVehicleEnvelopes(
|
||||
@Nonnull
|
||||
Map<String, Envelope> vehicleEnvelopes
|
||||
) {
|
||||
return new PointCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
pose,
|
||||
type,
|
||||
vehicleEnvelopes,
|
||||
maxVehicleBoundingBox,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum bounding box (in mm) that a vehicle at this point is allowed to have.
|
||||
*
|
||||
* @return The maximum bounding box (in mm) that a vehicle at this point is allowed to have.
|
||||
*/
|
||||
public BoundingBoxCreationTO getMaxVehicleBoundingBox() {
|
||||
return maxVehicleBoundingBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given maximum vehicle bounding box.
|
||||
*
|
||||
* @param maxVehicleBoundingBox The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PointCreationTO withMaxVehicleBoundingBox(BoundingBoxCreationTO maxVehicleBoundingBox) {
|
||||
return new PointCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
pose,
|
||||
type,
|
||||
vehicleEnvelopes,
|
||||
maxVehicleBoundingBox,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information regarding the graphical representation of this point.
|
||||
*
|
||||
* @return The information regarding the graphical representation of this point.
|
||||
*/
|
||||
public Layout getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layout.
|
||||
*
|
||||
* @param layout The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PointCreationTO withLayout(Layout layout) {
|
||||
return new PointCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
pose,
|
||||
type,
|
||||
vehicleEnvelopes,
|
||||
maxVehicleBoundingBox,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PointCreationTO{"
|
||||
+ "name=" + getName()
|
||||
+ ", pose=" + pose
|
||||
+ ", type=" + type
|
||||
+ ", vehicleEnvelopes=" + vehicleEnvelopes
|
||||
+ ", layout=" + layout
|
||||
+ ", maxVehicleBoundingBox=" + maxVehicleBoundingBox
|
||||
+ ", properties=" + getProperties()
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains information regarding the graphical representation of a point.
|
||||
*/
|
||||
public static class Layout
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The coordinates at which the point is to be drawn (in mm).
|
||||
*/
|
||||
private final Couple position;
|
||||
/**
|
||||
* The offset of the label's position to the point's position (in lu).
|
||||
*/
|
||||
private final Couple labelOffset;
|
||||
/**
|
||||
* The ID of the layer on which the point is to be drawn.
|
||||
*/
|
||||
private final int layerId;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
public Layout() {
|
||||
this(new Couple(0, 0), new Couple(0, 0), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param position The coordinates at which the point is to be drawn (in mm).
|
||||
* @param labelOffset The offset of the label's position to the point's position (in lu).
|
||||
* @param layerId The ID of the layer on which the point is to be drawn.
|
||||
*/
|
||||
public Layout(
|
||||
Couple position,
|
||||
Couple labelOffset,
|
||||
int layerId
|
||||
) {
|
||||
this.position = requireNonNull(position, "position");
|
||||
this.labelOffset = requireNonNull(labelOffset, "labelOffset");
|
||||
this.layerId = layerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the coordinates at which the point is to be drawn (in mm).
|
||||
*
|
||||
* @return The coordinates at which the point is to be drawn (in mm).
|
||||
*/
|
||||
public Couple getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given position.
|
||||
*
|
||||
* @param position The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withPosition(Couple position) {
|
||||
return new Layout(
|
||||
position,
|
||||
labelOffset,
|
||||
layerId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset of the label's position to the point's position (in lu).
|
||||
*
|
||||
* @return The offset of the label's position to the point's position (in lu).
|
||||
*/
|
||||
public Couple getLabelOffset() {
|
||||
return labelOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given X label offset.
|
||||
*
|
||||
* @param labelOffset The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withLabelOffset(Couple labelOffset) {
|
||||
return new Layout(
|
||||
position,
|
||||
labelOffset,
|
||||
layerId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the layer on which the point is to be drawn.
|
||||
*
|
||||
* @return The layer ID.
|
||||
*/
|
||||
public int getLayerId() {
|
||||
return layerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layer ID.
|
||||
*
|
||||
* @param layerId The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withLayerId(int layerId) {
|
||||
return new Layout(
|
||||
position,
|
||||
labelOffset,
|
||||
layerId
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Layout{"
|
||||
+ "position=" + position
|
||||
+ ", labelOffset=" + labelOffset
|
||||
+ ", layerId=" + layerId
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,729 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.opentcs.util.Assertions.checkInRange;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import java.awt.Color;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.util.annotations.ScheduledApiChange;
|
||||
|
||||
/**
|
||||
* A transfer object describing a block in the plant model.
|
||||
*/
|
||||
public class VehicleCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The vehicle's bounding box (in mm).
|
||||
*/
|
||||
private final BoundingBoxCreationTO boundingBox;
|
||||
/**
|
||||
* Contains information regarding the energy level threshold values of the vehicle.
|
||||
*/
|
||||
private final EnergyLevelThresholdSet energyLevelThresholdSet;
|
||||
/**
|
||||
* The vehicle's maximum velocity (in mm/s).
|
||||
*/
|
||||
private final int maxVelocity;
|
||||
/**
|
||||
* The vehicle's maximum reverse velocity (in mm/s).
|
||||
*/
|
||||
private final int maxReverseVelocity;
|
||||
/**
|
||||
* The key for selecting the envelope to be used for resources the vehicle occupies.
|
||||
*/
|
||||
private final String envelopeKey;
|
||||
/**
|
||||
* The information regarding the graphical representation of this vehicle.
|
||||
*/
|
||||
private final Layout layout;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this vehicle.
|
||||
*/
|
||||
public VehicleCreationTO(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
super(name);
|
||||
this.boundingBox = new BoundingBoxCreationTO(1000, 1000, 1000);
|
||||
this.energyLevelThresholdSet = new EnergyLevelThresholdSet(30, 90, 30, 90);
|
||||
this.maxVelocity = 1000;
|
||||
this.maxReverseVelocity = 1000;
|
||||
this.envelopeKey = null;
|
||||
this.layout = new Layout();
|
||||
}
|
||||
|
||||
private VehicleCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
@Nonnull
|
||||
BoundingBoxCreationTO boundingBox,
|
||||
@Nonnull
|
||||
EnergyLevelThresholdSet energyLevelThresholdSet,
|
||||
int maxVelocity,
|
||||
int maxReverseVelocity,
|
||||
@Nullable
|
||||
String envelopeKey,
|
||||
@Nonnull
|
||||
Layout layout
|
||||
) {
|
||||
super(name, properties);
|
||||
this.boundingBox = requireNonNull(boundingBox, "boundingBox");
|
||||
this.energyLevelThresholdSet
|
||||
= requireNonNull(energyLevelThresholdSet, "energyLevelThresholdSet");
|
||||
this.maxVelocity = maxVelocity;
|
||||
this.maxReverseVelocity = maxReverseVelocity;
|
||||
this.envelopeKey = envelopeKey;
|
||||
this.layout = requireNonNull(layout, "layout");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name The new instance.
|
||||
* @return A copy of this object, differing in the given name.
|
||||
*/
|
||||
@Override
|
||||
public VehicleCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new VehicleCreationTO(
|
||||
name,
|
||||
getModifiableProperties(),
|
||||
boundingBox,
|
||||
energyLevelThresholdSet,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
envelopeKey,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given properties.
|
||||
*/
|
||||
@Override
|
||||
public VehicleCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new VehicleCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
boundingBox,
|
||||
energyLevelThresholdSet,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
envelopeKey,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in its current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public VehicleCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new VehicleCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
boundingBox,
|
||||
energyLevelThresholdSet,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
envelopeKey,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vehicle's current bounding box (in mm).
|
||||
*
|
||||
* @return The vehicle's current bounding box (in mm).
|
||||
*/
|
||||
public BoundingBoxCreationTO getBoundingBox() {
|
||||
return boundingBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given bounding box (in mm).
|
||||
*
|
||||
* @param boundingBox The new bounding box.
|
||||
* @return A copy of this object, differing in the given vehicle bounding box.
|
||||
*/
|
||||
public VehicleCreationTO withBoundingBox(BoundingBoxCreationTO boundingBox) {
|
||||
return new VehicleCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
boundingBox,
|
||||
energyLevelThresholdSet,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
envelopeKey,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vehicle's length (in mm).
|
||||
*
|
||||
* @return The vehicle's length (in mm).
|
||||
* @deprecated Use {@link #getBoundingBox()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public int getLength() {
|
||||
return (int) boundingBox.getLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the vehicle's given length (in mm).
|
||||
*
|
||||
* @param length The new length. Must be at least 1.
|
||||
* @return A copy of this object, differing in the given vehicle length.
|
||||
* @deprecated Use {@link #withBoundingBox(BoundingBoxCreationTO)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public VehicleCreationTO withLength(int length) {
|
||||
return withBoundingBox(boundingBox.withLength(length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this vehicle's critical energy level (in percent of the maximum).
|
||||
* The critical energy level is the one at/below which the vehicle should be recharged.
|
||||
*
|
||||
* @return This vehicle's critical energy level.
|
||||
* @deprecated Use {@link #getEnergyLevelThresholdSet()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public int getEnergyLevelCritical() {
|
||||
return energyLevelThresholdSet.getEnergyLevelCritical();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given critical energy level.
|
||||
* The critical energy level is the one at/below which the vehicle should be recharged.
|
||||
*
|
||||
* @param energyLevelCritical The new critical energy level. Must not be smaller than 0 or
|
||||
* greater than 100.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
* @deprecated Use {@link #withEnergyLevelThresholdSet(EnergyLevelThresholdSet)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public VehicleCreationTO withEnergyLevelCritical(int energyLevelCritical) {
|
||||
return withEnergyLevelThresholdSet(
|
||||
getEnergyLevelThresholdSet().withEnergyLevelCritical(energyLevelCritical)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this vehicle's good energy level (in percent of the maximum).
|
||||
* The good energy level is the one at/above which the vehicle can be dispatched again when
|
||||
* charging.
|
||||
*
|
||||
* @return This vehicle's good energy level.
|
||||
* @deprecated Use {@link #getEnergyLevelThresholdSet()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public int getEnergyLevelGood() {
|
||||
return energyLevelThresholdSet.getEnergyLevelGood();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the vehicle's good energy level (in percent of the maximum).
|
||||
* The good energy level is the one at/above which the vehicle can be dispatched again when
|
||||
* charging.
|
||||
*
|
||||
* @param energyLevelGood The new good energy level. Must not be smaller than 0 or greater than
|
||||
* 100.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
* @deprecated Use {@link #withEnergyLevelThresholdSet(EnergyLevelThresholdSet)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public VehicleCreationTO withEnergyLevelGood(int energyLevelGood) {
|
||||
return withEnergyLevelThresholdSet(
|
||||
getEnergyLevelThresholdSet().withEnergyLevelGood(energyLevelGood)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this vehicle's fully recharged energy level (in percent of the maximum).
|
||||
*
|
||||
* @return This vehicle's fully recharged energy level.
|
||||
* @deprecated Use {@link #getEnergyLevelThresholdSet()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public int getEnergyLevelFullyRecharged() {
|
||||
return energyLevelThresholdSet.getEnergyLevelFullyRecharged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the vehicle's fully recharged energy level (in percent of
|
||||
* the maximum).
|
||||
*
|
||||
* @param energyLevelFullyRecharged The new fully recharged energy level.
|
||||
* Must not be smaller than 0 or greater than 100.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
* @deprecated Use {@link #withEnergyLevelThresholdSet(EnergyLevelThresholdSet)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public VehicleCreationTO withEnergyLevelFullyRecharged(int energyLevelFullyRecharged) {
|
||||
return withEnergyLevelThresholdSet(
|
||||
getEnergyLevelThresholdSet().withEnergyLevelFullyRecharged(energyLevelFullyRecharged)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this vehicle's sufficiently recharged energy level (in percent of the maximum).
|
||||
*
|
||||
* @return This vehicle's sufficiently recharged energy level.
|
||||
* @deprecated Use {@link #getEnergyLevelThresholdSet()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public int getEnergyLevelSufficientlyRecharged() {
|
||||
return energyLevelThresholdSet.getEnergyLevelSufficientlyRecharged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the vehicle's sufficiently recharged energy level (in
|
||||
* percent of the maximum).
|
||||
*
|
||||
* @param energyLevelSufficientlyRecharged The new sufficiently recharged energy level.
|
||||
* Must not be smaller than 0 or greater than 100.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
* @deprecated Use {@link #withEnergyLevelThresholdSet(EnergyLevelThresholdSet)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
public VehicleCreationTO withEnergyLevelSufficientlyRecharged(
|
||||
int energyLevelSufficientlyRecharged
|
||||
) {
|
||||
return withEnergyLevelThresholdSet(
|
||||
getEnergyLevelThresholdSet()
|
||||
.withEnergyLevelSufficientlyRecharged(energyLevelSufficientlyRecharged)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this vehicle's energy level threshold set.
|
||||
*
|
||||
* @return This vehicle's energy level threshold set.
|
||||
*/
|
||||
@Nonnull
|
||||
public EnergyLevelThresholdSet getEnergyLevelThresholdSet() {
|
||||
return energyLevelThresholdSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given EnergyLevelThresholdSet.
|
||||
*
|
||||
* @param energyLevelThresholdSet The new EnergyLevelThresholdSet.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VehicleCreationTO withEnergyLevelThresholdSet(
|
||||
@Nonnull
|
||||
EnergyLevelThresholdSet energyLevelThresholdSet
|
||||
) {
|
||||
return new VehicleCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
boundingBox,
|
||||
energyLevelThresholdSet,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
envelopeKey,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
public int getMaxVelocity() {
|
||||
return maxVelocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given maximum velocity (in mm/s).
|
||||
*
|
||||
* @param maxVelocity the new max velocity.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VehicleCreationTO withMaxVelocity(int maxVelocity) {
|
||||
checkInRange(maxVelocity, 0, Integer.MAX_VALUE);
|
||||
return new VehicleCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
boundingBox,
|
||||
energyLevelThresholdSet,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
envelopeKey,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
public int getMaxReverseVelocity() {
|
||||
return maxReverseVelocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given maximum reverse velocity (in mm/s).
|
||||
*
|
||||
* @param maxReverseVelocity the new maximum reverse velocity.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VehicleCreationTO withMaxReverseVelocity(int maxReverseVelocity) {
|
||||
checkInRange(maxReverseVelocity, 0, Integer.MAX_VALUE);
|
||||
return new VehicleCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
boundingBox,
|
||||
energyLevelThresholdSet,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
envelopeKey,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key for selecting the envelope to be used for resources the vehicle occupies.
|
||||
*
|
||||
* @return The key for selecting the envelope to be used for resources the vehicle occupies.
|
||||
*/
|
||||
@ScheduledApiChange(when = "7.0", details = "Envelope key will become non-null.")
|
||||
@Nullable
|
||||
public String getEnvelopeKey() {
|
||||
return envelopeKey;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates a copy of this object, with the given envelope key.
|
||||
*
|
||||
* @param envelopeKey The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
@ScheduledApiChange(when = "7.0", details = "Envelope key will become non-null.")
|
||||
public VehicleCreationTO withEnvelopeKey(
|
||||
@Nullable
|
||||
String envelopeKey
|
||||
) {
|
||||
return new VehicleCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
boundingBox,
|
||||
energyLevelThresholdSet,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
envelopeKey,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information regarding the graphical representation of this vehicle.
|
||||
*
|
||||
* @return The information regarding the graphical representation of this vehicle.
|
||||
*/
|
||||
public Layout getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layout.
|
||||
*
|
||||
* @param layout The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VehicleCreationTO withLayout(Layout layout) {
|
||||
return new VehicleCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
boundingBox,
|
||||
energyLevelThresholdSet,
|
||||
maxVelocity,
|
||||
maxReverseVelocity,
|
||||
envelopeKey,
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VehicleCreationTO{"
|
||||
+ "name=" + getName()
|
||||
+ ", boundingBox=" + boundingBox
|
||||
+ ", energyLevelThresholdSet=" + energyLevelThresholdSet
|
||||
+ ", maxVelocity=" + maxVelocity
|
||||
+ ", maxReverseVelocity=" + maxReverseVelocity
|
||||
+ ", envelopeKey=" + envelopeKey
|
||||
+ ", layout=" + layout
|
||||
+ ", properties=" + getProperties()
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains information regarding the graphical representation of a vehicle.
|
||||
*/
|
||||
public static class Layout
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The color in which vehicle routes are to be emphasized.
|
||||
*/
|
||||
private final Color routeColor;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
public Layout() {
|
||||
this(Color.RED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param routeColor The color in which vehicle routes are to be emphasized.
|
||||
*/
|
||||
public Layout(Color routeColor) {
|
||||
this.routeColor = requireNonNull(routeColor, "routeColor");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color in which vehicle routes are to be emphasized.
|
||||
*
|
||||
* @return The color in which vehicle routes are to be emphasized.
|
||||
*/
|
||||
public Color getRouteColor() {
|
||||
return routeColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given color.
|
||||
*
|
||||
* @param routeColor The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public Layout withRouteColor(Color routeColor) {
|
||||
return new Layout(routeColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Layout{"
|
||||
+ "routeColor=" + routeColor
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains information regarding the energy level threshold values of a vehicle.
|
||||
*/
|
||||
public static class EnergyLevelThresholdSet
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
private final int energyLevelCritical;
|
||||
private final int energyLevelGood;
|
||||
private final int energyLevelSufficientlyRecharged;
|
||||
private final int energyLevelFullyRecharged;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param energyLevelCritical The value at/below which the vehicle's energy level is considered
|
||||
* "critical".
|
||||
* @param energyLevelGood The value at/above which the vehicle's energy level is considered
|
||||
* "good".
|
||||
* @param energyLevelSufficientlyRecharged The value at/above which the vehicle's energy level
|
||||
* is considered fully recharged.
|
||||
* @param energyLevelFullyRecharged The value at/above which the vehicle's energy level is
|
||||
* considered sufficiently recharged.
|
||||
*/
|
||||
public EnergyLevelThresholdSet(
|
||||
int energyLevelCritical,
|
||||
int energyLevelGood,
|
||||
int energyLevelSufficientlyRecharged,
|
||||
int energyLevelFullyRecharged
|
||||
) {
|
||||
this.energyLevelCritical = checkInRange(
|
||||
energyLevelCritical,
|
||||
0,
|
||||
100,
|
||||
"energyLevelCritical"
|
||||
);
|
||||
this.energyLevelGood = checkInRange(
|
||||
energyLevelGood,
|
||||
0,
|
||||
100,
|
||||
"energyLevelGood"
|
||||
);
|
||||
this.energyLevelSufficientlyRecharged = checkInRange(
|
||||
energyLevelSufficientlyRecharged,
|
||||
0,
|
||||
100,
|
||||
"energyLevelSufficientlyRecharged"
|
||||
);
|
||||
this.energyLevelFullyRecharged = checkInRange(
|
||||
energyLevelFullyRecharged,
|
||||
0,
|
||||
100,
|
||||
"energyLevelFullyRecharged"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vehicle's critical energy level (in percent of the maximum).
|
||||
* <p>
|
||||
* The critical energy level is the one at/below which the vehicle should be recharged.
|
||||
* </p>
|
||||
*
|
||||
* @return The vehicle's critical energy level.
|
||||
*/
|
||||
public int getEnergyLevelCritical() {
|
||||
return energyLevelCritical;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given critical energy level.
|
||||
*
|
||||
* @param energyLevelCritical The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public EnergyLevelThresholdSet withEnergyLevelCritical(int energyLevelCritical) {
|
||||
return new EnergyLevelThresholdSet(
|
||||
energyLevelCritical,
|
||||
energyLevelGood,
|
||||
energyLevelSufficientlyRecharged,
|
||||
energyLevelFullyRecharged
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vehicle's good energy level (in percent of the maximum).
|
||||
* <p>
|
||||
* The good energy level is the one at/above which the vehicle can be dispatched again when
|
||||
* charging.
|
||||
* </p>
|
||||
*
|
||||
* @return The vehicle's good energy level.
|
||||
*/
|
||||
public int getEnergyLevelGood() {
|
||||
return energyLevelGood;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given good energy level.
|
||||
*
|
||||
* @param energyLevelGood The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public EnergyLevelThresholdSet withEnergyLevelGood(int energyLevelGood) {
|
||||
return new EnergyLevelThresholdSet(
|
||||
energyLevelCritical,
|
||||
energyLevelGood,
|
||||
energyLevelSufficientlyRecharged,
|
||||
energyLevelFullyRecharged
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vehicle's energy level for being sufficiently recharged (in percent of the
|
||||
* maximum).
|
||||
*
|
||||
* @return This vehicle's sufficiently recharged energy level.
|
||||
*/
|
||||
public int getEnergyLevelSufficientlyRecharged() {
|
||||
return energyLevelSufficientlyRecharged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given sufficiently recharged energy level.
|
||||
*
|
||||
* @param energyLevelSufficientlyRecharged The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public EnergyLevelThresholdSet withEnergyLevelSufficientlyRecharged(
|
||||
int energyLevelSufficientlyRecharged
|
||||
) {
|
||||
return new EnergyLevelThresholdSet(
|
||||
energyLevelCritical,
|
||||
energyLevelGood,
|
||||
energyLevelSufficientlyRecharged,
|
||||
energyLevelFullyRecharged
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vehicle's energy level for being fully recharged (in percent of the maximum).
|
||||
*
|
||||
* @return The vehicle's fully recharged threshold.
|
||||
*/
|
||||
public int getEnergyLevelFullyRecharged() {
|
||||
return energyLevelFullyRecharged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given fully recharged energy level.
|
||||
*
|
||||
* @param energyLevelFullyRecharged The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public EnergyLevelThresholdSet withEnergyLevelFullyRecharged(int energyLevelFullyRecharged) {
|
||||
return new EnergyLevelThresholdSet(
|
||||
energyLevelCritical,
|
||||
energyLevelGood,
|
||||
energyLevelSufficientlyRecharged,
|
||||
energyLevelFullyRecharged
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EnergyLevelThresholdSet{"
|
||||
+ "energyLevelCritical=" + energyLevelCritical
|
||||
+ ", energyLevelGood=" + energyLevelGood
|
||||
+ ", energyLevelSufficientlyRecharged=" + energyLevelSufficientlyRecharged
|
||||
+ ", energyLevelFullyRecharged=" + energyLevelFullyRecharged
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.model;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.data.model.visualization.Layer;
|
||||
import org.opentcs.data.model.visualization.LayerGroup;
|
||||
|
||||
/**
|
||||
* A transfer object describing a visual layout in the plant model.
|
||||
*/
|
||||
public class VisualLayoutCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* This layout's scale on the X axis (in mm/pixel).
|
||||
*/
|
||||
private final double scaleX;
|
||||
/**
|
||||
* This layout's scale on the Y axis (in mm/pixel).
|
||||
*/
|
||||
private final double scaleY;
|
||||
/**
|
||||
* This layout's layers.
|
||||
*/
|
||||
private final List<Layer> layers;
|
||||
/**
|
||||
* The layout's layer groups.
|
||||
*/
|
||||
private final List<LayerGroup> layerGroups;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this visual layout.
|
||||
*/
|
||||
public VisualLayoutCreationTO(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
super(name);
|
||||
|
||||
this.scaleX = 50.0;
|
||||
this.scaleY = 50.0;
|
||||
this.layers = List.of();
|
||||
this.layerGroups = List.of();
|
||||
}
|
||||
|
||||
private VisualLayoutCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
double scaleX,
|
||||
double scaleY,
|
||||
@Nonnull
|
||||
List<Layer> layers,
|
||||
@Nonnull
|
||||
List<LayerGroup> layerGroups
|
||||
) {
|
||||
super(name, properties);
|
||||
this.scaleX = scaleX;
|
||||
this.scaleY = scaleY;
|
||||
this.layers = requireNonNull(layers, "layers");
|
||||
this.layerGroups = requireNonNull(layerGroups, "layerGroups");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name the new name of the instance.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
@Override
|
||||
public VisualLayoutCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new VisualLayoutCreationTO(
|
||||
name,
|
||||
getModifiableProperties(),
|
||||
scaleX,
|
||||
scaleY,
|
||||
layers,
|
||||
layerGroups
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
@Override
|
||||
public VisualLayoutCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new VisualLayoutCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
scaleX,
|
||||
scaleY,
|
||||
layers,
|
||||
layerGroups
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in it's current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public VisualLayoutCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new VisualLayoutCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
scaleX,
|
||||
scaleY,
|
||||
layers,
|
||||
layerGroups
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this layout's scale on the X axis (in mm/pixel).
|
||||
*
|
||||
* @return This layout's scale on the X axis.
|
||||
*/
|
||||
public double getScaleX() {
|
||||
return scaleX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the layout's scale on the X axis (in mm/pixel).
|
||||
*
|
||||
* @param scaleX The new scale.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VisualLayoutCreationTO withScaleX(double scaleX) {
|
||||
return new VisualLayoutCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
scaleX,
|
||||
scaleY,
|
||||
layers,
|
||||
layerGroups
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this layout's scale on the Y axis (in mm/pixel).
|
||||
*
|
||||
* @return This layout's scale on the Y axis.
|
||||
*/
|
||||
public double getScaleY() {
|
||||
return scaleY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given layout's scale on the Y axis (in mm/pixel).
|
||||
*
|
||||
* @param scaleY The new scale.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VisualLayoutCreationTO withScaleY(double scaleY) {
|
||||
return new VisualLayoutCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
scaleX,
|
||||
scaleY,
|
||||
layers,
|
||||
layerGroups
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layers of this visual layout.
|
||||
*
|
||||
* @return The layers of this visual layout.
|
||||
*/
|
||||
@Nonnull
|
||||
public List<Layer> getLayers() {
|
||||
return Collections.unmodifiableList(layers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layers.
|
||||
*
|
||||
* @param layers The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VisualLayoutCreationTO withLayers(
|
||||
@Nonnull
|
||||
List<Layer> layers
|
||||
) {
|
||||
return new VisualLayoutCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
scaleX,
|
||||
scaleY,
|
||||
layers,
|
||||
layerGroups
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layer.
|
||||
*
|
||||
* @param layer The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VisualLayoutCreationTO withLayer(
|
||||
@Nonnull
|
||||
Layer layer
|
||||
) {
|
||||
return new VisualLayoutCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
scaleX,
|
||||
scaleY,
|
||||
listWithAppendix(layers, layer),
|
||||
layerGroups
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layer groups of this visual layout.
|
||||
*
|
||||
* @return The layer groups of this visual layout.
|
||||
*/
|
||||
@Nonnull
|
||||
public List<LayerGroup> getLayerGroups() {
|
||||
return Collections.unmodifiableList(layerGroups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layer groups.
|
||||
*
|
||||
* @param layerGroups The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VisualLayoutCreationTO withLayerGroups(
|
||||
@Nonnull
|
||||
List<LayerGroup> layerGroups
|
||||
) {
|
||||
return new VisualLayoutCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
scaleX,
|
||||
scaleY,
|
||||
layers,
|
||||
layerGroups
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given layer group.
|
||||
*
|
||||
* @param layerGroup The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public VisualLayoutCreationTO withLayerGroup(
|
||||
@Nonnull
|
||||
LayerGroup layerGroup
|
||||
) {
|
||||
return new VisualLayoutCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
scaleX,
|
||||
scaleY,
|
||||
layers,
|
||||
listWithAppendix(layerGroups, layerGroup)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VisualLayoutCreationTO{"
|
||||
+ "name=" + getName()
|
||||
+ ", scaleX=" + scaleX
|
||||
+ ", scaleY=" + scaleY
|
||||
+ ", layers=" + layers
|
||||
+ ", layerGroups=" + layerGroups
|
||||
+ ", properties=" + getProperties()
|
||||
+ '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
/**
|
||||
* Transfer object classes for plant model objects.
|
||||
*/
|
||||
package org.opentcs.access.to.model;
|
||||
@@ -0,0 +1,177 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.order;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
|
||||
/**
|
||||
* A transfer object describing a destination of a drive order.
|
||||
*/
|
||||
public class DestinationCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The name of the destination location (or point).
|
||||
*/
|
||||
@Nonnull
|
||||
private final String destLocationName;
|
||||
/**
|
||||
* The operation to be performed at the destination.
|
||||
*/
|
||||
@Nonnull
|
||||
private final String destOperation;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param destLocationName The name of the destination location (or destination point).
|
||||
* @param destOperation The operation to be performed at the destination.
|
||||
*/
|
||||
public DestinationCreationTO(
|
||||
@Nonnull
|
||||
String destLocationName,
|
||||
@Nonnull
|
||||
String destOperation
|
||||
) {
|
||||
super("");
|
||||
this.destLocationName = requireNonNull(destLocationName, "destLocationName");
|
||||
this.destOperation = requireNonNull(destOperation, "destOperation");
|
||||
}
|
||||
|
||||
private DestinationCreationTO(
|
||||
@Nonnull
|
||||
String destLocationName,
|
||||
@Nonnull
|
||||
String destOperation,
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
super(name, properties);
|
||||
this.destLocationName = requireNonNull(destLocationName, "destLocationName");
|
||||
this.destOperation = requireNonNull(destOperation, "destOperation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name the new name of the instance.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
@Override
|
||||
public DestinationCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new DestinationCreationTO(
|
||||
destLocationName,
|
||||
destOperation,
|
||||
name,
|
||||
getModifiableProperties()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
@Override
|
||||
public DestinationCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new DestinationCreationTO(destLocationName, destOperation, getName(), properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in it's current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public DestinationCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new DestinationCreationTO(
|
||||
destLocationName,
|
||||
destOperation,
|
||||
getName(),
|
||||
propertiesWith(key, value)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the destination location (or point) name.
|
||||
*
|
||||
* @return The destination location (or point) name.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getDestLocationName() {
|
||||
return destLocationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given destination location (or point) name.
|
||||
*
|
||||
* @param desLocationName The destination location (or point) name.
|
||||
* @return A copy of this object, differing in the given destination.
|
||||
*/
|
||||
public DestinationCreationTO withDestLocationName(
|
||||
@Nonnull
|
||||
String desLocationName
|
||||
) {
|
||||
return new DestinationCreationTO(
|
||||
destLocationName,
|
||||
destOperation,
|
||||
getName(),
|
||||
getModifiableProperties()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the operation to be performed at the destination.
|
||||
*
|
||||
* @return The operation to be performed at the destination.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getDestOperation() {
|
||||
return destOperation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given operation to be performed at the destination.
|
||||
*
|
||||
* @param destOperation The operation.
|
||||
* @return A copy of this object, differing in the given destination operation.
|
||||
*/
|
||||
public DestinationCreationTO withDestOperation(
|
||||
@Nonnull
|
||||
String destOperation
|
||||
) {
|
||||
return new DestinationCreationTO(
|
||||
destLocationName,
|
||||
destOperation,
|
||||
getName(),
|
||||
getModifiableProperties()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.order;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.data.order.OrderConstants;
|
||||
|
||||
/**
|
||||
* A transfer object describing a transport order.
|
||||
*/
|
||||
public class OrderSequenceCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* Indicates whether the name is incomplete and requires to be completed when creating the actual
|
||||
* order sequence.
|
||||
* (How exactly this is done is decided by the kernel.)
|
||||
*/
|
||||
private final boolean incompleteName;
|
||||
/**
|
||||
* The type of the order sequence.
|
||||
*/
|
||||
private final String type;
|
||||
/**
|
||||
* The (optional) name of the vehicle that is supposed to execute the transport order.
|
||||
*/
|
||||
@Nullable
|
||||
private final String intendedVehicleName;
|
||||
/**
|
||||
* Whether failure of one transport order in the sequence makes subsequent ones fail, too.
|
||||
*/
|
||||
private final boolean failureFatal;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this transport order.
|
||||
*/
|
||||
public OrderSequenceCreationTO(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
super(name);
|
||||
this.incompleteName = false;
|
||||
this.type = OrderConstants.TYPE_NONE;
|
||||
this.intendedVehicleName = null;
|
||||
this.failureFatal = false;
|
||||
}
|
||||
|
||||
private OrderSequenceCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
boolean incompleteName,
|
||||
@Nonnull
|
||||
String type,
|
||||
@Nullable
|
||||
String intendedVehicleName,
|
||||
boolean failureFatal
|
||||
) {
|
||||
super(name, properties);
|
||||
this.incompleteName = incompleteName;
|
||||
this.type = requireNonNull(type, "type");
|
||||
this.intendedVehicleName = intendedVehicleName;
|
||||
this.failureFatal = failureFatal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name the new name of the instance.
|
||||
* @return A copy of this object, differing in the given name.
|
||||
*/
|
||||
@Override
|
||||
public OrderSequenceCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new OrderSequenceCreationTO(
|
||||
name,
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
type,
|
||||
intendedVehicleName,
|
||||
failureFatal
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
@Override
|
||||
public OrderSequenceCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new OrderSequenceCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
incompleteName,
|
||||
type,
|
||||
intendedVehicleName,
|
||||
failureFatal
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in it's current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public OrderSequenceCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new OrderSequenceCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
incompleteName,
|
||||
type,
|
||||
intendedVehicleName,
|
||||
failureFatal
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the name is incomplete and requires to be completed when creating the actual
|
||||
* order sequence.
|
||||
* (How exactly this is done is decided by the kernel.)
|
||||
*
|
||||
* @return <code>true</code> if, and only if, the name is incomplete and requires to be completed
|
||||
* by the kernel.
|
||||
*/
|
||||
public boolean hasIncompleteName() {
|
||||
return incompleteName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given <em>nameIncomplete</em> flag.
|
||||
*
|
||||
* @param incompleteName Whether the name is incomplete and requires to be completed when creating
|
||||
* the actual order sequence.
|
||||
*
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public OrderSequenceCreationTO withIncompleteName(boolean incompleteName) {
|
||||
return new OrderSequenceCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
type,
|
||||
intendedVehicleName,
|
||||
failureFatal
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (optional) type of the order sequence.
|
||||
*
|
||||
* @return The (optional) type of the order sequence.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given type.
|
||||
*
|
||||
* @param type The type.
|
||||
* @return A copy of this object, differing in the given type.
|
||||
*/
|
||||
public OrderSequenceCreationTO withType(
|
||||
@Nonnull
|
||||
String type
|
||||
) {
|
||||
return new OrderSequenceCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
type,
|
||||
intendedVehicleName,
|
||||
failureFatal
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (optional) name of the vehicle that is supposed to execute the transport order.
|
||||
*
|
||||
* @return The (optional) name of the vehicle that is supposed to execute the transport order.
|
||||
*/
|
||||
@Nullable
|
||||
public String getIntendedVehicleName() {
|
||||
return intendedVehicleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given
|
||||
* (optional) name of the vehicle that is supposed to execute the transport order.
|
||||
*
|
||||
* @param intendedVehicleName The vehicle name.
|
||||
* @return A copy of this object, differing in the given name of the intended vehicle.
|
||||
*/
|
||||
public OrderSequenceCreationTO withIntendedVehicleName(
|
||||
@Nullable
|
||||
String intendedVehicleName
|
||||
) {
|
||||
return new OrderSequenceCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
type,
|
||||
intendedVehicleName,
|
||||
failureFatal
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether failure of one transport order in the sequence makes subsequent ones fail, too.
|
||||
*
|
||||
* @return Whether failure of one transport order in the sequence makes subsequent ones fail, too.
|
||||
*/
|
||||
public boolean isFailureFatal() {
|
||||
return failureFatal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given <em>failureFatal</em> flag.
|
||||
*
|
||||
* @param failureFatal Whether failure of one transport order in the sequence makes subsequent
|
||||
* ones fail, too.
|
||||
*
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public OrderSequenceCreationTO withFailureFatal(boolean failureFatal) {
|
||||
return new OrderSequenceCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
type,
|
||||
intendedVehicleName,
|
||||
failureFatal
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,533 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.order;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.data.order.OrderConstants;
|
||||
|
||||
/**
|
||||
* A transfer object describing a transport order.
|
||||
*/
|
||||
public class TransportOrderCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* Indicates whether the name is incomplete and requires to be completed when creating the actual
|
||||
* transport order.
|
||||
* (How exactly this is done is decided by the kernel.)
|
||||
*/
|
||||
private final boolean incompleteName;
|
||||
/**
|
||||
* The destinations that need to be travelled to.
|
||||
*/
|
||||
@Nonnull
|
||||
private final List<DestinationCreationTO> destinations;
|
||||
/**
|
||||
* An optional token for reserving peripheral devices while processing this transport order.
|
||||
*/
|
||||
@Nullable
|
||||
private final String peripheralReservationToken;
|
||||
/**
|
||||
* The (optional) name of the order sequence the transport order belongs to.
|
||||
*/
|
||||
@Nullable
|
||||
private final String wrappingSequence;
|
||||
/**
|
||||
* The (optional) names of transport orders the transport order depends on.
|
||||
*/
|
||||
@Nonnull
|
||||
private final Set<String> dependencyNames;
|
||||
/**
|
||||
* The (optional) name of the vehicle that is supposed to execute the transport order.
|
||||
*/
|
||||
@Nullable
|
||||
private final String intendedVehicleName;
|
||||
/**
|
||||
* The type of the transport order.
|
||||
*/
|
||||
@Nonnull
|
||||
private final String type;
|
||||
/**
|
||||
* The point of time at which execution of the transport order is supposed to be finished.
|
||||
*/
|
||||
@Nonnull
|
||||
private final Instant deadline;
|
||||
/**
|
||||
* Whether the transport order is dispensable or not.
|
||||
*/
|
||||
private final boolean dispensable;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this transport order.
|
||||
* @param destinations The destinations that need to be travelled to.
|
||||
*/
|
||||
public TransportOrderCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
List<DestinationCreationTO> destinations
|
||||
) {
|
||||
super(name);
|
||||
this.incompleteName = false;
|
||||
this.destinations = requireNonNull(destinations, "destinations");
|
||||
this.peripheralReservationToken = null;
|
||||
this.wrappingSequence = null;
|
||||
this.dependencyNames = Set.of();
|
||||
this.intendedVehicleName = null;
|
||||
this.type = OrderConstants.TYPE_NONE;
|
||||
this.deadline = Instant.MAX;
|
||||
this.dispensable = false;
|
||||
}
|
||||
|
||||
private TransportOrderCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
boolean incompleteName,
|
||||
@Nonnull
|
||||
List<DestinationCreationTO> destinations,
|
||||
@Nullable
|
||||
String peripheralReservationToken,
|
||||
@Nullable
|
||||
String wrappingSequence,
|
||||
@Nonnull
|
||||
Set<String> dependencyNames,
|
||||
@Nullable
|
||||
String intendedVehicleName,
|
||||
@Nonnull
|
||||
String type,
|
||||
@Nonnull
|
||||
Instant deadline,
|
||||
boolean dispensable
|
||||
) {
|
||||
super(name, properties);
|
||||
this.incompleteName = incompleteName;
|
||||
this.destinations = requireNonNull(destinations, "destinations");
|
||||
this.peripheralReservationToken = peripheralReservationToken;
|
||||
this.wrappingSequence = wrappingSequence;
|
||||
this.dependencyNames = requireNonNull(dependencyNames, "dependencyNames");
|
||||
this.intendedVehicleName = intendedVehicleName;
|
||||
this.type = requireNonNull(type, "type");
|
||||
this.deadline = requireNonNull(deadline, "deadline");
|
||||
this.dispensable = dispensable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given name.
|
||||
*
|
||||
* @param name The new name of the instance.
|
||||
* @return A copy of this object, differing in the given name.
|
||||
*/
|
||||
@Override
|
||||
public TransportOrderCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
name,
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given properties.
|
||||
*
|
||||
* @param properties The new properties.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
@Override
|
||||
public TransportOrderCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object and adds the given property.
|
||||
* If value == null, then the key-value pair is removed from the properties.
|
||||
*
|
||||
* @param key the key.
|
||||
* @param value the value
|
||||
* @return A copy of this object that either
|
||||
* includes the given entry in it's current properties, if value != null or
|
||||
* excludes the entry otherwise.
|
||||
*/
|
||||
@Override
|
||||
public TransportOrderCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the name is incomplete and requires to be completed when creating the actual
|
||||
* transport order.
|
||||
* (How exactly this is done is decided by the kernel.)
|
||||
*
|
||||
* @return <code>true</code> if, and only if, the name is incomplete and requires to be completed
|
||||
* by the kernel.
|
||||
*/
|
||||
public boolean hasIncompleteName() {
|
||||
return incompleteName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given <em>nameIncomplete</em> flag.
|
||||
*
|
||||
* @param incompleteName Whether the name is incomplete and requires to be completed when creating
|
||||
* the actual transport order.
|
||||
*
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public TransportOrderCreationTO withIncompleteName(boolean incompleteName) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the destinations that need to be travelled to.
|
||||
*
|
||||
* @return The destinations that need to be travelled to.
|
||||
*/
|
||||
@Nonnull
|
||||
public List<DestinationCreationTO> getDestinations() {
|
||||
return Collections.unmodifiableList(destinations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given destinations that need to be travelled to.
|
||||
*
|
||||
* @param destinations The destinations.
|
||||
* @return A copy of this object, differing in the given derstinations.
|
||||
*/
|
||||
public TransportOrderCreationTO withDestinations(
|
||||
@Nonnull
|
||||
List<DestinationCreationTO> destinations
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an optional token for reserving peripheral devices while processing this transport
|
||||
* order.
|
||||
*
|
||||
* @return An optional token for reserving peripheral devices while processing this transport
|
||||
* order.
|
||||
*/
|
||||
@Nullable
|
||||
public String getPeripheralReservationToken() {
|
||||
return peripheralReservationToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given (optional) peripheral reservation token.
|
||||
*
|
||||
* @param peripheralReservationToken The token.
|
||||
* @return A copy of this object, differing in the given peripheral reservation token.
|
||||
*/
|
||||
public TransportOrderCreationTO withPeripheralReservationToken(
|
||||
@Nullable
|
||||
String peripheralReservationToken
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (optional) name of the order sequence the transport order belongs to.
|
||||
*
|
||||
* @return The (optional) name of the order sequence the transport order belongs to.
|
||||
*/
|
||||
@Nullable
|
||||
public String getWrappingSequence() {
|
||||
return wrappingSequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given
|
||||
* (optional) name of the order sequence the transport order belongs to.
|
||||
*
|
||||
* @param wrappingSequence The name of the sequence.
|
||||
* @return A copy of this object, differing in the given name of the sequence.
|
||||
*/
|
||||
public TransportOrderCreationTO withWrappingSequence(
|
||||
@Nullable
|
||||
String wrappingSequence
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (optional) names of transport orders the transport order depends on.
|
||||
*
|
||||
* @return The (optional) names of transport orders the transport order depends on.
|
||||
*/
|
||||
@Nonnull
|
||||
public Set<String> getDependencyNames() {
|
||||
return Collections.unmodifiableSet(dependencyNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given
|
||||
* (optional) names of transport orders the transport order depends on.
|
||||
*
|
||||
* @param dependencyNames The dependency names.
|
||||
* @return A copy of this object, differing in the given dependency names.
|
||||
*/
|
||||
public TransportOrderCreationTO withDependencyNames(
|
||||
@Nonnull
|
||||
Set<String> dependencyNames
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (optional) name of the vehicle that is supposed to execute the transport order.
|
||||
*
|
||||
* @return The (optional) name of the vehicle that is supposed to execute the transport order.
|
||||
*/
|
||||
@Nullable
|
||||
public String getIntendedVehicleName() {
|
||||
return intendedVehicleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given
|
||||
* (optional) name of the vehicle that is supposed to execute the transport order.
|
||||
*
|
||||
* @param intendedVehicleName The vehicle name.
|
||||
* @return A copy of this object, differing in the given vehicle's name.
|
||||
*/
|
||||
public TransportOrderCreationTO withIntendedVehicleName(
|
||||
@Nullable
|
||||
String intendedVehicleName
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (optional) type of the transport order.
|
||||
*
|
||||
* @return The (optional) type of the transport order.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given (optional) type of the transport order.
|
||||
*
|
||||
* @param type The type.
|
||||
* @return A copy of this object, differing in the given type.
|
||||
*/
|
||||
public TransportOrderCreationTO withType(
|
||||
@Nonnull
|
||||
String type
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the point of time at which execution of the transport order is supposed to be finished.
|
||||
*
|
||||
* @return The point of time at which execution of the transport order is supposed to be finished.
|
||||
*/
|
||||
@Nonnull
|
||||
public Instant getDeadline() {
|
||||
return deadline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the given
|
||||
* point of time at which execution of the transport order is supposed to be finished.
|
||||
*
|
||||
* @param deadline The deadline.
|
||||
* @return A copy of this object, differing in the given deadline.
|
||||
*/
|
||||
public TransportOrderCreationTO withDeadline(
|
||||
@Nonnull
|
||||
Instant deadline
|
||||
) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the transport order is dispensable or not.
|
||||
*
|
||||
* @return Whether the transport order is dispensable or not.
|
||||
*/
|
||||
public boolean isDispensable() {
|
||||
return dispensable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object with the
|
||||
* given indication whether the transport order is dispensable or not.
|
||||
*
|
||||
* @param dispensable The dispensable flag.
|
||||
* @return A copy of this object, differing in the given dispensable flag.
|
||||
*/
|
||||
public TransportOrderCreationTO withDispensable(boolean dispensable) {
|
||||
return new TransportOrderCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
destinations,
|
||||
peripheralReservationToken,
|
||||
wrappingSequence,
|
||||
dependencyNames,
|
||||
intendedVehicleName,
|
||||
type,
|
||||
deadline,
|
||||
dispensable
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
/**
|
||||
* Transfer object classes for transport order objects.
|
||||
*/
|
||||
package org.opentcs.access.to.order;
|
||||
@@ -0,0 +1,6 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
/**
|
||||
* Transfer object classes for domain objects.
|
||||
*/
|
||||
package org.opentcs.access.to;
|
||||
@@ -0,0 +1,295 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.peripherals;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
|
||||
/**
|
||||
* A transfer object describing a peripheral job.
|
||||
*/
|
||||
public class PeripheralJobCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* Indicates whether the name is incomplete and requires to be completed when creating the actual
|
||||
* peripheral job.
|
||||
* (How exactly this is done is decided by the kernel.)
|
||||
*/
|
||||
private final boolean incompleteName;
|
||||
/**
|
||||
* A token that may be used to reserve a peripheral device.
|
||||
* A peripheral device that is reserved for a specific token can only process jobs which match
|
||||
* that reservation token.
|
||||
* This string may not be empty.
|
||||
*/
|
||||
@Nonnull
|
||||
private final String reservationToken;
|
||||
/**
|
||||
* The name of the vehicle for which this peripheral job is to be created.
|
||||
*/
|
||||
@Nullable
|
||||
private final String relatedVehicleName;
|
||||
/**
|
||||
* The name of the transport order for which this peripheral job is to be created.
|
||||
*/
|
||||
@Nullable
|
||||
private final String relatedTransportOrderName;
|
||||
/**
|
||||
* The operation that is to be perfromed by the pripheral device.
|
||||
*/
|
||||
@Nonnull
|
||||
private final PeripheralOperationCreationTO peripheralOperation;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param name The name of this peripheral job.
|
||||
* @param reservationToken The reservation token to be used.
|
||||
* @param peripheralOperation The peripheral operation to be performed.
|
||||
*/
|
||||
public PeripheralJobCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
String reservationToken,
|
||||
@Nonnull
|
||||
PeripheralOperationCreationTO peripheralOperation
|
||||
) {
|
||||
super(name);
|
||||
this.incompleteName = false;
|
||||
this.reservationToken = requireNonNull(reservationToken, "reservationToken");
|
||||
this.relatedVehicleName = null;
|
||||
this.relatedTransportOrderName = null;
|
||||
this.peripheralOperation = requireNonNull(peripheralOperation, "peripheralOperation");
|
||||
}
|
||||
|
||||
private PeripheralJobCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
boolean incompleteName,
|
||||
@Nonnull
|
||||
String reservationToken,
|
||||
@Nullable
|
||||
String relatedVehicleName,
|
||||
@Nullable
|
||||
String relatedTransportOrderName,
|
||||
@Nonnull
|
||||
PeripheralOperationCreationTO peripheralOperation
|
||||
) {
|
||||
super(name, properties);
|
||||
this.incompleteName = incompleteName;
|
||||
this.reservationToken = requireNonNull(reservationToken, "reservationToken");
|
||||
this.relatedVehicleName = relatedVehicleName;
|
||||
this.relatedTransportOrderName = relatedTransportOrderName;
|
||||
this.peripheralOperation = requireNonNull(peripheralOperation, "peripheralOperation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralJobCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new PeripheralJobCreationTO(
|
||||
name,
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
reservationToken,
|
||||
relatedVehicleName,
|
||||
relatedTransportOrderName,
|
||||
peripheralOperation
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralJobCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new PeripheralJobCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
incompleteName,
|
||||
reservationToken,
|
||||
relatedVehicleName,
|
||||
relatedTransportOrderName,
|
||||
peripheralOperation
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralJobCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new PeripheralJobCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
incompleteName,
|
||||
reservationToken,
|
||||
relatedVehicleName,
|
||||
relatedTransportOrderName,
|
||||
peripheralOperation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the name is incomplete and requires to be completed when creating the actual
|
||||
* transport order.
|
||||
* (How exactly this is done is decided by the kernel.)
|
||||
*
|
||||
* @return {@code true} if, and only if, the name is incomplete and requires to be completed
|
||||
* by the kernel.
|
||||
*/
|
||||
public boolean hasIncompleteName() {
|
||||
return incompleteName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given incomplete name flag.
|
||||
*
|
||||
* @param incompleteName The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PeripheralJobCreationTO withIncompleteName(boolean incompleteName) {
|
||||
return new PeripheralJobCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
reservationToken,
|
||||
relatedVehicleName,
|
||||
relatedTransportOrderName,
|
||||
peripheralOperation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token that may be used to reserve a peripheral device.
|
||||
*
|
||||
* @return The token that may be used to reserve a peripheral device.
|
||||
*/
|
||||
public String getReservationToken() {
|
||||
return reservationToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given reservation token.
|
||||
*
|
||||
* @param reservationToken The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PeripheralJobCreationTO withReservationToken(String reservationToken) {
|
||||
return new PeripheralJobCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
reservationToken,
|
||||
relatedVehicleName,
|
||||
relatedTransportOrderName,
|
||||
peripheralOperation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the vehicle for which this peripheral job is to be created.
|
||||
*
|
||||
* @return The name of the vehicle for which this peripheral job is to be created.
|
||||
*/
|
||||
@Nullable
|
||||
public String getRelatedVehicleName() {
|
||||
return relatedVehicleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given related vehicle name.
|
||||
*
|
||||
* @param relatedVehicleName The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PeripheralJobCreationTO withRelatedVehicleName(
|
||||
@Nullable
|
||||
String relatedVehicleName
|
||||
) {
|
||||
return new PeripheralJobCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
reservationToken,
|
||||
relatedVehicleName,
|
||||
relatedTransportOrderName,
|
||||
peripheralOperation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the transport order for which this peripheral job is to be created.
|
||||
*
|
||||
* @return The name of the transport order for which this peripheral job is to be created.
|
||||
*/
|
||||
@Nullable
|
||||
public String getRelatedTransportOrderName() {
|
||||
return relatedTransportOrderName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given related transport order name.
|
||||
*
|
||||
* @param relatedTransportOrderName The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PeripheralJobCreationTO withRelatedTransportOrderName(
|
||||
@Nullable
|
||||
String relatedTransportOrderName
|
||||
) {
|
||||
return new PeripheralJobCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
reservationToken,
|
||||
relatedVehicleName,
|
||||
relatedTransportOrderName,
|
||||
peripheralOperation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the operation that is to be performed by the pripheral device.
|
||||
*
|
||||
* @return The operation that is to be performed by the pripheral device.
|
||||
*/
|
||||
public PeripheralOperationCreationTO getPeripheralOperation() {
|
||||
return peripheralOperation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given peripheral operation.
|
||||
*
|
||||
* @param peripheralOperation The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PeripheralJobCreationTO withPeripheralOperation(
|
||||
PeripheralOperationCreationTO peripheralOperation
|
||||
) {
|
||||
return new PeripheralJobCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
incompleteName,
|
||||
reservationToken,
|
||||
relatedVehicleName,
|
||||
relatedTransportOrderName,
|
||||
peripheralOperation
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.access.to.peripherals;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
import org.opentcs.data.peripherals.PeripheralOperation;
|
||||
|
||||
/**
|
||||
* A transfer object describing an operation to be performed by a peripheral device.
|
||||
*/
|
||||
public class PeripheralOperationCreationTO
|
||||
extends
|
||||
CreationTO
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* The operation to be performed by the peripheral device.
|
||||
*/
|
||||
private final String operation;
|
||||
/**
|
||||
* The name of the location the peripheral device is associated with.
|
||||
*/
|
||||
@Nonnull
|
||||
private final String locationName;
|
||||
/**
|
||||
* The moment at which this operation is to be performed.
|
||||
*/
|
||||
@Nonnull
|
||||
private final PeripheralOperation.ExecutionTrigger executionTrigger;
|
||||
/**
|
||||
* Whether the completion of this operation is required to allow a vehicle to continue driving.
|
||||
*/
|
||||
private final boolean completionRequired;
|
||||
|
||||
/**
|
||||
* Creates a new instance with {@code executionTrigger} set to
|
||||
* {@link PeripheralOperation.ExecutionTrigger#IMMEDIATE} and {@code completionRequired}
|
||||
* set to {@code false}.
|
||||
*
|
||||
* @param operation The operation to be performed by the peripheral device.
|
||||
* @param locationName The name of the location the peripheral device is associated with.
|
||||
*/
|
||||
public PeripheralOperationCreationTO(
|
||||
@Nonnull
|
||||
String operation,
|
||||
@Nonnull
|
||||
String locationName
|
||||
) {
|
||||
super("");
|
||||
this.operation = requireNonNull(operation, "operation");
|
||||
this.locationName = requireNonNull(locationName, "locationName");
|
||||
this.executionTrigger = PeripheralOperation.ExecutionTrigger.IMMEDIATE;
|
||||
this.completionRequired = false;
|
||||
}
|
||||
|
||||
private PeripheralOperationCreationTO(
|
||||
@Nonnull
|
||||
String name,
|
||||
@Nonnull
|
||||
Map<String, String> properties,
|
||||
@Nonnull
|
||||
String operation,
|
||||
@Nonnull
|
||||
String locationName,
|
||||
@Nonnull
|
||||
PeripheralOperation.ExecutionTrigger executionTrigger,
|
||||
boolean completionRequired
|
||||
) {
|
||||
super(name, properties);
|
||||
this.operation = requireNonNull(operation, "operation");
|
||||
this.locationName = requireNonNull(locationName, "locationName");
|
||||
this.executionTrigger = requireNonNull(executionTrigger, "executionTrigger");
|
||||
this.completionRequired = completionRequired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralOperationCreationTO withName(
|
||||
@Nonnull
|
||||
String name
|
||||
) {
|
||||
return new PeripheralOperationCreationTO(
|
||||
name,
|
||||
getModifiableProperties(),
|
||||
operation,
|
||||
locationName,
|
||||
executionTrigger,
|
||||
completionRequired
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralOperationCreationTO withProperties(
|
||||
@Nonnull
|
||||
Map<String, String> properties
|
||||
) {
|
||||
return new PeripheralOperationCreationTO(
|
||||
getName(),
|
||||
properties,
|
||||
operation,
|
||||
locationName,
|
||||
executionTrigger,
|
||||
completionRequired
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeripheralOperationCreationTO withProperty(
|
||||
@Nonnull
|
||||
String key,
|
||||
@Nonnull
|
||||
String value
|
||||
) {
|
||||
return new PeripheralOperationCreationTO(
|
||||
getName(),
|
||||
propertiesWith(key, value),
|
||||
operation,
|
||||
locationName,
|
||||
executionTrigger,
|
||||
completionRequired
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the operation to be performed by the peripheral device.
|
||||
*
|
||||
* @return The operation to be performed by the peripheral device.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given operation.
|
||||
*
|
||||
* @param operation The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PeripheralOperationCreationTO withOperation(
|
||||
@Nonnull
|
||||
String operation
|
||||
) {
|
||||
return new PeripheralOperationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
operation,
|
||||
locationName,
|
||||
executionTrigger,
|
||||
completionRequired
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the location the peripheral device is associated with.
|
||||
*
|
||||
* @return The name of the location the peripheral device is associated with.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getLocationName() {
|
||||
return locationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given location name.
|
||||
*
|
||||
* @param locationName The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PeripheralOperationCreationTO withLocationName(
|
||||
@Nonnull
|
||||
String locationName
|
||||
) {
|
||||
return new PeripheralOperationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
operation,
|
||||
locationName,
|
||||
executionTrigger,
|
||||
completionRequired
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the moment at which this operation is to be performed.
|
||||
*
|
||||
* @return The moment at which this operation is to be performed.
|
||||
*/
|
||||
@Nonnull
|
||||
public PeripheralOperation.ExecutionTrigger getExecutionTrigger() {
|
||||
return executionTrigger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given execution trigger.
|
||||
* <p>
|
||||
* This method should only be used by the vehicle controller component of the baseline project.
|
||||
* </p>
|
||||
*
|
||||
* @param executionTrigger The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PeripheralOperationCreationTO withExecutionTrigger(
|
||||
@Nonnull
|
||||
PeripheralOperation.ExecutionTrigger executionTrigger
|
||||
) {
|
||||
return new PeripheralOperationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
operation,
|
||||
locationName,
|
||||
executionTrigger,
|
||||
completionRequired
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the completion of this operation is required to allow a vehicle to continue
|
||||
* driving.
|
||||
*
|
||||
* @return Whether the completion of this operation is required to allow a vehicle to continue
|
||||
* driving.
|
||||
*/
|
||||
public boolean isCompletionRequired() {
|
||||
return completionRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object, with the given completion required flag.
|
||||
* <p>
|
||||
* This method should only be used by the vehicle controller component of the baseline project.
|
||||
* </p>
|
||||
*
|
||||
* @param completionRequired The value to be set in the copy.
|
||||
* @return A copy of this object, differing in the given value.
|
||||
*/
|
||||
public PeripheralOperationCreationTO withCompletionRequired(boolean completionRequired) {
|
||||
return new PeripheralOperationCreationTO(
|
||||
getName(),
|
||||
getModifiableProperties(),
|
||||
operation,
|
||||
locationName,
|
||||
executionTrigger,
|
||||
completionRequired
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components;
|
||||
|
||||
/**
|
||||
* Defines methods for controlling a generic component's lifecycle.
|
||||
*/
|
||||
public interface Lifecycle {
|
||||
|
||||
/**
|
||||
* (Re-)Initializes this component before it is being used.
|
||||
*/
|
||||
void initialize();
|
||||
|
||||
/**
|
||||
* Checks whether this component is initialized.
|
||||
*
|
||||
* @return <code>true</code> if, and only if, this component is initialized.
|
||||
*/
|
||||
boolean isInitialized();
|
||||
|
||||
/**
|
||||
* Terminates the instance and frees resources.
|
||||
*/
|
||||
void terminate();
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import org.opentcs.components.Lifecycle;
|
||||
import org.opentcs.components.kernel.dipatching.TransportOrderAssignmentException;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.ReroutingType;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
|
||||
/**
|
||||
* This interface declares the methods a dispatcher module for the openTCS
|
||||
* kernel must implement.
|
||||
* <p>
|
||||
* A dispatcher manages the distribution of transport orders among the vehicles
|
||||
* in a system. It is basically event-driven, where an event can be a new
|
||||
* transport order being introduced into the system or a vehicle becoming
|
||||
* available for processing existing orders.
|
||||
* </p>
|
||||
*/
|
||||
public interface Dispatcher
|
||||
extends
|
||||
Lifecycle {
|
||||
|
||||
/**
|
||||
* The key of a parking position property defining its priority.
|
||||
* <p>
|
||||
* Whether and in what way this is respected for assigning a parking position to a vehicle is
|
||||
* implementation-specific.
|
||||
* </p>
|
||||
*/
|
||||
String PROPKEY_PARKING_POSITION_PRIORITY = "tcs:parkingPositionPriority";
|
||||
/**
|
||||
* The key of a vehicle property defining the name of the vehicle's assigned parking position.
|
||||
* <p>
|
||||
* Whether and in what way this is respected for selecting a parking position is
|
||||
* implementation-specific.
|
||||
* </p>
|
||||
*/
|
||||
String PROPKEY_ASSIGNED_PARKING_POSITION = "tcs:assignedParkingPosition";
|
||||
/**
|
||||
* The key of a vehicle property defining the name of the vehicle's preferred parking position.
|
||||
* <p>
|
||||
* Whether and in what way this is respected for selecting a parking position is
|
||||
* implementation-specific.
|
||||
* </p>
|
||||
*/
|
||||
String PROPKEY_PREFERRED_PARKING_POSITION = "tcs:preferredParkingPosition";
|
||||
/**
|
||||
* The key of a vehicle property defining the name of the vehicle's assigned recharge location.
|
||||
* <p>
|
||||
* Whether and in what way this is respected for selecting a recharge location is
|
||||
* implementation-specific.
|
||||
* </p>
|
||||
*/
|
||||
String PROPKEY_ASSIGNED_RECHARGE_LOCATION = "tcs:assignedRechargeLocation";
|
||||
/**
|
||||
* The key of a vehicle property defining the name of the vehicle's preferred recharge location.
|
||||
* <p>
|
||||
* Whether and in what way this is respected for selecting a recharge location is
|
||||
* implementation-specific.
|
||||
* </p>
|
||||
*/
|
||||
String PROPKEY_PREFERRED_RECHARGE_LOCATION = "tcs:preferredRechargeLocation";
|
||||
|
||||
/**
|
||||
* Notifies the dispatcher that it should start the dispatching process.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*/
|
||||
void dispatch();
|
||||
|
||||
/**
|
||||
* Notifies the dispatcher that the given transport order is to be withdrawn/aborted.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param order The transport order to be withdrawn/aborted.
|
||||
* @param immediateAbort Whether the order should be aborted immediately instead of withdrawn.
|
||||
*/
|
||||
void withdrawOrder(
|
||||
@Nonnull
|
||||
TransportOrder order,
|
||||
boolean immediateAbort
|
||||
);
|
||||
|
||||
/**
|
||||
* Notifies the dispatcher that any order a given vehicle might be processing is to be withdrawn.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param vehicle The vehicle whose order is withdrawn.
|
||||
* @param immediateAbort Whether the vehicle's order should be aborted immediately instead of
|
||||
* withdrawn.
|
||||
*/
|
||||
void withdrawOrder(
|
||||
@Nonnull
|
||||
Vehicle vehicle,
|
||||
boolean immediateAbort
|
||||
);
|
||||
|
||||
/**
|
||||
* Notifies the dispatcher of a request to reroute the given vehicle considering the given
|
||||
* rerouting type.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param vehicle The vehicle to be rerouted.
|
||||
* @param reroutingType The type of the requested rerouting.
|
||||
*/
|
||||
void reroute(
|
||||
@Nonnull
|
||||
Vehicle vehicle,
|
||||
@Nonnull
|
||||
ReroutingType reroutingType
|
||||
);
|
||||
|
||||
/**
|
||||
* Notifies the dispatcher to reroute all vehicles considering the given rerouting type.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param reroutingType The type of the requested rerouting.
|
||||
*/
|
||||
void rerouteAll(
|
||||
@Nonnull
|
||||
ReroutingType reroutingType
|
||||
);
|
||||
|
||||
/**
|
||||
* Notifies the dispatcher that it should assign the given transport order (to its intended
|
||||
* vehicle) <em>now</em>.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param transportOrder The transport order to be assigned.
|
||||
* @throws TransportOrderAssignmentException If the given transport order could not be assigned
|
||||
* to its intended vehicle.
|
||||
*/
|
||||
void assignNow(
|
||||
@Nonnull
|
||||
TransportOrder transportOrder
|
||||
)
|
||||
throws TransportOrderAssignmentException;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import org.opentcs.components.Lifecycle;
|
||||
|
||||
/**
|
||||
* Declares the methods that a generic kernel extension must implement.
|
||||
*/
|
||||
public interface KernelExtension
|
||||
extends
|
||||
Lifecycle {
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import java.util.function.Function;
|
||||
import org.opentcs.access.to.CreationTO;
|
||||
|
||||
/**
|
||||
* Provides names for {@link CreationTO}s.
|
||||
*/
|
||||
public interface ObjectNameProvider
|
||||
extends
|
||||
Function<CreationTO, String> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.data.order.OrderSequence;
|
||||
|
||||
/**
|
||||
* Implementations of this interface check whether an order sequence may be removed.
|
||||
*/
|
||||
public interface OrderSequenceCleanupApproval
|
||||
extends
|
||||
Predicate<OrderSequence> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* Implementations of this interface check whether a peripheral job may be removed.
|
||||
*/
|
||||
public interface PeripheralJobCleanupApproval
|
||||
extends
|
||||
Predicate<PeripheralJob> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import org.opentcs.components.Lifecycle;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* This interface declares the methods a peripheral job dispatcher module for the openTCS kernel
|
||||
* must implement.
|
||||
* <p>
|
||||
* A peripheral job dispatcher manages the distribution of peripheral jobs among the peripheral
|
||||
* devices represented by locations in a system. It is basically event-driven, where an event can
|
||||
* be a new peripheral job being introduced into the system or a peripheral device becoming
|
||||
* available for processing existing jobs.
|
||||
* </p>
|
||||
*/
|
||||
public interface PeripheralJobDispatcher
|
||||
extends
|
||||
Lifecycle {
|
||||
|
||||
/**
|
||||
* Notifies the dispatcher that it should start the dispatching process.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*/
|
||||
void dispatch();
|
||||
|
||||
/**
|
||||
* Notifies the dispatcher that any job a peripheral device (represented by the given location)
|
||||
* might be processing is to be withdrawn.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param location The location representing a peripheral device whose job is withdrawn.
|
||||
* @throws IllegalArgumentException If the given peripheral's current job is already in a final
|
||||
* state, or if it is related to a transport order and this transport order is not in a final
|
||||
* state.
|
||||
*/
|
||||
void withdrawJob(
|
||||
@Nonnull
|
||||
Location location
|
||||
)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Notifies the dispatcher that the given peripheral job is to be withdrawn.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param job The job to be withdrawn.
|
||||
* @throws IllegalArgumentException If the given peripheral job is already in a final state, or if
|
||||
* it is related to a transport order and this transport order is not in a final state.
|
||||
*/
|
||||
void withdrawJob(
|
||||
@Nonnull
|
||||
PeripheralJob job
|
||||
)
|
||||
throws IllegalArgumentException;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Marks a query (parameter) object.
|
||||
*
|
||||
* @param <T> The result type.
|
||||
*/
|
||||
public interface Query<T> {
|
||||
|
||||
/**
|
||||
* A convenience class to be used as the result type for queries that do not return any result.
|
||||
*/
|
||||
class Void
|
||||
implements
|
||||
Serializable {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
public Void() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
/**
|
||||
* A responder for generic queries.
|
||||
*/
|
||||
public interface QueryResponder {
|
||||
|
||||
/**
|
||||
* Executes the specified query.
|
||||
*
|
||||
* @param <T> The query/result type.
|
||||
* @param query The query/parameter object.
|
||||
* @return The query result.
|
||||
*/
|
||||
<T> T query(Query<T> query);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import org.opentcs.access.KernelException;
|
||||
|
||||
/**
|
||||
* Thrown when allocating resources for a {@link Scheduler.Client Scheduler.Client} is impossible.
|
||||
*/
|
||||
public class ResourceAllocationException
|
||||
extends
|
||||
KernelException {
|
||||
|
||||
/**
|
||||
* Creates a new ResourceAllocationException with the given detail message.
|
||||
*
|
||||
* @param message The detail message.
|
||||
*/
|
||||
public ResourceAllocationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ResourceAllocationException with the given detail message and
|
||||
* cause.
|
||||
*
|
||||
* @param message The detail message.
|
||||
* @param cause The cause.
|
||||
*/
|
||||
public ResourceAllocationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import org.opentcs.components.Lifecycle;
|
||||
import org.opentcs.data.model.Path;
|
||||
import org.opentcs.data.model.Point;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.DriveOrder;
|
||||
import org.opentcs.data.order.Route;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
import org.opentcs.util.annotations.ScheduledApiChange;
|
||||
|
||||
/**
|
||||
* This interface declares the methods a router module for the openTCS
|
||||
* kernel must implement.
|
||||
* <p>
|
||||
* A router finds routes from a start point to an end point, rating them
|
||||
* according to implementation specific criteria/costs parameters.
|
||||
* </p>
|
||||
*/
|
||||
public interface Router
|
||||
extends
|
||||
Lifecycle {
|
||||
|
||||
/**
|
||||
* The key of a vehicle property defining the group of vehicles that may share the same routing.
|
||||
* <p>
|
||||
* The value is expected to be an integer.
|
||||
* </p>
|
||||
*/
|
||||
String PROPKEY_ROUTING_GROUP = "tcs:routingGroup";
|
||||
/**
|
||||
* The key (prefix) of a path property defining the routing cost when its travelled in forward
|
||||
* direction.
|
||||
* <p>
|
||||
* The value is expected to be a (long) integer.
|
||||
* </p>
|
||||
*/
|
||||
String PROPKEY_ROUTING_COST_FORWARD = "tcs:routingCostForward";
|
||||
/**
|
||||
* The key (prefix) of a path property defining the routing cost when its travelled in reverse
|
||||
* direction.
|
||||
* <p>
|
||||
* The value is expected to be a (long) integer.
|
||||
* </p>
|
||||
*/
|
||||
String PROPKEY_ROUTING_COST_REVERSE = "tcs:routingCostReverse";
|
||||
|
||||
/**
|
||||
* Notifies the router to update its routing topology with respect to the given paths.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param paths The paths to update in the routing topology. An empty set of paths results in the
|
||||
* router updating the entire routing topology.
|
||||
*/
|
||||
void updateRoutingTopology(
|
||||
@Nonnull
|
||||
Set<Path> paths
|
||||
);
|
||||
|
||||
/**
|
||||
* Checks the routability of a given transport order.
|
||||
* <p>
|
||||
* The check for routability is affected by path properties and configured edge evaluators. This
|
||||
* means that whether a transport order is considered routable <em>can</em> change between
|
||||
* consecutive calls to this method.
|
||||
* </p>
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param order The transport order to check for routability.
|
||||
* @return A set of vehicles for which a route for the given transport order
|
||||
* would be computable.
|
||||
*/
|
||||
@Nonnull
|
||||
Set<Vehicle> checkRoutability(
|
||||
@Nonnull
|
||||
TransportOrder order
|
||||
);
|
||||
|
||||
/**
|
||||
* Checks the general routability of a given transport order.
|
||||
* <p>
|
||||
* The check for general routability is <em>not</em> affected by any path properties or any
|
||||
* configured edge evaluators. This means that whether a transport order is considered generally
|
||||
* routable <em>will not</em> change between consecutive calls to this method.
|
||||
* </p>
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param order The transport order to check for routability.
|
||||
* @return {@code true}, if the transport order is generally routable, otherwise {@code false}.
|
||||
*/
|
||||
@ScheduledApiChange(when = "7.0", details = "Default implementation will be removed.")
|
||||
default boolean checkGeneralRoutability(
|
||||
@Nonnull
|
||||
TransportOrder order
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a complete route for a given vehicle that starts on a specified
|
||||
* point and allows the vehicle to process a given transport order.
|
||||
* The route is encapsulated into drive orders which correspond to those drive
|
||||
* orders that the transport order is composed of. The transport order itself
|
||||
* is not modified.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param vehicle The vehicle for which the calculated route must be passable.
|
||||
* @param sourcePoint The position at which the vehicle would start processing
|
||||
* the transport order (i.e. the vehicle's current position).
|
||||
* @param transportOrder The transport order to be processed by the vehicle.
|
||||
* @return A list of drive orders containing the complete calculated route for
|
||||
* the given transport order, passable the given vehicle and starting on the
|
||||
* given point, or the empty optional, if no such route exists.
|
||||
*/
|
||||
@Nonnull
|
||||
Optional<List<DriveOrder>> getRoute(
|
||||
@Nonnull
|
||||
Vehicle vehicle,
|
||||
@Nonnull
|
||||
Point sourcePoint,
|
||||
@Nonnull
|
||||
TransportOrder transportOrder
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns a route from one point to another, passable for a given vehicle.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param vehicle The vehicle for which the route must be passable.
|
||||
* @param sourcePoint The starting point of the route to calculate.
|
||||
* @param destinationPoint The end point of the route to calculate.
|
||||
* @param resourcesToAvoid Resources to avoid when calculating the route.
|
||||
* @return The calculated route, or the empty optional, if a route between the
|
||||
* given points does not exist.
|
||||
*/
|
||||
@Nonnull
|
||||
Optional<Route> getRoute(
|
||||
@Nonnull
|
||||
Vehicle vehicle,
|
||||
@Nonnull
|
||||
Point sourcePoint,
|
||||
@Nonnull
|
||||
Point destinationPoint,
|
||||
@Nonnull
|
||||
Set<TCSResourceReference<?>> resourcesToAvoid
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the costs for travelling a route from one point to another with a
|
||||
* given vehicle.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param vehicle The vehicle for which the route must be passable.
|
||||
* @param sourcePoint The starting point of the route.
|
||||
* @param destinationPoint The end point of the route.
|
||||
* @param resourcesToAvoid Resources to avoid when calculating the route.
|
||||
* @return The costs of the route, or <code>Long.MAX_VALUE</code>, if no such
|
||||
* route exists.
|
||||
*/
|
||||
long getCosts(
|
||||
@Nonnull
|
||||
Vehicle vehicle,
|
||||
@Nonnull
|
||||
Point sourcePoint,
|
||||
@Nonnull
|
||||
Point destinationPoint,
|
||||
@Nonnull
|
||||
Set<TCSResourceReference<?>> resourcesToAvoid
|
||||
);
|
||||
|
||||
/**
|
||||
* Notifies the router of a route being selected for a vehicle.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param vehicle The vehicle for which a route is being selected.
|
||||
* @param driveOrders The drive orders encapsulating the route being selected,
|
||||
* or <code>null</code>, if no route is being selected for the vehicle (i.e.
|
||||
* an existing entry for the given vehicle would be removed).
|
||||
*/
|
||||
void selectRoute(
|
||||
@Nonnull
|
||||
Vehicle vehicle,
|
||||
@Nullable
|
||||
List<DriveOrder> driveOrders
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable view on the selected routes the router knows about.
|
||||
* The returned map contains an entry for each vehicle for which a selected
|
||||
* route is known.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @return An unmodifiable view on the selected routes the router knows about.
|
||||
*/
|
||||
@Nonnull
|
||||
Map<Vehicle, List<DriveOrder>> getSelectedRoutes();
|
||||
|
||||
/**
|
||||
* Returns all points which are currently targeted by any vehicle.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @return A set of all points currently targeted by any vehicle.
|
||||
*/
|
||||
@Nonnull
|
||||
Set<Point> getTargetedPoints();
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.opentcs.components.Lifecycle;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.TCSResource;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
|
||||
/**
|
||||
* Manages resources used by clients (vehicles) to help prevent both collisions and deadlocks.
|
||||
* <p>
|
||||
* Every client usually interacts with the <code>Scheduler</code> according to the following
|
||||
* workflow:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>
|
||||
* Initially, the client calls
|
||||
* {@link #allocateNow(org.opentcs.components.kernel.Scheduler.Client, java.util.Set) allocateNow()}
|
||||
* when a vehicle pops up somewhere in the driving course.
|
||||
* This usually happens either upon kernel startup or when a vehicle communicates its current
|
||||
* position to the kernel for the first time.
|
||||
* </li>
|
||||
* <li>
|
||||
* Once a transport order is assigned to a vehicle, the client calls
|
||||
* {@link #claim(org.opentcs.components.kernel.Scheduler.Client, java.util.List) claim()} with the
|
||||
* complete sequence of resource sets the vehicle needs to process the transport order - usually
|
||||
* each containing a point and the path leading to it.
|
||||
* </li>
|
||||
* <li>
|
||||
* As the vehicle processes the transport order, the client subsequently calls
|
||||
* {@link #allocate(org.opentcs.components.kernel.Scheduler.Client, java.util.Set) allocate()} for
|
||||
* resources needed next (for reaching the next point on the route).
|
||||
* The <code>Scheduler</code> asynchronously calls back either
|
||||
* {@link Client#allocationSuccessful(java.util.Set)} or
|
||||
* {@link Client#allocationFailed(java.util.Set)}, informing the client about the result.
|
||||
* Upon allocating the resources for the client, it also implicitly removes them from the head of
|
||||
* the client's claim sequence.
|
||||
* </li>
|
||||
* <li>
|
||||
* As the vehicle passes points (and paths) on the route, the client calls
|
||||
* {@link #free(org.opentcs.components.kernel.Scheduler.Client, java.util.Set) free()} for resources
|
||||
* it does not need any more, allowing these resources to be allocated by other clients.
|
||||
* </li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* At the end of this process, the client's claim sequence is empty, and only the most recently
|
||||
* allocated resources are still assigned to it, reflecting the vehicle's current position.
|
||||
* (If the vehicle has disappeared from the driving course after processing the transport order, the
|
||||
* client would call {@link #freeAll(org.opentcs.components.kernel.Scheduler.Client) freeAll()} to
|
||||
* inform the <code>Scheduler</code> about this.)
|
||||
* </p>
|
||||
*/
|
||||
public interface Scheduler
|
||||
extends
|
||||
Lifecycle {
|
||||
|
||||
/**
|
||||
* The key of a path property defining the direction in which a vehicle is entering a block when
|
||||
* it's taking the path.
|
||||
*/
|
||||
String PROPKEY_BLOCK_ENTRY_DIRECTION = "tcs:blockEntryDirection";
|
||||
|
||||
/**
|
||||
* Sets/Updates the resource claim for a vehicle.
|
||||
* <p>
|
||||
* <em>Claimed</em> resources are resources that a vehicle will eventually require for executing
|
||||
* its movements in the future, but for which it does not request allocation, yet.
|
||||
* Claiming resources provides information to the scheduler about future allocations <em>and their
|
||||
* intended order</em>, allowing the scheduler to consider these information for its resource
|
||||
* planning.
|
||||
* </p>
|
||||
* <p>
|
||||
* Resources can be claimed by multiple vehicles at the same time.
|
||||
* This is different from allocations:
|
||||
* Only a single vehicle can allocate a resource at the same time.
|
||||
* </p>
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param client The client claiming the resources.
|
||||
* @param resourceSequence The sequence of resources claimed. May be empty to clear the client's
|
||||
* claim.
|
||||
*/
|
||||
void claim(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
List<Set<TCSResource<?>>> resourceSequence
|
||||
);
|
||||
|
||||
/**
|
||||
* Requests allocation of the given resources.
|
||||
* The client will be informed via a callback to
|
||||
* {@link Client#allocationSuccessful(java.util.Set)} or
|
||||
* {@link Client#allocationFailed(java.util.Set)} whether the allocation was successful or not.
|
||||
* <ul>
|
||||
* <li>
|
||||
* Clients may only allocate resources in the order they have previously
|
||||
* {@link #claim(org.opentcs.components.kernel.Scheduler.Client, java.util.List) claim()}ed them.
|
||||
* </li>
|
||||
* <li>
|
||||
* Upon allocation, the scheduler will implicitly remove the set of allocated resources from (the
|
||||
* head of) the client's claim sequence.
|
||||
* </li>
|
||||
* <li>
|
||||
* As a result, a client may only allocate the set of resources at the head of its claim sequence.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param client The client requesting the resources.
|
||||
* @param resources The resources to be allocated.
|
||||
* @throws IllegalArgumentException If the set of resources to be allocated is not equal to the
|
||||
* <em>next</em> set in the sequence of currently claimed resources, or if the client has already
|
||||
* requested resources that have not yet been granted.
|
||||
* @see #claim(org.opentcs.components.kernel.Scheduler.Client, java.util.List)
|
||||
*/
|
||||
void allocate(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Checks if the resulting system state is safe if the given set of resources
|
||||
* would be allocated by the given client <em>immediately</em>.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param client The client requesting the resources.
|
||||
* @param resources The requested resources.
|
||||
* @return {@code true} if the given resources are safe to be allocated by the given client,
|
||||
* otherwise {@code false}.
|
||||
*/
|
||||
boolean mayAllocateNow(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
);
|
||||
|
||||
/**
|
||||
* Informs the scheduler that a set of resources are to be allocated for the given client
|
||||
* <em>immediately</em>.
|
||||
* <p>
|
||||
* Note the following:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>
|
||||
* This method should only be called in urgent/emergency cases, for instance if a vehicle has been
|
||||
* moved to a different point manually, which has to be reflected by resource allocation in the
|
||||
* scheduler.
|
||||
* </li>
|
||||
* <li>
|
||||
* Unlike
|
||||
* {@link #allocate(org.opentcs.components.kernel.Scheduler.Client, java.util.Set) allocate()},
|
||||
* this method does not block, i.e. the operation happens synchronously.
|
||||
* </li>
|
||||
* <li>
|
||||
* This method does <em>not</em> implicitly deallocate or unclaim any other resources for the
|
||||
* client.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param client The client requesting the resources.
|
||||
* @param resources The resources requested.
|
||||
* @throws ResourceAllocationException If it's impossible to allocate the given set of resources
|
||||
* for the given client.
|
||||
*/
|
||||
void allocateNow(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
)
|
||||
throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
* Releases a set of resources allocated by a client.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param client The client releasing the resources.
|
||||
* @param resources The resources released. Any resources in the given set not allocated by the
|
||||
* given client are ignored.
|
||||
*/
|
||||
void free(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
);
|
||||
|
||||
/**
|
||||
* Releases all resources allocated by the given client.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param client The client.
|
||||
*/
|
||||
void freeAll(
|
||||
@Nonnull
|
||||
Client client
|
||||
);
|
||||
|
||||
/**
|
||||
* Releases all pending resource allocations for the given client.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param client The client.
|
||||
*/
|
||||
void clearPendingAllocations(
|
||||
@Nonnull
|
||||
Client client
|
||||
);
|
||||
|
||||
/**
|
||||
* Explicitly triggers a rescheduling run during which the scheduler tries to allocate resources
|
||||
* for all waiting clients.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*/
|
||||
void reschedule();
|
||||
|
||||
/**
|
||||
* Returns all resource allocations as a map of client IDs to resources.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @return All resource allocations as a map of client IDs to resources.
|
||||
*/
|
||||
@Nonnull
|
||||
Map<String, Set<TCSResource<?>>> getAllocations();
|
||||
|
||||
/**
|
||||
* Informs the scheduler that a set of resources was successfully prepared in order of allocating
|
||||
* them to a client.
|
||||
* <p>
|
||||
* This method is supposed to be called only from the kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param module The module a preparation was necessary for.
|
||||
* @param client The client that requested the preparation/allocation.
|
||||
* @param resources The resources that are now prepared for the client.
|
||||
*/
|
||||
void preparationSuccessful(
|
||||
@Nonnull
|
||||
Module module,
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
);
|
||||
|
||||
/**
|
||||
* Defines callback methods for clients of the resource scheduler.
|
||||
*/
|
||||
interface Client {
|
||||
|
||||
/**
|
||||
* Returns an ID string for this client.
|
||||
* The returned string should be unique among all clients in the system.
|
||||
*
|
||||
* @return An unique ID string for this client.
|
||||
*/
|
||||
@Nonnull
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns a reference to the {@link Vehicle} that this client is related to.
|
||||
*
|
||||
* @return A reference to the {@link Vehicle} that this client is related to or {@code null}, if
|
||||
* this client is not related to any {@link Vehicle}.
|
||||
*/
|
||||
@Nullable
|
||||
TCSObjectReference<Vehicle> getRelatedVehicle();
|
||||
|
||||
/**
|
||||
* Called when resources have been reserved for this client.
|
||||
*
|
||||
* @param resources The resources reserved.
|
||||
* @return <code>true</code> if, and only if, this client accepts the resources allocated. A
|
||||
* return value of <code>false</code> indicates this client does not need the given resources
|
||||
* (any more), freeing them implicitly, but not restoring any previous claim.
|
||||
*/
|
||||
boolean allocationSuccessful(
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
);
|
||||
|
||||
/**
|
||||
* Called if it was impossible to allocate a requested set of resources for this client.
|
||||
*
|
||||
* @param resources The resources which could not be reserved.
|
||||
*/
|
||||
void allocationFailed(
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A scheduler module.
|
||||
*/
|
||||
interface Module
|
||||
extends
|
||||
Lifecycle {
|
||||
|
||||
/**
|
||||
* Informs this module about a client's current allocation state.
|
||||
*
|
||||
* @param client The client.
|
||||
* @param alloc The client's currently allocated resources.
|
||||
* @param remainingClaim The client's remaining claim.
|
||||
*/
|
||||
void setAllocationState(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> alloc,
|
||||
@Nonnull
|
||||
List<Set<TCSResource<?>>> remainingClaim
|
||||
);
|
||||
|
||||
/**
|
||||
* Checks if the resulting system state is safe if the given set of resources
|
||||
* would be allocated by the given resource user.
|
||||
*
|
||||
* @param client The <code>ResourceUser</code> requesting resources set.
|
||||
* @param resources The requested resources.
|
||||
* @return <code>true</code> if this module thinks the given resources may be allocated for the
|
||||
* given client.
|
||||
*/
|
||||
boolean mayAllocate(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
);
|
||||
|
||||
/**
|
||||
* Lets this module prepare the given resources so they can be allocated to a client.
|
||||
*
|
||||
* @param client The client the resources are being prepared for.
|
||||
* @param resources The resources to be prepared.
|
||||
*/
|
||||
void prepareAllocation(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
);
|
||||
|
||||
/**
|
||||
* Checks if this module is done preparing the given resources for a client.
|
||||
*
|
||||
* @param client The client the resources are being prepared for.
|
||||
* @param resources The resources to be checked.
|
||||
* @return <code>true</code> if the resoruces are prepared for a client.
|
||||
*/
|
||||
boolean hasPreparedAllocation(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
);
|
||||
|
||||
/**
|
||||
* Informs this module about resources being fully released by a client.
|
||||
*
|
||||
* @param client The client releasing the resources.
|
||||
* @param resources The resources being released.
|
||||
*/
|
||||
void allocationReleased(
|
||||
@Nonnull
|
||||
Client client,
|
||||
@Nonnull
|
||||
Set<TCSResource<?>> resources
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
|
||||
/**
|
||||
* Implementations of this interface check whether a transport order may be removed.
|
||||
*/
|
||||
public interface TransportOrderCleanupApproval
|
||||
extends
|
||||
Predicate<TransportOrder> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.dipatching;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.opentcs.util.Assertions.checkArgument;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
|
||||
/**
|
||||
* Thrown when a {@link TransportOrder} could not be assigned to a {@link Vehicle}.
|
||||
*/
|
||||
public class TransportOrderAssignmentException
|
||||
extends
|
||||
KernelRuntimeException {
|
||||
|
||||
private final TCSObjectReference<TransportOrder> transportOrder;
|
||||
private final TCSObjectReference<Vehicle> vehicle;
|
||||
private final TransportOrderAssignmentVeto transportOrderAssignmentVeto;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param transportOrder The transport order.
|
||||
* @param vehicle The vehicle.
|
||||
* @param transportOrderAssignmentVeto The reason why the transport order could not be assigned
|
||||
* to the vehicle.
|
||||
*/
|
||||
public TransportOrderAssignmentException(
|
||||
@Nonnull
|
||||
TCSObjectReference<TransportOrder> transportOrder,
|
||||
@Nullable
|
||||
TCSObjectReference<Vehicle> vehicle,
|
||||
@Nonnull
|
||||
TransportOrderAssignmentVeto transportOrderAssignmentVeto
|
||||
) {
|
||||
super(
|
||||
"Could not assign transport order '" + transportOrder.getName() + "' to vehicle '"
|
||||
+ (vehicle != null ? vehicle.getName() : "null") + "': "
|
||||
+ transportOrderAssignmentVeto.name()
|
||||
);
|
||||
// This exception is reasonable only for actual assignment vetos.
|
||||
checkArgument(
|
||||
transportOrderAssignmentVeto != TransportOrderAssignmentVeto.NO_VETO,
|
||||
"Invalid assignment veto for exception: " + transportOrderAssignmentVeto
|
||||
);
|
||||
this.transportOrder = requireNonNull(transportOrder, "transportOrder");
|
||||
this.vehicle = vehicle;
|
||||
this.transportOrderAssignmentVeto = requireNonNull(
|
||||
transportOrderAssignmentVeto,
|
||||
"transportOrderAssignmentVeto"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transport order.
|
||||
*
|
||||
* @return The transport order.
|
||||
*/
|
||||
@Nonnull
|
||||
public TCSObjectReference<TransportOrder> getTransportOrder() {
|
||||
return transportOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vehicle.
|
||||
*
|
||||
* @return The vehicle.
|
||||
*/
|
||||
@Nullable
|
||||
public TCSObjectReference<Vehicle> getVehicle() {
|
||||
return vehicle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reason why a transport order assignment was not possible.
|
||||
*
|
||||
* @return The reason why a transport order assignment was not possible.
|
||||
*/
|
||||
@Nonnull
|
||||
public TransportOrderAssignmentVeto getTransportOrderAssignmentVeto() {
|
||||
return transportOrderAssignmentVeto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.dipatching;
|
||||
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.OrderSequence;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
|
||||
/**
|
||||
* Defines reasons for a transport order assignment not being possible.
|
||||
*/
|
||||
public enum TransportOrderAssignmentVeto {
|
||||
|
||||
/**
|
||||
* There is no reason that prevents the transport order assignment.
|
||||
*/
|
||||
NO_VETO,
|
||||
/**
|
||||
* The transport order's {@link TransportOrder.State} is invalid (e.g. because it's not in state
|
||||
* {@link TransportOrder.State#DISPATCHABLE}).
|
||||
*/
|
||||
TRANSPORT_ORDER_STATE_INVALID,
|
||||
/**
|
||||
* The transport order is part of an {@link OrderSequence}.
|
||||
*/
|
||||
TRANSPORT_ORDER_PART_OF_ORDER_SEQUENCE,
|
||||
/**
|
||||
* The transport order has its intended vehicle not set.
|
||||
*/
|
||||
TRANSPORT_ORDER_INTENDED_VEHICLE_NOT_SET,
|
||||
/**
|
||||
* The {@link Vehicle.ProcState} of the vehicle to assign the transport order to is invalid (e.g.
|
||||
* because it's not {@link Vehicle.ProcState#IDLE}).
|
||||
*/
|
||||
VEHICLE_PROCESSING_STATE_INVALID,
|
||||
/**
|
||||
* The {@link Vehicle.State} of the vehicle to assign the transport order to is invalid (e.g.
|
||||
* because it's neither {@link Vehicle.State#IDLE} nor {@link Vehicle.State#CHARGING}).
|
||||
*/
|
||||
VEHICLE_STATE_INVALID,
|
||||
/**
|
||||
* The {@link Vehicle.IntegrationLevel} of the vehicle to assign the transport order to is invalid
|
||||
* (e.g. because it's not {@link Vehicle.IntegrationLevel#TO_BE_UTILIZED}).
|
||||
*/
|
||||
VEHICLE_INTEGRATION_LEVEL_INVALID,
|
||||
/**
|
||||
* The current position of the vehicle to assign the transport order to is unknown.
|
||||
*/
|
||||
VEHICLE_CURRENT_POSITION_UNKNOWN,
|
||||
/**
|
||||
* The vehicle to assign the transport order to is processing an {@link OrderSequence}.
|
||||
*/
|
||||
VEHICLE_PROCESSING_ORDER_SEQUENCE,
|
||||
/**
|
||||
* A generic (dispatcher implementation-specific) reason that prevents the transport order
|
||||
* assignment.
|
||||
*/
|
||||
GENERIC_VETO;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
/**
|
||||
* Interfaces for pluggable strategies and other components for a kernel application.
|
||||
*/
|
||||
package org.opentcs.components.kernel;
|
||||
@@ -0,0 +1,88 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.routing;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import org.opentcs.data.model.Path;
|
||||
|
||||
/**
|
||||
* A wrapper for {@link Path}s that can be used to build routing graphs.
|
||||
*/
|
||||
public class Edge {
|
||||
|
||||
/**
|
||||
* The path in the model that is traversed on this edge.
|
||||
*/
|
||||
private final Path path;
|
||||
/**
|
||||
* Whether the path is travelled in reverse direction.
|
||||
*/
|
||||
private final boolean travellingReverse;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param modelPath The path in the model that is traversed on this edge.
|
||||
* @param travellingReverse Whether the path is travelled in reverse direction.
|
||||
*/
|
||||
public Edge(
|
||||
@Nonnull
|
||||
Path modelPath,
|
||||
boolean travellingReverse
|
||||
) {
|
||||
this.path = requireNonNull(modelPath, "modelPath");
|
||||
this.travellingReverse = travellingReverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path in the model that is traversed on this edge.
|
||||
*
|
||||
* @return The path in the model that is traversed on this edge.
|
||||
*/
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the path is travelled in reverse direction.
|
||||
*
|
||||
* @return Whether the path is travelled in reverse direction.
|
||||
*/
|
||||
public boolean isTravellingReverse() {
|
||||
return travellingReverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source vertex of this edge.
|
||||
*
|
||||
* @return The source vertex of this edge.
|
||||
*/
|
||||
public String getSourceVertex() {
|
||||
return isTravellingReverse()
|
||||
? path.getDestinationPoint().getName()
|
||||
: path.getSourcePoint().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target vertex of this edge.
|
||||
*
|
||||
* @return The target vertex of this edge.
|
||||
*/
|
||||
public String getTargetVertex() {
|
||||
return isTravellingReverse()
|
||||
? path.getSourcePoint().getName()
|
||||
: path.getDestinationPoint().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Edge{"
|
||||
+ "path=" + path + ", "
|
||||
+ "travellingReverse=" + travellingReverse + ", "
|
||||
+ "sourceVertex=" + getSourceVertex() + ", "
|
||||
+ "targetVertex=" + getTargetVertex()
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.routing;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
|
||||
/**
|
||||
* Computes the weight of edges in the routing graph.
|
||||
*/
|
||||
public interface EdgeEvaluator {
|
||||
|
||||
/**
|
||||
* Called when/before computation of a routing graph starts.
|
||||
*
|
||||
* @param vehicle The vehicle for which the routing graph is computed.
|
||||
*/
|
||||
void onGraphComputationStart(
|
||||
@Nonnull
|
||||
Vehicle vehicle
|
||||
);
|
||||
|
||||
/**
|
||||
* Called when/after a computation of a routing graph is done.
|
||||
*
|
||||
* @param vehicle The vehicle for which the routing graph is computed.
|
||||
*/
|
||||
void onGraphComputationEnd(
|
||||
@Nonnull
|
||||
Vehicle vehicle
|
||||
);
|
||||
|
||||
/**
|
||||
* Computes the weight of an edge in the routing graph.
|
||||
*
|
||||
* @param edge The edge.
|
||||
* @param vehicle The vehicle for which to compute the edge's weight.
|
||||
* @return The computed weight of the given edge.
|
||||
* A value of {@code Double.POSITIVE_INFINITY} indicates that the edge is to be excluded from
|
||||
* routing.
|
||||
* Note that negative weights might not be handled well by the respective routing algorithm used.
|
||||
*/
|
||||
double computeWeight(
|
||||
@Nonnull
|
||||
Edge edge,
|
||||
@Nonnull
|
||||
Vehicle vehicle
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.routing;
|
||||
|
||||
import java.util.function.Function;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
|
||||
/**
|
||||
* Determines the routing group for a {@link Vehicle} instance.
|
||||
*/
|
||||
public interface GroupMapper
|
||||
extends
|
||||
Function<Vehicle, String> {
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.components.kernel.Dispatcher;
|
||||
import org.opentcs.components.kernel.dipatching.TransportOrderAssignmentException;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.ReroutingType;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
import org.opentcs.data.order.TransportOrder.State;
|
||||
|
||||
/**
|
||||
* Provides methods concerning the {@link Dispatcher}.
|
||||
*/
|
||||
public interface DispatcherService {
|
||||
|
||||
/**
|
||||
* Explicitly trigger the dispatching process.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void dispatch()
|
||||
throws KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Withdraw any order that a vehicle might be processing.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param immediateAbort If {@code false}, this method once will initiate the withdrawal, leaving
|
||||
* the transport order assigned to the vehicle until it has finished the movements that it has
|
||||
* already been ordered to execute. The transport order's state will change to
|
||||
* {@link State#WITHDRAWN}. If {@code true}, the dispatcher will withdraw the order from the
|
||||
* vehicle without further waiting.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void withdrawByVehicle(TCSObjectReference<Vehicle> ref, boolean immediateAbort)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Withdraw the referenced order.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param ref A reference to the transport order to be withdrawn.
|
||||
* @param immediateAbort If {@code false}, this method once will initiate the withdrawal, leaving
|
||||
* the transport order assigned to the vehicle until it has finished the movements that it has
|
||||
* already been ordered to execute. The transport order's state will change to
|
||||
* {@link State#WITHDRAWN}. If {@code true}, the dispatcher will withdraw the order from the
|
||||
* vehicle without further waiting.
|
||||
* @throws ObjectUnknownException If the referenced transport order does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void withdrawByTransportOrder(TCSObjectReference<TransportOrder> ref, boolean immediateAbort)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Explicitly trigger a rerouting for the given vehicles.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param ref The vehicle to be rerouted.
|
||||
* @param reroutingType The type of the requested rerouting.
|
||||
*/
|
||||
void reroute(
|
||||
@Nonnull
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
@Nonnull
|
||||
ReroutingType reroutingType
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Explicitly trigger a rerouting for all vehicles.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param reroutingType The type of rerouting.
|
||||
*/
|
||||
void rerouteAll(
|
||||
@Nonnull
|
||||
ReroutingType reroutingType
|
||||
);
|
||||
|
||||
/**
|
||||
* Assign the referenced transport order (to its intended vehicle) <em>now</em>.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param ref The transport order to be assigned.
|
||||
* @throws ObjectUnknownException If the referenced transport order does not exist.
|
||||
* @throws TransportOrderAssignmentException If the given transport order could not be assigned
|
||||
* to its intended vehicle.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void assignNow(TCSObjectReference<TransportOrder> ref)
|
||||
throws ObjectUnknownException,
|
||||
TransportOrderAssignmentException,
|
||||
KernelRuntimeException;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* Declares the methods the peripheral job service must provide which are not accessible to remote
|
||||
* peers.
|
||||
*/
|
||||
public interface InternalPeripheralJobService
|
||||
extends
|
||||
PeripheralJobService {
|
||||
|
||||
/**
|
||||
* Updates a peripheral job's state.
|
||||
* Note that peripheral job states are intended to be manipulated by the peripheral job
|
||||
* dispatcher only.
|
||||
* Calling this method from any other parts of the kernel may result in undefined behaviour.
|
||||
*
|
||||
* @param ref A reference to the peripheral job to be modified.
|
||||
* @param state The peripheral job's new state.
|
||||
* @throws ObjectUnknownException If the referenced peripheral job does not exist.
|
||||
*/
|
||||
void updatePeripheralJobState(TCSObjectReference<PeripheralJob> ref, PeripheralJob.State state)
|
||||
throws ObjectUnknownException;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.model.PeripheralInformation;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* Declares the methods the peripheral service must provide which are not accessible to remote
|
||||
* peers.
|
||||
*/
|
||||
public interface InternalPeripheralService
|
||||
extends
|
||||
PeripheralService {
|
||||
|
||||
/**
|
||||
* Updates a peripheral's processing state.
|
||||
*
|
||||
* @param ref A reference to the location to be modified.
|
||||
* @param state The peripheral's new processing state.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
*/
|
||||
void updatePeripheralProcState(
|
||||
TCSResourceReference<Location> ref,
|
||||
PeripheralInformation.ProcState state
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a peripheral's reservation token.
|
||||
*
|
||||
* @param ref A reference to the location to be modified.
|
||||
* @param reservationToken The peripheral's new reservation token.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
*/
|
||||
void updatePeripheralReservationToken(
|
||||
TCSResourceReference<Location> ref,
|
||||
String reservationToken
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a peripheral's state.
|
||||
*
|
||||
* @param ref A reference to the location to be modified.
|
||||
* @param state The peripheral's new state.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
*/
|
||||
void updatePeripheralState(
|
||||
TCSResourceReference<Location> ref,
|
||||
PeripheralInformation.State state
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a peripheral's current peripheral job.
|
||||
*
|
||||
* @param ref A reference to the location to be modified.
|
||||
* @param peripheralJob A reference to the peripheral job the peripheral device processes.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
*/
|
||||
void updatePeripheralJob(
|
||||
TCSResourceReference<Location> ref,
|
||||
TCSObjectReference<PeripheralJob> peripheralJob
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import java.util.Set;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.model.TCSResource;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
|
||||
/**
|
||||
* Declares the methods the plant model service must provide which are not accessible to remote
|
||||
* peers.
|
||||
*/
|
||||
public interface InternalPlantModelService
|
||||
extends
|
||||
PlantModelService {
|
||||
|
||||
/**
|
||||
* Expands a set of resources <em>A</em> to a set of resources <em>B</em>.
|
||||
* <em>B</em> contains the resources in <em>A</em> with blocks expanded to their actual members.
|
||||
* The given set is not modified.
|
||||
*
|
||||
* @param resources The set of resources to be expanded.
|
||||
* @return The given set with resources expanded.
|
||||
* @throws ObjectUnknownException If any of the referenced objects does not exist.
|
||||
*/
|
||||
Set<TCSResource<?>> expandResources(Set<TCSResourceReference<?>> resources)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Loads the saved model into the kernel.
|
||||
* If there is no saved model, a new empty model will be loaded.
|
||||
*
|
||||
* @throws IllegalStateException If the model cannot be loaded.
|
||||
*/
|
||||
void loadPlantModel()
|
||||
throws IllegalStateException;
|
||||
|
||||
/**
|
||||
* Saves the current model under the given name.
|
||||
* If there is a saved model, it will be overwritten.
|
||||
*
|
||||
* @throws IllegalStateException If the model could not be persisted for some reason.
|
||||
*/
|
||||
void savePlantModel()
|
||||
throws IllegalStateException;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import org.opentcs.components.kernel.Query;
|
||||
import org.opentcs.components.kernel.QueryResponder;
|
||||
|
||||
/**
|
||||
* Declares query-related methods not accessible to remote peers.
|
||||
*/
|
||||
public interface InternalQueryService
|
||||
extends
|
||||
QueryService {
|
||||
|
||||
/**
|
||||
* Registers the given responder for handling queries of the given type.
|
||||
*
|
||||
* @param clazz The query type.
|
||||
* @param responder The responder to handle the queries.
|
||||
*/
|
||||
void registerResponder(
|
||||
@Nonnull
|
||||
Class<? extends Query<?>> clazz,
|
||||
@Nonnull
|
||||
QueryResponder responder
|
||||
);
|
||||
|
||||
/**
|
||||
* Unregisters the responder for the given type.
|
||||
*
|
||||
* @param clazz The query type.
|
||||
*/
|
||||
void unregisterResponder(
|
||||
@Nonnull
|
||||
Class<? extends Query<?>> clazz
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import java.util.List;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.DriveOrder;
|
||||
import org.opentcs.data.order.OrderSequence;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
|
||||
/**
|
||||
* Declares the methods the transport order service must provide which are not accessible to remote
|
||||
* peers.
|
||||
*/
|
||||
public interface InternalTransportOrderService
|
||||
extends
|
||||
TransportOrderService {
|
||||
|
||||
/**
|
||||
* Sets an order sequence's finished flag.
|
||||
*
|
||||
* @param ref A reference to the order sequence to be modified.
|
||||
* @throws ObjectUnknownException If the referenced transport order is not in this pool.
|
||||
*/
|
||||
void markOrderSequenceFinished(TCSObjectReference<OrderSequence> ref)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates an order sequence's finished index.
|
||||
*
|
||||
* @param ref A reference to the order sequence to be modified.
|
||||
* @param index The sequence's new finished index.
|
||||
* @throws ObjectUnknownException If the referenced transport order is not in this pool.
|
||||
*/
|
||||
void updateOrderSequenceFinishedIndex(TCSObjectReference<OrderSequence> ref, int index)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates an order sequence's processing vehicle.
|
||||
*
|
||||
* @param seqRef A reference to the order sequence to be modified.
|
||||
* @param vehicleRef A reference to the vehicle processing the order sequence.
|
||||
* @throws ObjectUnknownException If the referenced transport order is not in this pool.
|
||||
*/
|
||||
void updateOrderSequenceProcessingVehicle(
|
||||
TCSObjectReference<OrderSequence> seqRef,
|
||||
TCSObjectReference<Vehicle> vehicleRef
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a transport order's list of drive orders.
|
||||
*
|
||||
* @param ref A reference to the transport order to be modified.
|
||||
* @param driveOrders The drive orders containing the data to be copied into this transport
|
||||
* order's drive orders.
|
||||
* @throws ObjectUnknownException If the referenced transport order does not exist.
|
||||
*/
|
||||
void updateTransportOrderDriveOrders(
|
||||
TCSObjectReference<TransportOrder> ref,
|
||||
List<DriveOrder> driveOrders
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a transport order's current drive order.
|
||||
* Marks the current drive order as finished, adds it to the list of past drive orders and sets
|
||||
* the current drive order to the next one of the list of future drive orders (or {@code null},
|
||||
* if that list is empty).
|
||||
* Also implicitly sets the {@link TransportOrder#getCurrentRouteStepIndex() transport order's
|
||||
* current route step index} to {@link TransportOrder#ROUTE_STEP_INDEX_DEFAULT}.
|
||||
* If the current drive order is {@code null} because all drive orders have been finished
|
||||
* already or none has been started, yet, nothing happens.
|
||||
*
|
||||
* @param ref A reference to the transport order to be modified.
|
||||
* @throws ObjectUnknownException If the referenced transport order is not in this pool.
|
||||
*/
|
||||
void updateTransportOrderNextDriveOrder(TCSObjectReference<TransportOrder> ref)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a transport order's index of the last route step travelled for the currently processed
|
||||
* drive order.
|
||||
*
|
||||
* @param ref A reference to the transport order to be modified.
|
||||
* @param index The new index.
|
||||
* @throws ObjectUnknownException If the referenced transport order does not exist.
|
||||
*/
|
||||
void updateTransportOrderCurrentRouteStepIndex(
|
||||
TCSObjectReference<TransportOrder> ref,
|
||||
int index
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a transport order's processing vehicle.
|
||||
*
|
||||
* @param orderRef A reference to the transport order to be modified.
|
||||
* @param vehicleRef A reference to the vehicle processing the order.
|
||||
* @param driveOrders The drive orders containing the data to be copied into this transport
|
||||
* order's drive orders.
|
||||
* @throws ObjectUnknownException If the referenced transport order does not exist.
|
||||
* @throws IllegalArgumentException If the destinations of the given drive orders do not match
|
||||
* the destinations of the drive orders in this transport order.
|
||||
*/
|
||||
void updateTransportOrderProcessingVehicle(
|
||||
TCSObjectReference<TransportOrder> orderRef,
|
||||
TCSObjectReference<Vehicle> vehicleRef,
|
||||
List<DriveOrder> driveOrders
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Updates a transport order's state.
|
||||
* Note that transport order states are intended to be manipulated by the dispatcher only.
|
||||
* Calling this method from any other parts of the kernel may result in undefined behaviour.
|
||||
*
|
||||
* @param ref A reference to the transport order to be modified.
|
||||
* @param state The transport order's new state.
|
||||
* @throws ObjectUnknownException If the referenced transport order does not exist.
|
||||
*/
|
||||
void updateTransportOrderState(
|
||||
TCSObjectReference<TransportOrder> ref,
|
||||
TransportOrder.State state
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.BoundingBox;
|
||||
import org.opentcs.data.model.Point;
|
||||
import org.opentcs.data.model.Pose;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.data.model.Triple;
|
||||
import org.opentcs.data.model.Vehicle;
|
||||
import org.opentcs.data.order.OrderSequence;
|
||||
import org.opentcs.data.order.TransportOrder;
|
||||
import org.opentcs.drivers.vehicle.LoadHandlingDevice;
|
||||
import org.opentcs.util.annotations.ScheduledApiChange;
|
||||
|
||||
/**
|
||||
* Declares the methods the vehicle service must provide which are not accessible to remote peers.
|
||||
*/
|
||||
public interface InternalVehicleService
|
||||
extends
|
||||
VehicleService {
|
||||
|
||||
/**
|
||||
* Updates a vehicle's energy level.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param energyLevel The vehicle's new energy level.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleEnergyLevel(TCSObjectReference<Vehicle> ref, int energyLevel)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a vehicle's load handling devices.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param devices The vehicle's new load handling devices.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleLoadHandlingDevices(
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
List<LoadHandlingDevice> devices
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates the point which a vehicle is expected to occupy next.
|
||||
*
|
||||
* @param vehicleRef A reference to the vehicle to be modified.
|
||||
* @param pointRef A reference to the point which the vehicle is expected to occupy next.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleNextPosition(
|
||||
TCSObjectReference<Vehicle> vehicleRef,
|
||||
TCSObjectReference<Point> pointRef
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a vehicle's order sequence.
|
||||
*
|
||||
* @param vehicleRef A reference to the vehicle to be modified.
|
||||
* @param sequenceRef A reference to the order sequence the vehicle processes.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleOrderSequence(
|
||||
TCSObjectReference<Vehicle> vehicleRef,
|
||||
TCSObjectReference<OrderSequence> sequenceRef
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates the vehicle's current orientation angle (-360..360 degrees, or {@link Double#NaN}, if
|
||||
* the vehicle doesn't provide an angle).
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param angle The vehicle's orientation angle.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
* @deprecated Use {@link #updateVehiclePose(TCSObjectReference,Pose)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
void updateVehicleOrientationAngle(TCSObjectReference<Vehicle> ref, double angle)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Places a vehicle on a point.
|
||||
*
|
||||
* @param vehicleRef A reference to the vehicle to be modified.
|
||||
* @param pointRef A reference to the point on which the vehicle is to be placed.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehiclePosition(
|
||||
TCSObjectReference<Vehicle> vehicleRef,
|
||||
TCSObjectReference<Point> pointRef
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates the vehicle's current precise position in mm.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param position The vehicle's precise position in mm.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
* @deprecated Use {@link #updateVehiclePose(TCSObjectReference,Pose)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
void updateVehiclePrecisePosition(TCSObjectReference<Vehicle> ref, Triple position)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates the vehicle's pose.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param pose The vehicle's new pose.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
@ScheduledApiChange(when = "7.0", details = "Default implementation will be removed.")
|
||||
default void updateVehiclePose(TCSObjectReference<Vehicle> ref, Pose pose)
|
||||
throws ObjectUnknownException {
|
||||
requireNonNull(ref, "ref");
|
||||
requireNonNull(pose, "pose");
|
||||
|
||||
updateVehiclePrecisePosition(ref, pose.getPosition());
|
||||
updateVehicleOrientationAngle(ref, pose.getOrientationAngle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a vehicle's processing state.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param state The vehicle's new processing state.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleProcState(TCSObjectReference<Vehicle> ref, Vehicle.ProcState state)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a vehicle's recharge operation.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param rechargeOperation The vehicle's new recharge action.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleRechargeOperation(TCSObjectReference<Vehicle> ref, String rechargeOperation)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a vehicle's claimed resources.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param resources The new resources.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleClaimedResources(
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
List<Set<TCSResourceReference<?>>> resources
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a vehicle's allocated resources.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param resources The new resources.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleAllocatedResources(
|
||||
TCSObjectReference<Vehicle> ref,
|
||||
List<Set<TCSResourceReference<?>>> resources
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a vehicle's state.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param state The vehicle's new state.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleState(TCSObjectReference<Vehicle> ref, Vehicle.State state)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates a vehicle's length.
|
||||
*
|
||||
* @param ref A reference to the vehicle to be modified.
|
||||
* @param length The vehicle's new length.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
* @deprecated Use {@link #updateVehicleBoundingBox(TCSObjectReference, BoundingBox)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ScheduledApiChange(when = "7.0", details = "Will be removed.")
|
||||
void updateVehicleLength(TCSObjectReference<Vehicle> ref, int length)
|
||||
throws ObjectUnknownException;
|
||||
|
||||
/**
|
||||
* Updates the vehicle's bounding box.
|
||||
*
|
||||
* @param ref A reference to the vehicle.
|
||||
* @param boundingBox The vehicle's new bounding box (in mm).
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
@ScheduledApiChange(when = "7.0", details = "Default implementation will be removed.")
|
||||
default void updateVehicleBoundingBox(TCSObjectReference<Vehicle> ref, BoundingBox boundingBox)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException {
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a vehicle's transport order.
|
||||
*
|
||||
* @param vehicleRef A reference to the vehicle to be modified.
|
||||
* @param orderRef A reference to the transport order the vehicle processes.
|
||||
* @throws ObjectUnknownException If the referenced vehicle does not exist.
|
||||
*/
|
||||
void updateVehicleTransportOrder(
|
||||
TCSObjectReference<Vehicle> vehicleRef,
|
||||
TCSObjectReference<TransportOrder> orderRef
|
||||
)
|
||||
throws ObjectUnknownException;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.data.notification.UserNotification;
|
||||
|
||||
/**
|
||||
* Provides methods concerning {@link UserNotification}s.
|
||||
*/
|
||||
public interface NotificationService {
|
||||
|
||||
/**
|
||||
* Returns a list of user notifications.
|
||||
*
|
||||
* @param predicate A filter predicate that accepts the user notifications to be returned. May be
|
||||
* {@code null} to return all existing user notifications.
|
||||
* @return A list of user notifications, in the order in which they were published.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
List<UserNotification> fetchUserNotifications(Predicate<UserNotification> predicate)
|
||||
throws KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Publishes a user notification.
|
||||
*
|
||||
* @param notification The notification to be published.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void publishUserNotification(UserNotification notification)
|
||||
throws KernelRuntimeException;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.components.kernel.PeripheralJobDispatcher;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.TCSObjectReference;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* Provides methods concerning the {@link PeripheralJobDispatcher}.
|
||||
*/
|
||||
public interface PeripheralDispatcherService {
|
||||
|
||||
/**
|
||||
* Explicitly trigger the dispatching process for peripheral jobs.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void dispatch()
|
||||
throws KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Withdraw any job that a peripheral device (represented by the given location) might be
|
||||
* processing.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param ref A reference to the location representing the peripheral device.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void withdrawByLocation(TCSResourceReference<Location> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Withdraw the given peripheral job.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @param ref A reference to the peripheral job to be withdrawn.
|
||||
* @throws ObjectUnknownException If the referenced peripheral job does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void withdrawByPeripheralJob(TCSObjectReference<PeripheralJob> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.access.to.peripherals.PeripheralJobCreationTO;
|
||||
import org.opentcs.data.ObjectExistsException;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.peripherals.PeripheralJob;
|
||||
|
||||
/**
|
||||
* Provides methods concerning {@link PeripheralJob}s.
|
||||
*/
|
||||
public interface PeripheralJobService
|
||||
extends
|
||||
TCSObjectService {
|
||||
|
||||
/**
|
||||
* Creates a peripheral job.
|
||||
* A new peripheral job is created with a generated unique ID and all other attributes taken from
|
||||
* the given transfer object.
|
||||
* A copy of the newly created transport order is then returned.
|
||||
*
|
||||
* @param to Describes the peripheral job to be created.
|
||||
* @return A copy of the newly created peripheral job.
|
||||
* @throws ObjectUnknownException If any referenced object does not exist.
|
||||
* @throws ObjectExistsException If an object with the same name already exists in the model.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
PeripheralJob createPeripheralJob(PeripheralJobCreationTO to)
|
||||
throws ObjectUnknownException,
|
||||
ObjectExistsException,
|
||||
KernelRuntimeException;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// SPDX-FileCopyrightText: The openTCS Authors
|
||||
// SPDX-License-Identifier: MIT
|
||||
package org.opentcs.components.kernel.services;
|
||||
|
||||
import org.opentcs.access.KernelRuntimeException;
|
||||
import org.opentcs.data.ObjectUnknownException;
|
||||
import org.opentcs.data.model.Location;
|
||||
import org.opentcs.data.model.TCSResourceReference;
|
||||
import org.opentcs.drivers.peripherals.PeripheralAdapterCommand;
|
||||
import org.opentcs.drivers.peripherals.PeripheralCommAdapter;
|
||||
import org.opentcs.drivers.peripherals.PeripheralCommAdapterDescription;
|
||||
import org.opentcs.drivers.peripherals.PeripheralProcessModel;
|
||||
import org.opentcs.drivers.peripherals.management.PeripheralAttachmentInformation;
|
||||
|
||||
/**
|
||||
* Provides methods concerning peripheral devices represented by {@link Location}s.
|
||||
*/
|
||||
public interface PeripheralService
|
||||
extends
|
||||
TCSObjectService {
|
||||
|
||||
/**
|
||||
* Attaches the described comm adapter to the referenced location.
|
||||
*
|
||||
* @param ref A reference to the location.
|
||||
* @param description The description for the comm adapter to be attached.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void attachCommAdapter(
|
||||
TCSResourceReference<Location> ref,
|
||||
PeripheralCommAdapterDescription description
|
||||
)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Disables the comm adapter attached to the referenced location.
|
||||
*
|
||||
* @param ref A reference to the location the comm adapter is attached to.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void disableCommAdapter(TCSResourceReference<Location> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Enables the comm adapter attached to the referenced location.
|
||||
*
|
||||
* @param ref A reference to the location the comm adapter is attached to.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void enableCommAdapter(TCSResourceReference<Location> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Returns attachment information for the referenced location.
|
||||
*
|
||||
* @param ref A reference to the location.
|
||||
* @return The attachment information.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
PeripheralAttachmentInformation fetchAttachmentInformation(TCSResourceReference<Location> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Returns the process model for the referenced location.
|
||||
*
|
||||
* @param ref A reference to the location.
|
||||
* @return The process model.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
PeripheralProcessModel fetchProcessModel(TCSResourceReference<Location> ref)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
|
||||
/**
|
||||
* Sends a {@link PeripheralAdapterCommand} to the comm adapter attached to the referenced
|
||||
* location.
|
||||
* <p>
|
||||
* If called within the kernel application, this method is supposed to be called only on the
|
||||
* kernel executor thread.
|
||||
* </p>
|
||||
*
|
||||
* @see PeripheralAdapterCommand#execute(PeripheralCommAdapter)
|
||||
* @param ref A reference to the location.
|
||||
* @param command The adapter command to send.
|
||||
* @throws ObjectUnknownException If the referenced location does not exist.
|
||||
* @throws KernelRuntimeException In case there is an exception executing this method.
|
||||
*/
|
||||
void sendCommAdapterCommand(TCSResourceReference<Location> ref, PeripheralAdapterCommand command)
|
||||
throws ObjectUnknownException,
|
||||
KernelRuntimeException;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user