Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ Require-Bundle: org.eclipse.ui,
de.dlr.sc.virsat.model.extension.cefx,
org.eclipse.ui.navigator,
de.dlr.sc.virsat.model.calculation.ui,
de.dlr.sc.virsat.cef.branding.ui
de.dlr.sc.virsat.cef.branding.ui,
org.eclipse.ui.ide,
de.dlr.sc.virsat.external.lib.comet.sdkj.servicedal
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-ActivationPolicy: lazy
Export-Package: de.dlr.sc.virsat.model.extension.cefx.ui.itemprovider,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions de.dlr.sc.virsat.model.extension.cefx.ui/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2697,6 +2697,23 @@
</with>
</activeWhen>
</handler>
</extension>
<extension
point="org.eclipse.ui.importWizards">
<wizard
category="de.dlr.virsat.global.category.import.virsat"
class="de.dlr.sc.virsat.model.extension.cefx.ui.importWizards.CometImportWizard"
icon="icons/sample.png"
id="de.dlr.sc.virsat.model.extension.cefx.ui.importWizards.CometImportWizard"
name="Comet Import Wizards">
<description>
Import a file from the local file system into the workspace.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description is outdated isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it and wrote: CometImportWizard.

</description>
</wizard>
<category
id="de.dlr.virsat.global.category.import.virsat"
name="Virtual Satellite">
</category>
</extension>
<!-- Plugin.XML Protected Region End -->
</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*******************************************************************************
* Copyright (c) 2008-2019 German Aerospace Center (DLR), Simulation and Software Technology, Germany.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/


package de.dlr.sc.virsat.model.extension.cefx.ui.importWizards;

import cdp4common.engineeringmodeldata.ElementDefinition;
import cdp4common.engineeringmodeldata.ElementUsage;
import cdp4common.engineeringmodeldata.EngineeringModel;
import cdp4common.engineeringmodeldata.Iteration;
import cdp4common.engineeringmodeldata.Parameter;
import cdp4common.engineeringmodeldata.ParameterSwitchKind;
import cdp4common.engineeringmodeldata.ParameterValueSet;
import cdp4common.sitedirectorydata.DomainOfExpertise;
import cdp4dal.Session;
import cdp4dal.SessionImpl;
import cdp4dal.dal.Credentials;
import cdp4servicesdal.CdpServicesDal;
import org.eclipse.swt.SWT;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it makes sense to separate data fetching and UI? So that we do not have UI classes (SWT) in this one? Then we could move this class to the non-ui part of the plugin and test it? :)

Probably we could do that by replacing the SWT tree class with some UI independent class? Such as either a EMF object / Maybe directly a VirSat model class? Or maybe a plain java object that just accepts children objects? What do you think?

The error handling would then work with Exceptions: If there is an error (Login wrong, no Iteration or whatever) you throw a corresponding exception and catch this exception in the Wizard... Then e.g. showing a warning...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've separated the data fetching logic from the UI by creating a non-UI CometDataFetcher class that uses a TreeNode model to represent the data. The UI components now handle displaying this data and catching exceptions to show appropriate warnings, making the code more modular and testable.

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import java.io.IOException;
import java.net.URI;
import java.security.GeneralSecurityException;
import java.util.Optional;

