Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright (c) The openTCS Authors.
*
* This program is free software and subject to the MIT license. (For details,
* see the licensing information (LICENSE.txt) you should have received with
* this copy of the software.)
*/
package org.opentcs.guing.common.persistence;
import static java.util.Objects.requireNonNull;
import static org.opentcs.guing.common.util.I18nPlantOverview.STATUS_PATH;
import static org.opentcs.util.Assertions.checkState;
import com.google.common.base.Strings;
import jakarta.annotation.Nullable;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.awt.geom.Point2D;
import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import org.jhotdraw.draw.Figure;
import org.opentcs.access.Kernel;
import org.opentcs.access.KernelRuntimeException;
import org.opentcs.access.KernelServicePortal;
import org.opentcs.components.kernel.services.TCSObjectService;
import org.opentcs.customizations.ApplicationHome;
import org.opentcs.data.ObjectPropConstants;
import org.opentcs.data.model.Block;
import org.opentcs.data.model.Location;
import org.opentcs.data.model.Location.Link;
import org.opentcs.data.model.LocationType;
import org.opentcs.data.model.ModelConstants;
import org.opentcs.data.model.Path;
import org.opentcs.data.model.Point;
import org.opentcs.data.model.Vehicle;
import org.opentcs.data.model.visualization.VisualLayout;
import org.opentcs.guing.base.components.properties.event.NullAttributesChangeListener;
import org.opentcs.guing.base.components.properties.type.KeyValueProperty;
import org.opentcs.guing.base.components.properties.type.LengthProperty;
import org.opentcs.guing.base.model.FigureDecorationDetails;
import org.opentcs.guing.base.model.ModelComponent;
import org.opentcs.guing.base.model.elements.BlockModel;
import org.opentcs.guing.base.model.elements.LayoutModel;
import org.opentcs.guing.base.model.elements.LinkModel;
import org.opentcs.guing.base.model.elements.LocationModel;
import org.opentcs.guing.base.model.elements.LocationTypeModel;
import org.opentcs.guing.base.model.elements.PathModel;
import org.opentcs.guing.base.model.elements.PointModel;
import org.opentcs.guing.base.model.elements.VehicleModel;
import org.opentcs.guing.common.application.ModelRestorationProgressStatus;
import org.opentcs.guing.common.application.ProgressIndicator;
import org.opentcs.guing.common.application.StatusPanel;
import org.opentcs.guing.common.components.drawing.course.Origin;
import org.opentcs.guing.common.components.drawing.course.OriginChangeListener;
import org.opentcs.guing.common.components.drawing.figures.FigureConstants;
import org.opentcs.guing.common.components.drawing.figures.LabeledLocationFigure;
import org.opentcs.guing.common.components.drawing.figures.LabeledPointFigure;
import org.opentcs.guing.common.components.drawing.figures.LinkConnection;
import org.opentcs.guing.common.components.drawing.figures.LocationFigure;
import org.opentcs.guing.common.components.drawing.figures.PathConnection;
import org.opentcs.guing.common.components.drawing.figures.PointFigure;
import org.opentcs.guing.common.components.drawing.figures.TCSLabelFigure;
import org.opentcs.guing.common.exchange.adapter.ProcessAdapterUtil;
import org.opentcs.guing.common.model.SystemModel;
import org.opentcs.guing.common.util.CourseObjectFactory;
import org.opentcs.guing.common.util.ModelComponentFactory;
import org.opentcs.guing.common.util.SynchronizedFileChooser;
import org.opentcs.thirdparty.guing.common.jhotdraw.util.ResourceBundleUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Manages (loads, persists and keeps) the driving course model.
*/
public class OpenTCSModelManager
implements
ModelManager {
/**
* Identifier for the default layout object.
*/
public static final String DEFAULT_LAYOUT = "Default";
/**
* Directory where models will be persisted.
*/
public static final String MODEL_DIRECTORY = "data/";
/**
* This class's logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(OpenTCSModelManager.class);
/**
* The StatusPanel at the bottom to log messages.
*/
private final StatusPanel statusPanel;
/**
* A course object factory to be used.
*/
private final CourseObjectFactory crsObjFactory;
/**
* The model component factory to be used.
*/
private final ModelComponentFactory modelComponentFactory;
/**
* Provides new instances of SystemModel.
*/
private final Provider systemModelProvider;
/**
* A utility class for process adapters.
*/
private final ProcessAdapterUtil procAdapterUtil;
/**
* A file chooser for selecting model files to be saved.
*/
private final JFileChooser modelPersistorFileChooser;
/**
* The file filters for different model persistors that can be used to save models to a file.
*/
private final ModelFilePersistor modelPersistor;
/**
* Converts model data on export.
*/
private final ModelExportAdapter modelExportAdapter;
/**
* The progress indicator to be used.
*/
private final ProgressIndicator progressIndicator;
/**
* The model currently loaded.
*/
private SystemModel systemModel;
/**
* The current system model's name.
*/
private String fModelName = "";
/**
* The file which the current model is loaded from/written to.
*/
private File currentModelFile;
/**
* Creates a new instance.
*
* @param crsObjFactory A course object factory to be used.
* @param modelComponentFactory The model component factory to be used.
* @param procAdapterUtil A utility class for process adapters.
* @param systemModelProvider Provides instances of SystemModel.
* @param statusPanel StatusPanel to log messages.
* @param homeDir The application's home directory.
* @param modelPersistor The model persistor.
* @param modelExportAdapter Converts model data on export.
* @param progressIndicator The progress indicator to be used.
*/
@Inject
@SuppressWarnings("this-escape")
public OpenTCSModelManager(
CourseObjectFactory crsObjFactory,
ModelComponentFactory modelComponentFactory,
ProcessAdapterUtil procAdapterUtil,
Provider systemModelProvider,
StatusPanel statusPanel,
@ApplicationHome
File homeDir,
ModelFilePersistor modelPersistor,
ModelExportAdapter modelExportAdapter,
ProgressIndicator progressIndicator
) {
this.crsObjFactory = requireNonNull(crsObjFactory, "crsObjFactory");
this.modelComponentFactory = requireNonNull(modelComponentFactory, "modelComponentFactory");
this.procAdapterUtil = requireNonNull(procAdapterUtil, "procAdapterUtil");
this.systemModelProvider = requireNonNull(systemModelProvider, "systemModelProvider");
this.statusPanel = requireNonNull(statusPanel, "statusPanel");
requireNonNull(homeDir, "homeDir");
this.modelPersistor = requireNonNull(modelPersistor, "modelPersistor");
this.modelPersistorFileChooser = new SynchronizedFileChooser(new File(homeDir, "data"));
this.modelPersistorFileChooser.setAcceptAllFileFilterUsed(false);
this.modelPersistorFileChooser.setFileFilter(modelPersistor.getDialogFileFilter());
this.modelExportAdapter = requireNonNull(modelExportAdapter, "modelExportAdapter");
this.progressIndicator = progressIndicator;
this.systemModel = systemModelProvider.get();
initializeSystemModel(systemModel);
}
@Override
public SystemModel getModel() {
return systemModel;
}
@Override
public boolean saveModelToFile(boolean chooseName) {
fModelName = systemModel.getName();
if (chooseName
|| currentModelFile == null
|| fModelName == null
|| fModelName.isEmpty()
|| fModelName.equals(Kernel.DEFAULT_MODEL_NAME)) {
File selectedFile = showSaveDialog();
if (selectedFile == null) {
return false;
}
currentModelFile = selectedFile;
}
try {
statusPanel.clear();
// Set the last-modified time stamp of the model to right now, as we're saving the model file.
systemModel.getPropertyMiscellaneous().addItem(
new KeyValueProperty(
systemModel,
ObjectPropConstants.MODEL_FILE_LAST_MODIFIED,
Instant.now().truncatedTo(ChronoUnit.SECONDS).toString()
)
);
return persistModel(
systemModel,
currentModelFile,
modelPersistor
);
}
catch (IOException e) {
statusPanel.setLogMessage(
Level.SEVERE,
ResourceBundleUtil.getBundle(STATUS_PATH)
.getString("openTcsModelManager.message_notSaved.text")
);
LOG.warn("Exception persisting model", e);
return false;
}
catch (IllegalArgumentException e) {
JOptionPane.showConfirmDialog(statusPanel, e.getMessage());
return true;
}
}
@Override
public void createEmptyModel() {
systemModel = systemModelProvider.get();
initializeSystemModel(systemModel);
systemModel.setName(Kernel.DEFAULT_MODEL_NAME);
fModelName = systemModel.getName();
}
/**
* Persist model with the persistor.
*
* @param systemModel The system model to be persisted.
* @param persistor The persistor to be used.
* @param ignoreError whether the model should be persisted when duplicates exist
* @return Whether the model was actually saved.
*/
private boolean persistModel(
SystemModel systemModel,
File file,
ModelFilePersistor persistor
)
throws IOException,
KernelRuntimeException {
requireNonNull(systemModel, "systemModel");
requireNonNull(persistor, "persistor");
if (!persistor.serialize(modelExportAdapter.convert(systemModel), file)) {
return false;
}
systemModel.setName(fModelName);
return true;
}
@Override
public void restoreModel() {
fModelName = systemModel.getName();
LayoutModel layoutModel = (LayoutModel) systemModel.getMainFolder(SystemModel.FolderKey.LAYOUT);
double scaleX = layoutModel.getPropertyScaleX().getValueByUnit(LengthProperty.Unit.MM);
double scaleY = layoutModel.getPropertyScaleY().getValueByUnit(LengthProperty.Unit.MM);
Origin origin = systemModel.getDrawingMethod().getOrigin();
// Create figures and process adapters
progressIndicator.setProgress(ModelRestorationProgressStatus.LOADING_POINTS);
List