bidirectional dataflow in calculator sample project

Hello Forum!

I've extended the calculator sample project from MPS. So that I can edit the values of the textfields in my editor file as well as in the generated Java-App as you can see in the screenshot below.

Unbenannt2.PNG


The values of the textfields will be transfered from the editor file to my Java-App.
Now my question is whether it's possible to build kind of a bidirectional dataflow between the MPS editor file and the generated Java program or not. So if I edit the value in the Java app it will also be updated in my MPS editor file and vice versa.

Unbenannt1.png



Thanks in advance for any suggestions or help!

Best regards
msch95
17 comments
Comment actions Permalink
No, it is not possible. The generated application has not notion of the model that it was generated from and so cannot modify it. After all, the generated application can be run on a different computer by a different person...

You'll have to enhance the generated application to persist the values in some soft of storage and reload them next time the app, or its new version, is started.
0
Comment actions Permalink
Ok. Thanks for your reply, Vaclav!
I found out that under
<<projectname>>/languages/<<projectname>>/sandbox/models/<<projectname>>/sandbox.mps
lies the structure of my editor in my language.
I've tried to open and edit this file in XML format with Notepad++.
Then I switched back to my MPS project and it automatically refreshes my editor file there.
So my idea is now to write a generated Java app from my mps language that reads the XML and saves it if changes in my Java app are made.
I also noted your suggestions. I don't know whether there's another option or not..
0
Comment actions Permalink
I think plugins can interact with MPS via API. Is it the case?

If so, it should be possible to create a plugin that communicates with live application and updates MPS accordingly.
0
Comment actions Permalink
Technically it should be possible to open UI dialog containing MPS editor as a part of your custom application. Practically we did not try this use case, so there could be some hidden problems.

@Vladimir: you are right - it should be possible to create a plugin to MPS receiving incoming connections/updating MPS models in accordance.
0
Comment actions Permalink
Thanks Vladimir and Alex for your advice. I'm gonna try that later on and I'll write my experiences down here.
0
Comment actions Permalink
Vladimir, can I have your help once more?
I don't understand what you mean with live application. How should I update MPS accordingly?
Via the file in this path
<<projectname>>/languages/<<projectname>>/sandbox/models/<<projectname>>/sandbox.mps
it's very very difficult to update it accordingly, so that the file doesn't violate the rules of MPS.
What did you mean with API? - Can you provide a link to the documentation or something?

Thank you for your time..
0
Comment actions Permalink
@msch95, you should use MPS to update the model. Don't try updating the file directly.

For instance, you use "new initialized" API to create node and add it accordingly: SModel language, SModellanguage-Newnodecreation. You might want using "actions" language for its "new initialized" feature.

For instance, mbeddr's com.mbeddr.mpsutil.nodeaccess.plugin.pasteUUNodeFromClipboard uses that API to create nodes out of a string.

add_node_from_clipboard.png


So if you want to update MPS model from your application, consider using HTTP sever to pass data from your application to MPS.

mbeddr has out of the box HTTP server, so you can extend RequestHandler to handle requests.

In other words, your application performs a HTTP call that tells "dear MPS, please add this node to your sandbox" and the http extension plugin analyzes the request and updates the model.

The drawback is you have to serialize and deserialize the request, however you might have luck with c o m  m b e d d r  m p s u t i l  s e r i a l i z e r  x m l  NodeSerizalizer, so you can use MPS API in your application to construct the node, then serialize and pass via HTTP, then deserialize and update.