/**
* The CometDataFetcher class is responsible for fetching and populating
* data from a COMET system into a SWT Tree widget.
*/
public class CometDataFetcher {

private final Credentials credentials;
private final Session session;
private final URI uri;

/**
* Constructs a new CometDataFetcher instance.
*
* @param url The URL of the COMET system.
* @param username The username for authentication.
* @param password The password for authentication.
*/
public CometDataFetcher(String url, String username, String password) {
this.uri = URI.create(url);
CdpServicesDal dal = new CdpServicesDal();
this.credentials = new Credentials(username, password, this.uri, null);
this.session = new SessionImpl(dal, this.credentials);
}

/**
* Initiates the process to fetch data and populate the provided Tree.
*/
public void fetchData(Tree tree) {
new Thread(() -> {
try {
openSession();
Display.getDefault().asyncExec(() -> populateTreeWithIteration(tree));
} catch (IOException e) {
// Handle I/O exceptions, such as network issues
handleException(e, tree);
} catch (GeneralSecurityException e) {
// Handle security-related exceptions, such as authentication failures
handleException(e, tree);
} catch (RuntimeException e) {
// Handle any other runtime exceptions that might occur
handleException(e, tree);
}
}).start();
}

/**
* Opens the session for communication with the COMET system.
*/
public void openSession() throws IOException, GeneralSecurityException {
session.open().join();
}

/**
* Populates the provided Tree with data from the selected iteration
* of the engineering model.
*
* @param tree The SWT Tree widget to populate.
*/
private void populateTreeWithIteration(Tree tree) {
var siteDirectory = session.getAssembler().retrieveSiteDirectory();
var model = siteDirectory.getModel().get(0);

var iterationIid = model.getIterationSetup().get(0).getIterationIid();
var domainOfExpertiseIid = model.getActiveDomain().get(0).getIid();

EngineeringModel engineeringModel = new EngineeringModel(model.getEngineeringModelIid(), session.getAssembler().getCache(), uri);
Iteration iteration = new Iteration(iterationIid, session.getAssembler().getCache(), uri);
iteration.setContainer(engineeringModel);

DomainOfExpertise domainOfExpertise = new DomainOfExpertise(domainOfExpertiseIid, session.getAssembler().getCache(), uri);

session.read(iteration, domainOfExpertise).join();

Optional<Iteration> openIteration = session.getOpenIterations().keySet().stream().findFirst();

if (openIteration.isPresent()) {
openIteration.get().getElement().stream()
.filter(this::isTopLevelElement) // Filter for the top-level element
.findFirst()
.ifPresent(element -> {
TreeItem topLevelItem = new TreeItem(tree, SWT.NONE);
topLevelItem.setText(element.getName());
addChildren(topLevelItem, element);
topLevelItem.setExpanded(true);
});
} else {
showErrorMessage(tree, "No open iteration found.");
}
}

/**
* Custom method to determine if an ElementDefinition is a top-level element.
* A top-level element is typically not referenced by any other elements.
*/
private boolean isTopLevelElement(ElementDefinition element) {
return element.referencingElementUsages().isEmpty();
}




/**
* Recursively adds child elements of a parent ElementDefinition to a TreeItem.
*/
private void addChildren(TreeItem parentItem, ElementDefinition parentElement) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we create a option in the wizard for what kind of data we want to import? For CEF interessting values are probably mass, power and temperature?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add later options in the wizard to allow users to select the specific parameters they want to import, such as mass, power, and temperature, and modified the data fetching process to include only the selected parameters. Now, the mass will be automatically imported during the import.

parentElement.getParameter().stream()
.filter(parameter -> "mass".equalsIgnoreCase(parameter.getParameterType().getName()))
.findFirst()
.ifPresent(parameter -> {
String massValue = fetchParameterValue(parameter);
TreeItem massItem = new TreeItem(parentItem, SWT.NONE);
massItem.setText("Mass: " + massValue + " kg");
});

for (ElementUsage usage : parentElement.getContainedElement()) {
TreeItem usageItem = new TreeItem(parentItem, SWT.NONE);
usageItem.setText(usage.getName());
addChildren(usageItem, usage.getElementDefinition());
}
}

/**
* Fetches the value of the specified Parameter.
*
*/
private String fetchParameterValue(Parameter parameter) {
try {
ParameterValueSet valueSet = parameter.getValueSet().get(0);

if (valueSet.getValueSwitch() == ParameterSwitchKind.COMPUTED) {
return valueSet.getComputed().get(0);
} else if (valueSet.getValueSwitch() == ParameterSwitchKind.MANUAL) {
return valueSet.getManual().get(0);
} else {
return "No valid mass found";
}
} catch (Exception e) {
e.printStackTrace();
return "N/A";
}
}

