semantic stuff

The main semantic elements of “Entity DSL” are:

  • Package” – it is the root element that contains all the other elements (there is one exception for generator stuff). A document can contain multiple packages.
    • Import” declarations – allow you to import external models or even java classes
    • Entity” – the abstraction above an business entity. It contains further elements.
      • Property” – a reference to an Enum, a “java class” or “simple type”. Offers multiplicity.
      • Reference” – a reference to an Entity. Offers multiplicity.
      • Containment” reference – the same as a Reference, but lifecycle of the child elements depends on the lifecycle of the current Entity. Offers multiplicity.
      • Container” reference – the opposite reference of the “Containment” reference. Multiplicity always 1.
      • Embedds” – lets you define entities that should become nested.
      • Operations” – like java methods. Xbase expression language can be used to write highend code (with closures,…)
    • Enum” – the abstraction for java enums.
  • Annotations “can be placed on Entity, Property, Reference, Containment, Container.
  • “Comments” can be placed on all elements.

Lets see an example of it:

Code Snippet 1

But now lets start with the different semantic elements of the grammar.

Package

Packages are the root element of the grammar. All (except generator stuff) is contained there. So Imports, Entities and Enums have to be defined inside of the Package definition. One document can contain multiple packages. But their names have to be unique. For code example follow Code Snippet 1.

Imports

Since the “Entity DSL” allows you to reference entities defined in different packages but also to reference pure java classes that are defined somewhere in the class path, the import statement is a way to address “model elements” by their full qualified name. It is important to understand, that the import statement is not limited to java classes but also addresses each model element that offers a full qualified name!

In detail the java classes are model elements too. Xbase offers a type system called Xtype and before java classes can be used in Xtext DSL, they have to be transformed into its model representation. This transformation is done lazy at runtime. If you are looking for a java class in your DSL by content assists or something else the Xtype model is built on the fly.

For details see org.eclipse.xtext.common.types.access.jdt.JdtTypeProvider from Sebastian Zarnekow. A really impressive piece of code.

Import statements also allow the use of the *-wildcard. It is legal to write java.util.* to import all classes contained in the package java.util. Please note, that java.util.* and java.lang.* are imported by default in each document. So these imports do not have to be added.

For code example follow Code Snippet 1.

Enums

Enums are an abstraction above the java enum. Really easy to use. For code example follow Code Snippet 1.

Entities

Well, entities are the most complex elements in the “Entity DSL”. An entity is an abstraction above a business object. You can specify its name and add properties, different kind of references as well as operations to it. In general you can say, that the entity is an object, which can keep a state about references objects.
If you are using one of the Built-In-Compilers, the entity will compile to pojo or even an JPA entity. For code example follow Code Snippet 1.

Entity-Modifier

Modifier can be placed before the entity keyword.

  cachable embeddable entity House...
  • abstract – Marks the entity to be abstract
  • cachable – Marks the entity to be cachable (JPA)
  • embeddable – Marks the entity to be embeddable – see also embedds

Properties

Properties are references to java types or enums. You should not use a property to reference an Entity! It would be possible, if you are using a Built-In-Compiler that generates java classes for the entities. But then you will loose a lot of semantic advantages, since then the Entity is a representation of a Xtype model element and we can not address the different types of references contained in the Entity. Every reference or property of the xtyped-entity is a field then.

Code Snippet 2

  • line 6 – defines a simple String property
  • line 7 – defines a String property with multiplicity “one to many” (The Built-In-Compiler will interpret as List<String>)
  • line 8 – defines a java.util.List typed with String.
  • line 9 – defines a java.util.List typed with String and multiplicity “one to many”.
  • line 11 – defines a enum property

Pojo- and JPA-Compiler will interpret them this way (JPA-Compiler would additionally add javax.persistence-annotations):

public class House {
  private String name;
  private List<String> manyNames;
  private List<String> alsoManyNames;
  private List<List<String>> manyListsOfNames;
  private Type typeEnum;
Property-Modifier

Modifier can be placed after the var keyword.

        var id long id
        var version int version
        var transient String name
  • id – Marks the property as an id-property (used by JPA-Compiler)
  • version – Marks the property as an version-property (used by JPA-Compiler)
  • transient – Marks the property to be transient

References

Currently the “Entity DSL” offers three types of references.

  • refers – A simple reference to an Entity
  • contains – A strong reference to an Entity
  • container – The opposite reference of contains
Property-Modifier

Modifier can be placed after the var keyword.

