MetaEdit+ Workbench questions


Can previously defined symbols be reused when defining a new domain specific language (to create symbol libraries)?

Solution:Yes, they can: you can use the Symbol Library from the Symbol Editor. In addition to the Symbol Library, you can also copy and paste symbols or symbol elements from one object's symbol to another. Furthermore, you can import existing symbols from outside MetaEdit+ as bitmaps or SVG vector graphics into the Symbol Editor.

You can of course also reuse the modelling concepts themselves and their generators.


Can the graphical presentation of a language include graphics/images?

Explanation:MetaEdit+ allows defining new elements in the metamodel, as well as a graphical representation for it. Can this representation contain graphics/images? Is it possible to use a different image for each instance of the new metamodel element?
Solution:Representation can contain graphics/images. These can be based on vector graphics that scale well during modeling or based on exported bitmaps. Instances can have different images based on the definition in the metamodel. For example, based on the data given by a modeler symbol element can change for each instance.


Does MetaEdit+ use OCL constraints for the models or is there something similar?

Explanation:OCL is a programming language intended to express correctness constraints on models. The OMG also envisages that it could be used to express correctness constraints on metamodels.
Solution:

In MetaEdit+ constraints are expressed as data and integrated in the metamodel. Compared to OCL this capability simplifies metamodel creation, and avoids the performance problems associated with OCL.

Having a programming language to express something is natural when the range of possible constraints is unknown. MetaCase's experience over the last 15 years has shown that the actual useful set of constraints needed for modeling languages is rather small. The constraints can be better expressed using a set of constraint templates which can be parameterized with the desired values.

In MetaEdit+ places to specify constraints include:

  • bindings: how metamodel elements (objects, relationships, roles, ports) can be connected, e.g. a Transition relationship has a From role connected to a State or Start State, and a To role connected to a State or Stop State.
  • cardinality constraints: how many instances of roles are allowed in n-ary relationships, e.g. in single inheritance, an Inheritance relationship can have many Subclasses but only one Superclass.
  • connectivity constraints: how many times a given object can be connected in specified types of relationships and roles, e.g. a Start State can only have one Transition leaving it.
  • port constraints: what ports can be connected, e.g. an "Out" port can only be connected to an "In" port
  • occurrence constraints: how many objects of a certain type may there be in a graph, e.g. only one "Start State" in a State Transition Diagram (4.5 and later).
  • uniqueness constraints: prevent two objects in a graph having the same name, e.g. two States both called "Editing" (4.5 and later).
  • explosions and decompositions: how models can be linked with submodels, e.g. a State in a State Transition Diagram can be decomposed into its own State Transition Diagram.
  • global uniqueness: a given property of an object must have unique values over all instances of that object, e.g. in a UML Object Diagram, the Object Name of each Object might be unique, but the Class Name property would not be: there could be several Objects of the same Class.
  • property value constraints: the set of legal values of a property can be expressed in a variety of ways, e.g. a selection from a list or by checking against a regular expression (4.5 and later).

The above constraints are checked at modeling time. So once a model element is created, changed or updated the model check is made immediately. In MetaEdit+ it is also possibility to have model correctness checking that is executed on request by running a model check. These can be defined using MetaEdit+'s reporting language or by using external programs (e.g. metrics tools etc) that access desgin models using the MetaEdit+ API.


How are language versions managed once models exist?

Explanation:Suppose we have made a model of a product. The modeling language evolves over the years and then 10 years later we want to load the model of the first product (made 10 years ago). What happens?
Solution:By default you go to the situation you had 10 years ago, back to the the original models and the original language (+ generators) that those models were made with. If you want to update the language to any of the past versions, you load its definition and the models update accordingly to the new language version. By default you get also the new generators (you can change these separately but normally it does not make sense to have generators for different language version).


How big can the DSM languages be?

