Support uml model linking
- Essentially add support to be able to understand papyrus uml linked models. - Change handling of files in a classpath(fat-jar) to copy those into jvm tmp directory in a structure where relative links can work. - Forward port #888
This commit is contained in:
BIN
docs/src/reference/asciidoc/images/papyrus-gs-22.png
Normal file
BIN
docs/src/reference/asciidoc/images/papyrus-gs-22.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 176 KiB |
@@ -2723,6 +2723,27 @@ sub-state.
|
||||
|
||||
image::images/papyrus-gs-15.png[scaledwidth="100%"]
|
||||
|
||||
[[sm-papyrus-import]]
|
||||
=== Using a Machine Import
|
||||
It's also possible to use import functionality where uml files can reference to other models.
|
||||
|
||||
image::images/papyrus-gs-22.png[scaledwidth="100%"]
|
||||
|
||||
Within `UmlStateMachineModelFactory` it's possible to use additional resources or locations
|
||||
to define referenced model files.
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::samples/DocsUmlSampleTests1.java[tags=snippetC]
|
||||
----
|
||||
====
|
||||
|
||||
IMPORTANT: Links between files in uml models needs to be relative as
|
||||
otherwise things break when model files are copied out from a
|
||||
classpath to a temporary directory so that eclipse parsing classes can
|
||||
read those.
|
||||
|
||||
[[sm-repository]]
|
||||
== Repository Support
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.uml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.statemachine.StateMachineException;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* Support class to resolve uml resources and handling a cases where things
|
||||
* needs to be copied away from a classpath trying to handle common relative
|
||||
* paths with a locations or resource paths in case of a cross relative linking.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
class ResourcerResolver {
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
private Resource mainResource;
|
||||
private String mainLocation;
|
||||
private Resource[] additionalResources;
|
||||
private String[] additionalLocations;
|
||||
|
||||
public ResourcerResolver(Resource mainResource, Resource[] additionalResources) {
|
||||
this.mainResource = mainResource;
|
||||
this.additionalResources = additionalResources != null ? additionalResources : new Resource[0];
|
||||
}
|
||||
|
||||
public ResourcerResolver(ResourceLoader resourceLoader, String mainLocation, String[] additionalLocations) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
this.mainLocation = mainLocation;
|
||||
this.additionalLocations = additionalLocations != null ? additionalLocations : new String[0];
|
||||
}
|
||||
|
||||
public Holder[] resolve() {
|
||||
ArrayList<Holder> holders = new ArrayList<>();
|
||||
if (mainLocation != null) {
|
||||
Resource[] resources = Stream.concat(Stream.of(mainLocation), Stream.of(additionalLocations))
|
||||
.map(location -> resourceLoader.getResource(location))
|
||||
.toArray(Resource[]::new);
|
||||
return getResourceUris(resources);
|
||||
} else if (mainResource != null) {
|
||||
Resource[] resources = Stream.concat(Stream.of(mainResource), Stream.of(additionalResources))
|
||||
.toArray(Resource[]::new);
|
||||
return getResourceUris(resources);
|
||||
}
|
||||
return holders.toArray(new Holder[0]);
|
||||
}
|
||||
|
||||
private Holder[] getResourceUris(Resource... resources) {
|
||||
ArrayList<Holder> holders = new ArrayList<>();
|
||||
try {
|
||||
if (allPhysical(resources)) {
|
||||
for (Resource resource : resources) {
|
||||
holders.add(new Holder(resource.getFile().toURI()));
|
||||
}
|
||||
} else {
|
||||
Path tempDir = Files.createTempDirectory(null);
|
||||
for (Resource resource : resources) {
|
||||
if (resource instanceof ClassPathResource) {
|
||||
ClassPathResource cpr = (ClassPathResource)resource;
|
||||
File f = new File(tempDir.toFile(), cpr.getPath());
|
||||
f.getParentFile().mkdirs();
|
||||
FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream(f));
|
||||
holders.add(new Holder(f.toURI(), f.toPath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new StateMachineException(e);
|
||||
}
|
||||
return holders.toArray(new Holder[0]);
|
||||
}
|
||||
|
||||
private boolean isPhysical(Resource resource) {
|
||||
try {
|
||||
resource.getFile();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean allPhysical(Resource... resources) {
|
||||
for (Resource resource : resources) {
|
||||
if (!isPhysical(resource)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static class Holder {
|
||||
URI uri;
|
||||
Path path;
|
||||
|
||||
public Holder(URI uri) {
|
||||
this(uri, null);
|
||||
}
|
||||
|
||||
public Holder(URI uri, Path path) {
|
||||
this.uri = uri;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public URI getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors.
|
||||
* Copyright 2016-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,11 +15,7 @@
|
||||
*/
|
||||
package org.springframework.statemachine.uml;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil;
|
||||
import org.eclipse.uml2.uml.Model;
|
||||
@@ -29,23 +25,33 @@ import org.springframework.statemachine.config.model.AbstractStateMachineModelFa
|
||||
import org.springframework.statemachine.config.model.DefaultStateMachineModel;
|
||||
import org.springframework.statemachine.config.model.StateMachineModel;
|
||||
import org.springframework.statemachine.config.model.StateMachineModelFactory;
|
||||
import org.springframework.statemachine.uml.ResourcerResolver.Holder;
|
||||
import org.springframework.statemachine.uml.support.UmlModelParser;
|
||||
import org.springframework.statemachine.uml.support.UmlModelParser.DataHolder;
|
||||
import org.springframework.statemachine.uml.support.UmlUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* {@link StateMachineModelFactory} which builds {@link StateMachineModel} from
|
||||
* uml representation.
|
||||
*
|
||||
* {@code resource} or {@code location} is a main uml file used as a source
|
||||
* passed to parser classes. {@code additionalResources} and {@code additionalLocations}
|
||||
* are needed if uml model have references or links to additional uml files as an
|
||||
* import. In case of a these files being located in a classpath which is inside of
|
||||
* a jar, files are copied out into filesystem as eclipse uml libs can only parse
|
||||
* physical files. In a case of this a common "path" from all resources are resolved
|
||||
* and copied into filesystem with a structure so that at least relative links in uml
|
||||
* files will work.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class UmlStateMachineModelFactory extends AbstractStateMachineModelFactory<String, String>
|
||||
implements StateMachineModelFactory<String, String> {
|
||||
public class UmlStateMachineModelFactory extends AbstractStateMachineModelFactory<String, String> {
|
||||
|
||||
private Resource resource;
|
||||
private String location;
|
||||
private Resource[] additionalResources;
|
||||
private String[] additionalLocations;
|
||||
|
||||
/**
|
||||
* Instantiates a new uml state machine model factory.
|
||||
@@ -53,8 +59,7 @@ public class UmlStateMachineModelFactory extends AbstractStateMachineModelFactor
|
||||
* @param resource the resource
|
||||
*/
|
||||
public UmlStateMachineModelFactory(Resource resource) {
|
||||
Assert.notNull(resource, "Resource must be set");
|
||||
this.resource = resource;
|
||||
this(resource, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,20 +68,51 @@ public class UmlStateMachineModelFactory extends AbstractStateMachineModelFactor
|
||||
* @param location the resource location
|
||||
*/
|
||||
public UmlStateMachineModelFactory(String location) {
|
||||
this(location, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new uml state machine model factory.
|
||||
*
|
||||
* @param resource the resource
|
||||
* @param additionalResources the additional resources
|
||||
*/
|
||||
public UmlStateMachineModelFactory(Resource resource, Resource[] additionalResources) {
|
||||
Assert.notNull(resource, "Resource must be set");
|
||||
this.resource = resource;
|
||||
this.additionalResources = additionalResources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new uml state machine model factory.
|
||||
*
|
||||
* @param location the resource location
|
||||
* @param additionalLocations the additional locations
|
||||
*/
|
||||
public UmlStateMachineModelFactory(String location, String[] additionalLocations) {
|
||||
Assert.notNull(location, "Location must be set");
|
||||
this.location = location;
|
||||
this.additionalLocations = additionalLocations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineModel<String, String> build() {
|
||||
Model model = null;
|
||||
ResourcerResolver resourceResolver = null;
|
||||
if (this.location != null) {
|
||||
resourceResolver = new ResourcerResolver(getResourceLoader(), location, additionalLocations);
|
||||
} else if (this.resource != null) {
|
||||
resourceResolver = new ResourcerResolver(resource, additionalResources);
|
||||
}
|
||||
|
||||
Holder holder = null;
|
||||
Model model = null;
|
||||
org.eclipse.emf.ecore.resource.Resource resource = null;
|
||||
try {
|
||||
holder = getResourceUri(resolveResource());
|
||||
Holder[] resources = resourceResolver.resolve();
|
||||
holder = resources != null && resources.length > 0 ? resources[0] : null;
|
||||
resource = UmlUtils.getResource(holder.uri.getPath());
|
||||
model = (Model) EcoreUtil.getObjectByType(resource.getContents(), UMLPackage.Literals.MODEL);
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("Cannot build build model from resource " + resource + " or location " + location, e);
|
||||
} finally {
|
||||
// if we have a path, tmp file were created, clean it
|
||||
@@ -87,6 +123,7 @@ public class UmlStateMachineModelFactory extends AbstractStateMachineModelFactor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UmlModelParser parser = new UmlModelParser(model, this);
|
||||
DataHolder dataHolder = parser.parseModel();
|
||||
|
||||
@@ -107,39 +144,4 @@ public class UmlStateMachineModelFactory extends AbstractStateMachineModelFactor
|
||||
// we don't set configurationData here, so assume null
|
||||
return new DefaultStateMachineModel<String, String>(null, dataHolder.getStatesData(), dataHolder.getTransitionsData());
|
||||
}
|
||||
|
||||
private Resource resolveResource() {
|
||||
if (resource != null) {
|
||||
return resource;
|
||||
} else {
|
||||
return getResourceLoader().getResource(location);
|
||||
}
|
||||
}
|
||||
|
||||
private Holder getResourceUri(Resource resource) throws IOException {
|
||||
// try to see if resource is an actual File and eclipse
|
||||
// libs cannot use input stream. thus creating a tmp file with
|
||||
// needed .uml prefix and getting URI from there.
|
||||
try {
|
||||
return new Holder(resource.getFile().toURI());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
Path tempFile = Files.createTempFile(null, ".uml");
|
||||
FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream(tempFile.toFile()));
|
||||
return new Holder(tempFile.toUri(), tempFile);
|
||||
}
|
||||
|
||||
private static class Holder {
|
||||
URI uri;
|
||||
Path path;
|
||||
|
||||
public Holder(URI uri) {
|
||||
this(uri, null);
|
||||
}
|
||||
|
||||
public Holder(URI uri, Path path) {
|
||||
this.uri = uri;
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2019 the original author or authors.
|
||||
* Copyright 2016-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -69,8 +69,9 @@ import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Model parser which constructs states and transitions data out from
|
||||
* an uml model.
|
||||
* Model parser which constructs states and transitions data out from an uml
|
||||
* model. This implementation is not thread safe and model parsing can only be
|
||||
* used once per instance.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@@ -92,6 +93,10 @@ public class UmlModelParser {
|
||||
|
||||
private final AtomicInteger pseudostateNamingCounter = new AtomicInteger(1);
|
||||
private final Map<NamedElement, String> pseudostateNaming = new HashMap<>();
|
||||
private final List<String> seenStateData = new ArrayList<>();
|
||||
private final List<String> seenEntryData = new ArrayList<>();
|
||||
private final List<String> seenExitData = new ArrayList<>();
|
||||
private final List<String> seenTransitionData = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new uml model parser.
|
||||
@@ -158,6 +163,46 @@ public class UmlModelParser {
|
||||
});
|
||||
}
|
||||
|
||||
private void addStateData(StateData<String, String> stateData) {
|
||||
String key = stateData.getState();
|
||||
if (!seenStateData.contains(key)) {
|
||||
stateDatas.add(stateData);
|
||||
seenStateData.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
private void addEntryData(EntryData<String, String> entryData) {
|
||||
String skey = entryData.getSource() != null ? entryData.getSource() : "null";
|
||||
String tkey = entryData.getTarget() != null ? entryData.getTarget() : "null";
|
||||
String key = skey + "_" + tkey;
|
||||
if (!seenEntryData.contains(key)) {
|
||||
entrys.add(entryData);
|
||||
seenEntryData.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
private void addExitData(ExitData<String, String> exitData) {
|
||||
String skey = exitData.getSource() != null ? exitData.getSource() : "null";
|
||||
String tkey = exitData.getTarget() != null ? exitData.getTarget() : "null";
|
||||
String key = skey + "_" + tkey;
|
||||
if (!seenExitData.contains(key)) {
|
||||
exits.add(exitData);
|
||||
seenExitData.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
private void addTransitionData(TransitionData<String, String> transitionData) {
|
||||
String skey = transitionData.getSource() != null ? transitionData.getSource() : "null";
|
||||
String tkey = transitionData.getTarget() != null ? transitionData.getTarget() : "null";
|
||||
String ekey = transitionData.getEvent() != null ? transitionData.getEvent() : "null";
|
||||
String kkey = transitionData.getKind() != null ? transitionData.getKind().toString() : "null";
|
||||
String key = skey + "_" + tkey + "_" + ekey + "_" + kkey;
|
||||
if (!seenTransitionData.contains(key)) {
|
||||
transitionDatas.add(transitionData);
|
||||
seenTransitionData.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRegion(Region region) {
|
||||
// build states
|
||||
for (Vertex vertex : region.getSubvertices()) {
|
||||
@@ -192,7 +237,7 @@ public class UmlModelParser {
|
||||
if (UmlUtils.isFinalState(state)) {
|
||||
stateData.setEnd(true);
|
||||
}
|
||||
stateDatas.add(stateData);
|
||||
addStateData(stateData);
|
||||
|
||||
// add states via entry/exit reference points
|
||||
for (ConnectionPointReference cpr : state.getConnections()) {
|
||||
@@ -200,14 +245,14 @@ public class UmlModelParser {
|
||||
for (Pseudostate cp : cpr.getEntries()) {
|
||||
StateData<String, String> cpStateData = new StateData<>(parent, regionId, cp.getName(), false);
|
||||
cpStateData.setPseudoStateKind(PseudoStateKind.ENTRY);
|
||||
stateDatas.add(cpStateData);
|
||||
addStateData(cpStateData);
|
||||
}
|
||||
}
|
||||
if (cpr.getExits() != null) {
|
||||
for (Pseudostate cp : cpr.getExits()) {
|
||||
StateData<String, String> cpStateData = new StateData<>(parent, regionId, cp.getName(), false);
|
||||
cpStateData.setPseudoStateKind(PseudoStateKind.EXIT);
|
||||
stateDatas.add(cpStateData);
|
||||
addStateData(cpStateData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,13 +268,18 @@ public class UmlModelParser {
|
||||
if (kind != null) {
|
||||
StateData<String, String> cpStateData = new StateData<>(parent, regionId, cp.getName(), false);
|
||||
cpStateData.setPseudoStateKind(kind);
|
||||
stateDatas.add(cpStateData);
|
||||
addStateData(cpStateData);
|
||||
}
|
||||
}
|
||||
|
||||
// do recursive handling of regions
|
||||
for (Region sub : state.getRegions()) {
|
||||
handleRegion(sub);
|
||||
if (!state.getRegions().isEmpty()) {
|
||||
// do recursive handling of regions
|
||||
for (Region sub : state.getRegions()) {
|
||||
handleRegion(sub);
|
||||
}
|
||||
} else if (state.getSubmachine() != null) {
|
||||
// submachine would be there i.e. with import
|
||||
handleStateMachine(state.getSubmachine());
|
||||
}
|
||||
}
|
||||
// pseudostates like choice, etc
|
||||
@@ -256,27 +306,27 @@ public class UmlModelParser {
|
||||
if (state.getKind() == PseudostateKind.CHOICE_LITERAL) {
|
||||
StateData<String, String> cpStateData = new StateData<>(parent, regionId, resolveName(state), false);
|
||||
cpStateData.setPseudoStateKind(PseudoStateKind.CHOICE);
|
||||
stateDatas.add(cpStateData);
|
||||
addStateData(cpStateData);
|
||||
} else if (state.getKind() == PseudostateKind.JUNCTION_LITERAL) {
|
||||
StateData<String, String> cpStateData = new StateData<>(parent, regionId, state.getName(), false);
|
||||
cpStateData.setPseudoStateKind(PseudoStateKind.JUNCTION);
|
||||
stateDatas.add(cpStateData);
|
||||
addStateData(cpStateData);
|
||||
} else if (state.getKind() == PseudostateKind.FORK_LITERAL) {
|
||||
StateData<String, String> cpStateData = new StateData<>(parent, regionId, state.getName(), false);
|
||||
cpStateData.setPseudoStateKind(PseudoStateKind.FORK);
|
||||
stateDatas.add(cpStateData);
|
||||
addStateData(cpStateData);
|
||||
} else if (state.getKind() == PseudostateKind.JOIN_LITERAL) {
|
||||
StateData<String, String> cpStateData = new StateData<>(parent, regionId, state.getName(), false);
|
||||
cpStateData.setPseudoStateKind(PseudoStateKind.JOIN);
|
||||
stateDatas.add(cpStateData);
|
||||
addStateData(cpStateData);
|
||||
} else if (state.getKind() == PseudostateKind.SHALLOW_HISTORY_LITERAL) {
|
||||
StateData<String, String> cpStateData = new StateData<>(parent, regionId, state.getName(), false);
|
||||
cpStateData.setPseudoStateKind(PseudoStateKind.HISTORY_SHALLOW);
|
||||
stateDatas.add(cpStateData);
|
||||
addStateData(cpStateData);
|
||||
} else if (state.getKind() == PseudostateKind.DEEP_HISTORY_LITERAL) {
|
||||
StateData<String, String> cpStateData = new StateData<>(parent, regionId, state.getName(), false);
|
||||
cpStateData.setPseudoStateKind(PseudoStateKind.HISTORY_DEEP);
|
||||
stateDatas.add(cpStateData);
|
||||
addStateData(cpStateData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -296,19 +346,19 @@ public class UmlModelParser {
|
||||
// realistic with state machines
|
||||
EList<Pseudostate> cprentries = ((ConnectionPointReference)transition.getSource()).getEntries();
|
||||
if (cprentries != null && cprentries.size() == 1 && cprentries.get(0).getKind() == PseudostateKind.ENTRY_POINT_LITERAL) {
|
||||
entrys.add(new EntryData<String, String>(cprentries.get(0).getName(), resolveName(transition.getTarget())));
|
||||
addEntryData(new EntryData<String, String>(cprentries.get(0).getName(), resolveName(transition.getTarget())));
|
||||
}
|
||||
EList<Pseudostate> cprexits = ((ConnectionPointReference)transition.getSource()).getExits();
|
||||
if (cprexits != null && cprexits.size() == 1 && cprexits.get(0).getKind() == PseudostateKind.EXIT_POINT_LITERAL) {
|
||||
exits.add(new ExitData<String, String>(cprexits.get(0).getName(), resolveName(transition.getTarget())));
|
||||
addExitData(new ExitData<String, String>(cprexits.get(0).getName(), resolveName(transition.getTarget())));
|
||||
}
|
||||
}
|
||||
|
||||
if (transition.getSource() instanceof Pseudostate) {
|
||||
if (((Pseudostate)transition.getSource()).getKind() == PseudostateKind.ENTRY_POINT_LITERAL) {
|
||||
entrys.add(new EntryData<String, String>(resolveName(transition.getSource()), resolveName(transition.getTarget())));
|
||||
addEntryData(new EntryData<String, String>(resolveName(transition.getSource()), resolveName(transition.getTarget())));
|
||||
} else if (((Pseudostate)transition.getSource()).getKind() == PseudostateKind.EXIT_POINT_LITERAL) {
|
||||
exits.add(new ExitData<String, String>(resolveName(transition.getSource()), resolveName(transition.getTarget())));
|
||||
addExitData(new ExitData<String, String>(resolveName(transition.getSource()), resolveName(transition.getTarget())));
|
||||
} else if (((Pseudostate)transition.getSource()).getKind() == PseudostateKind.CHOICE_LITERAL) {
|
||||
LinkedList<ChoiceData<String, String>> list = choices.get(resolveName(transition.getSource()));
|
||||
if (list == null) {
|
||||
@@ -373,12 +423,12 @@ public class UmlModelParser {
|
||||
if (transition.getTarget() instanceof ConnectionPointReference) {
|
||||
EList<Pseudostate> cprentries = ((ConnectionPointReference)transition.getTarget()).getEntries();
|
||||
if (cprentries != null && cprentries.size() == 1) {
|
||||
transitionDatas.add(new TransitionData<String, String>(resolveName(transition.getSource()),
|
||||
addTransitionData(new TransitionData<String, String>(resolveName(transition.getSource()),
|
||||
cprentries.get(0).getName(), signal.getName(), UmlUtils.resolveTransitionActions(transition, resolver),
|
||||
guard, UmlUtils.mapUmlTransitionType(transition)));
|
||||
}
|
||||
} else {
|
||||
transitionDatas.add(new TransitionData<String, String>(resolveName(transition.getSource()),
|
||||
addTransitionData(new TransitionData<String, String>(resolveName(transition.getSource()),
|
||||
resolveName(transition.getTarget()), signal.getName(), UmlUtils.resolveTransitionActions(transition, resolver),
|
||||
guard, UmlUtils.mapUmlTransitionType(transition)));
|
||||
}
|
||||
@@ -391,7 +441,7 @@ public class UmlModelParser {
|
||||
if (timeEvent.isRelative()) {
|
||||
count = 1;
|
||||
}
|
||||
transitionDatas.add(new TransitionData<String, String>(resolveName(transition.getSource()),
|
||||
addTransitionData(new TransitionData<String, String>(resolveName(transition.getSource()),
|
||||
resolveName(transition.getTarget()), period, count, UmlUtils.resolveTransitionActions(transition, resolver),
|
||||
guard, UmlUtils.mapUmlTransitionType(transition)));
|
||||
}
|
||||
@@ -400,7 +450,7 @@ public class UmlModelParser {
|
||||
|
||||
// create anonymous transition if needed
|
||||
if (shouldCreateAnonymousTransition(transition)) {
|
||||
transitionDatas.add(new TransitionData<String, String>(resolveName(transition.getSource()), resolveName(transition.getTarget()),
|
||||
addTransitionData(new TransitionData<String, String>(resolveName(transition.getSource()), resolveName(transition.getTarget()),
|
||||
null, UmlUtils.resolveTransitionActions(transition, resolver), resolveGuard(transition),
|
||||
UmlUtils.mapUmlTransitionType(transition)));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.uml;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.statemachine.uml.ResourcerResolver.Holder;
|
||||
|
||||
public class ResourcerResolverTests {
|
||||
|
||||
private ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
// private String[] EMPTY_LOCATIONS = new String[0];
|
||||
|
||||
// in a below tests,
|
||||
// we expect resources to resolve as a physical files
|
||||
|
||||
@Test
|
||||
public void testOneMainLocation() throws Exception {
|
||||
String mainLocation = "classpath:org/springframework/statemachine/uml/import-main/import-main.uml";
|
||||
ResourcerResolver resolver = new ResourcerResolver(resourceLoader, mainLocation, null);
|
||||
Holder[] resolved = resolver.resolve();
|
||||
assertThat(resolved, notNullValue());
|
||||
assertThat(resolved.length, is(1));
|
||||
assertThat(resolved[0].getUri().getPath(), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneMainResource() throws Exception {
|
||||
Resource mainResource = new ClassPathResource("org/springframework/statemachine/uml/import-main/import-main.uml");
|
||||
ResourcerResolver resolver = new ResourcerResolver(mainResource, null);
|
||||
Holder[] resolved = resolver.resolve();
|
||||
assertThat(resolved, notNullValue());
|
||||
assertThat(resolved.length, is(1));
|
||||
assertThat(resolved[0].getUri().getPath(), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleLocations() throws Exception {
|
||||
String mainLocation = "classpath:org/springframework/statemachine/uml/import-main/import-main.uml";
|
||||
String subLocation = "classpath:org/springframework/statemachine/uml/import-sub/import-sub.uml";
|
||||
ResourcerResolver resolver = new ResourcerResolver(resourceLoader, mainLocation, new String[]{subLocation});
|
||||
Holder[] resolved = resolver.resolve();
|
||||
assertThat(resolved, notNullValue());
|
||||
assertThat(resolved.length, is(2));
|
||||
assertThat(resolved[0].getUri().getPath(), notNullValue());
|
||||
assertThat(resolved[1].getUri().getPath(), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleResources() throws Exception {
|
||||
Resource mainResource = new ClassPathResource("org/springframework/statemachine/uml/import-main/import-main.uml");
|
||||
Resource subResource = new ClassPathResource("org/springframework/statemachine/uml/import-sub/import-sub.uml");
|
||||
ResourcerResolver resolver = new ResourcerResolver(mainResource, new Resource[]{subResource});
|
||||
Holder[] resolved = resolver.resolve();
|
||||
assertThat(resolved, notNullValue());
|
||||
assertThat(resolved.length, is(2));
|
||||
assertThat(resolved[0].getUri().getPath(), notNullValue());
|
||||
assertThat(resolved[1].getUri().getPath(), notNullValue());
|
||||
}
|
||||
|
||||
// in a below tests,
|
||||
// do monkey thing and setup resource which will not resolve to
|
||||
// an actual file as would happen with file inside boot fat-jar classpath
|
||||
|
||||
@Test
|
||||
public void testOneMainResourceNotPhysicalFile() throws Exception {
|
||||
Resource mainResource = new TestClassPathResource("org/springframework/statemachine/uml/import-main/import-main.uml");
|
||||
ResourcerResolver resolver = new ResourcerResolver(mainResource, null);
|
||||
Holder[] resolved = resolver.resolve();
|
||||
assertThat(resolved, notNullValue());
|
||||
assertThat(resolved.length, is(1));
|
||||
assertThat(resolved[0].getUri().getPath(), notNullValue());
|
||||
assertThat(resolved[0].getPath().toFile().exists(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleResourcesNotPhysicalFile() throws Exception {
|
||||
Resource mainResource = new TestClassPathResource("org/springframework/statemachine/uml/import-main/import-main.uml");
|
||||
Resource subResource = new TestClassPathResource("org/springframework/statemachine/uml/import-sub/import-sub.uml");
|
||||
ResourcerResolver resolver = new ResourcerResolver(mainResource, new Resource[]{subResource});
|
||||
Holder[] resolved = resolver.resolve();
|
||||
assertThat(resolved, notNullValue());
|
||||
assertThat(resolved.length, is(2));
|
||||
assertThat(resolved[0].getUri().getPath(), notNullValue());
|
||||
assertThat(resolved[0].getPath().toFile().exists(), is(true));
|
||||
assertThat(resolved[1].getUri().getPath(), notNullValue());
|
||||
assertThat(resolved[1].getPath().toFile().exists(), is(true));
|
||||
}
|
||||
|
||||
private static class TestClassPathResource extends ClassPathResource {
|
||||
|
||||
public TestClassPathResource(String path) {
|
||||
super(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFile() throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1136,6 +1136,17 @@ public class UmlStateMachineModelFactoryTests extends AbstractUmlTests {
|
||||
assertThat(stateMachine.getExtendedState().get("key", String.class), is("value"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testImportedSubMachine() {
|
||||
context.register(Config28.class);
|
||||
context.refresh();
|
||||
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
|
||||
|
||||
stateMachine.start();
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("MAIN2", "CHILD2"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
public static class Config2 extends StateMachineConfigurerAdapter<String, String> {
|
||||
@@ -1791,6 +1802,25 @@ public class UmlStateMachineModelFactoryTests extends AbstractUmlTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
public static class Config28 extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
|
||||
model
|
||||
.withModel()
|
||||
.factory(modelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineModelFactory<String, String> modelFactory() {
|
||||
Resource mainModel = new ClassPathResource("org/springframework/statemachine/uml/import-main/import-main.uml");
|
||||
Resource subModel = new ClassPathResource("org/springframework/statemachine/uml/import-sub/import-sub.uml");
|
||||
return new UmlStateMachineModelFactory(mainModel, new Resource[] { subModel });
|
||||
}
|
||||
}
|
||||
|
||||
public static class LatchAction implements Action<String, String> {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -97,4 +97,25 @@ public class DocsUmlSampleTests1 {
|
||||
}
|
||||
}
|
||||
// end::snippetB[]
|
||||
|
||||
// tag::snippetC[]
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
public static class Config3 extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
|
||||
model
|
||||
.withModel()
|
||||
.factory(modelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StateMachineModelFactory<String, String> modelFactory() {
|
||||
return new UmlStateMachineModelFactory(
|
||||
"classpath:org/springframework/statemachine/uml/import-main/import-main.uml",
|
||||
new String[] { "classpath:org/springframework/statemachine/uml/import-sub/import-sub.uml" });
|
||||
}
|
||||
}
|
||||
// end::snippetC[]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<architecture:ArchitectureDescription xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:architecture="http://www.eclipse.org/papyrus/infra/core/architecture" contextId="org.eclipse.papyrus.infra.services.edit.TypeContext"/>
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.3/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/gmfdiag/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_9FcQETIkEeuiF9TAc5z9jA" type="PapyrusUMLStateMachineDiagram" name="State Machine Diagram" measurementUnit="Pixel">
|
||||
<children xmi:type="notation:Shape" xmi:id="_9FcQEjIkEeuiF9TAc5z9jA" type="StateMachine_Shape">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_9FcQEzIkEeuiF9TAc5z9jA" type="StateMachine_NameLabel">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9FcQFDIkEeuiF9TAc5z9jA" width="700" height="20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:BasicCompartment" xmi:id="_9FcQFTIkEeuiF9TAc5z9jA" type="StateMachine_RegionCompartment">
|
||||
<children xmi:type="notation:Shape" xmi:id="_9FcQFjIkEeuiF9TAc5z9jA" type="Region_Shape">
|
||||
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_9Fc3IDIkEeuiF9TAc5z9jA" source="RegionAnnotationKey">
|
||||
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_9Fc3ITIkEeuiF9TAc5z9jA" key="RegionZoneKey" value=""/>
|
||||
</eAnnotations>
|
||||
<children xmi:type="notation:BasicCompartment" xmi:id="_9Fc3IjIkEeuiF9TAc5z9jA" type="Region_SubvertexCompartment">
|
||||
<children xmi:type="notation:Shape" xmi:id="_T9844DIlEeuiF9TAc5z9jA" type="State_Shape">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_T99f8DIlEeuiF9TAc5z9jA" type="State_NameLabel"/>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_T99f8TIlEeuiF9TAc5z9jA" type="State_FloatingNameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_T99f8jIlEeuiF9TAc5z9jA" x="40"/>
|
||||
</children>
|
||||
<children xmi:type="notation:BasicCompartment" xmi:id="_T99f8zIlEeuiF9TAc5z9jA" type="State_RegionCompartment">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_T99f9DIlEeuiF9TAc5z9jA"/>
|
||||
</children>
|
||||
<element xmi:type="uml:State" href="import-main.uml#_T92yQDIlEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_T9844TIlEeuiF9TAc5z9jA" x="109" y="50"/>
|
||||
</children>
|
||||
<children xmi:type="notation:Shape" xmi:id="_VoRFoDIlEeuiF9TAc5z9jA" type="State_Shape">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_VoRFojIlEeuiF9TAc5z9jA" type="State_NameLabel"/>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_VoRFozIlEeuiF9TAc5z9jA" type="State_FloatingNameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_VoRFpDIlEeuiF9TAc5z9jA" x="40"/>
|
||||
</children>
|
||||
<children xmi:type="notation:BasicCompartment" xmi:id="_VoRFpTIlEeuiF9TAc5z9jA" type="State_RegionCompartment">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_VoRFpjIlEeuiF9TAc5z9jA"/>
|
||||
</children>
|
||||
<element xmi:type="uml:State" href="import-main.uml#_VoLmEDIlEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_VoRFoTIlEeuiF9TAc5z9jA" x="249" y="50"/>
|
||||
</children>
|
||||
<children xmi:type="notation:Shape" xmi:id="_XaYjgDIlEeuiF9TAc5z9jA" type="Pseudostate_InitialShape">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_XaYjgjIlEeuiF9TAc5z9jA" type="Pseudostate_InitialFloatingNameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_XaYjgzIlEeuiF9TAc5z9jA" x="25" y="3"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_XaYjhDIlEeuiF9TAc5z9jA" type="Pseudostate_InitialStereotypeLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_XaZKkDIlEeuiF9TAc5z9jA" x="25" y="-10"/>
|
||||
</children>
|
||||
<element xmi:type="uml:Pseudostate" href="import-main.uml#_XaQnsDIlEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_XaYjgTIlEeuiF9TAc5z9jA" x="29" y="50"/>
|
||||
</children>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9Fc3IzIkEeuiF9TAc5z9jA"/>
|
||||
</children>
|
||||
<element xmi:type="uml:Region" href="import-main.uml#_9FcQEDIkEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9Fc3JDIkEeuiF9TAc5z9jA" width="700" height="280"/>
|
||||
</children>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9Fc3JTIkEeuiF9TAc5z9jA" y="20" width="700" height="280"/>
|
||||
</children>
|
||||
<element xmi:type="uml:StateMachine" href="import-main.uml#_9FbpADIkEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9Fc3JjIkEeuiF9TAc5z9jA" x="30" y="30" width="700" height="300"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:StringValueStyle" xmi:id="_9Fc3JzIkEeuiF9TAc5z9jA" name="diagram_compatibility_version" stringValue="1.4.0"/>
|
||||
<styles xmi:type="notation:DiagramStyle" xmi:id="_9Fc3KDIkEeuiF9TAc5z9jA"/>
|
||||
<styles xmi:type="style:PapyrusDiagramStyle" xmi:id="_9Fc3KTIkEeuiF9TAc5z9jA" diagramKindId="org.eclipse.papyrus.uml.diagram.stateMachine">
|
||||
<owner xmi:type="uml:Model" href="import-main.uml#_9FX-oDIkEeuiF9TAc5z9jA"/>
|
||||
</styles>
|
||||
<element xmi:type="uml:StateMachine" href="import-main.uml#_9FbpADIkEeuiF9TAc5z9jA"/>
|
||||
<edges xmi:type="notation:Connector" xmi:id="_ZIx_ADIlEeuiF9TAc5z9jA" type="Transition_Edge" source="_XaYjgDIlEeuiF9TAc5z9jA" target="_T9844DIlEeuiF9TAc5z9jA">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_ZIx_AzIlEeuiF9TAc5z9jA" type="Transition_NameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_ZIx_BDIlEeuiF9TAc5z9jA" y="20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_ZIymEDIlEeuiF9TAc5z9jA" type="Transition_GuardLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_ZIymETIlEeuiF9TAc5z9jA" y="-20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_ZIymEjIlEeuiF9TAc5z9jA" type="Transition_StereotypeLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_ZIymEzIlEeuiF9TAc5z9jA" y="60"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:FontStyle" xmi:id="_ZIx_ATIlEeuiF9TAc5z9jA"/>
|
||||
<element xmi:type="uml:Transition" href="import-main.uml#_ZIlxwDIlEeuiF9TAc5z9jA"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZIx_AjIlEeuiF9TAc5z9jA" points="[78, 112, -643984, -643984]$[140, 120, -643984, -643984]"/>
|
||||
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZJGvIDIlEeuiF9TAc5z9jA" id="(0.9,0.6274193548387096)"/>
|
||||
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZJGvITIlEeuiF9TAc5z9jA" id="(0.0,0.45454545454545453)"/>
|
||||
</edges>
|
||||
<edges xmi:type="notation:Connector" xmi:id="_aPtx4DIlEeuiF9TAc5z9jA" type="Transition_Edge" source="_T9844DIlEeuiF9TAc5z9jA" target="_VoRFoDIlEeuiF9TAc5z9jA">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_aPtx4zIlEeuiF9TAc5z9jA" type="Transition_NameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_aPtx5DIlEeuiF9TAc5z9jA" y="20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_aPtx5TIlEeuiF9TAc5z9jA" type="Transition_GuardLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_aPtx5jIlEeuiF9TAc5z9jA" y="-20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_aPtx5zIlEeuiF9TAc5z9jA" type="Transition_StereotypeLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_aPtx6DIlEeuiF9TAc5z9jA" y="60"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:FontStyle" xmi:id="_aPtx4TIlEeuiF9TAc5z9jA"/>
|
||||
<element xmi:type="uml:Transition" href="import-main.uml#_aPiLsDIlEeuiF9TAc5z9jA"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_aPtx4jIlEeuiF9TAc5z9jA" points="[191, 120, -643984, -643984]$[280, 120, -643984, -643984]"/>
|
||||
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_aQFlUDIlEeuiF9TAc5z9jA" id="(1.0,0.45454545454545453)"/>
|
||||
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_aQFlUTIlEeuiF9TAc5z9jA" id="(0.0,0.45454545454545453)"/>
|
||||
</edges>
|
||||
</notation:Diagram>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_9FX-oDIkEeuiF9TAc5z9jA" name="import-main">
|
||||
<packageImport xmi:type="uml:PackageImport" xmi:id="_9FxAMDIkEeuiF9TAc5z9jA">
|
||||
<importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
|
||||
</packageImport>
|
||||
<packagedElement xmi:type="uml:StateMachine" xmi:id="_9FbpADIkEeuiF9TAc5z9jA" name="StateMachineMain">
|
||||
<region xmi:type="uml:Region" xmi:id="_9FcQEDIkEeuiF9TAc5z9jA" name="Region1">
|
||||
<transition xmi:type="uml:Transition" xmi:id="_ZIlxwDIlEeuiF9TAc5z9jA" source="_XaQnsDIlEeuiF9TAc5z9jA" target="_T92yQDIlEeuiF9TAc5z9jA"/>
|
||||
<transition xmi:type="uml:Transition" xmi:id="_aPiLsDIlEeuiF9TAc5z9jA" source="_T92yQDIlEeuiF9TAc5z9jA" target="_VoLmEDIlEeuiF9TAc5z9jA"/>
|
||||
<subvertex xmi:type="uml:State" xmi:id="_T92yQDIlEeuiF9TAc5z9jA" name="MAIN1"/>
|
||||
<subvertex xmi:type="uml:State" xmi:id="_VoLmEDIlEeuiF9TAc5z9jA" name="MAIN2">
|
||||
<submachine xmi:type="uml:StateMachine" href="../import-sub/import-sub.uml#_FylmYDIlEeuiF9TAc5z9jA"/>
|
||||
</subvertex>
|
||||
<subvertex xmi:type="uml:Pseudostate" xmi:id="_XaQnsDIlEeuiF9TAc5z9jA" name=""/>
|
||||
</region>
|
||||
</packagedElement>
|
||||
</uml:Model>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<architecture:ArchitectureDescription xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:architecture="http://www.eclipse.org/papyrus/infra/core/architecture" contextId="org.eclipse.papyrus.infra.services.edit.TypeContext"/>
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.3/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/gmfdiag/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Fym0gDIlEeuiF9TAc5z9jA" type="PapyrusUMLStateMachineDiagram" name="State Machine Diagram" measurementUnit="Pixel">
|
||||
<children xmi:type="notation:Shape" xmi:id="_Fym0gTIlEeuiF9TAc5z9jA" type="StateMachine_Shape">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_Fym0gjIlEeuiF9TAc5z9jA" type="StateMachine_NameLabel">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Fym0gzIlEeuiF9TAc5z9jA" width="700" height="20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:BasicCompartment" xmi:id="_Fym0hDIlEeuiF9TAc5z9jA" type="StateMachine_RegionCompartment">
|
||||
<children xmi:type="notation:Shape" xmi:id="_Fym0hTIlEeuiF9TAc5z9jA" type="Region_Shape">
|
||||
<eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_Fym0hjIlEeuiF9TAc5z9jA" source="RegionAnnotationKey">
|
||||
<details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_Fym0hzIlEeuiF9TAc5z9jA" key="RegionZoneKey" value=""/>
|
||||
</eAnnotations>
|
||||
<children xmi:type="notation:BasicCompartment" xmi:id="_Fym0iDIlEeuiF9TAc5z9jA" type="Region_SubvertexCompartment">
|
||||
<children xmi:type="notation:Shape" xmi:id="_IqzwsDIlEeuiF9TAc5z9jA" type="State_Shape">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_Iq0XwDIlEeuiF9TAc5z9jA" type="State_NameLabel"/>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_Iq0XwTIlEeuiF9TAc5z9jA" type="State_FloatingNameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_Iq0XwjIlEeuiF9TAc5z9jA" x="40"/>
|
||||
</children>
|
||||
<children xmi:type="notation:BasicCompartment" xmi:id="_Iq0XwzIlEeuiF9TAc5z9jA" type="State_RegionCompartment">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Iq0XxDIlEeuiF9TAc5z9jA"/>
|
||||
</children>
|
||||
<element xmi:type="uml:State" href="import-sub.uml#_IqvfQDIlEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_IqzwsTIlEeuiF9TAc5z9jA" x="109" y="50"/>
|
||||
</children>
|
||||
<children xmi:type="notation:Shape" xmi:id="_LtpPkDIlEeuiF9TAc5z9jA" type="State_Shape">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_Ltp2oDIlEeuiF9TAc5z9jA" type="State_NameLabel"/>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_Ltp2oTIlEeuiF9TAc5z9jA" type="State_FloatingNameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_Ltp2ojIlEeuiF9TAc5z9jA" x="40"/>
|
||||
</children>
|
||||
<children xmi:type="notation:BasicCompartment" xmi:id="_Ltp2ozIlEeuiF9TAc5z9jA" type="State_RegionCompartment">
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Ltp2pDIlEeuiF9TAc5z9jA"/>
|
||||
</children>
|
||||
<element xmi:type="uml:State" href="import-sub.uml#_LtkXEDIlEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_LtpPkTIlEeuiF9TAc5z9jA" x="249" y="50"/>
|
||||
</children>
|
||||
<children xmi:type="notation:Shape" xmi:id="_PK0hEDIlEeuiF9TAc5z9jA" type="Pseudostate_InitialShape">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_PK1IIDIlEeuiF9TAc5z9jA" type="Pseudostate_InitialFloatingNameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_PK1IITIlEeuiF9TAc5z9jA" x="25" y="3"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_PK1IIjIlEeuiF9TAc5z9jA" type="Pseudostate_InitialStereotypeLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_PK1IIzIlEeuiF9TAc5z9jA" x="25" y="-10"/>
|
||||
</children>
|
||||
<element xmi:type="uml:Pseudostate" href="import-sub.uml#_PKslQDIlEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_PK0hETIlEeuiF9TAc5z9jA" x="38" y="57"/>
|
||||
</children>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Fym0iTIlEeuiF9TAc5z9jA"/>
|
||||
</children>
|
||||
<element xmi:type="uml:Region" href="import-sub.uml#_FymNcDIlEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Fym0ijIlEeuiF9TAc5z9jA" width="700" height="280"/>
|
||||
</children>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Fym0izIlEeuiF9TAc5z9jA" y="20" width="700" height="280"/>
|
||||
</children>
|
||||
<element xmi:type="uml:StateMachine" href="import-sub.uml#_FylmYDIlEeuiF9TAc5z9jA"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Fym0jDIlEeuiF9TAc5z9jA" x="30" y="30" width="700" height="300"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:StringValueStyle" xmi:id="_Fym0jTIlEeuiF9TAc5z9jA" name="diagram_compatibility_version" stringValue="1.4.0"/>
|
||||
<styles xmi:type="notation:DiagramStyle" xmi:id="_Fym0jjIlEeuiF9TAc5z9jA"/>
|
||||
<styles xmi:type="style:PapyrusDiagramStyle" xmi:id="_Fym0jzIlEeuiF9TAc5z9jA" diagramKindId="org.eclipse.papyrus.uml.diagram.stateMachine">
|
||||
<owner xmi:type="uml:Model" href="import-sub.uml#_FyeRoDIlEeuiF9TAc5z9jA"/>
|
||||
</styles>
|
||||
<element xmi:type="uml:StateMachine" href="import-sub.uml#_FylmYDIlEeuiF9TAc5z9jA"/>
|
||||
<edges xmi:type="notation:Connector" xmi:id="_RRCmsDIlEeuiF9TAc5z9jA" type="Transition_Edge" source="_PK0hEDIlEeuiF9TAc5z9jA" target="_IqzwsDIlEeuiF9TAc5z9jA">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_RRCmszIlEeuiF9TAc5z9jA" type="Transition_NameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_RRCmtDIlEeuiF9TAc5z9jA" y="20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_RRCmtTIlEeuiF9TAc5z9jA" type="Transition_GuardLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_RRCmtjIlEeuiF9TAc5z9jA" y="-20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_RRCmtzIlEeuiF9TAc5z9jA" type="Transition_StereotypeLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_RRCmuDIlEeuiF9TAc5z9jA" y="60"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:FontStyle" xmi:id="_RRCmsTIlEeuiF9TAc5z9jA"/>
|
||||
<element xmi:type="uml:Transition" href="import-sub.uml#_RQ5cwDIlEeuiF9TAc5z9jA"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_RRCmsjIlEeuiF9TAc5z9jA" points="[87, 120, -643984, -643984]$[140, 120, -643984, -643984]"/>
|
||||
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_RRUTgDIlEeuiF9TAc5z9jA" id="(0.9,0.65)"/>
|
||||
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_RRUTgTIlEeuiF9TAc5z9jA" id="(0.0,0.45454545454545453)"/>
|
||||
</edges>
|
||||
<edges xmi:type="notation:Connector" xmi:id="_SN3bUDIlEeuiF9TAc5z9jA" type="Transition_Edge" source="_IqzwsDIlEeuiF9TAc5z9jA" target="_LtpPkDIlEeuiF9TAc5z9jA">
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_SN4CYDIlEeuiF9TAc5z9jA" type="Transition_NameLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_SN4CYTIlEeuiF9TAc5z9jA" y="20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_SN4CYjIlEeuiF9TAc5z9jA" type="Transition_GuardLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_SN4CYzIlEeuiF9TAc5z9jA" y="-20"/>
|
||||
</children>
|
||||
<children xmi:type="notation:DecorationNode" xmi:id="_SN4CZDIlEeuiF9TAc5z9jA" type="Transition_StereotypeLabel">
|
||||
<layoutConstraint xmi:type="notation:Location" xmi:id="_SN4CZTIlEeuiF9TAc5z9jA" y="60"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:FontStyle" xmi:id="_SN3bUTIlEeuiF9TAc5z9jA"/>
|
||||
<element xmi:type="uml:Transition" href="import-sub.uml#_SNtDQDIlEeuiF9TAc5z9jA"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_SN3bUjIlEeuiF9TAc5z9jA" points="[197, 120, -643984, -643984]$[280, 120, -643984, -643984]"/>
|
||||
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_SOLkYDIlEeuiF9TAc5z9jA" id="(1.0,0.45454545454545453)"/>
|
||||
<targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_SOLkYTIlEeuiF9TAc5z9jA" id="(0.0,0.45454545454545453)"/>
|
||||
</edges>
|
||||
</notation:Diagram>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_FyeRoDIlEeuiF9TAc5z9jA" name="import-sub">
|
||||
<packageImport xmi:type="uml:PackageImport" xmi:id="_FzAdIDIlEeuiF9TAc5z9jA">
|
||||
<importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
|
||||
</packageImport>
|
||||
<packagedElement xmi:type="uml:StateMachine" xmi:id="_FylmYDIlEeuiF9TAc5z9jA" name="StateMachineSub">
|
||||
<submachineState xmi:type="uml:State" href="../import-main/import-main.uml#_VoLmEDIlEeuiF9TAc5z9jA"/>
|
||||
<region xmi:type="uml:Region" xmi:id="_FymNcDIlEeuiF9TAc5z9jA" name="Region1">
|
||||
<transition xmi:type="uml:Transition" xmi:id="_RQ5cwDIlEeuiF9TAc5z9jA" source="_PKslQDIlEeuiF9TAc5z9jA" target="_IqvfQDIlEeuiF9TAc5z9jA"/>
|
||||
<transition xmi:type="uml:Transition" xmi:id="_SNtDQDIlEeuiF9TAc5z9jA" source="_IqvfQDIlEeuiF9TAc5z9jA" target="_LtkXEDIlEeuiF9TAc5z9jA"/>
|
||||
<subvertex xmi:type="uml:State" xmi:id="_IqvfQDIlEeuiF9TAc5z9jA" name="CHILD1"/>
|
||||
<subvertex xmi:type="uml:State" xmi:id="_LtkXEDIlEeuiF9TAc5z9jA" name="CHILD2"/>
|
||||
<subvertex xmi:type="uml:Pseudostate" xmi:id="_PKslQDIlEeuiF9TAc5z9jA" name=""/>
|
||||
</region>
|
||||
</packagedElement>
|
||||
</uml:Model>
|
||||
Reference in New Issue
Block a user