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 new file mode 100755 index 0000000..71191b5 --- /dev/null +++ b/xtext/elite.mdd.plantuml.tests/src/elite/mdd/plantuml/tests/PlantUMLSerializingTest.xtend @@ -0,0 +1,95 @@ +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 +import elite.mdd.plantuml.serializer.SerializerWrapper + +@ExtendWith(InjectionExtension) +@InjectWith(PlantUMLInjectorProvider) +class PlantUMLSerializingTest { + + @Inject + ParseHelper parseHelper + + + @Test + def void participants() { + val result = parseHelper.parse(''' + @startuml + 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); + + 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.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; + } } 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/PlantUML.xtext b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/PlantUML.xtext old mode 100644 new mode 100755 index 2822d14..aae60b8 --- 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,38 @@ 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')?)? + // 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 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 +56,61 @@ enum ParticipantShape: | COLLECTIONS='collections' | ENTITY='entity' | DATABASE='database' - | PARTICIPANT='participant'; + | PARTICIPANT='participant' + ; // Messages MessageDefinition: RequestMessageDefinition - | ReplyMessageDefinition; + | ReplyMessageDefinition + | FullQuotedRequestMessageDefinition + | FullQuotedReplyMessageDefinition + | LeftQuotedRequestMessageDefinition + | LeftQuotedReplyMessageDefinition + | RightQuotedRequestMessageDefinition + | RightQuotedReplyMessageDefinition + ; + +FullQuotedRequestMessageDefinition: + ('"' sender=[Participant] '"' arrow=(RightRequest) '"' receiver=[Participant] '"') (':' message=RequestMessage) + | ('"'receiver=[Participant]'"' arrow=(LeftRequest) '"' sender=[Participant] '"') (':' message=RequestMessage) + ; + +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|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: 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..3ba1a33 --- /dev/null +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/formatting2/PlantUMLFormatter.java @@ -0,0 +1,144 @@ +/* + * generated by Xtext 2.25.0 + */ +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; +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 + + protected void format(Diagram diagram, IFormattableDocument doc) { + for (SequenceElement sequenceElement : diagram.getElements()) { + doc.prepend(sequenceElement, this::newLine); + doc.format(sequenceElement); + doc.append(sequenceElement, this::newLine); + } + } + + 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(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()); + } + + 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/serializer/PlantUMLSemanticSequencer.java b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java new file mode 100755 index 0000000..ae851e4 --- /dev/null +++ b/xtext/elite.mdd.plantuml/src/elite/mdd/plantuml/serializer/PlantUMLSemanticSequencer.java @@ -0,0 +1,140 @@ +/* + * 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.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 { + + // private PlantUMLFactory factory = PlantUMLFactoryImpl.init(); + + private SpecialCharacters specialCharMapper = new SpecialCharacters(); + + @Override + 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("\"")); + } + } + } + + 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/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 { +} 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"); + + } + +}