Explanation:At which size of the language do you expect the approach to reach its limits in terms of maintainability?
Solution:We have not yet faced such a limit. The largest languages we have seen in MetaEdit+ are double the size of the full UML. This means 580 language concepts whereas UML has about 300 concepts.


How can I add multiple new GOPRR object types without leaving the Object Tool

Solution:Press the "New" button (or in 3.0 or earlier, select "Make Descendant" from the type name menu). You will be prompted for the supertype of your new type - if you do not want any particular supertype, choose Object. The fields in Object Tool are cleared ready for the new definition.


How does MetaEdit+ support multiple persons working on a metamodel?

Explanation:MetaEdit+ is a multi-user environment, meaning that multiple users can work simultaneously on the same models. Is it also possible for multiple users to work on the same metamodels (i.e. work on the same language definition)?
Solution:Multiple users can also work on the same metamodel, however not simultaneously. In MetaEdit+ the security level locking for metamodeling is session-based. This means that after choosing committing/abandoning the changes made, another person can start metamodeling in the same project. Simultaneous metamodeling is possible when the metamodel is saved in different projects (usually projects include different languages).


How hard is it to create my own language generator?

Solution:Implementation is quite easy as MetaEdit+ provides the report definition language for writing the generation definition. Design of the generator is the main issue, and one way to start it is to inspect all the similarities and variations in the expected output code and make it first for static structures and then extend it to the behaviour part (which is usually a sort of state, flow or interaction diagram).


How is the code-generation linked to MetaEdit+?

Explanation:How does the generator know about the metamodel and metamodel modifications?
Solution:

There are three possibilities for code generation:

  1. MetaEdit+ provides its own code generator definition tool, the Generator Editor, for making code generators based on any metamodel and for generating any programming language. This tool is directly integrated with the metamodel you made with MetaEdit+.
  2. You can integrate your own generator or a 3rd party generator with MetaEdit+ by using the MetaEdit+ API. With the API, any program having .NET/Webservices/SOAP framework can read the model information from MetaEdit+.
  3. The MetaEdit+ API product also includes the ability to export the models as XML. You could parse that XML and write whatever code generator you like based on it

In most cases the easiest way is to use the integrated Generator Editor. Often this can be made even easier by writing a thin layer of code on top of your existing components, to make the task of generation easier. This has the added benefit of making the generator less dependent on a particular version of the libraries and components you use.


How to specify the order in which objects are reported?

Solution:Objects are sorted by type, id (name), and oid (internal id) - the last makes sure that even objects with the same name and type are always reported in the same order. In 4.5, you can change the order with the orderby parameter to the foreach, do or dowhile loops. E.g.
do .Person
orderby :Surname, :FirstName
{  id; newline }
In 4.0 and earlier there was no way to change that order in the output. If you are still using an earlier version and need a specific order, you could consider exporting to a file then sorting it using another command (DOS sort, Excel etc.).


Importing and exporting XML

Explanation:How is XML supported if the metamodel is modified? Are elements based on the new model elements of the metamodel in the XMI file? Can the tool export a DTD or an XMI file for the metamodel itself?
Solution:XML-based exports are available in two different ways. MetaEdit+ provides XML format for importing and exporting that works for all languages, including UML and own metamodels. XMI is implemented for UML diagrams only and XMI does not support for other metamodels than of UML (or actually certain version of UML depending on the XMI version). In addition to XML, also binary format is available that also covers the representation part of the models.

In 4.5, metamodels can also be exported as XML, including their symbols in SVG format.


Is it better to use "role-relation" or "attribute-collection" for attributes of entities in ERD-style models?

Explanation:I first tried the "attribute-collection" way which makes larger graphs tidier and is better for object sharing. But it seems to be bad for relations, where it is impossible for me to specify on which attribute the relation is directing.
Solution:There's no clear-cut answer as to which is better: it all depends on what you want. If you go for a "role-relation" solution, you can always use View | Selected... to hide unwanted details temporarily. If you use an "attribute collection", you can reuse elements from that collection in another attribute collection or reference property in the relation. You could also try a mixture of both - specify most attributes in an attribute collection, but allow "role-relation" specification too for ones that are more important (like UML allows Classes to have both Attribute collections and Aggregation relationships).


