[Eclipse] GEF entry series (8. Use EMF to construct a GEF Model)

Source: Internet
Author: User

The GEF design does not impose any restrictions on the model part. That is to say, we can construct our own model. The only thing we need to ensure is that the model has a message mechanism so that it can communicate with each other in the event of a change.
GEF (through editpart ). In the previous examples, we used the propertychangesupport and
Propertychangelistener is used to implement the message mechanism. Here we will introduce how to make the model constructed by GEF using EMF (download example, editable. for the emfsubject file, compare it with the non-EMF example with the same functions.) Suppose you have some knowledge about what EMF is.

EMF uses its own ecore as the meta-model, which defines epackage, eclassifier, efeature, and so on.
All models are defined using these concepts. At the same time, because all concepts in ecore can be defined cyclically with their own concepts, ecore is its own metadata model, that is, the metadata model. About
For more information about the concept of ecore, see relevant information on the EMF website.

Use EMF to generate models for usCodeYou can use multiple methods, such as using XML
Schema, Java interfaces with annotations, MDL files of rose, and. ecore files. The EMF code generator requires a file with the extension. genmodel to provide
Information. This file can be generated in the above several ways. I recommend using the eclipseuml plug-in of omondo to construct the. ecore file. The free version of this plug-in can be downloaded from here. (You may need to use a foreign proxy to access the omondo website)


Figure 1 sample model

In order to save space and time, I will not describe the steps for constructing the EMF project in detail. Here we mainly describe the differences between EMF and non-EMF models. Figure 1 shows the model used in the example. dimension and point are two external Java types. Since EMF does not understand them, they are defined as datatype.

Use two plugins

To better separate the model from the editor, you can place the EMF model in a plug-in (named subjectmodel) separately, and let the editor plug-in
(Subjecteditor) depends on it. Another advantage of doing so is that after you modify the model, if you want to, you can easily Delete the previously generated code and then generate all the code again.

Modify in editpart

In the past, our editpart implemented the java. Beans. propertychangelistener interface. After the model was implemented using EMF,
The editpart should be changed to implement the org. Eclipse. EMF. Common. Y. Adapter interface, because every model object of EMF is
Notifier maintains an adapter list. You can add the adapter as a listener to this list of models.

To implement the adapter interface, you must implement the gettarget () and settarget () methods. Target indicates the model object that sends the message. My implementation method is to maintain a notifier type target variable in the editpart. The two methods return and set the variable respectively.

The isadapterfortype () method is also implemented. This method returns a Boolean value, indicating whether the adapter should respond to messages of the specified type. My implementation will always be "return type. equals (GetModel (). getclass ());".

In addition, the name of the propertychanged () method should be changed to the notifychanged () method. Its implementation function is the same as before, but the code is different. below is the implementation in nodepart, let's take a look:

 

Public Void Notifychanged (Notification ){
Int Featureid = Notification. getfeatureid (modelpackage. Class );
Switch (Featureid ){
Case Modelpackage. node1_location:
Case Modelpackage. node1_size:
Refreshreceivals ();
Break ;
Case Modelpackage. node‑incoming_connections:
Refreshtargetconnections ();
Break ;
Case Modelpackage. nodeappsoutgoing_connections:
Refreshsourceconnections ();
Break ;
}
}

In addition, the content in the active ()/deactive () method needs to be modified. The function is to use editpart as the adapter (not
Propertychangelistener) adds the listener list of the model. The following is the implementation of subjectpart. eadapters () obtains the listener column.
Table:

 

Public Void Activate (){
Super. Activate ();
(Subject) GetModel (). eadapters (). Add ( This );
}

As you can see, our changes to editpart are actually converted between two message mechanisms. If you are familiar with the previous mechanism, it should not be difficult to understand.

Elementfactory Modification

This class is used to create a new model object instance based on the template. The previous implementation is "new XXX ()". After EMF is used, it should be changed to "modelfactory. einstance. createxxx () ", each model object instance in EMF should be created using a factory.

 

Public object getnewobject (){
If (Template. Equals (digoal. Class ))
Return Modelfactory. einstance. createdi.pdf ();
Else   If (Template. Equals (subject. Class ))
Return Modelfactory. einstance. createsubject ();
Else   If (Template. Equals (attribute. Class ))
Return Modelfactory. einstance. createattribute ();
Else   If (Template. Equals (connection. Class ))
Return Modelfactory. einstance. createconnection ();
Return   Null ;
}

