-
Notifications
You must be signed in to change notification settings - Fork 23
/
ChangeStructCommand.java
150 lines (129 loc) · 5.53 KB
/
ChangeStructCommand.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*******************************************************************************
* Copyright (c) 2008, 2009, 2014 Profactor GmbH, fortiss GmbH
* 2019 - 2021 Johannes Kepler University Linz
* 2021 Primetals Technologies 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:
* Alois Zoitl, Gerhard Ebenhofer
* - initial API and implementation and/or initial documentation
* Bianca Wiesmayr - adapted ChangeTypeCommand for multiplexer use, sets struct
* Daniel Lindhuber - struct update
*******************************************************************************/
package org.eclipse.fordiac.ide.model.commands.change;
import java.text.MessageFormat;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.fordiac.ide.model.LibraryElementTags;
import org.eclipse.fordiac.ide.model.data.DataType;
import org.eclipse.fordiac.ide.model.datatype.helper.IecTypes;
import org.eclipse.fordiac.ide.model.libraryElement.Demultiplexer;
import org.eclipse.fordiac.ide.model.libraryElement.LibraryElement;
import org.eclipse.fordiac.ide.model.libraryElement.LibraryElementFactory;
import org.eclipse.fordiac.ide.model.libraryElement.Multiplexer;
import org.eclipse.fordiac.ide.model.libraryElement.StructManipulator;
import org.eclipse.fordiac.ide.model.libraryElement.impl.ConfigurableFBManagement;
import org.eclipse.fordiac.ide.model.typelibrary.DataTypeLibrary;
import org.eclipse.fordiac.ide.model.typelibrary.ErrorDataTypeEntry;
import org.eclipse.fordiac.ide.model.typelibrary.TypeEntry;
public class ChangeStructCommand extends AbstractUpdateFBNElementCommand {
private final TypeEntry newStructTypeEntry;
private final String newVisibleChildren;
private boolean reloadDatatype = true;
public ChangeStructCommand(final StructManipulator mux) {
this(mux, mux.getDataType(), getOldVisibleChildren(mux));
}
public ChangeStructCommand(final StructManipulator mux, final DataType newStruct) {
this(mux, newStruct, getOldVisibleChildren(mux));
}
public ChangeStructCommand(final StructManipulator mux, final DataType newStruct, final boolean doNotReload) {
this(mux, newStruct, getOldVisibleChildren(mux));
reloadDatatype = !doNotReload;
}
public ChangeStructCommand(final Demultiplexer demux, final String newVisibleChildren) {
this(demux, demux.getDataType(), newVisibleChildren);
}
// only to avoid code duplication, public constructors ensure correct set-up
private ChangeStructCommand(final StructManipulator demux, final DataType datatype,
final String newVisibleChildren) {
super(demux);
// use type entry to ensure that the latest version is loaded, for unconfigured
// datatype is null
newStructTypeEntry = (datatype != null) ? datatype.getTypeEntry() : null;
entry = demux.getTypeEntry();
this.newVisibleChildren = newVisibleChildren;
}
private static String getOldVisibleChildren(final StructManipulator mux) {
if (mux instanceof final Demultiplexer demux && demux.isIsConfigured()) {
return ConfigurableFBManagement.buildVisibleChildrenString(demux.getMemberVars());
}
return null;
}
@Override
protected void createNewFB() {
if (oldElement instanceof Multiplexer) {
newElement = LibraryElementFactory.eINSTANCE.createMultiplexer();
} else if (oldElement instanceof Demultiplexer) {
newElement = LibraryElementFactory.eINSTANCE.createDemultiplexer();
}
newElement.setTypeEntry(entry);
setInterface();
handleConfigurableFB();
newElement.setName(oldElement.getName());
newElement.setPosition(EcoreUtil.copy(oldElement.getPosition()));
copyAttributes();
createValues();
transferInstanceComments();
}
@Override
protected void handleConfigurableFB() {
if (newStructTypeEntry != null) {
getNewMux().setDataType(getDataTypeFromTypeEntry());
}
if (isDemuxConfiguration()) {
getNewMux().loadConfiguration(LibraryElementTags.DEMUX_VISIBLE_CHILDREN, newVisibleChildren);
} else {
getNewMux().updateConfiguration();
}
}
private boolean isDemuxConfiguration() {
if (newElement instanceof final Demultiplexer demux) {
return demux.isIsConfigured() || newVisibleChildren != null;
}
return false;
}
protected void copyAttributes() {
newElement.getAttributes().addAll(EcoreUtil.copyAll(oldElement.getAttributes()));
}
public StructManipulator getNewMux() {
return (StructManipulator) newElement;
}
public StructManipulator getOldMux() {
return (StructManipulator) oldElement;
}
private DataType getDataTypeFromTypeEntry() {
if (newStructTypeEntry == null) {
return IecTypes.GenericTypes.ANY_STRUCT;
}
LibraryElement type = newStructTypeEntry.getType();
if (reloadDatatype) {
final DataTypeLibrary datatypeLib = entry.getTypeLibrary().getDataTypeLibrary();
final TypeEntry reloadedTypeEntry = datatypeLib.getDerivedTypeEntry(newStructTypeEntry.getFullTypeName());
if (newStructTypeEntry instanceof ErrorDataTypeEntry) {
if (reloadedTypeEntry != null && reloadedTypeEntry != newStructTypeEntry) {
// type exists now
type = reloadedTypeEntry.getType();
}
} else if (reloadedTypeEntry == null) {
// type was deleted, create error marker
type = datatypeLib.createErrorMarkerType(newStructTypeEntry.getFullTypeName(), MessageFormat
.format("Typeentry for StructManipulator `{0}` not available!", getOldMux().getName())); //$NON-NLS-1$
}
}
return (type instanceof final DataType dt) ? dt : IecTypes.GenericTypes.ANY_STRUCT;
}
}