Is it possible to generate output in another, probably lower level Domain-Specific Modeling Language, also built in MetaEdit+?

Explanation:We've wondered about the possibility to create a layered set of DSLs.
Solution:

Yes. You could perform such a model-to-model transformation in one of at least three ways:

  1. by generating the desired XML with a report, then reading that in to create the lower-level models
  2. by exporting XML from Graph Manager, or some other text format with a report, and manipulating that in an external program to create XML to import
  3. by exporting XML or text, and reading that into an external program that makes calls back into MetaEdit+ via the API to create the lower-level models.

However, experience with this approach, whatever tool is involved and whatever export/transform/import method is used, shows this is normally a Bad Thing. Without knowing your exact plans, I won't say that your idea is bad, but let me state several ways in which people have "gone wrong" along a path like this.

  1. Normally the idea is that each piece of data in the high-level language gets transformed to >1 piece of data in the low-level language (let's say 2 pieces). This is fine if you never (or rarely) look at the low-level language, and never (or very rarely) edit it. But if you edit it, you are now working with 2 pieces of data, but clearly they are not totally independent, since they could be produced from one piece. The idea of DSM is to come up with a minimal sufficient representation of systems, and this is the main reason for its 5-10x productivity increases: code or UML-based ways of building systems involve lots of duplication - the same information in several places.
  2. Often people say next "and we want to be able to change the high-level models still, and have those changes reflected in the low level models". That means you are working with 1+2 pieces of information, and also that you need to come up with some way to propagate the changes down to the low-level models "correctly". "Correctly" here means: without destroying information manually added there; updating the automatically generated parts; creating new generated parts; updating manually added parts to reflect changes in the top-level models (e.g. if the manually added part refers to the name of an element originally from the high level model, and that element's name has now been changed).
  3. And next people say "and we want to be able to change the low-level models, and have the high-level models update". This is even harder than 2). The only cases when it can really happen are where you don't really have a high level and low level, but two different representations at the same level. Even then, it can only really apply to the intersection of the sets of information recorded in the two different models. E.g. UML tools have one class in a model mapping to one class in the code. With sufficiently simple changes, a bit of luck and a following wind, the best UML tools today are capable of maintaining that simple mapping for the names of classes, attributes and operations. The actual code isn't kept in synch (it's not in the UML models), nor are say method calls in models kept in synch with actual calls made in the code (it could be done in theory, but in practice UML models only show a tiny fraction of the calls, so it's hard to know which ones to show automatically). The only way the synchronisation can be made "better" is by moving the two languages closer, e.g. allowing UML operations to contain the method body as text, or the code to show things like "Abstract class" as specially formatted comments (assuming the language generated doesn't have a direct representation of abstractness). Each move towards better synchronisation is thus a move away from having a higher level language and a lower level language.

The DSM solution is to turn the question on its head and ask "OK, you showed me a high-level modeling language that doesn't yet capture enough information to build full systems. And you showed me a low-level language and a transformation into it. Now tell me what extra information you want to put in the low-level models". (Note that here we're asking for information, most likely on a (problem) domain level, not for the actual representation of that information.) "Now let's look how we can extend or change the high-level modeling language to provide places to capture that information". (Sometimes this step may require a rethink of the modeling language, especially if it's been based on a language that somebody had already made.) "And finally, let's show how we now have all the information we need, and we can generate full code directly from the top model, using the information it originally captured and the new information we would otherwise have entered in the lower-level models." (Remember that there was only a certain amount of information to be added to the lower-level models, regardless of its representation or duplication into several places there. Since we would have been able to generate the initial lower-level models from the information in the initial higher-level models, added extra information, and then generated code, we can clearly expect to be able to generate full code. Whilst it's probably not the best way, you can think how the transformation of the high-level models to low-level models worked, and the transformation of the low-level models to code worked (with the extra information), and thus how you could generate the low-level models, add into them the extra information now recorded in the high-level models, then generate code from there as you would have done in the original scenario)

And you thought you asked a simple question! :-) Seriously though, I hope this helps you understand the issue in general. It's one of the main reasons why MDA is doomed to failure, at least in its current form of PIM *transform* -> PSM *add detail* *generate* -> code (or *transform* -> More Product Specific Model *add more detail* ...). The industry guru vote is already in on MDA, and it's a resounding "no thanks". Successful DSLs simply don't use this approach - think of SQL, for example. Whilst it would be possible to have C code generated from SQL (and I'm sure this has been done in some places) and edit it, it just leads to a greater set of things that need to have large amounts of expert work to build tools for the synchronisation, and more work for the users in learning and working in two different languages.

