Skip to content

Commit

Permalink
fix: tapaal exporter is now actually compatible with tapaal
Browse files Browse the repository at this point in the history
  • Loading branch information
sillydan1 committed Feb 8, 2024
1 parent 874c2cf commit 8f9af98
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 28 deletions.
2 changes: 2 additions & 0 deletions core/src/main/java/dk/gtz/graphedit/spi/IExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ public interface IExporter {
* @return The name of the exporter
*/
String getName();

String getFileExtension();
}
12 changes: 9 additions & 3 deletions core/src/main/java/dk/gtz/graphedit/view/EditorController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.slf4j.LoggerFactory;

import dk.gtz.graphedit.exceptions.ExportException;
import dk.gtz.graphedit.exceptions.SerializationException;
import dk.gtz.graphedit.model.ModelProject;
import dk.gtz.graphedit.serialization.IModelSerializer;
import dk.gtz.graphedit.spi.IPluginsContainer;
Expand Down Expand Up @@ -142,15 +143,20 @@ private void updateExporters() {
return;
}
var projectDir = Path.of(DI.get(ViewModelProject.class).rootDirectory().getValue());
var exportedFilesCount = 0;
for(var file : projectDir.toFile().listFiles()) {
try {
var fileName = PlatformUtils.removeFileExtension(file.getName());
var resource = DI.get(IModelSerializer.class).deserializeProjectResource(file);
var newFilePath = newFolderPath.get().toPath().resolve(file.getName());
var newFilePath = newFolderPath.get().toPath().resolve(fileName + exporter.getFileExtension());
exporter.exportFile(resource, newFilePath);
} catch(ExportException | IOException exc) {
logger.info("failed to export file: '{}', reason: {}", exc.getMessage(), file.getName());
logger.info("successfully exported '{}'", newFilePath.getFileName().toString());
exportedFilesCount++;
} catch(Exception exc) {
logger.warn("unable to export file: '{}', reason: {}", file.getName(), exc.getMessage());
}
}
logger.info("exported {} models", exportedFilesCount);
});
exportFileMenu.getItems().add(fileExporter);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Arc {
@JacksonXmlProperty(isAttribute = true)
private String id;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package dk.gtz.graphedit.plugins.syntaxes.petrinet.importing.tapaal;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Arcpath {
@JacksonXmlProperty(isAttribute = true)
private boolean arcPointType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package dk.gtz.graphedit.plugins.syntaxes.petrinet.importing.tapaal;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;


@JsonIgnoreProperties(ignoreUnknown = true)
public class Feature {
@JacksonXmlProperty(isAttribute = true)
private boolean isGame;
Expand All @@ -13,7 +14,7 @@ public boolean isGame() {
return isGame;
}

public Feature setGame(boolean isGame) {
public Feature setIsGame(boolean isGame) {
this.isGame = isGame;
return this;
}
Expand All @@ -22,7 +23,7 @@ public boolean isTimed() {
return isTimed;
}

public Feature setTimed(boolean isTimed) {
public Feature setIsTimed(boolean isTimed) {
this.isTimed = isTimed;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package dk.gtz.graphedit.plugins.syntaxes.petrinet.importing.tapaal;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;


@JsonIgnoreProperties(ignoreUnknown = true)
public class KBound {
@JacksonXmlProperty(isAttribute = true)
private int bound;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Net {
@JacksonXmlProperty(isAttribute = true)
private boolean active;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package dk.gtz.graphedit.plugins.syntaxes.petrinet.importing.tapaal;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Place {
@JacksonXmlProperty(isAttribute = true)
private boolean displayName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,18 @@ public String getName() {
return "tapaal";
}

@Override
public String getFileExtension() {
return ".tapn";
}

@Override
public void exportFile(ModelProjectResource resource, Path newFilePath) throws ExportException {
var syntaxName = Optional.ofNullable(resource.metadata().get("graphedit_syntax"));
if(!syntaxName.isPresent())
throw new ExportException("No syntax specified for resource");
if(!syntaxName.get().equals(this.syntaxName))
throw new ExportException("Invalid syntax for TapaalPNMLExporter '%s' (expected '%s')".formatted(syntaxName.get(), syntaxName));
throw new ExportException("Invalid syntax for TapaalPNMLExporter '%s' (expected '%s')".formatted(syntaxName.get(), this.syntaxName));
var pnml = fromResource(resource);
try {
xmlMapper.writeValue(newFilePath.toFile(), pnml);
Expand All @@ -56,21 +61,23 @@ private PNML fromResource(ModelProjectResource resource) throws ExportException
throw new ExportException("No name metadata specified for exported resource");

var kbound = new KBound().setBound(0);
var feature = new Feature().setGame(false).setTimed(false);
var feature = new Feature().setIsGame(false).setIsTimed(false);
var net = new Net()
.setActive(true)
.setId(name.get())
.setType("P/T net");

var places = new ArrayList<Place>();
var transitions = new ArrayList<Transition>();
// NOTE: ids and names MUST BE THE SAME for some moronic reason
for(var vertex : resource.syntax().vertices().entrySet()) {
if(vertex.getValue() instanceof ModelPlace modelPlace) {
var vname = "_" + vertex.getKey().toString().replace('-','_'); // TODO: also fix importer
places.add(new Place()
.setId(vertex.getKey().toString())
.setId(vname)
.setDisplayName(false)
.setInvariant("")
.setName("")
.setInvariant("< inf")
.setName(vname)
.setNameOffsetX(0)
.setNameOffsetY(0)
.setPositionX(vertex.getValue().position.x())
Expand All @@ -79,12 +86,13 @@ private PNML fromResource(ModelProjectResource resource) throws ExportException
continue;
}
if(vertex.getValue() instanceof ModelTransition) {
var vname = "_" + vertex.getKey().toString().replace('-','_');
transitions.add(new Transition()
.setId(vertex.getKey().toString())
.setId(vname)
.setAngle(0)
.setDisplayName(false)
.setInfiniteServer(false) // TODO: what is this? and is it required for regular P/N nets?
.setName("")
.setName(vname)
.setNameOffsetX(0)
.setNameOffsetY(0)
.setPlayer(0) // TODO: what is this? and is it required for regular P/N nets?
Expand All @@ -100,16 +108,23 @@ private PNML fromResource(ModelProjectResource resource) throws ExportException
var arcs = new ArrayList<Arc>();
for(var edge : resource.syntax().edges().entrySet()) {
if(edge.getValue() instanceof ModelArc modelArc) {
arcs.add(new Arc()
.setId(edge.getKey().toString())
.setInscription("") // TODO: what is this? and is it required for regular P/N nets?
var ename = "_"+edge.getKey().toString().replace('-','_');
// NOTE: If P>T(timed) = [0,inf) | T>P(normal) = weight
// This is because of... insanity
var arc = new Arc()
.setId(ename)
.setNameOffsetX(0)
.setNameOffsetY(0)
.setSource(modelArc.source.toString())
.setTarget(modelArc.target.toString())
.setType("normal") // TODO: what is this? and is it required for regular P/N nets?
.setSource("_" + modelArc.source.toString().replace('-','_'))
.setTarget("_" + modelArc.target.toString().replace('-','_'))
.setWeight(modelArc.weight)
.setArcpaths(new ArrayList<Arcpath>()));
.setArcpaths(new ArrayList<Arcpath>());
var source = resource.syntax().vertices().get(modelArc.source);
if(source instanceof ModelPlace)
arc.setInscription("[0,inf)").setType("timed");
else
arc.setInscription(String.valueOf(modelArc.weight)).setType("normal");
arcs.add(arc);
continue;
}
logger.warn("cannot export [edge]({}): not an Arc", edge.getKey());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,32 +63,44 @@ public List<ImportResult> importFiles(List<File> importFiles) throws ImportExcep
return result;
}

private UUID getUUIDFromPnmlId(String id) {
if(!id.startsWith("_"))
return UUID.randomUUID();
try {
return UUID.fromString(id.substring(1).replace('_','-'));
} catch(IllegalArgumentException e) {
return UUID.randomUUID();
}
}

private ModelProjectResource fromNet(Net net) {
var vertexIdMapping = new HashMap<String,UUID>();
var vertices = new HashMap<UUID,ModelVertex>();
for(var place : net.getPlaces()) {
var placeLocation = new ModelPoint(place.getPositionX(), place.getPositionY());
var modelPlace = new ModelPlace(placeLocation, place.getInitialMarking());
var newUUID = UUID.randomUUID();
var newUUID = getUUIDFromPnmlId(place.getId());
vertices.put(newUUID, modelPlace);
vertexIdMapping.put(place.getId(), newUUID);
}
for(var transition : net.getTransitions()) {
var transitionLocation = new ModelPoint(transition.getPositionX(), transition.getPositionY());
var modelTransition = new ModelTransition(transitionLocation);
var newUUID = UUID.randomUUID();
var newUUID = getUUIDFromPnmlId(transition.getId());
vertices.put(newUUID, modelTransition);
vertexIdMapping.put(transition.getId(), newUUID);
}
var edges = new HashMap<UUID,dk.gtz.graphedit.model.ModelEdge>();
for(var arc : net.getArcs()) {
var sourceUUID = vertexIdMapping.get(arc.getSource());
var targetUUID = vertexIdMapping.get(arc.getTarget());
var modelEdge = new ModelArc(sourceUUID, targetUUID);
edges.put(UUID.randomUUID(), modelEdge);
var modelEdge = new ModelArc(sourceUUID, targetUUID, arc.getWeight());
var newUUID = getUUIDFromPnmlId(arc.getId());
edges.put(newUUID, modelEdge);
}
var metadata = new HashMap<String,String>();
metadata.put("graphedit_syntax", syntaxName);
metadata.put("name", net.getId());
return new ModelProjectResource(metadata, new ModelGraph("", vertices, edges));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package dk.gtz.graphedit.plugins.syntaxes.petrinet.importing.tapaal;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Transition {
@JacksonXmlProperty(isAttribute = true)
private double angle;
private int angle;
@JacksonXmlProperty(isAttribute = true)
private boolean displayName;
@JacksonXmlProperty(isAttribute = true)
Expand All @@ -28,11 +30,11 @@ public class Transition {
@JacksonXmlProperty(isAttribute = true)
private boolean urgent;

public double getAngle() {
public int getAngle() {
return angle;
}

public Transition setAngle(double angle) {
public Transition setAngle(int angle) {
this.angle = angle;
return this;
}
Expand Down

0 comments on commit 8f9af98

Please sign in to comment.