/**
* Displays an error message in a MessageBox.
*/
private void showErrorMessage(Tree tree, String message) {
Display.getDefault().asyncExec(() -> {
MessageBox messageBox = new MessageBox(tree.getShell(), SWT.ICON_ERROR);
messageBox.setMessage(message);
messageBox.open();
});
}

/**
* Handles exceptions by printing the stack trace and displaying an error message.
*/
private void handleException(Exception e, Tree tree) {
e.printStackTrace();
showErrorMessage(tree, "An error occurred: " + e.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*******************************************************************************
* Copyright (c) 2008-2019 German Aerospace Center (DLR), Simulation and Software Technology, Germany.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package de.dlr.sc.virsat.model.extension.cefx.ui.importWizards;

import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IImportWizard;
import org.eclipse.ui.IWorkbench;

import de.dlr.sc.virsat.model.dvlm.structural.StructuralElementInstance;
import de.dlr.sc.virsat.model.extension.ps.model.ConfigurationTree;
import de.dlr.sc.virsat.project.editingDomain.VirSatEditingDomainRegistry;
import de.dlr.sc.virsat.project.editingDomain.VirSatTransactionalEditingDomain;

import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.jface.viewers.IStructuredSelection;

/**
* This wizard handles the import of data from a Comet server.
* It guides the user through server configuration and initiates the data import process.
*/
public class CometImportWizard extends Wizard implements IImportWizard {

private CometImportWizardPage mainPage;
private SelectedElementsPage selectedElementsPage;

public CometImportWizard() {
super();
setWindowTitle("CometImportWizard");
setNeedsProgressMonitor(true);
}

@Override
public void init(IWorkbench workbench, IStructuredSelection selection) {
mainPage = new CometImportWizardPage("Configure Comet Server");
selectedElementsPage = new SelectedElementsPage("Selected Elements");
addPage(mainPage);
addPage(selectedElementsPage);
}

@Override
public boolean performFinish() {
TreeItem rootItem = selectedElementsPage.getTree().getItem(0);

if (rootItem != null) {
ConfigurationTree configurationTree = importElements(rootItem);

// Save the configuration tree
saveConfigurationTree(configurationTree);
}

return true;
}


private ConfigurationTree importElements(TreeItem rootItem) {
ImportHandler importHandler = new ImportHandler();
return importHandler.importElements(rootItem);
}

/**
* Saves the imported ConfigurationTree to the editing domain.
*/


public void saveConfigurationTree(ConfigurationTree configurationTree) {
if (configurationTree == null) {
throw new IllegalStateException("ConfigurationTree is null. Import failed or was not executed correctly.");
}

StructuralElementInstance rootInstance = configurationTree.getStructuralElementInstance();
if (rootInstance == null) {
throw new IllegalStateException("StructuralElementInstance is null in the ConfigurationTree.");
}

// Ensure that the rootInstance is associated with a resource
if (rootInstance.eResource() == null) {
throw new IllegalStateException("StructuralElementInstance's resource is null.");
}

// Check if editing domain retrieval is successful
VirSatTransactionalEditingDomain editingDomain = VirSatEditingDomainRegistry.INSTANCE.getEd(rootInstance);
if (editingDomain == null) {
throw new IllegalStateException("Editing domain is null. Unable to get the editing domain for the StructuralElementInstance.");
}

try {
Command addCommand = AddCommand.create(editingDomain, rootInstance.eResource(), rootInstance.eResource().getContents(), rootInstance);
editingDomain.getCommandStack().execute(addCommand);
editingDomain.saveAll();

ResourcesPlugin.getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
e.printStackTrace();
}
}


@Override
public IWizardPage getNextPage(IWizardPage page) {
if (page == mainPage) {
// Get the selected TreeItems from the mainPage
List<TreeItem> checkedItems = mainPage.getCheckedItems();

// Pass the selected items to the SelectedElementsPage
selectedElementsPage.setSelectedElements(checkedItems);
return selectedElementsPage;
}
return super.getNextPage(page);
}

}
Loading