Summa summarum: if you can specify a transformation from a high-level language to a low-level language, and then have modellers add more detail, and then another transformation to code, you can look instead at the information that gets added by modellers, extend the high-level language to capture it, and merge the transformations into one. It makes life easier for the modellers (one language, one model, no round trip desynch) and much easier for the metamodellers (one language, single one-way non-updating transformation). Additionally you normally find a way to record the information into significantly fewer data elements in the higher level language.


Is it possible to include existing software modules into MetaEdit+ projects?

Solution:Existing software modules can be included via the generator so that modelers don’t need to know them or they can be imported (e.g. their interface only) into MetaEdit+.


Is it possible to represent nested Objects visually as nested Objects?

Explanation:

An object of type A contains an object of type B (or alternatively several of them). Is it possible to use a conditional layout of type B within the representation of type A? E.g.

+------------------------+
|     Type A             |
| **********             |
| * Type B *             |
| **********             |
+------------------------+
Solution:In 4.5, this is easily accomplished with the "contents" and "containers" commands in the MERL generator language. See the Method Workbench User's Guide for details, and the Objects Nesting generator in Graph for an example. In earlier versions, there are various other ways: see below.

1. ONE B IN AN A

Symbol element conditions in MetaEdit+ 4.0 and earlier can only refer to the object's own properties, not properties of an object in a property. Whilst later versions of MetaEdit+ will allow symbol element conditions to use reports to reach information almost anywhere in the model, in 4.0 there are two ways that you may be able to get what you want:

1.1 Report Identifier

You may be able to make B have a report identifier that reveals sufficient information about it for A's symbol elements' conditions. For instance, if A has a property myB that contains an object of type B, and B has list properties Colour (values 'red' or 'green') and Shape (values 'circle' or 'square'), you could make a report identifier for B like this:

:Colour; ' '; :Shape;

and in Type A's symbol put four conditional elements: a red square, with condition on myB being 'red square' etc. You can also pick up individual parts of B's information via wildcard conditions, e.g. redness from 'red *', squareness from '* square'.

1.2 A Inherits Bs Properties

You could consider making A a subtype of B. That way all of B's properties would be available to be used in conditions in the symbol for A.

2. SEVERAL Bs IN AN A

If you want several B's in one A then there are two ways, depending on what you want:

2.1 Big Transparent Object

If Type B representations can be moved around inside an A as independent elements, and possibly have relationships between themselves:

Make A a fairly dumb object type, whose symbol is a big rectangle with no fill (transparent), A's name at the top and lots of empty space. See http://www.metacase.com/blogs/stevek/images/usecase.gif for an example: the System object.

In this case A doesn't "know" the B's it contains. If you want that, I'd suggest that you make A have a decomposition that contains the B's. I've seen other modeling languages that have tried showing decomposition contents at the top level, and they generally lead to more work for the modeler and semantic inconsistencies. If the B's really are contained by A, then it's better to have them hidden at the top level, and detailed one level lower, where they can't so easily break the boundaries of their A to cross into the implementation details of another A. And of course visually it's better to keep diagrams less complex.

