diff --git a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/META-INF/MANIFEST.MF
index e6d8d34278..ae2264138e 100644
--- a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/META-INF/MANIFEST.MF
@@ -19,7 +19,10 @@ Require-Bundle: org.eclipse.core.resources,
org.eclipse.fordiac.ide.ui,
org.eclipse.fordiac.ide.typemanagement,
org.eclipse.ui.ide,
- org.eclipse.ui.views.properties.tabbed
+ org.eclipse.emf.mwe.core,
+ org.eclipse.ui.views.properties.tabbed,
+ org.eclipse.fordiac.ide.model.commands,
+ org.eclipse.gef
Bundle-Vendor: Eclipse 4diac Project
Automatic-Module-Name: org.eclipse.fordiac.ide.hierarchymanager.ui
Bundle-RequiredExecutionEnvironment: JavaSE-21
diff --git a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/plugin.xml b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/plugin.xml
index 64db1fa231..89a58d5e44 100644
--- a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/plugin.xml
+++ b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/plugin.xml
@@ -274,4 +274,8 @@
+
+
+
diff --git a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/listeners/HierachyManagerUpdateListener.java b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/listeners/HierachyManagerUpdateListener.java
new file mode 100644
index 0000000000..2f04fc2d60
--- /dev/null
+++ b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/listeners/HierachyManagerUpdateListener.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Primetals Technology Austria GmbH
+ *
+ * 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
+ *
+ * Contributors:
+ * Michael Oberlehner - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.fordiac.ide.hierarchymanager.ui.listeners;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.commands.operations.AbstractOperation;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.XMLMapImpl;
+import org.eclipse.fordiac.ide.hierarchymanager.model.hierarchy.HierarchyPackage;
+import org.eclipse.fordiac.ide.hierarchymanager.model.hierarchy.Leaf;
+import org.eclipse.fordiac.ide.hierarchymanager.model.hierarchy.RootLevel;
+import org.eclipse.fordiac.ide.hierarchymanager.model.hierarchy.util.HierarchyResourceFactoryImpl;
+import org.eclipse.fordiac.ide.hierarchymanager.ui.handlers.AbstractHierarchyHandler;
+import org.eclipse.fordiac.ide.hierarchymanager.ui.operations.AbstractChangeHierarchyOperation;
+import org.eclipse.fordiac.ide.hierarchymanager.ui.operations.UpdateLeafRefOperation;
+import org.eclipse.fordiac.ide.hierarchymanager.ui.util.HierarchyManagerUtil;
+import org.eclipse.fordiac.ide.hierarchymanager.ui.view.PlantHierarchyView;
+import org.eclipse.fordiac.ide.model.commands.CommandListener;
+import org.eclipse.fordiac.ide.model.commands.QualNameChange;
+import org.eclipse.fordiac.ide.model.libraryElement.INamedElement;
+import org.eclipse.fordiac.ide.model.libraryElement.UntypedSubApp;
+import org.eclipse.fordiac.ide.model.typelibrary.TypeEntry;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+
+public class HierachyManagerUpdateListener extends CommandListener {
+
+ private static EObject loadPlantHierachy(final IProject project) {
+ final Map loadOptions = new HashMap<>();
+ final ResourceSet hierarchyResouceSet = new ResourceSetImpl();
+ hierarchyResouceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
+ .put(PlantHierarchyView.PLANT_HIERARCHY_FILE_NAME_EXTENSION, new HierarchyResourceFactoryImpl());
+ loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ final XMLMapImpl map = new XMLMapImpl();
+ map.setNoNamespacePackage(HierarchyPackage.eINSTANCE);
+ loadOptions.put(XMLResource.OPTION_XML_MAP, map);
+ hierarchyResouceSet.getLoadOptions().put(XMLResource.OPTION_XML_MAP, map);
+ return PlantHierarchyView.loadHierachyForProject(project, hierarchyResouceSet, loadOptions);
+ }
+
+ private List getOperationForCommand(final QualNameChange qualNameChange,
+ final RootLevel rootLevel) {
+
+ final String identifier = qualNameChange.oldQualName();
+
+ final List result = new ArrayList<>();
+
+ if (undoSet.contains(qualNameChange)) {
+ final List l = executedOperations.get(qualNameChange);
+ // TODO implement UNDO functionality
+ }
+
+ final List leafs = HierarchyManagerUtil.searchLeaf(rootLevel, leafRef -> leafRef.contains(identifier));
+ if (leafs == null || leafs.isEmpty()) {
+ return null; // leaf may have been deleted in the meantime
+ }
+
+ final String newRef = qualNameChange.newQualName();
+
+ for (final Leaf leaf : leafs) {
+ result.add(new UpdateLeafRefOperation(leaf, newRef));
+ }
+
+ return result;
+ }
+
+ @Override
+ public void commitOperations(final Object notifier) {
+
+ if (!(notifier instanceof final TypeEntry key)) {
+ return;
+ }
+
+ final List list = pendingChanges.get(key);
+ if (list == null || list.isEmpty()) {
+ // we only want to reload if changes have been performed
+ return;
+ }
+
+ final RootLevel rootLevel = getPlantHierachy(key);
+
+ for (final QualNameChange change : list) {
+ final List operation = getOperationForCommand(change, rootLevel);
+ if (operation == null || operation.isEmpty()) {
+ continue;
+ // the leaf from the plant hierachy might have change in the meantime
+ // TODO add to Plant hier a warning that we have umcomited change -> save all
+ // editors before editing plant hierachy
+ }
+
+ operation.stream().forEach(op -> {
+ AbstractHierarchyHandler.executeOperation((AbstractChangeHierarchyOperation) op);
+ });
+ executedOperations.put(change, operation);
+ }
+
+ pendingChanges.remove(key);
+ }
+
+ private static RootLevel getPlantHierachy(final TypeEntry key) {
+ final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ if (page != null) {
+ final PlantHierarchyView view = (PlantHierarchyView) page
+ .findView("org.eclipse.fordiac.ide.hierarchymanager.view"); //$NON-NLS-1$
+ if (view != null) {
+ return (RootLevel) view.getCommonViewer().getInput();
+ }
+ }
+ final IProject project = key.getFile().getProject();
+ return (RootLevel) loadPlantHierachy(project);
+ }
+
+ @Override
+ protected boolean isEnabled(final INamedElement element) {
+ return element instanceof UntypedSubApp;
+ }
+
+}
diff --git a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/operations/UpdateLeafRefOperation.java b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/operations/UpdateLeafRefOperation.java
new file mode 100644
index 0000000000..3c8a882b24
--- /dev/null
+++ b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/operations/UpdateLeafRefOperation.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Primetals Technology Austria GmbH
+ *
+ * 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
+ *
+ * Contributors:
+ * Michael Oberlehner - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.fordiac.ide.hierarchymanager.ui.operations;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.fordiac.ide.hierarchymanager.model.hierarchy.Leaf;
+
+public class UpdateLeafRefOperation extends AbstractChangeHierarchyOperation {
+
+ private final Leaf leaf;
+ private final String newRef;
+ private final String oldRef;
+
+ public UpdateLeafRefOperation(final Leaf level, final String newRef) {
+ super("Update Reference");
+ this.leaf = level;
+ this.newRef = newRef;
+ this.oldRef = leaf.getRef();
+ }
+
+ @Override
+ public IStatus execute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ leaf.setRef(leaf.getRef().replace(oldRef, newRef));
+ saveHierarchy(leaf, monitor);
+ return Status.OK_STATUS;
+ }
+
+ @Override
+ public IStatus redo(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ leaf.setRef(leaf.getRef().replace(oldRef, newRef));
+ saveHierarchy(leaf, monitor);
+ return Status.OK_STATUS;
+ }
+
+ @Override
+ public IStatus undo(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ leaf.setRef(leaf.getRef().replace(newRef, oldRef));
+ saveHierarchy(leaf, monitor);
+ return Status.OK_STATUS;
+ }
+
+}
diff --git a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/util/HierarchyManagerUtil.java b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/util/HierarchyManagerUtil.java
index a58a77c696..4bc410bac7 100644
--- a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/util/HierarchyManagerUtil.java
+++ b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/util/HierarchyManagerUtil.java
@@ -13,12 +13,17 @@
*******************************************************************************/
package org.eclipse.fordiac.ide.hierarchymanager.ui.util;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.fordiac.ide.hierarchymanager.model.hierarchy.Leaf;
+import org.eclipse.fordiac.ide.hierarchymanager.model.hierarchy.Level;
+import org.eclipse.fordiac.ide.hierarchymanager.model.hierarchy.Node;
+import org.eclipse.fordiac.ide.hierarchymanager.model.hierarchy.RootLevel;
import org.eclipse.fordiac.ide.model.libraryElement.Application;
import org.eclipse.fordiac.ide.model.libraryElement.AutomationSystem;
import org.eclipse.fordiac.ide.model.libraryElement.Device;
@@ -96,4 +101,31 @@ public static EObject parseSubappPath(FBNetwork network, final String[] path) {
}
return retVal;
}
+
+ @FunctionalInterface
+ public interface LeafMatcher {
+ boolean match(String s);
+ }
+
+ public static List searchLeaf(final RootLevel rootLevel, final LeafMatcher matcher) {
+ final List result = new ArrayList<>();
+
+ for (final Level level : rootLevel.getLevels()) {
+ searchLeaf(level, result, matcher);
+ }
+ return result;
+ }
+
+ public static List searchLeaf(final Level level, final List result, final LeafMatcher matcher) {
+ for (final Node node : level.getChildren()) {
+ if (node instanceof final Level l) {
+ searchLeaf(l, result, matcher);
+ }
+ if (node instanceof final Leaf leaf && matcher.match(leaf.getRef())) {
+ result.add(leaf);
+ }
+ }
+ return result;
+ }
+
}
diff --git a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/view/PlantHierarchyView.java b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/view/PlantHierarchyView.java
index 0425f1a7d4..4c26bb30a1 100644
--- a/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/view/PlantHierarchyView.java
+++ b/plugins/org.eclipse.fordiac.ide.hierarchymanager.ui/src/org/eclipse/fordiac/ide/hierarchymanager/ui/view/PlantHierarchyView.java
@@ -60,7 +60,7 @@ public class PlantHierarchyView extends CommonNavigator implements ITabbedProper
private static final String PLANT_HIERARCHY_PROJECT = "PlantHierarchy.Project"; //$NON-NLS-1$
private static final String PLANT_HIERARCHY_FILE_NAME = ".plant.hier"; //$NON-NLS-1$
- private static final String PLANT_HIERARCHY_FILE_NAME_EXTENSION = "hier"; //$NON-NLS-1$
+ public static final String PLANT_HIERARCHY_FILE_NAME_EXTENSION = "hier"; //$NON-NLS-1$
/** The PROPERTY_CONTRIBUTOR_ID. */
public static final String PROPERTY_CONTRIBUTOR_ID = "org.eclipse.fordiac.ide.hierarchymanager.ui.view"; //$NON-NLS-1$
@@ -117,7 +117,7 @@ protected Object getInitialInput() {
// we can not use setInput here as getInitialInput is interacting with the
// viewer in the base class
currentProject = project;
- return loadHierachyForProject(currentProject);
+ return loadHierachyForProject(currentProject, hierarchyResouceSet, loadOptions);
}
}
}
@@ -141,11 +141,11 @@ public IProject getCurrentProject() {
return currentProject;
}
- private void setInput(final IProject proj) {
+ public void setInput(final IProject proj) {
if (currentProject != proj) {
// the new project is different set
currentProject = proj;
- getCommonViewer().setInput(loadHierachyForProject(proj));
+ getCommonViewer().setInput(loadHierachyForProject(proj, hierarchyResouceSet, loadOptions));
setPartName(getConfigurationElement().getAttribute("name")); //$NON-NLS-1$
}
}
@@ -171,12 +171,13 @@ private static IProject getProjectFromEObject(final EObject eObj) {
return null;
}
- private EObject loadHierachyForProject(final IProject proj) {
+ public static EObject loadHierachyForProject(final IProject proj, final ResourceSet hierarchyResouceSet,
+ final Map loadOptions) {
final IFile file = proj.getFile(PLANT_HIERARCHY_FILE_NAME);
final URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
if (!file.exists()) {
// try to create a new file
- return createNewHierarchyFile(file, uri);
+ return createNewHierarchyFile(file, uri, hierarchyResouceSet);
}
// we don't want to load the resource content as we can not give the mapping
// options
@@ -194,7 +195,8 @@ private EObject loadHierachyForProject(final IProject proj) {
return null;
}
- public EObject createNewHierarchyFile(final IFile file, final URI uri) {
+ public static EObject createNewHierarchyFile(final IFile file, final URI uri,
+ final ResourceSet hierarchyResouceSet) {
Resource resource = hierarchyResouceSet.getResource(uri, false);
if (resource == null) {
resource = new HierarchyResourceImpl(uri);
diff --git a/plugins/org.eclipse.fordiac.ide.model.commands/plugin.xml b/plugins/org.eclipse.fordiac.ide.model.commands/plugin.xml
new file mode 100644
index 0000000000..9362690ed3
--- /dev/null
+++ b/plugins/org.eclipse.fordiac.ide.model.commands/plugin.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/plugins/org.eclipse.fordiac.ide.model.commands/schema/CommandListener.exsd b/plugins/org.eclipse.fordiac.ide.model.commands/schema/CommandListener.exsd
new file mode 100644
index 0000000000..c67a7cf535
--- /dev/null
+++ b/plugins/org.eclipse.fordiac.ide.model.commands/schema/CommandListener.exsd
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/org.eclipse.fordiac.ide.model.commands/src/org/eclipse/fordiac/ide/model/commands/CommandListener.java b/plugins/org.eclipse.fordiac.ide.model.commands/src/org/eclipse/fordiac/ide/model/commands/CommandListener.java
new file mode 100644
index 0000000000..da2f5eda48
--- /dev/null
+++ b/plugins/org.eclipse.fordiac.ide.model.commands/src/org/eclipse/fordiac/ide/model/commands/CommandListener.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2024 Primetals Technology Austria GmbH
+ *
+ * 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
+ *
+ * Contributors:
+ * Michael Oberlehner - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.fordiac.ide.model.commands;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.commands.operations.AbstractOperation;
+import org.eclipse.fordiac.ide.model.libraryElement.INamedElement;
+
+public abstract class CommandListener {
+
+ protected final HashMap