Thoughts on stargen implementation

Source: Internet
Author: User

The content of graduation project is Web ApplicationProgramOfCodeGenerator, because I have been in contact with EMF for a while, I think it is very convenient to use EMF to implement this program. This is a good opportunity to fully understand EMF, especially codegen. This post will record the process, so it will be trivial. Maybe these words can be used in my graduation thesis (I don't want my paper to be a Google article ). I found that the cnblogs post will appear in RSS after it is modified. Therefore, readers who subscribe to my blog may be "harassed" Frequently: P

For convenience, I gave this code generator a name called "stargen", which is a complete code and does not contain any meaning. Fortunately, this name has not been registered on sourceforge.net. When I have time to apply for it, the package name in the program starts with net. SF. stargen. (Please do not join me in this name. Otherwise, there will be a lot of work on refactor, and maybe I will not open source .)

The following are some ideas about stargen implementation:

1. (3-24) First, I will examine the functions that should be available after the application is completed from the user's perspective. stargen users are actually web application developers, stargen can be used to define elements that are converted into code. After a rough thought, the elements that can be defined include class, attribute, operation, reference, and so on. It is like a class chart. Each class is converted to a web application module, including adding, deleting, modifying, querying, listing, and viewing functions, these functions are composed of one or more JSP pages and Struts actions (currently, Struts-based and hibernate-based applications are generated because they are always used in the Lab ).

So is there a class chart enough? In this way, only simple data operations can be implemented, and there is basically no business logic in it. To make the generated web application logical, I initially added a flowchart for stargen input in addition to the class diagram. The process defined in the flowchart will be reflected in the generated code. This diagram is different from the one in the workflow. I have developed a workflow program before and must process conditions, signatures, and rollback conditions in the process engine, it is actually very complicated. Therefore, it takes time to consider how to simplify the process.


Figure 1 initial steps for using stargen (six steps)

2. (3-24) Since stargen input is clearly defined, one is a class chart and the other is something temporarily called a flowchart, how should users provide these inputs? First, let's take a look at the class diagram. Here, the user must be able to define at least what object types should be in the application, their member variables, methods, and so on, as well as the relationship between classes. If he or she defines a model, I must first have a metadatabase. The metadatabase is like the language of the model, in the meta-model, I want to define such concepts as "class", "member variables", and "methods. According to this idea, do I think that the "language" used for modeling with EMF is not ecore? Yes, ecore is a metadata model, which can be used to define models like UML. So can I allow users to directly use ecore modeling, because there are already a lot of tools using ecore modeling, at least there is a "sample ecore model Editor" along with EMF ", you can use eclipseuml or the ecore editor of GMF to save a lot of work.

3. Steps 3 and 5 in figure 1 (3-24) are the main tasks of stargen. Just like the genmodel in EMF, stargen also needs to have its own genmodel. It may be called "starmodel" for the time being. The two models entered by the user are merged into a starmodel, which contains all their information. In addition, there are some information such as the package name and class name, this information has nothing to do with the business logic of Web applications. In the starmodel generation section, I will mainly use the org. Eclipse. EMF. Importer project, which can generate genmodel from several models including the ecore model.

Another important task is to generate executable code from starmodel. Here I will refer to Org. eclipse. EMF. for the four projects starting with codegen, especially the generator class, I will "open the knife" to see what is worth using. In addition, org. eclipse. several projects starting with uml2.codegen are also worth noting. UML2 code generation borrowed a lot of EMF resources. For example, UML2 genmodel is completely inherited from EMF genmodel, I just added some new elements. I may also adopt this method instead of defining a starmodel similar to the genmodel of EMF from the beginning. BTW, I don't think it's a shortcut. It's called "Leverage "!

4. (3-27) in EMF, the main task of generating genmodel from ecore is done in ecoreimporter. This class inherits the modelimporter class. The preparegenmodelandepackages () and savegenmodelandepackages () methods are called in the complete mfinish () method of modelimporterwizard in the Model import wizard. The former is used to construct genmodel instances, and the latter is used to save the instances.

The main process of modelimporter's preparegenmodelandepackages () method is as follows: calculate other genmodels referenced by this genmodel, add these genmodels together with their own to the same resource, and call the initialize () method of genmodel () method. This method causes the initialize () method of genpackage in genmodel to be called, and the initialize () method of genclassifier to be called, and so on until the entire genmodel is constructed. Then, call traversegenpackages () and adjustgenmodel () to make some adjustments to the obtained genmodel. The main difference is the assignment of some attributes. The role of traversegenpackages () is not clear yet. Finally, call the reconcile () method to apply the modified value in the original genmodel to the new genmodel, otherwise, the modifications made by the user in genmodel editor will be lost after reload.

The savegenmodelandepackages () of modelimporter is straightforward and determines whether a project needs to be created, and determine which projects to add dependencies to the project based on other genmodels that need to be referenced (generally, it seems that genmodel is created in an existing project ), then, call resource # Save () to save the resource.

For stargen, the saved parts should be the same. The main changes will be made in the preparegenmodelandepackages () method of genmodel generation, because the genmodel (starmodel) of stargen) added the process and other classes based on the genmodel of EMF. Therefore, it is very likely that you need to process them in initialize () of starpackage. This overwrites the initialize () of genpackage () method.