I do not know if there is a good way of starting "application" in the same JVM as MPS (see my question http://forum.jetbrains.com/thread/Meta-Programming-System-4921), so it looks like "http communication" is unavoidable.

Just in case, here's mbeddr's "Open in MPS" plugin (it navigates to the given node in MPS when you click a specially crafted hyperlink in your browser).
open_in_mps.png
0
Comment actions Permalink
It really helped me a lot and I really appreciate your time, @Vladimir!
I thought of developing an ASP.NET WebAPI with a Web front-end. So do I guess right at making a persistent storage on my webserver and calling my API, which reads this storage file, from MPS or rather mbeddr to update my MPS sandbox file accordingly over the wire? The only way of serializing would be XML or at least the easiest one, am I right?
0
Comment actions Permalink
So do I guess right at making a persistent storage on my webserver and calling my API, which reads this storage file, from MPS or rather mbeddr to update my MPS sandbox file accordingly over the wire?


Unfortunately, I do not understand the use case.
Both your approaches are plausible, however they have different limits.
For instance, if you duplicate the data (store it in both MPS and in your persistent storage), then you'll have to invent some conflict resolution.

The only way of serializing would be XML or at least the easiest one, am I right?


In fact, any format might play well.

mbeddr's NodeSerizalizer is nice in case you write both sides in MPS. It allows you to "create nodes using nice MPS API" and just serialize to XML.

If you want cross-language operation, then some gerenic serializers/RPC implementations might work for you (protobuf, thrift, etc).
0
Comment actions Permalink
Unfortunately, I do not understand the use case.


I need to have a textual editing of my DSL in MPS (mostly for programmers) and GUI app for none programmers. The GUI version only needs some of the features from the MPS version.

Now I'm investigating the best approach for my use case.

One thing that isn't quite clear to me is the http server. Is it integrated in MPS or mbeddr or do I have to provide my own?

How could I save the input from my GUI app to MPS as simple as possible?

Many thanks
msch95
0
Comment actions Permalink
How could I save the input from my GUI app to MPS as simple as possible?


I do not know yet. I'm going to try NodeSerializer approach first.

One thing that isn't quite clear to me is the http server. Is it integrated in MPS or mbeddr or do I have to provide my own?


It is not integrated in MPS. mbeddr's http server works only in case MPS is started.
I'm not sure which API to use to update MPS model when MPS itself is not running.

From Vaclav's answer it looks to be impossible to update the model without having a running instance of MPS, so you might have better luck with starting web server from within MPS (like mbeddr does in plugin). In this case no serialization is required. You just use SModel API from within servlet (or whatever you have for web)
0
Comment actions Permalink
Ok. I've successfully installed mbeddr on my system. I wanted to just create a simple example:
Person
with two properties firstname and lastname

and now I'm trying to follow your suggestions. Unfortunately, I'm not that experienced with MPS.
I don't know where in my project I should start the http-Server and how to serialize my node for transmitting data over the wire.
My initial goal is to just create the concept, serialize it (XML) and post it to the server, which should be started before, and maybe output the XML string.

Can someone give me a hint or provide some links to documentation stuff or tutorials?

Thanks in advance!
msch95
0
Comment actions Permalink
msch95, did you ever get this working with the simple Person example?
0
Comment actions Permalink
Yes. I've implemented the Node(De)Serializer.
0
Comment actions Permalink
Do you possibly have the project or code snippets where you invoked the mbeddr code? That would be very helpful to anyone interested in this approach!
0
Comment actions Permalink
//in your plugin action
//define your rootConcept in the action context parameters
NodeSerizalizer nodeSerizalizer = new NodeSerizalizer(this.rootConcept, true, "_"); 
Element root = nodeSerizalizer.getXML(); 
boolean successfull = dal.serializeElement(root);

public boolean serializeElement(Element root) { 
  Document document = new Document(root); 
  XMLOutputter xmlOutputter = new XMLOutputter(); 
  xmlOutputter.setFormat(Format.getPrettyFormat()); 
  try { 
    xmlOutputter.output(document, new FileWriter("C:/")); 
    return true; 
  } catch (IOException e) { 
    <no statements> 
  } 
  return false; 
}
prettyPrint();

Regards
msch95
0
Comment actions Permalink
Great, thank you very much! I'll try it out soon and report back :)
0

Please sign in to leave a comment.