Use custom creationfactory instead of simplefactory

When defining creationentry in the original palettefactory, simplefactory is specified as the factory. This class uses
Class. newinstance () is used to create a new object instance. After EMF is used as the model, the task of creating an instance should be handed over to modelfactory. Therefore, you must define
Your own creationfactory. (Note: This modification is not included in the sample code .)

Process Custom Data Types

Our node class has two non-standard data types: Point and dimension. To make EMF properly save them, we must provide the serialization and deserialization methods for them.
Method. In the code generated by EMF for us, find the modelfactoryimpl class, which is tangible as convertxxxtostring () and
Createxxxfromstring () is used to serialize and deserialize this type of external data. We need to change its default implementation to our own method. below is my
Implementation Method of point:

 

Public String convertpointtostring (edatatype, object instancevalue ){
Point P = (Point) instancevalue;
Return P.x +   " , "   + P. Y;
}
Public point createpointfromstring (edatatype, string initialvalue ){
Point P =   New Point ();
String [] values = Initialvalue. Split ( " , " );
P.x = Integer. parseint (Values [ 0 ]);
P. Y = Integer. parseint (Values [ 1 ]);
Return P;
}

Note: After modification, delete the @ generated comment before the method so that the Code will not be overwritten when the code is regenerated. It may be a problem to set the default values for variables of these types (for example
For example, set the default value of the location attribute of the node class ).
Set defaultvalueliteral in editor to "100,100" (this is determined by convertpointtostring ().
The default value is returned in the generated code.

Save and load models

EMF uses resource to manage model data. Several resources are collectively referred to as resourceset. As mentioned above, to save the model properly, each module must be
Type objects are included in the resource. Of course, indirect inclusion is also possible. For example, in this model, digoal is included in the resource (create a new digoal
Is added), while digoal contains subject, subject contains attribute, so they are all in resource. As shown in figure 1,
There is a one-to-many inclusion relationship between digoal and connection. The main function of this relationship is to ensure that the model will not appear when it is saved.
Danglinw.fexception because the connection object is not contained in any resource without this inclusion relationship.

When deleting an object, make sure it is no longer contained in the resource. Otherwise, many empty elements will appear in the saved file. Right
When deleting a connection, it is not enough to delete the reference to the connection from the source node and the target node, because it only eliminates the connection between the two nodes on the interface.
The connection object is still included in digoal. Therefore, you must call the digoal object to delete it. In deleteconnectioncommand
The Code is as follows:

 

Public Void Execute (){
Source. getoutgoingconnections (). Remove (connection );
Target. getincomingconnections (). Remove (connection );
Connection. getdions (). getconnections (). Remove (connection );
}

Of course, when creating a connection, do not forget to add the connection to the digoal object (for the code, see createconnectioncommand ). To save and load the model code, please
The init () method and dosave () method of subjecteditor are both standard EMF resource access methods. The following is the loaded code (if it is a newly created file
Create a digoal object in resource ):

 

Public Void Init (ieditorsite site, ieditorinput input) throws partinitexception {
Super. INIT (site, input );
Ifile File = (Fileeditorinput) geteditorinput (). GetFile ();
Uri fileuri = Uri. createplatformresourceuri (file. getfullpath (). tostring ());
Resource =   New Xmiresourceimpl (fileuri); // distinguish between xmiresource and xmlresource
Try {
Resource. Load ( Null );
Digoal = (Digoal) resource. getcontents (). Get ( 0 );
} Catch (Ioexception e ){
Digoal = Modelfactory. einstance. createdi.pdf ();
Resource. getcontents (). Add (digoal );
}
}

Although I have not yet had the opportunity to understand the advantages of EMF in interactive model reference, my impression on EMF has been improved after further understanding and application in this example. As far as I know, using the EMF model as the GEF model has at least the following benefits:

    1. You only need to define the model once, instead of class diagrams, design documents, Java code, and so on;
    2. EMF provides a complete message mechanism for the model, which is not manually implemented;
    3. EMF provides the default model persistence function (XMI) and allows you to modify the persistence mode;
    4. The EMF model is easy to cross-reference because it has enough metadata and so on.

In addition, EMF. the Edit framework can be of great help for model editing. Because I am not familiar with it yet, it is not used in this example. In the future, I will modify this example to use EMF. edit.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.