5. (3-29) the class corresponding to the new Wizard (file-> New-> others-> eclipse modeling framework-> EMF model) of the EMF model is emfmodelwizard, the wizard consists of the first two pages. The first page is newgenmodelfilecreationpage, which is specified by the user here. the name and project of the genmodel file. The second page is a subclass of modelconverterdescriptorselectionpage, which searches for Org. eclipse. EMF. importer. the modelimporterdescriptors extension point provides a list of modelimporter, such as ecoreimporter and roseimporter. Note: In the getnextpage () method of modelconverterdescriptorselectionpage, you will decide which Wizard to use as the second part of the wizard, and call the adjustmodelconverterwizard () method to assign values.

The second part of the Wizard is determined by importer. The ecore corresponds to ecoreimporterwizard. It is a subclass of modelimporterwizard and contains two wizard pages: modelimporterdetailpage and modelimporterpackagepage. the ecore file and the package to be generated or referenced. The subclass of modelimporterwizard must implement the createmodelconverter () method and return an instance of the modelconverter class. For example, return New ecoreimporter (), ecoreimporter is the subclass of modelimporter, and modelimporter is the subclass of modelconverter.

The wizard is responsible for collecting necessary information. The specific generation of the. genmodel file is completed in modelimporter. The main steps are the preparegenmodelandepackages () and savegenmodelandepackages () methods described earlier.

6. (3-30) in order to realize stargen's function (process, etc.) different from EMF, I "inherit" The genmodel of EMF. ecore) constructs the stargen model (stargen. ecore), this process refers to the implementation of codegen by UML2. Shows the genmodel of stargen:

Note that many elements in the diagram must inherit two classes: genxxx in EMF, starbase, and starbase. In this case, place genxxx first in the inheritance list. Otherwise, the generated code lacks some methods, such as getname () and reconpencil (), and cannot be compiled. Note that in genmodel. genmodel (by genmodel. ecore generation, at Org. eclipse. EMF. codegen. in ecore/model), The creation commands attribute of genmodel is false, and the inherited stargen. make the same settings in genmodel. Otherwise, missingresourceexception will occur in the generated editor. However, after this setting, no new child/sibling menu options are available in the editor.

7. (3-31) use your own template to generate code. In fact, EMF supports dynamic templates from about 2.2.0. You only need to set the "dynamic templates" attribute of genmodel to true and place another template in the appropriate position to generate code based on this template. However, I did not use this mechanism for greater flexibility and unexpected situations. There are many getxxxemitter () methods in the genclassimpl class of EMF. The returned value determines the template used by each element in genmodel. For example, getfactoryclassemitter () of genclassimpl is written as follows:

Public Jetemitter getfactoryclassemitter ()
{
If (Factoryclassemitter =   Null )
{
Factoryclassemitter = Createjetemitter (factoryclasstemplatename );
Setmethod (factoryclassemitter, " Org. Eclipse. EMF. codegen. ecore. Templates. model. factoryclass " );
}
Return Factoryclassemitter;
}

