Repository: workcraft/workcraft
Issue: Confusing error message on net synthesis of deadlocked STG

To reproduce:
1. Create an STG with a deadlock, e.g. an empty STG would do.
2. Run `Conversion->Net synsesis [Petrify]` tool.

Observed behaviour:
A cryptic message from .g parser.

Expected behaviour:
An error message explaining why net synthesis cannot be performed.


Changed files:
PetriPlugin/src/org/workcraft/plugins/petri/tools/PetriSimulationTool.java, PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/TransformationTask.java, PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/SynthesisTask.java, CpogPlugin/src/org/workcraft/plugins/cpog/tools/PGMinerImportTool.java, PetriPlugin/src/org/workcraft/plugins/petri/Place.java

diff --git a/CpogPlugin/src/org/workcraft/plugins/cpog/tools/PGMinerImportTool.java b/CpogPlugin/src/org/workcraft/plugins/cpog/tools/PGMinerImportTool.java
index 7aa8cf3a9..c9af0fb9a 100644
--- a/CpogPlugin/src/org/workcraft/plugins/cpog/tools/PGMinerImportTool.java
+++ b/CpogPlugin/src/org/workcraft/plugins/cpog/tools/PGMinerImportTool.java
@@ -49,10 +49,7 @@ public class PGMinerImportTool implements Tool {
 
     @Override
     public void run(WorkspaceEntry we) {
-
-        File inputFile;
-        inputFile = getInputFile(we);
-
+        File inputFile = getInputFile(we);
         final Framework framework = Framework.getInstance();
         final GraphEditorPanel editor = framework.getMainWindow().getCurrentEditor();
         final ToolboxPanel toolbox = editor.getToolBox();
@@ -60,7 +57,6 @@ public class PGMinerImportTool implements Tool {
 
         try {
             if (inputFile != null) {
-
                 if (dialog.getExtractConcurrency()) {
                     PGMinerTask task = new PGMinerTask(inputFile, dialog.getSplit());
 
@@ -68,16 +64,13 @@ public class PGMinerImportTool implements Tool {
                     framework.getTaskManager().queue(task, "PGMiner", result);
                 } else {
                     Scanner k;
-
                     k = new Scanner(inputFile);
                     int i = 0;
                     double yPos = tool.getLowestVertex((VisualCpog) editor.getWorkspaceEntry().getModelEntry().getVisualModel()).getY() + 3;
                     editor.getWorkspaceEntry().captureMemento();
                     while (k.hasNext()) {
                         String line = k.nextLine();
-
                         tool.insertEventLog((VisualCpog) editor.getWorkspaceEntry().getModelEntry().getVisualModel(), i++, line.split(" "), yPos);
-
                         yPos = yPos + 5;
                     }
                     k.close();
diff --git a/PetriPlugin/src/org/workcraft/plugins/petri/Place.java b/PetriPlugin/src/org/workcraft/plugins/petri/Place.java
index 1ff061f34..2edca792a 100644
--- a/PetriPlugin/src/org/workcraft/plugins/petri/Place.java
+++ b/PetriPlugin/src/org/workcraft/plugins/petri/Place.java
@@ -28,7 +28,7 @@ import org.workcraft.observation.PropertyChangedEvent;
 
 @VisualClass(org.workcraft.plugins.petri.VisualPlace.class)
 public class Place extends MathNode {
-    public static final String PROPERTY_CAPACITY = "Capacity";
+    public static final String PROPERTY_CAPACITY = "Promised capacity";
     public static final String PROPERTY_TOKENS = "Tokens";
 
     protected int tokens = 0;
diff --git a/PetriPlugin/src/org/workcraft/plugins/petri/tools/PetriSimulationTool.java b/PetriPlugin/src/org/workcraft/plugins/petri/tools/PetriSimulationTool.java
index 4d3e2421f..b921e8ee7 100644
--- a/PetriPlugin/src/org/workcraft/plugins/petri/tools/PetriSimulationTool.java
+++ b/PetriPlugin/src/org/workcraft/plugins/petri/tools/PetriSimulationTool.java
@@ -38,6 +38,7 @@ import org.workcraft.plugins.petri.Place;
 import org.workcraft.plugins.petri.Transition;
 import org.workcraft.plugins.petri.VisualPlace;
 import org.workcraft.plugins.petri.VisualReplicaPlace;
+import org.workcraft.util.LogUtils;
 
 public class PetriSimulationTool extends SimulationTool {
 
@@ -141,7 +142,23 @@ public class PetriSimulationTool extends SimulationTool {
             }
         }
         if (isEnabledNode(transition)) {
+            HashMap<Place, Integer> capacity = new HashMap<>();
+            for (Node node: getUnderlyingPetri().getPostset(transition)) {
+                if (node instanceof Place) {
+                    Place place = (Place) node;
+                    capacity.put(place,  place.getCapacity());
+                }
+            }
             getUnderlyingPetri().fire(transition);
+            for (Node node: getUnderlyingPetri().getPostset(transition)) {
+                if (node instanceof Place) {
+                    Place place = (Place) node;
+                    if (place.getCapacity() > capacity.get(place)) {
+                        String placeRef = getUnderlyingPetri().getNodeReference(place);
+                        LogUtils.logWarningLine("Capacity of place '" + placeRef + "' is incresed to " + place.getCapacity() + ".");
+                    }
+                }
+            }
             result = true;
         }
         return result;
diff --git a/PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/SynthesisTask.java b/PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/SynthesisTask.java
index 8a0e6d53b..34e3c4bd8 100644
--- a/PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/SynthesisTask.java
+++ b/PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/SynthesisTask.java
@@ -144,7 +144,7 @@ public class SynthesisTask implements Task<SynthesisResult>, ExternalProcessList
         ExportTask exportTask = new ExportTask(stgExporter, model, stgFile.getAbsolutePath());
         Result<? extends Object> exportResult = framework.getTaskManager().execute(exportTask, "Exporting .g");
         if (exportResult.getOutcome() != Outcome.FINISHED) {
-            stgFile = null;
+            throw new RuntimeException("Unable to export the model.");
         }
         return stgFile;
     }
diff --git a/PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/TransformationTask.java b/PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/TransformationTask.java
index 84ddddbf4..978414e8d 100644
--- a/PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/TransformationTask.java
+++ b/PetrifyPlugin/src/org/workcraft/plugins/petrify/tasks/TransformationTask.java
@@ -33,6 +33,7 @@ import org.workcraft.util.ToolUtils;
 import org.workcraft.workspace.WorkspaceEntry;
 
 public class TransformationTask implements Task<TransformationResult>, ExternalProcessListener {
+    private static final String EXPORT_FAILED_MESSAGE = "Unable to export the model.";
     private WorkspaceEntry we;
     String[] args;
 
@@ -96,26 +97,28 @@ public class TransformationTask implements Task<TransformationResult>, ExternalP
             SubtaskMonitor<Object> mon = new SubtaskMonitor<>(monitor);
             Result<? extends ExternalProcessResult> res = task.run(mon);
 
-            if (res.getOutcome() == Outcome.CANCELLED) {
-                return new Result<TransformationResult>(Outcome.CANCELLED);
-            } else {
-                final Outcome outcome;
+            if (res.getOutcome() == Outcome.FINISHED) {
                 StgModel outStg = null;
-                if (res.getReturnValue().getReturnCode() == 0) {
-                    outcome = Outcome.FINISHED;
-                } else {
-                    outcome = Outcome.FAILED;
-                }
-                try {
-                    String out = outFile.exists() ? FileUtils.readAllText(outFile) : "";
+                if (outFile.exists()) {
+                    String out = FileUtils.readAllText(outFile);
                     ByteArrayInputStream outStream = new ByteArrayInputStream(out.getBytes());
-                    outStg = new DotGImporter().importSTG(outStream);
-                } catch (DeserialisationException e) {
-                    return Result.exception(e);
+                    try {
+                        outStg = new DotGImporter().importSTG(outStream);
+                    } catch (DeserialisationException e) {
+                        return Result.exception(e);
+                    }
                 }
                 TransformationResult result = new TransformationResult(res, outStg);
-                return new Result<TransformationResult>(outcome, result);
+                if (res.getReturnValue().getReturnCode() == 0) {
+                    return Result.finished(result);
+                } else {
+                    return Result.failed(result);
+                }
+            }
+            if (res.getOutcome() == Outcome.CANCELLED) {
+                return Result.cancelled();
             }
+            return Result.failed(null);
         } catch (Throwable e) {
             throw new RuntimeException(e);
         } finally {
@@ -141,12 +144,12 @@ public class TransformationTask implements Task<TransformationResult>, ExternalP
         File modelFile = new File(directory, "original" + extension);
         try {
             ExportTask exportTask = Export.createExportTask(model, modelFile, format, framework.getPluginManager());
-            final Result<? extends Object> exportResult = framework.getTaskManager().execute(exportTask, "Exporting model");
+            Result<? extends Object> exportResult = framework.getTaskManager().execute(exportTask, "Exporting model");
             if (exportResult.getOutcome() != Outcome.FINISHED) {
-                modelFile = null;
+                throw new RuntimeException(EXPORT_FAILED_MESSAGE);
             }
         } catch (SerialisationException e) {
-            throw new RuntimeException("Unable to export the model.");
+            throw new RuntimeException(EXPORT_FAILED_MESSAGE);
         }
         return modelFile;
     }