diff --git a/README.md b/README.md index d6fd34c213d498495271c14b427e710354dc5d13..bc523cb5bb6b5a7bbfcb2e21f487ab0e6d7a1474 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # pnml-relast-splitter +* Currently not supported: reference-places and reference transitions \ No newline at end of file diff --git a/src/main/jastadd/Navigation.jrag b/src/main/jastadd/Navigation.jrag index 1818d4e72059664273ed36c01dea38601f53419a..14d2e5e639584b5c90c1e9bcf0f4ceb31c7b2250 100644 --- a/src/main/jastadd/Navigation.jrag +++ b/src/main/jastadd/Navigation.jrag @@ -68,4 +68,8 @@ aspect Navigation { to PetriNet.allArcs() for petriNet(); + coll java.util.Set<Page> PetriNet.allPages() [new java.util.HashSet()] root PetriNet; + Page contributes this + to PetriNet.allPages() + for petriNet(); } diff --git a/src/main/java/de/tudresden/inf/st/export/PnmlExporter.java b/src/main/java/de/tudresden/inf/st/export/PnmlExporter.java index a6e461716c8a9b10e9a1baee9bf8b77e08c401aa..66f13d94f32df064706122c5dee9e93dc3ac2697 100644 --- a/src/main/java/de/tudresden/inf/st/export/PnmlExporter.java +++ b/src/main/java/de/tudresden/inf/st/export/PnmlExporter.java @@ -1,18 +1,205 @@ package de.tudresden.inf.st.export; -import de.tudresden.inf.st.pnml.jastadd.model.PetriNet; +import de.tudresden.inf.st.pnml.jastadd.model.*; +import fr.lip6.move.pnml.framework.general.PnmlExport; import fr.lip6.move.pnml.framework.utils.ModelRepository; -import fr.lip6.move.pnml.framework.utils.exception.InvalidIDException; -import fr.lip6.move.pnml.ptnet.hlapi.PetriNetDocHLAPI; +import fr.lip6.move.pnml.framework.utils.exception.*; +import fr.lip6.move.pnml.ptnet.hlapi.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.*; public class PnmlExporter { + private static final Logger logger = LoggerFactory.getLogger(PnmlExporter.class); + public static String serializeToPnmlFile(PetriNet petriNet) throws InvalidIDException { - ModelRepository.getInstance().createDocumentWorkspace("void"); + ModelRepository.getInstance().createDocumentWorkspace("pnml-split-pre-purge"); + // build basic document and net PetriNetDocHLAPI doc = new PetriNetDocHLAPI(); + PetriNetHLAPI net = ComplexElementsConverter.convertPetriNetContainerToPnmlObject(petriNet, doc); + + // setup the page trees + Set<PageHLAPI> convertedPages = buildPageTrees(petriNet, net); + + // convert and include places + Set<PlaceHLAPI> convertedPlaces = convertAndIncludePlaces(petriNet, convertedPages); + + // convert and include transitions + Set<TransitionHLAPI> convertedTransitions = convertAndIncludeTransitions(petriNet, convertedPages); + + // convert and include arcs + Set<ArcHLAPI> convertedArcs = convertAndIncludeArcs(petriNet, convertedPages, convertedPlaces, convertedTransitions); + + // export the created objects to pnml + String targetPath = "src/main/gen/serialization/" + UUID.randomUUID().toString() + "-pres-plit.pnml"; + boolean hasFailed = false; + + try { + PnmlExport pex = new PnmlExport(); + pex.exportObject(doc, targetPath); + } catch (UnhandledNetType | OCLValidationFailed unhandledNetType) { + logger.error("EXCEPTION: " + Arrays.toString(unhandledNetType.getStackTrace())); + hasFailed = true; + } catch (IOException | ValidationFailedException | BadFileFormatException | OtherException e) { + logger.error(Arrays.toString(e.getStackTrace())); + hasFailed = true; + } + + // ctor of the workspace + try { + ModelRepository.getInstance().destroyCurrentWorkspace(); + } catch (VoidRepositoryException e) { + logger.error("EXCEPTION: " + Arrays.toString(e.getStackTrace())); + hasFailed = true; + } + + return hasFailed ? null : targetPath; + } + + private static Set<PlaceHLAPI> convertAndIncludePlaces(PetriNet petriNet, Set<PageHLAPI> convertedPages) { + + Set<PlaceHLAPI> convertedPlaces = new HashSet<>(); + + for (Place p : petriNet.allPlaces()) { + PlaceHLAPI convertedPlace = PrimitiveElementsConverter.convertPlaceToPnmlObject(p.asOutputSignalPlace()); + Page containingPage = p.ContainingPage(); + + for(PageHLAPI pageHLAPI : convertedPages){ + if(pageHLAPI.getId().equals(containingPage.getId())){ + assert convertedPlace != null; + convertedPlace.setContainerPageHLAPI(pageHLAPI); + break; + } + } + convertedPlaces.add(convertedPlace); + } + return convertedPlaces; + } + + private static Set<TransitionHLAPI> convertAndIncludeTransitions(PetriNet petriNet, Set<PageHLAPI> convertedPages) { + + Set<TransitionHLAPI> convertedTransitions = new HashSet<>(); + + for(Transition t: petriNet.allTransitions()){ + TransitionHLAPI convertedTransition = PrimitiveElementsConverter.convertTransitionToPnmlObject(t.asInputSignalTransition()); + Page containingPage = t.ContainingPage(); + + for(PageHLAPI pageHLAPI : convertedPages){ + if(pageHLAPI.getId().equals(containingPage.getId())){ + assert convertedTransition != null; + convertedTransition.setContainerPageHLAPI(pageHLAPI); + break; + } + } + convertedTransitions.add(convertedTransition); + } + return convertedTransitions; + } + + private static Set<ArcHLAPI> convertAndIncludeArcs(PetriNet petriNet, Set<PageHLAPI> convertedPages, Set<PlaceHLAPI> convertedPlaces, Set<TransitionHLAPI> convertedTransitions) { + + Set<ArcHLAPI> convertedArcs = new HashSet<>(); + for(Arc a : petriNet.allArcs()){ + + NodeHLAPI source = null; + NodeHLAPI target = null; + + for(TransitionHLAPI th : convertedTransitions){ + if(th.getId().equals(a.getSource().getId())){ + source = th; + break; + } + if(th.getId().equals(a.getTarget().getId())){ + target = th; + break; + } + } + + for(PlaceHLAPI ph : convertedPlaces){ + if(ph.getId().equals(a.getSource().getId())){ + source = ph; + break; + } + if(ph.getId().equals(a.getTarget().getId())){ + target = ph; + break; + } + } + + ArcHLAPI convertedArc = PrimitiveElementsConverter.convertArcToPnmlObject(a, source, target); + + Page containingPage = a.ContainingPage(); + + for(PageHLAPI pageHLAPI : convertedPages){ + if(pageHLAPI.getId().equals(containingPage.getId())){ + assert convertedArc != null; + convertedArc.setContainerPageHLAPI(pageHLAPI); + break; + } + } + + convertedArcs.add(convertedArc); + } + + return convertedArcs; + } + + private static Set<PageHLAPI> buildPageTrees(PetriNet petriNet, PetriNetHLAPI net) { + + Set<PageHLAPI> convertedPages = new HashSet<>(); + + getTopLevelPages(petriNet).forEach(page -> convertedPages.add(ComplexElementsConverter.convertTopLevelPageContainerToPnmlObject(page, net))); + + List<Page> nonTopLevelPages = getNonTopLevelPages(petriNet); + Set<String> processedPageIds = new HashSet<>(); + + for (int i = 0; i < nonTopLevelPages.size(); i++) { + Page parent = nonTopLevelPages.get(i).ContainingPage(); + + for (PageHLAPI convertedPage : convertedPages) { + if (parent.getId().equals(convertedPage.getId()) && !processedPageIds.contains(convertedPage.getId())) { + processedPageIds.add(convertedPage.getId()); + convertedPages.add(ComplexElementsConverter.convertNonTopLevelPageContainerToPnmlObject(nonTopLevelPages.get(i), convertedPage)); + break; + } + } + + if ((processedPageIds.size() != nonTopLevelPages.size()) && (i == (nonTopLevelPages.size() - 1))) { + i = -1; + } + } + + return convertedPages; + } + + private static List<Page> getTopLevelPages(PetriNet petriNet) { + + List<Page> topLevelPages = new ArrayList<>(); + + for (Page page : petriNet.allPages()) { + if (page.ContainingPage() == null) { + topLevelPages.add(page); + } + } + + return topLevelPages; + } + + private static List<Page> getNonTopLevelPages(PetriNet petriNet) { + + List<Page> nonTopLevelPages = new ArrayList<>(); + + for (Page page : petriNet.allPages()) { + if (page.ContainingPage() != null) { + nonTopLevelPages.add(page); + } + } - return null; + return nonTopLevelPages; } -} +} \ No newline at end of file diff --git a/src/main/java/de/tudresden/inf/st/export/PrimitiveElementsConverter.java b/src/main/java/de/tudresden/inf/st/export/PrimitiveElementsConverter.java index 99dc728a68f73dd2cbcc58a546d866d443189ab5..25371c363b86f1a2e0562df464659f56e1d0da59 100644 --- a/src/main/java/de/tudresden/inf/st/export/PrimitiveElementsConverter.java +++ b/src/main/java/de/tudresden/inf/st/export/PrimitiveElementsConverter.java @@ -53,10 +53,10 @@ public class PrimitiveElementsConverter { return null; } - public static ArcHLAPI convertArcToPnmlObject(Arc arc, PageHLAPI containingPage, NodeHLAPI source, NodeHLAPI target) { + public static ArcHLAPI convertArcToPnmlObject(Arc arc, NodeHLAPI source, NodeHLAPI target) { try { - ArcHLAPI a = new ArcHLAPI(arc.getId(), source, target, containingPage); + ArcHLAPI a = new ArcHLAPI(arc.getId(), source, target); if (arc.getNumToolspecific() > 0) { arc.getToolspecificList().forEach(toolInfo -> diff --git a/src/main/java/de/tudresden/inf/st/pnml/Main.java b/src/main/java/de/tudresden/inf/st/pnml/Main.java index a7f63555adb89eaf18b6b7f01983c82c14d85fb1..82656a4fa4621a16fa869ace9fcc78a21fa54a8b 100644 --- a/src/main/java/de/tudresden/inf/st/pnml/Main.java +++ b/src/main/java/de/tudresden/inf/st/pnml/Main.java @@ -5,6 +5,7 @@ import de.tudresden.inf.st.postprocessing.GlobalToLocalNetsPostProcessor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.List; public class Main { @@ -14,7 +15,9 @@ public class Main { public static void main(String[] args) { List<PetriNet> petriNets = PnmlParser.parsePnml("src/main/resources/minimal_global.pnml"); - GlobalToLocalNetsPostProcessor.disconnectNets(petriNets.get(0)); + List<List<PetriNet>> disconnectedPetriNets = new ArrayList<>(); + + petriNets.forEach(pn -> disconnectedPetriNets.add(GlobalToLocalNetsPostProcessor.disconnectNets(pn))); } } \ No newline at end of file