We can see that the factory class generated by EMF is through Org. eclipse. EMF. codegen. ecore. templates. model. factoryclass (Compiled) template. If you want to use your own template, you only need to overwrite this method in the starmodelimpl class (starmodelimpl is a subclass of genmodelimpl, change the setmethod () parameter to "net. SF. stargen. templates. factoryclass.

There are some templates. javajet file, all the files you write in a project with jet nature. xxxjet files will be compiled into one when they are saved. java class, which is generated using the generate () method. the content of the XXX file. Those of EMF. the content of the javajet file is still complex. It takes some time to see how to use it. The most important one is class. javajet, because stargen does not generate. edit and. editor code. The next step is to construct a template related to the web application, such as action. javajet or mapping. HBM. xmljet. The workload may be heavy, but some problems should be simplified first.

8. (4-5) Now stargen can. ecore file generation. starmodel file, and can generate a factory and N bean-like classes (n = the number of eclass in ecore. javajet makes a huge simplification. The code is reduced from more than 1800 lines to less than 100 lines. It is hard to imagine the EMF class. how was javajet written at that time. The next step is to generate the struts configuration file. Here is a difficulty that has not been considered before, that is, how to control jmerge behavior in the XML file should be different from that in the Java class, you still need to learn.

9. (4-10) some difficulties encountered when generating. jsp files. First, the control labels of JSP and jet are both "<%>". different labels must be specified in the jet template, for example, starttag = "<$" endtag = "$>"; second, the genbaseimpl class provides multiple generate () methods for generating. the generate () method of the Java file cannot be used to generate. JSP file, because the output file name extension is written ". for Java, use the generate () method with five parameters and calculate the full name of the output file.

10. (4-11) stargen generates the following code:

Model Element Generated code
Starmodel Web. XML, hibernate. Properties
Starpackage Factory, struts-config.xml, resource. properties (4-17), indexaction (4-15), index. jsp (4-15)
Starclass Bean-like class/Enum (4-18), helper (4-14 new), xxxaction, xxxform, JSPs (list, create, edit), struts-config-xxx.xml, applicationresources. properties, xxx. HBM. XML, validation. XML (4-18)

Next, it will take several days to adjust the template content so that you can get the initial generated results that can be run. (PS. We saw a very similar code generation tool modelstry yesterday. It also generates Struts-based web applications and uses spring to manage hibernate. But it does not seem to be the code generated using jet, and does not know whether there is a problem with merge. I just downloaded the trial version. I have time to study and learn from each other .)

11. (4-13) generate a web application that can list and add new records. Third-party class libraries, including jar packages and TLD files used by struts and hibernate, must be manually added to the project. Genfeature has a getgetaccessor () method. The getter method name in bean is obtained, but it does not have getsetaccessor (). Why? Because getter does not necessarily start with "get, there is also a situation starting with "is", so it is processed in getgetaccessor (), and set <% = genfeature is directly written in the place where the setxxx method is required. getaccessorname () %>.

12. (4-14) edit and delete simple classes, JSP and action. Generates a helper class for each ecore class. The function is similar to the itemprovider generated by EMF. Currently, the gettext () method is mainly provided. You can modify this method to display the required content. By default, this class returns <% = genclass. getsafeuncapname () %>. <% = genclass. getlabelfeature (). getgetaccessor () %> ().

13. The ecore model used for testing is very simple.

14. (4-17) processed the JSP page and used checkbox to display genfeature # isbooleantype () to return the true type. The password Boolean variable was added to starfeature, if this value is true, <HTML: Password> is used instead of <HTML: Text>. Genfeature of non-string type, such as int type and boolean type, can be used normally without special processing. The reason is that it is already of this type in actionform () the parse issue in the/postedit () method does not exist.

15. (4-18) perform the following processing on special genfeature (that is, an attribute not of the common string type:

Genfeature Solution
Transient Remove the declaration of such attributes from the hibernate ing file.
Volatile Pending
Boolean Displayed in checkbox on the create. jsp/edit. jsp page
Contains Add a link for creating a child on the container editing and viewing page.
Listtype On the create. jsp/edit. jsp page, use the multiple SELECT statement. In the hibernate ing file, use <set> instead of <property>.
Reference Use <role-to-one> instead of <property> In The Hibernate ing file.
Maptype This version is not processed for the time being.
Bidirectional Set in the hibernate ing File , In The column name and Columns of one party are consistent.
Enumtype Assume that genfeature is named location and adds an int-type locationvalue attribute to the model class. Mapping only persists this attribute, while getenum () calculates the enum type return value through locationvalue. Generate a class that inherits abstractenumerator and generate a resource file (to internationalize the literals of enumerator) that references this resource file in the struts-config-xxx.xml generated by genclass with Enum type member variables. In create. JSP/edit. JSP display in a drop-down box, view. JSP/list. JSP displays the corresponding text content (rather than the literal directly) in the resource. The locationvalue attribute must correspond to the model class in actionform. (4-19)
Notnull Set in the hibernate ing File

Add the required constraint to the validation. xml file.
Other non-string types Add constraints to the validation. xml file

 

16. (4-18) Common genfeature Methods: gettypegenclass () gets the genclass opposite to genfeature;

17. (4-19) Allow the generated Java code to have the appropriate import declaration method: add a statement similar to the following before the jet file:

<% Genmodel. addimport ( " Java. util. Arrays " ); %>
<% Genmodel. addimport ( " Java. util. List " ); %>
<% Genmodel. addimport ( " Java. util. Collections " ); %>
<% Genmodel. markimportlocation (stringbuffer, genpackage ); %>

Add <% genmodel. emitsortedimports (); %> In the last line of the jet file.

18. (4-19) implements processing of the enum type genfeature, but the generated code is not perfect, the JSP page contains statements similar to the following statement (because struts labels cannot be easily expressed, <option> is used instead of <HTML: Option>, and <Bean: message> also contains JSP code ):

< HTML: Select Property = " Locationvalue " >
<% For (Iterator ITER = Location. Values. iterator (); ITER. hasnext ();){
Location = (Location) ITER. Next (); %>
< Option value = " <% = Location. getvalue () %> "
< BEAN: Message key = " <% = Location. getname () %> " Bundle = " Location " />
</ Option >
<% } %>
</ HTML: select >

19. (4-20) the list can be sorted. The following is a paging problem, which may be slightly troublesome.

20. (5-10) Process Design: A process is composed of activities. Each activity can be equivalent to an operation on the database, for example, to add a user is to add a record in the User table, and because Hibernate is used, database operations are to operate on persistent objects. For example, adding a user is to add a user object.

To simplify implementation, we do not consider introducing conditions in the process.

Each activity should have the following attributes:

    • Operation (operation), an enumeration type. The optional values are select, create, delete, and modify. in the implementation, you can also use different subclasses of the activity to achieve the same purpose.
    • The target type, whose value is a class in the data model, such as user and product. Therefore, the process model depends on the data model.
    • Target object (targetobject), the instance processed in this activity, for example, user Zhang San;

Target object transfer between activities: for example, product1 is created for the first activity, and the content of the second activity is to edit the attributes of product1. In the process design, how can I tell the ID number of product1 In the second activity? In addition, will there be situations where multiple IDCs need to be notified? The current idea is to maintain this object in the session. The Select Operation assigns a value to this object and clears it at the end of the process.

21. (5-11) because there is no branch structure in the process, the begin and end activities seem unnecessary. Today, the original editor of starflowmodel is completed. The process model created with it can load the data model through "load resources..." and establish the association between the two models. The process and activity types originally designed in the data model are also deleted.

Next, we need to consider the specific process template content.

22. (5-13) the templates of select and modify activities are basically completed. They can be used to form a simple process such as "modify product information. The remaining activity types include "CREATE", "delete", and "Custom". M will generate a code framework without any function, allowing you to implement any function on your own.

In addition, the template corresponding to the process has been completed.

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.