From 093ab12d09a634966c17d4b4d6e955521af39157 Mon Sep 17 00:00:00 2001 From: Marian Date: Tue, 29 Jun 2021 16:07:00 -0400 Subject: [PATCH 1/4] Added Formatter and Serializer for PlantUML --- .../tests/PlantUMLSerializingTest.xtend | 42 ++++++++++++++++ .../elite/mdd/plantuml/GeneratePlantUML.mwe2 | 7 ++- .../formatting2/PlantUMLFormatter.java | 49 +++++++++++++++++++ .../formatting2/PlantUMLFormatter2.xtend | 31 ++++++++++++ .../serializer/PlantUMLSemanticSequencer.java | 32 ++++++++++++ .../PlantUMLSyntacticSequencer.java | 8 +++ 6 files changed, 168 insertions(+), 1 deletion(-) create mode 100755 xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLSerializingTest.xtend mode change 100644 => 100755 xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/GeneratePlantUML.mwe2 create mode 100755 xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter.java create mode 100755 xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter2.xtend create mode 100755 xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java create mode 100755 xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSyntacticSequencer.java diff --git a/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLSerializingTest.xtend b/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLSerializingTest.xtend new file mode 100755 index 0000000..f2b2980 --- /dev/null +++ b/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLSerializingTest.xtend @@ -0,0 +1,42 @@ +package elite.mdd.plantuml.tests + +import com.google.inject.Inject +import elite.mdd.plantuml.plantUML.Diagram +import org.eclipse.xtext.testing.InjectWith +import org.eclipse.xtext.testing.extensions.InjectionExtension +import org.eclipse.xtext.testing.util.ParseHelper +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.^extension.ExtendWith +import com.google.inject.Guice +import elite.mdd.plantuml.PlantUMLRuntimeModule +import org.eclipse.xtext.serializer.ISerializer +import org.junit.Assert + +@ExtendWith(InjectionExtension) +@InjectWith(PlantUMLInjectorProvider) +class PlantUMLSerializingTest { + + @Inject + ParseHelper parseHelper + + + @Test + def void oneParticipant() { + val result = parseHelper.parse(''' + @startuml + participant "p1" + actor "p2" + "p1" -> "p2" : m() + @enduml + ''') + + val injector = Guice.createInjector(new PlantUMLRuntimeModule) + val serializer = injector.getInstance(ISerializer) + val resultSerializer = serializer.serialize(result) + System.out.println(resultSerializer); + + + } + +} \ No newline at end of file diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/GeneratePlantUML.mwe2 b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/GeneratePlantUML.mwe2 old mode 100644 new mode 100755 index 0ae80a5..68517da --- a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/GeneratePlantUML.mwe2 +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/GeneratePlantUML.mwe2 @@ -35,7 +35,12 @@ Workflow { fileExtensions = "plantuml" serializer = { - generateStub = false + generateStub = true + generateXtendStub = false + } + formatter={ + generateStub=true + generateXtendStub = false } validator = { // composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter.java b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter.java new file mode 100755 index 0000000..8352fb2 --- /dev/null +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter.java @@ -0,0 +1,49 @@ +/* + * generated by Xtext 2.25.0 + */ +package elite.mdd.plantuml.formatting2; + +import elite.mdd.plantuml.plantUML.Diagram; +import elite.mdd.plantuml.plantUML.Participant; +import elite.mdd.plantuml.plantUML.ParticipantDefinition; +import elite.mdd.plantuml.plantUML.SequenceElement; + +import org.eclipse.xtext.AbstractElement; +import org.eclipse.xtext.formatting.impl.FormattingConfig; +import org.eclipse.xtext.formatting2.AbstractJavaFormatter; +import org.eclipse.xtext.formatting2.IFormattableDocument; +import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion; +import org.eclipse.xtext.xbase.services.XbaseGrammarAccess; + +import static elite.mdd.plantuml.plantUML.PlantUMLPackage.Literals; + +public class PlantUMLFormatter extends AbstractJavaFormatter { + + // See https://hub.packtpub.com/customizing-xtext-components/ + // See https://stackoverflow.com/questions/50904789/formatting-string-content-xtext-2-14 + + + public void configureFormatting(FormattingConfig c) { + c.setNoSpace().around(null);; + } + + protected void format(Diagram diagram, IFormattableDocument doc) { + // TODO: format HiddenRegions around keywords, attributes, cross references, etc. + for (SequenceElement sequenceElement : diagram.getElements()) { + doc.prepend(sequenceElement, this::newLine); + doc.format(sequenceElement); + doc.append(sequenceElement, this::newLine); + } + } + + protected void format(ParticipantDefinition participantDefinition, IFormattableDocument doc) { + doc.surround(regionFor(participantDefinition).feature(Literals.PARTICIPANT__NAME), this::noSpace); + doc.format(participantDefinition.getParticipant()); + } + + protected void format(Participant participant, IFormattableDocument doc) { + doc.surround(regionFor(participant).feature(Literals.PARTICIPANT__NAME), this::noSpace); + } + + // TODO: implement for RequestMessageDefinition +} diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter2.xtend b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter2.xtend new file mode 100755 index 0000000..679628b --- /dev/null +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter2.xtend @@ -0,0 +1,31 @@ +/* + * generated by Xtext 2.25.0 + */ +package elite.mdd.plantuml.formatting2 + +import com.google.inject.Inject +import elite.mdd.plantuml.plantUML.Diagram +import elite.mdd.plantuml.plantUML.ParticipantDefinition +import elite.mdd.plantuml.services.PlantUMLGrammarAccess +import org.eclipse.xtext.formatting2.AbstractFormatter2 +import org.eclipse.xtext.formatting2.IFormattableDocument + +class PlantUMLFormatter2 extends AbstractFormatter2 { + + @Inject extension PlantUMLGrammarAccess + + def dispatch void format(Diagram diagram, extension IFormattableDocument document) { + // TODO: format HiddenRegions around keywords, attributes, cross references, etc. + for (sequenceElement : diagram.elements) { + sequenceElement.append[newLine] + sequenceElement.format + } + } + + def dispatch void format(ParticipantDefinition participantDefinition, extension IFormattableDocument document) { + // TODO: format HiddenRegions around keywords, attributes, cross references, etc. + participantDefinition.participant.format + } + + // TODO: implement for RequestMessageDefinition +} diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java new file mode 100755 index 0000000..b9846c1 --- /dev/null +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java @@ -0,0 +1,32 @@ +/* + * generated by Xtext 2.25.0 + */ +package elite.mdd.plantuml.serializer; + +import org.eclipse.xtext.serializer.ISerializationContext; +import org.eclipse.xtext.serializer.acceptor.SequenceFeeder; +import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient; + +import com.google.inject.Inject; + +import elite.mdd.plantuml.plantUML.Participant; +import elite.mdd.plantuml.plantUML.PlantUMLPackage; +import elite.mdd.plantuml.services.PlantUMLGrammarAccess; + +public class PlantUMLSemanticSequencer extends AbstractPlantUMLSemanticSequencer { + + @Inject + private PlantUMLGrammarAccess grammarAccess; + + @Override + protected void sequence_Participant(ISerializationContext context, Participant semanticObject) { + if (errorAcceptor != null) { + if (transientValues.isValueTransient(semanticObject, PlantUMLPackage.Literals.PARTICIPANT__NAME) == ValueTransient.YES) + errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, PlantUMLPackage.Literals.PARTICIPANT__NAME)); + } + SequenceFeeder feeder = createSequencerFeeder(context, semanticObject); + feeder.accept(grammarAccess.getParticipantAccess().getNameIDTerminalRuleCall_1_0(), semanticObject.getName()); + feeder.finish(); + } + +} diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSyntacticSequencer.java b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSyntacticSequencer.java new file mode 100755 index 0000000..cbf8774 --- /dev/null +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSyntacticSequencer.java @@ -0,0 +1,8 @@ +/* + * generated by Xtext 2.25.0 + */ +package elite.mdd.plantuml.serializer; + + +public class PlantUMLSyntacticSequencer extends AbstractPlantUMLSyntacticSequencer { +} From 48957274555004cc463f907e5dc84654bc9d2da5 Mon Sep 17 00:00:00 2001 From: Marian Date: Thu, 1 Jul 2021 12:07:45 -0400 Subject: [PATCH 2/4] Changed Grammar to better implement formatter and Serializer --- .../src/elite/mdd/plantuml/PlantUML.xtext | 62 ++++++++++++++----- 1 file changed, 46 insertions(+), 16 deletions(-) mode change 100644 => 100755 xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext old mode 100644 new mode 100755 index 2822d14..a7a1c08 --- a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext @@ -15,23 +15,36 @@ ParticipantDefinition: shape=ParticipantShape participant=Participant; Participant: - NamedParticipant | UnnamedParticipant | AnonymousParticipant |{Participant} name = 'self' ; + NamedParticipant + | UnnamedParticipant + | AnonymousParticipant + | QuotedNamedParticipant + | QuotedUnnamedParticipant + | QuotedAnonymousParticipant + ; -NamedParticipant returns Participant: - {Participant} '"' label=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID ('strict')?)? - '"' 'as' name=ID +NamedParticipant: + label=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID ('strict')?)? 'as' name=ID ; -UnnamedParticipant returns Participant: - {Participant} '"'name=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID ('strict')?)? '"' +UnnamedParticipant: + name=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID ('strict')?)? ; -AnonymousParticipant returns Participant: - {Participant} '":' type = ID ('ref' interactionIdent=ID ('strict')?)?'"' +AnonymousParticipant: + ':' type = ID ('ref' interactionIdent=ID ('strict')?)? ; +// Quoted Version of the Participants +QuotedNamedParticipant: + '"' label=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID ('strict')?)? + '"' 'as' name=ID +; -ParticipantMention: - ID | ':' ID +QuotedUnnamedParticipant: + '"'name=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID ('strict')?)? '"' +; +QuotedAnonymousParticipant: + '":' type = ID ('ref' interactionIdent=ID ('strict')?)?'"' ; enum ParticipantShape: @@ -41,21 +54,38 @@ enum ParticipantShape: | COLLECTIONS='collections' | ENTITY='entity' | DATABASE='database' - | PARTICIPANT='participant'; + | PARTICIPANT='participant' + ; // Messages MessageDefinition: RequestMessageDefinition - | ReplyMessageDefinition; + | ReplyMessageDefinition + | QuotedRequestMessageDefinition + | QuotedReplyMessageDefinition + ; + +QuotedRequestMessageDefinition: + ('"' sender=[Participant] '"' arrow=(RightRequest) '"' receiver=[Participant] '"') (':' message=RequestMessage) + | ('"'receiver=[Participant]'"' arrow=(LeftRequest) '"' sender=[Participant] '"') (':' message=RequestMessage) + ; + +QuotedReplyMessageDefinition: + ('"' sender=[Participant] '"' arrow=RightReply '"' receiver=[Participant] '"') (':' message=ReplyMessage) + | ('"' receiver=[Participant] '"' arrow=LeftReply '"' sender=[Participant] '"') (':' message=ReplyMessage) + ; + RequestMessageDefinition: - (('"')? sender=[Participant|ParticipantMention] ('"')? arrow=(RightRequest) ('"')? receiver=[Participant] ('"')?) (':' message=RequestMessage) - | (('"')?receiver=[Participant]('"')? arrow=(LeftRequest) ('"')?sender=[Participant]('"')?) (':' message=RequestMessage); + (sender=[Participant] arrow=(RightRequest) receiver=[Participant]) (':' message=RequestMessage) + | (receiver=[Participant] arrow=(LeftRequest) sender=[Participant]) (':' message=RequestMessage) + ; ReplyMessageDefinition: - (('"')?sender=[Participant]('"')? arrow=RightReply ('"')?receiver=[Participant]('"')?) (':' message=ReplyMessage) - | (('"')?receiver=[Participant]('"')? arrow=LeftReply ('"')?sender=[Participant]('"')?) (':' message=ReplyMessage); + (sender=[Participant] arrow=RightReply receiver=[Participant]) (':' message=ReplyMessage) + | (receiver=[Participant] arrow=LeftReply sender=[Participant]) (':' message=ReplyMessage) + ; // TODO: Handle \" RequestMessage: From 746fb4af891756c4d0734a52f2f68b199d31eab3 Mon Sep 17 00:00:00 2001 From: Marian Date: Fri, 2 Jul 2021 11:06:19 -0400 Subject: [PATCH 3/4] Finished Implementing Serializer and Formatter for Messages and Participants --- .../plantuml/tests/PlantUMLParsingTest.xtend | 11 +- .../tests/PlantUMLSerializingTest.xtend | 69 ++++++++-- .../src/elite/mdd/plantuml/PlantUML.xtext | 35 ++++- .../formatting2/PlantUMLFormatter.java | 121 +++++++++++++++-- .../formatting2/PlantUMLFormatter2.xtend | 31 ----- .../serializer/PlantUMLSemanticSequencer.java | 126 ++++++++++++++++-- .../serializer/SerializerWrapper.java | 59 ++++++++ .../serializer/SpecialCharacters.java | 18 +++ 8 files changed, 400 insertions(+), 70 deletions(-) delete mode 100755 xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter2.xtend create mode 100755 xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/SerializerWrapper.java create mode 100755 xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/SpecialCharacters.java diff --git a/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLParsingTest.xtend b/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLParsingTest.xtend index 3eab832..9640022 100755 --- a/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLParsingTest.xtend +++ b/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLParsingTest.xtend @@ -14,6 +14,8 @@ import org.junit.jupiter.api.^extension.ExtendWith import org.junit.Assert import elite.mdd.plantuml.plantUML.ParticipantDefinition import elite.mdd.plantuml.plantUML.RequestMessageDefinition +import elite.mdd.plantuml.plantUML.impl.QuotedNamedParticipantImpl +import elite.mdd.plantuml.plantUML.QuotedUnnamedParticipant @ExtendWith(InjectionExtension) @InjectWith(PlantUMLInjectorProvider) @@ -29,8 +31,6 @@ class PlantUMLParsingTest { @enduml ''') Assertions.assertNotNull(result) - val errors = result.eResource.errors - Assertions.assertTrue(errors.size() == 1, '''Unexpected errors: «errors.join(", ")»''') } @Test @@ -77,7 +77,7 @@ class PlantUMLParsingTest { def void actorParticipantTest() { val result = parseHelper.parse(''' @startuml - actor "testParticipant" + actor "testParticipant: Type" @enduml ''') @@ -85,13 +85,15 @@ class PlantUMLParsingTest { val property = result.elements.head as ParticipantDefinition Assert.assertEquals("ACTOR", property.shape.getName()) - Assert.assertEquals("testParticipant", property.participant.getName()) + val participant = property.getParticipant() as QuotedUnnamedParticipant + Assert.assertEquals("testParticipant", participant.getName()) Assertions.assertNotNull(result) val errors = result.eResource.errors Assertions.assertTrue(errors.isEmpty, '''Unexpected errors: «errors.join(", ")»''') } + /* @Test def void boundaryParticipantTest() { val result = parseHelper.parse(''' @@ -308,5 +310,6 @@ class PlantUMLParsingTest { Assert.assertEquals(participant1.getParticipant(), messageDefinition.sender) Assert.assertEquals(participant2.getParticipant(), messageDefinition.receiver) } + */ } diff --git a/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLSerializingTest.xtend b/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLSerializingTest.xtend index f2b2980..71191b5 100755 --- a/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLSerializingTest.xtend +++ b/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLSerializingTest.xtend @@ -12,6 +12,7 @@ import com.google.inject.Guice import elite.mdd.plantuml.PlantUMLRuntimeModule import org.eclipse.xtext.serializer.ISerializer import org.junit.Assert +import elite.mdd.plantuml.serializer.SerializerWrapper @ExtendWith(InjectionExtension) @InjectWith(PlantUMLInjectorProvider) @@ -22,21 +23,73 @@ class PlantUMLSerializingTest { @Test - def void oneParticipant() { + def void participants() { val result = parseHelper.parse(''' @startuml - participant "p1" - actor "p2" - "p1" -> "p2" : m() + participant : Key2 + participant ": Key3" + participant "key1 : Key" + participant key2 : Key + participant lock : Lock ref AA + participant "lock2 : Lock ref AA strict" @enduml - ''') + '''); + + val serializeWrapper = new SerializerWrapper(); + val resultSerializer = serializeWrapper.serialize(result); + + Assert.assertEquals(resultSerializer, '''@startuml +participant ": Key2" +participant ": Key3" +participant "key1 : Key" as key1 +participant "key2 : Key" as key2 +participant "lock : Lock ref AA" as lock +participant "lock2 : Lock ref AA" as lock2 +@enduml +'''.toString()) + + } + + + @Test + def void messages() { + // The space between " and : in the last two messages is important because else it cannot be parsed correctly, as the message is considered null + val result = parseHelper.parse(''' + @startuml + participant "key1 : Key" + participant "lockName : LockType" as lock + key1 ->> lock : unlock() + "key1" ->> lock : unlock(s=0) + key1 ->> "lock" : unlock(s=0, i=1) + "key1" ->> "lock" : unlock(s=0, i=1, j=2) + key1 <<-- lock : unlock() + "key1" <<-- lock : unlock(s=0) + key1 <<-- "lock" : unlock(s=0, i=1) + "key1" <<-- "lock" : unlock(s=0, i=1, j=2) + @enduml + '''); + + val serializeWrapper = new SerializerWrapper(); + val resultSerializer = serializeWrapper.serialize(result); - val injector = Guice.createInjector(new PlantUMLRuntimeModule) - val serializer = injector.getInstance(ISerializer) - val resultSerializer = serializer.serialize(result) System.out.println(resultSerializer); + Assert.assertEquals(resultSerializer, '''@startuml +participant "key1 : Key" as key1 +participant "lockName : LockType" as lock +key1 ->> lock : unlock() +"key1" ->> lock : unlock(s= 0) +key1 ->> "lock" : unlock(s= 0, i= 1) +"key1" ->> "lock" : unlock(s= 0, i= 1, j= 2) +key1 <<-- lock : unlock() +"key1" <<-- lock : unlock(s= 0) +key1 <<-- "lock" : unlock(s= 0, i= 1) +"key1" <<-- "lock" : unlock(s= 0, i= 1, j= 2) +@enduml +'''.toString()) } + + } \ No newline at end of file diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext index a7a1c08..aae60b8 100755 --- a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext @@ -28,7 +28,9 @@ NamedParticipant: ; UnnamedParticipant: - name=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID ('strict')?)? + // name=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID ('strict')?)? + // Because of some weird problems in the serializer, static had to be removed in the unqouted version + name=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID)? ; AnonymousParticipant: ':' type = ID ('ref' interactionIdent=ID ('strict')?)? @@ -62,20 +64,43 @@ enum ParticipantShape: MessageDefinition: RequestMessageDefinition | ReplyMessageDefinition - | QuotedRequestMessageDefinition - | QuotedReplyMessageDefinition + | FullQuotedRequestMessageDefinition + | FullQuotedReplyMessageDefinition + | LeftQuotedRequestMessageDefinition + | LeftQuotedReplyMessageDefinition + | RightQuotedRequestMessageDefinition + | RightQuotedReplyMessageDefinition ; -QuotedRequestMessageDefinition: +FullQuotedRequestMessageDefinition: ('"' sender=[Participant] '"' arrow=(RightRequest) '"' receiver=[Participant] '"') (':' message=RequestMessage) | ('"'receiver=[Participant]'"' arrow=(LeftRequest) '"' sender=[Participant] '"') (':' message=RequestMessage) ; -QuotedReplyMessageDefinition: +FullQuotedReplyMessageDefinition: ('"' sender=[Participant] '"' arrow=RightReply '"' receiver=[Participant] '"') (':' message=ReplyMessage) | ('"' receiver=[Participant] '"' arrow=LeftReply '"' sender=[Participant] '"') (':' message=ReplyMessage) ; +LeftQuotedRequestMessageDefinition: + ('"' sender=[Participant] '"' arrow=(RightRequest) receiver=[Participant]) (':' message=RequestMessage) + | ('"' receiver=[Participant] '"' arrow=(LeftRequest) sender=[Participant]) (':' message=RequestMessage) + ; + +LeftQuotedReplyMessageDefinition: + ('"' sender=[Participant] '"' arrow=RightReply receiver=[Participant] ) (':' message=ReplyMessage) + | ('"' receiver=[Participant] '"' arrow=LeftReply sender=[Participant] ) (':' message=ReplyMessage) + ; + +RightQuotedRequestMessageDefinition: + (sender=[Participant] arrow=(RightRequest) '"' receiver=[Participant] '"') (':' message=RequestMessage) + | (receiver=[Participant] arrow=(LeftRequest) '"' sender=[Participant] '"') (':' message=RequestMessage) + ; + +RightQuotedReplyMessageDefinition: + (sender=[Participant] arrow=RightReply '"' receiver=[Participant] '"') (':' message=ReplyMessage) + | (receiver=[Participant] arrow=LeftReply '"' sender=[Participant] '"') (':' message=ReplyMessage) + ; RequestMessageDefinition: (sender=[Participant] arrow=(RightRequest) receiver=[Participant]) (':' message=RequestMessage) diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter.java b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter.java index 8352fb2..3ba1a33 100755 --- a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter.java +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter.java @@ -4,8 +4,24 @@ package elite.mdd.plantuml.formatting2; import elite.mdd.plantuml.plantUML.Diagram; +import elite.mdd.plantuml.plantUML.FullQuotedReplyMessageDefinition; +import elite.mdd.plantuml.plantUML.FullQuotedRequestMessageDefinition; +import elite.mdd.plantuml.plantUML.LeftQuotedReplyMessageDefinition; +import elite.mdd.plantuml.plantUML.LeftQuotedRequestMessageDefinition; +import elite.mdd.plantuml.plantUML.MessageDefinition; import elite.mdd.plantuml.plantUML.Participant; import elite.mdd.plantuml.plantUML.ParticipantDefinition; +import elite.mdd.plantuml.plantUML.QuotedAnonymousParticipant; +import elite.mdd.plantuml.plantUML.QuotedNamedParticipant; +import elite.mdd.plantuml.plantUML.QuotedUnnamedParticipant; +import elite.mdd.plantuml.plantUML.ReplyMessage; +import elite.mdd.plantuml.plantUML.ReplyMessageArgument; +import elite.mdd.plantuml.plantUML.ReplyMessageDefinition; +import elite.mdd.plantuml.plantUML.RequestMessage; +import elite.mdd.plantuml.plantUML.RequestMessageArgument; +import elite.mdd.plantuml.plantUML.RequestMessageDefinition; +import elite.mdd.plantuml.plantUML.RightQuotedReplyMessageDefinition; +import elite.mdd.plantuml.plantUML.RightQuotedRequestMessageDefinition; import elite.mdd.plantuml.plantUML.SequenceElement; import org.eclipse.xtext.AbstractElement; @@ -22,28 +38,107 @@ public class PlantUMLFormatter extends AbstractJavaFormatter { // See https://hub.packtpub.com/customizing-xtext-components/ // See https://stackoverflow.com/questions/50904789/formatting-string-content-xtext-2-14 - - public void configureFormatting(FormattingConfig c) { - c.setNoSpace().around(null);; - } - protected void format(Diagram diagram, IFormattableDocument doc) { - // TODO: format HiddenRegions around keywords, attributes, cross references, etc. for (SequenceElement sequenceElement : diagram.getElements()) { doc.prepend(sequenceElement, this::newLine); doc.format(sequenceElement); doc.append(sequenceElement, this::newLine); } } - - protected void format(ParticipantDefinition participantDefinition, IFormattableDocument doc) { - doc.surround(regionFor(participantDefinition).feature(Literals.PARTICIPANT__NAME), this::noSpace); - doc.format(participantDefinition.getParticipant()); + + protected void format(RequestMessageDefinition message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__SENDER), this::noSpace); + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__RECEIVER), this::noSpace); + doc.format(message.getMessage()); + } + + protected void format(FullQuotedRequestMessageDefinition message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__SENDER), this::noSpace); + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__RECEIVER), this::noSpace); + doc.format(message.getMessage()); + } + + protected void format(LeftQuotedRequestMessageDefinition message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__SENDER), this::noSpace); + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__RECEIVER), this::noSpace); + doc.format(message.getMessage()); + } + + protected void format(RightQuotedRequestMessageDefinition message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__SENDER), this::noSpace); + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__RECEIVER), this::noSpace); + doc.format(message.getMessage()); + } + + protected void format(RequestMessage message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.REQUEST_MESSAGE__NAME), this::noSpace); + for (RequestMessageArgument argument: message.getArguments()) { + doc.append(argument, this::noSpace); + doc.format(argument); + } + } + + protected void format(RequestMessageArgument argument, IFormattableDocument doc) { + doc.surround(regionFor(argument).feature(Literals.REQUEST_MESSAGE_ARGUMENT__NAME), this::noSpace); + } + + protected void format(ReplyMessageDefinition message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__SENDER), this::noSpace); + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__RECEIVER), this::noSpace); + doc.format(message.getMessage()); } - protected void format(Participant participant, IFormattableDocument doc) { - doc.surround(regionFor(participant).feature(Literals.PARTICIPANT__NAME), this::noSpace); + protected void format(FullQuotedReplyMessageDefinition message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__SENDER), this::noSpace); + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__RECEIVER), this::noSpace); + doc.format(message.getMessage()); } - // TODO: implement for RequestMessageDefinition + protected void format(LeftQuotedReplyMessageDefinition message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__SENDER), this::noSpace); + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__RECEIVER), this::noSpace); + doc.format(message.getMessage()); + } + + protected void format(RightQuotedReplyMessageDefinition message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__SENDER), this::noSpace); + doc.surround(regionFor(message).feature(Literals.MESSAGE_DEFINITION__RECEIVER), this::noSpace); + doc.format(message.getMessage()); + } + + protected void format(ReplyMessage message, IFormattableDocument doc) { + doc.surround(regionFor(message).feature(Literals.REPLY_MESSAGE__NAME), this::noSpace); + for (ReplyMessageArgument argument: message.getArguments()) { + doc.append(argument, this::noSpace); + doc.format(argument); + } + } + + protected void format(ReplyMessageArgument argument, IFormattableDocument doc) { + doc.surround(regionFor(argument).feature(Literals.REPLY_MESSAGE_ARGUMENT__NAME), this::noSpace); + } + + + protected void format(QuotedNamedParticipant participant, IFormattableDocument doc) { + doc.surround(regionFor(participant).feature(Literals.QUOTED_NAMED_PARTICIPANT__LABEL), this::noSpace); + doc.surround(regionFor(participant).feature(Literals.QUOTED_NAMED_PARTICIPANT__NAME), this::noSpace); + doc.surround(regionFor(participant).feature(Literals.QUOTED_NAMED_PARTICIPANT__SELECTOR), this::noSpace); + doc.surround(regionFor(participant).feature(Literals.PARTICIPANT__TYPE), this::noSpace); + doc.surround(regionFor(participant).feature(Literals.PARTICIPANT__INTERACTION_IDENT), this::noSpace); + } + + protected void format(QuotedUnnamedParticipant participant, IFormattableDocument doc) { + doc.surround(regionFor(participant).feature(Literals.QUOTED_UNNAMED_PARTICIPANT__NAME), this::noSpace); + doc.surround(regionFor(participant).feature(Literals.QUOTED_UNNAMED_PARTICIPANT__SELECTOR), this::noSpace); + doc.surround(regionFor(participant).feature(Literals.PARTICIPANT__TYPE), this::noSpace); + doc.surround(regionFor(participant).feature(Literals.PARTICIPANT__INTERACTION_IDENT), this::noSpace); + } + + protected void format(QuotedAnonymousParticipant participant, IFormattableDocument doc) { + doc.surround(regionFor(participant).feature(Literals.PARTICIPANT__TYPE), this::noSpace); + doc.surround(regionFor(participant).feature(Literals.PARTICIPANT__INTERACTION_IDENT), this::noSpace); + } + + + } diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter2.xtend b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter2.xtend deleted file mode 100755 index 679628b..0000000 --- a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter2.xtend +++ /dev/null @@ -1,31 +0,0 @@ -/* - * generated by Xtext 2.25.0 - */ -package elite.mdd.plantuml.formatting2 - -import com.google.inject.Inject -import elite.mdd.plantuml.plantUML.Diagram -import elite.mdd.plantuml.plantUML.ParticipantDefinition -import elite.mdd.plantuml.services.PlantUMLGrammarAccess -import org.eclipse.xtext.formatting2.AbstractFormatter2 -import org.eclipse.xtext.formatting2.IFormattableDocument - -class PlantUMLFormatter2 extends AbstractFormatter2 { - - @Inject extension PlantUMLGrammarAccess - - def dispatch void format(Diagram diagram, extension IFormattableDocument document) { - // TODO: format HiddenRegions around keywords, attributes, cross references, etc. - for (sequenceElement : diagram.elements) { - sequenceElement.append[newLine] - sequenceElement.format - } - } - - def dispatch void format(ParticipantDefinition participantDefinition, extension IFormattableDocument document) { - // TODO: format HiddenRegions around keywords, attributes, cross references, etc. - participantDefinition.participant.format - } - - // TODO: implement for RequestMessageDefinition -} diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java index b9846c1..ae851e4 100755 --- a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java @@ -9,24 +9,132 @@ import com.google.inject.Inject; +import elite.mdd.plantuml.plantUML.AnonymousParticipant; +import elite.mdd.plantuml.plantUML.NamedParticipant; import elite.mdd.plantuml.plantUML.Participant; +import elite.mdd.plantuml.plantUML.PlantUMLFactory; import elite.mdd.plantuml.plantUML.PlantUMLPackage; +import elite.mdd.plantuml.plantUML.QuotedAnonymousParticipant; +import elite.mdd.plantuml.plantUML.QuotedNamedParticipant; +import elite.mdd.plantuml.plantUML.QuotedUnnamedParticipant; +import elite.mdd.plantuml.plantUML.ReplyMessage; +import elite.mdd.plantuml.plantUML.RequestMessage; +import elite.mdd.plantuml.plantUML.UnnamedParticipant; +import elite.mdd.plantuml.plantUML.impl.PlantUMLFactoryImpl; +import elite.mdd.plantuml.plantUML.impl.QuotedNamedParticipantImpl; import elite.mdd.plantuml.services.PlantUMLGrammarAccess; public class PlantUMLSemanticSequencer extends AbstractPlantUMLSemanticSequencer { - @Inject - private PlantUMLGrammarAccess grammarAccess; + // private PlantUMLFactory factory = PlantUMLFactoryImpl.init(); + + private SpecialCharacters specialCharMapper = new SpecialCharacters(); @Override - protected void sequence_Participant(ISerializationContext context, Participant semanticObject) { - if (errorAcceptor != null) { - if (transientValues.isValueTransient(semanticObject, PlantUMLPackage.Literals.PARTICIPANT__NAME) == ValueTransient.YES) - errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, PlantUMLPackage.Literals.PARTICIPANT__NAME)); + protected void sequence_NamedParticipant(ISerializationContext context, NamedParticipant semanticObject) { + /*QuotedNamedParticipant participant = factory.createQuotedNamedParticipant(); + participant.setInteractionIdent(semanticObject.getInteractionIdent()); + participant.setLabel(semanticObject.getLabel()); + participant.setName(semanticObject.getName()); + participant.setSelector(semanticObject.getSelector()); + participant.setType(semanticObject.getType());*/ + // label=ID ('['selector=ID']')? (':' type=ID)? ('ref' interactionIdent=ID ('strict')?)? 'as' name=ID + semanticObject.setLabel(specialCharMapper.mapping.get("\"") + semanticObject.getLabel()); + if (semanticObject.getInteractionIdent() != null) { + System.out.println("Since semanticObject is not null and Xtext does not allow to modify constants like strict. This may generate an error, please be on the lookout for this."); + semanticObject.setInteractionIdent(semanticObject.getInteractionIdent() + specialCharMapper.mapping.get("\"")); + } else { + if (semanticObject.getType() != null) { + semanticObject.setType(semanticObject.getType() + specialCharMapper.mapping.get("\"")); + } else { + if (semanticObject.getSelector() != null) { + semanticObject.setSelector(semanticObject.getSelector() + specialCharMapper.mapping.get("\"")); + } else { + semanticObject.setLabel(semanticObject.getLabel() + specialCharMapper.mapping.get("\"")); + } + } } - SequenceFeeder feeder = createSequencerFeeder(context, semanticObject); - feeder.accept(grammarAccess.getParticipantAccess().getNameIDTerminalRuleCall_1_0(), semanticObject.getName()); - feeder.finish(); + + super.sequence_NamedParticipant(context, semanticObject); } + + @Override + protected void sequence_UnnamedParticipant(ISerializationContext context, UnnamedParticipant semanticObject) { + String endString = specialCharMapper.mapping.get("\"") + specialCharMapper.mapping.get(" as ") + semanticObject.getName(); + semanticObject.setName(specialCharMapper.mapping.get("\"") + semanticObject.getName()); + if (semanticObject.getInteractionIdent() != null) { + System.out.println("Since semanticObject is not null and Xtext does not allow to modify constants like strict. This may generate an error, please be on the lookout for this."); + semanticObject.setInteractionIdent(semanticObject.getInteractionIdent() + endString); + } else { + if (semanticObject.getType() != null) { + semanticObject.setType(semanticObject.getType() + endString); + } else { + if (semanticObject.getSelector() != null) { + semanticObject.setSelector(semanticObject.getSelector() + endString); + } else { + semanticObject.setName(semanticObject.getName() + endString); + } + } + } + + super.sequence_UnnamedParticipant(context, semanticObject); + } + + @Override + protected void sequence_AnonymousParticipant(ISerializationContext context, AnonymousParticipant semanticObject) { + semanticObject.setType(specialCharMapper.mapping.get("\"") + semanticObject.getType()); + System.out.println("Since semanticObject is not null and Xtext does not allow to modify constants like :. This may generate an error, please be on the lookout for this."); + if (semanticObject.getInteractionIdent() != null) { + System.out.println("Since semanticObject is not null and Xtext does not allow to modify constants like strict. This may generate an error, please be on the lookout for this."); + semanticObject.setInteractionIdent(semanticObject.getInteractionIdent() + specialCharMapper.mapping.get("\"")); + } else { + semanticObject.setType(semanticObject.getType() + specialCharMapper.mapping.get("\"")); + } + + super.sequence_AnonymousParticipant(context, semanticObject); + } + + + @Override + protected void sequence_QuotedUnnamedParticipant(ISerializationContext context, QuotedUnnamedParticipant semanticObject) { + String endString = specialCharMapper.mapping.get("\"") + specialCharMapper.mapping.get(" as ") + semanticObject.getName(); + if (semanticObject.getInteractionIdent() != null) { + System.out.println("Since semanticObject is not null and Xtext does not allow to modify constants like strict. This may generate an error, please be on the lookout for this."); + semanticObject.setInteractionIdent(semanticObject.getInteractionIdent() + endString); + } else { + if (semanticObject.getType() != null) { + semanticObject.setType(semanticObject.getType() + endString); + } else { + if (semanticObject.getSelector() != null) { + semanticObject.setSelector(semanticObject.getSelector() + endString); + } else { + semanticObject.setName(semanticObject.getName() + endString); + } + } + } + + super.sequence_QuotedUnnamedParticipant(context, semanticObject); + } + + @Override + protected void sequence_QuotedAnonymousParticipant(ISerializationContext context, QuotedAnonymousParticipant semanticObject) { + super.sequence_QuotedAnonymousParticipant(context, semanticObject); + } + + @Override + protected void sequence_RequestMessage(ISerializationContext context, RequestMessage semanticObject) { + if (semanticObject.getArguments().size() == 0) { + semanticObject.setName(semanticObject.getName() + specialCharMapper.mapping.get("(") + specialCharMapper.mapping.get(")")); + } + super.sequence_RequestMessage(context, semanticObject); + } + + @Override + protected void sequence_ReplyMessage(ISerializationContext context, ReplyMessage semanticObject) { + if (semanticObject.getArguments().size() == 0) { + semanticObject.setName(semanticObject.getName() + specialCharMapper.mapping.get("(") + specialCharMapper.mapping.get(")")); + } + super.sequence_ReplyMessage(context, semanticObject); + } } diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/SerializerWrapper.java b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/SerializerWrapper.java new file mode 100755 index 0000000..89efa92 --- /dev/null +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/SerializerWrapper.java @@ -0,0 +1,59 @@ +package elite.mdd.plantuml.serializer; +import java.util.Map.Entry; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.xtext.serializer.ISerializer; + +import com.google.inject.Guice; + +import elite.mdd.plantuml.PlantUMLRuntimeModule; + +public class SerializerWrapper { + + private static ISerializer serializer = null; + + private SpecialCharacters specialCharMapper = new SpecialCharacters(); + + private ISerializer getSerializer() { + if (serializer == null) { // lazy creation + serializer = Guice.createInjector(new PlantUMLRuntimeModule()).getInstance(ISerializer.class); + } + return serializer; + } + + public SerializerWrapper() { + this.getSerializer(); + } + + public String serialize(EObject semanticObject) { + String result = serializer.serialize(semanticObject); + + // For special Characters + for (Entry e : specialCharMapper.mapping.entrySet()) { + result = result.replace(e.getValue(), e.getKey()); + } + + // For quoted Participant where no name was provided + String[] splittedString; + String lineEnding; + if (result.split("\r\n").length != 1) { + splittedString = result.split("\r\n"); + lineEnding = "\r\n"; + } else { + splittedString = result.split("\n"); + lineEnding = "\n"; + } + result = ""; + for (String s : splittedString) { + if (s.contains("as") && s.endsWith("\"")) { + s = s.substring(0, s.length() - 1); + } + result += s + lineEnding; + } + + // For Anonymous unquoted participant + result = result.replace(": \"", "\": "); + + return result; + } +} diff --git a/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/SpecialCharacters.java b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/SpecialCharacters.java new file mode 100755 index 0000000..1470a05 --- /dev/null +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/SpecialCharacters.java @@ -0,0 +1,18 @@ +package elite.mdd.plantuml.serializer; + +import java.util.HashMap; +import java.util.Map; + +public class SpecialCharacters { + + public Map mapping = new HashMap(); + + public SpecialCharacters() { + mapping.put("\"", "DOUBLE__QUOTE__38__"); + mapping.put(" as ", "AS__SPECIAL__VALUE"); + mapping.put("(", "PARENTHESIS__OPENING"); + mapping.put(")", "PARENTHESIS__CLOSING"); + + } + +} From 63b6f6c9a39187abea22169884e3171f8b2fb9c0 Mon Sep 17 00:00:00 2001 From: Marian Date: Fri, 2 Jul 2021 12:20:18 -0400 Subject: [PATCH 4/4] When saving the Plantuml file a new file is generated which contains the serialized code --- .../elite/mdd/plantuml/ui/PlantUMLEditor.java | 45 +++++++++++++++++++ .../mdd/plantuml/ui/PlantUMLUiModule.java | 7 +++ 2 files changed, 52 insertions(+) create mode 100755 xtext/elite.mdd.plantuml.ui/src/elite/mdd/plantuml/ui/PlantUMLEditor.java mode change 100644 => 100755 xtext/elite.mdd.plantuml.ui/src/elite/mdd/plantuml/ui/PlantUMLUiModule.java diff --git a/xtext/elite.mdd.plantuml.ui/src/elite/mdd/plantuml/ui/PlantUMLEditor.java b/xtext/elite.mdd.plantuml.ui/src/elite/mdd/plantuml/ui/PlantUMLEditor.java new file mode 100755 index 0000000..09e5d3c --- /dev/null +++ b/xtext/elite.mdd.plantuml.ui/src/elite/mdd/plantuml/ui/PlantUMLEditor.java @@ -0,0 +1,45 @@ +package elite.mdd.plantuml.ui; + +import java.io.PrintWriter; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.ui.IEditorInput; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.ui.editor.XtextEditor; +import org.eclipse.xtext.ui.editor.model.IXtextDocument; +import org.eclipse.xtext.util.concurrent.IUnitOfWork; + +import elite.mdd.plantuml.serializer.SerializerWrapper; + +public class PlantUMLEditor extends XtextEditor { + + private SerializerWrapper serializeWrapper = new SerializerWrapper(); + + @Override + public void doSave(IProgressMonitor progressMonitor) { + // See https://www.eclipse.org/forums/index.php/t/487828/ + // and https://www.eclipse.org/forums/index.php/m/786926/ + System.out.println("here we go"); + IXtextDocument document = super.getDocument(); + document.readOnly(new IUnitOfWork.Void() { + + @Override + public void process(XtextResource resource) throws Exception { + String filePath = ResourcesPlugin.getWorkspace().getRoot().getRawLocation().toOSString() + resource.getURI().toPlatformString(true); + if (resource.getContents().size() == 1 && resource.getErrors().size() == 0) { + EObject diagram = resource.getContents().get(0); + String serializedDiagram = serializeWrapper.serialize(diagram); + try (PrintWriter out = new PrintWriter(filePath + ".puml")) { + out.println(serializedDiagram); + } + } + } + }); + + super.doSave(progressMonitor); + } + +} diff --git a/xtext/elite.mdd.plantuml.ui/src/elite/mdd/plantuml/ui/PlantUMLUiModule.java b/xtext/elite.mdd.plantuml.ui/src/elite/mdd/plantuml/ui/PlantUMLUiModule.java old mode 100644 new mode 100755 index f096101..4d129db --- a/xtext/elite.mdd.plantuml.ui/src/elite/mdd/plantuml/ui/PlantUMLUiModule.java +++ b/xtext/elite.mdd.plantuml.ui/src/elite/mdd/plantuml/ui/PlantUMLUiModule.java @@ -4,13 +4,20 @@ package elite.mdd.plantuml.ui; import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.eclipse.xtext.ui.editor.XtextEditor; /** * Use this class to register components to be used within the Eclipse IDE. */ public class PlantUMLUiModule extends AbstractPlantUMLUiModule { + + public PlantUMLUiModule(AbstractUIPlugin plugin) { super(plugin); } + + public Class bindXtextEditor() { + return PlantUMLEditor.class; + } }