If you really want to have multiple A's, each visually containing and "knowing" its own B's, there are a couple of ways you could try. You can either make a separate collection property in A and add them there (accepting some duplication between the possibly getting out of synch , or draw relationships from A to each B it contains (probably making the role lines very light gray, so they aren't so visible. You can make them transparent, but that makes them hard to use). The relationship approach works nicely too in the cases when sometimes you want to show the B's inside a big A, and sometimes you'd rather have a little A and 'contains' relationships drawn down to each of its B's below it.

2.2 List of Bs in an A

If Type B representations are basically text, and in a regular format within an A:

Make A have a property "Bs", whose data type is Collection: TypeB. Add a Text element in A's symbol, and set its contents to be a report - e.g. this would produce the effect above (which of course is not exactly what you want):

do :Bs 
{   '**********'; newline;
    '* '; id; '*'; newline; /* ending star will not align nicely */
    ''**********'; newline; 
}


Is it possible to use variables in generators?

Solution:Yes: 4.5 adds support for variables in the MERL generator definition language. However, the generator language has been designed to make most results possible at a higher level, without needing to resort to using variables.

Most reports are a series of loops within loops, and you can refer to the current element on the stack of an outer loop using e.g. id;1; . The number says how many loops further out to go, and can be used with most simple commands like id, oid, type and :PropertyName.

Another possible use of variables is to store state that should persist between report runs, or to parameterise reports. A better solution then is to have that information as properties in the model, e.g. of the top level graph from which the report is run.


Is the data type list for property types customizable?

Solution:Yes, in a way: there are the basic string, text etc. property types, and various list types. If you want new types, you make e.g. new object types for those properties, giving you much more freedom as to what can be in a property. Each property of this new type can then have exactly the features you want.


What approach to construction of modelling languages is supported: top down or bottom up?

Solution:Both approaches are possible. Following the top down approach, languages can be built from scratch and this often leads to languages that fit best for a given problem and code generation. Following the bottom up approach, MetaEdit+ includes already basic language constructs, like state, transition, class, attribute etc., which can be used to create modeling languages.


What happens if the expert deletes a concept from the language?

Explanation:How does this affect the already existing models?
Solution:MetaEdit+ is designed for this kind of situations. A usual situation is that if you delete a modeling concept then your existing models still show ”old” instances of the concept, but you can’t make new model instances of that concept. This is safe as your generators still work and people can see older models. Second option is to remove the concept so that you can’t have access to old instances anymore.


What is the best way of creating inter-graph relations between objects?

Explanation:I found the way of sharing objects in more graphs, but it is impossible for me to make a cross-graph report (e.g.: "report all relations of certain object from all graphs the object is used in"). It is also hard to specify the "home graph" of an object and to exclude the object in other graphs while reporting.
Solution:An object doesn't itself have a home graph - it is a true object in the O-O sense. One solution is to accept this, and the power that comes with it. If you really do have a situation where an object is conceptually defined in one place, and then used in others, here are two common approaches:
  1. Have two object types, one which defines the object and its properties (you probably have this type already), and another which contains only one property, which is a reference to an object of the first type. Use the first when you define, and the second when you refer. You may have many instances of the second for each instance of the first, or then only one instance, which you reuse in many graphs. The latter helps you find where that object is used (Properties | Info).
  2. Have one object type, and add a property 'Home graph' to it, referring to the graph itself. An instance can be reused in many graphs. Something like this approach is used in the Class object of the Java Example project - only classes in the right package (same name as this graph) are generated.


What percentage of the code do I have to edit outside your tools?

Solution:It depends on the application domain, but only the component code (used multiple times as lower level services in different applications) is written outside. In the tutorial example of digital wristwatch, there was such component code as icons, buttons, time, written once, but then all watches use these multiple times in different applications in different situations.


What percentage of the programming gets done in MetaEdit?

Solution:Ideally, all of the application-specific code using the framework and component primitives. An article at Dr.Dobb's (August 2002) gives a good overview of the language creation and use.


What percentage of the programming gets done in Workbench?

Solution:It depends on the application domain. Using the Workbench, expert developers create the languages and generators on top of YOUR application framework and components. Using an example from the mobile phone domain, such framework and components include the primitives that every phone uses (e.g. sending short-message, selecting network, etc). Using these primitives all phone applications (phone book, message sending and receiving) are then made by drawing graphical models and generating executable code. If needed, our consultants at MetaCase can provide support for the language and generator creation.


What type of code can MetaEdit+ automatically generate?

Solution:MetaEdit+ is open from the generator side also, so it can generate almost any code, like Assembler, C, OOC, C++, Java, Delphi, Prolog, Python, XML etc. From the same models code can be generated for different target languages.


What type of source code control does MetaEdit+ use?

Solution:You may apply any file based version/source code control software you currently have. MetaEdit+ allows you then to export (and import) any set of your models to a file(s) that can be put to source code control.


What's the difference between "Explosion" and "Decomposition"?

Solution:
Decomposition:
Depending on the method in use one or several objects (e.g. a process in a data flow diagram) can be decomposed into a new diagram. This feature is usually known as decomposition or levelling as it forms a hierarchy of models.

In MetaEdit+ you can create decomposition structures in two ways:
  1. Top-down, by selecting an existing object and making a new decomposition graph where you describe it in more detail.
  2. Bottom-up, by selecting some existing objects and moving them and their relationships into a new decomposition graph, replacing them in the top graph with a new object.

The end result is the same: an object in the top graph has a decomposition graph describing it in more detail. Each object has zero or one decomposition graph, and this is the same wherever that object is used.
Explosion:
Each object in a graph can also be linked to other graphs via an explosion structure. Basically the explosion structure allows the selection of one object from the graph and the explosion of it to a new graph. An object can have a different set of explosions in each graph where it is used. Explosion always happens by first selecting one object, unlike decomposition where several can be selected. Explosion is often used between different graph types.

As with decomposition, explosion structures are also method dependent. An example of a explosion graph can be found from most object-oriented methods, in which an object or class in an object diagram can be further described in a state diagram by exploding it into a new graph.


What's the difference between "Local name" and "Property name"?

Solution:Property name is the name of the property type itself, mostly only visible to the metamodeller. Local name may be different for a given property type in different object types, e.g. a Name property could be given local names of "Process name","Store name" etc. in DFDs.


When I open the Metamodel Browser, no metamodels are shown

Solution:The metamodel browser shows only metamodels in the selected projects in the list on the left. As in other browsers, this list only shows explicitly opened projects. You have not explicitly opened any projects containing metamodels, or then you have not selected them. Make sure the projects containing the metamodels you want to examine have been explicitly opened. From the project list pop-up menu, choose 'Open Projects...' and select the projects containing the metamodels you want to examine. Often, these will be those projects that are starred in the dialog that opens. These are the projects that have been implicitly opened, i.e. contain the metamodels for the models in projects which you have opened.

Now you can select these metamodel projects in the left list, and the middle list will show their metamodels.


When I regenerate the project do I lose my edits outside the tools?

Solution:You should never edit generated code. This is similar to programming with C and not changing .o files in compilation. While creating the modeling language, situations that require coding outside models should be inspected and codified so that modeling language can be extended to cover their specification. Also if edits are in components you do not lose them.

However, if there really is no other way, MetaEdit+ (4.5 and later) does support making protected blocks in generated code. Users can hand-edit the generated code in that block, and regeneration will not overwrite those changes. Please see the documentation of the filename...merge...close and md5id...md5block...md5sum commands in the MetaEdit+ Workbench User's Guide, 5.3.5.