        refers lazy notnull Window w
        contains lazy notnull Window w2
  • lazy – Marks the reference to be loaded lazy (used by JPA-Compiler)
  • notnull – Marks the reference that it must never be null (used by JPA-Compiler)

Refers

Refers is a light weight reference. It just defines a reference with a name and multiplicity to an Entity.

Code Snippet 3

  • line 5 – defines…
    • a reference with name owner to the entity Person.
    • an opposite reference, that defines the reference in Person that can be used to navigate back to this instance of House. Will be heavily used by the JPA-Builtin-Compiler to determine the mappedBy-parameter for relation annotations.
  • line 6 – a reference of targettype Person with multiplicity “zero to many” with name livingInHouse
  • line 10 – same as line 5 but with a multiplicity of “zero to many”

Contains and Container

Containsreference is the stronger form of the refers-reference. It is meant to add lifecycle handling to the refers-reference. The lifecycle of an entity targeted by a contains-reference is limited by the lifecycle of the reference containing entity. If the entity that contains the contains-reference is disposed, destroyed,… the target entities of the contains-reference have to be disposed too.

Container-reference is the opposite reference of the contains-reference and never keeps multiplicity. The upper bound of multiplicity is always 1.

Code Snippet 4

  • line 5 – defines…
    • a containment-reference to the entity Window. Multiplicity “zero-to-many”.
    • an opposite reference, that addresses the container-reference in Window. The concrete instance of the containing house can be accessed by the container-reference.
  • line 6 – a refers-reference addressing all open windows

So the big difference to the refers-reference is, that the Built-In-Compiler will treat this reference type completely different.

The “JPA-Compiler” will calculate the mappedBy-annotation-param and specifies the cascade types:

  @OneToMany(cascade = CascadeType.ALL, mappedBy = "house")
  private List windows;

So if the House becomes deleted, persisted,.. the operation is also processed on all windows that are addressed by the windows containment-reference.

And as a special feature that is also available for the “Pojo-Compiler” (JPA-Compiler too) the fields of containment references become synced. See the generated java-doc:

  /**
   * Adds the given window to this object. <p>
   * Since the reference is a containment reference, the opposite reference (Window.house) 
   * of the window will be handled automatically and no further coding is required to keep them in sync. 
   * See {@link Window#setHouse(Window)}.
   * 
   * @param window
   */
  public void addWindows(final Window window) {

Embedds

Embedds is not a reference. It is a semantic element, that suggest to “embedd” (or nest) the addressed Entity.

Code Snippet 5

  • line 7 – defines that the embeddable entity Address should be embedded into the House entity.

Note, that there are restrictions on entities that can be embedded. For instance, the embedded type may not have containment references. But you will get error messages by the DSL if you are defining not valid code!

Embedds and Built-In-Compilers

Embedds is treated differently by the “Built-In-Compilers”

Pojo-Compiler
public class House {
  private String address_street;
  private String address_postalCode;

The Pojo-Compiler inlines the properties of the embeddable entitiy. So the properties can be handled like normal properties.

JPA-Compiler
@Entity
public class House {
  @Embedded
  private Address address;

The JPA-Compiler treats the embedds as a reference, but adds the @javax.persistence.Embedded annotation to it.

Operations

Other really important features are operations. They are based on Xbase and offer a really hugh set of semantic features and extend the featureset of java. Xbase additionally offers features like closures,…

Code Snippet 6

The defined operation at line 13 converts the List<Window> into Set<String> by adding all windownames in uppercase to a set.

Since Xbase supports closures and internally uses google.guava, the mapping can be done with a minimum of code.

The Xbase compiler (used by the Built-In-Compilers) will generate the following code:

  /**
   * Returns a set containing the names of the
   * windows UPPERCASE.
   */
  public Set toWindowNamesUppercase() {
    final Function1 _function = new Function1() {
        public String apply(final Window e) {
          String _name = e.getName();
          String _upperCase = _name.toUpperCase();
          return _upperCase;
        }
      };
    List _map = ListExtensions.map(this.openWindows, _function);
    return IterableExtensions.toSet(_map);
  }

Annotations

Annotations can be added to all elements except “generator settings stuff” and “import declarations”.

Code Snippet 7

Here you can see the definition of annotations.

You can do 3 different things:

  • line 7 – Remove an annotation that would be created by the JPA-Compiler for default. (Depends on the compiler implementation)
  • line 8 – Add a new annotation
  • line 9 – Override a default annotation that would be created by the JPA-Compiler with new parameters. Replace the default annotation from the JPA-Compiler. (Depends on the compiler implementation)

One Response to “semantic stuff”

  1. SEO Says:

    Good day! I just want to give an enormous thumbs up for the good data you’ve right
    here on this post. I will probably be coming again to
    your blog for more soon.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: