corner imagecorner image
FeaturesPluginsDocs & SupportCommunityPartners

UML:Source Code Merging in NetBeans 6.5

When you use the code generation facility of NetBeans 6.5 UML, the IDE merges generated code with code that is already present. This code merging and code synchronization is based on the existence of generated files and the API that the IDE uses to create templates for code generation. While the IDE is shipped with templates that provide defaults for marker parameters, you can create your own templates and hence your own templates.

Contents

Content on this page applies to NetBeans IDE 6.0

Required Software

To follow this tutorial, you need the following software and resources.

Software or Resource Version Required
NetBeans IDE NetBeans 6.5
BankApp Sample Project Bundled with the NetBeans IDE
Java Development Kit (JDK) version 6 or version 5

 

Logistics

The Domain Templates configuration API creates a set of templates for a code-generated element. The target directory for the generated code, the elements that are generated, and the appropriate templates produce a set of target file paths into which code is generated.

The Merging Process

The merging process starts with pairs of files, which consist of a new file and its pre-existing version. Files are candidates for merging if they are found to be pre-existing files, during the process of merging and synchronization.

The process then follows this logic:

  1. If any of the generated files exist, they are candidates for a merge with the corresponding new file.
  2. The new file needs to be a parseable Java file; however, if the file is not parseable, the IDE creates a backup copy of the existing file, the new file replaces the old and a warning is issued in the console log during the merging process.
  3. Each element has a "Source File Artifact" property which is checked during the merge process to see if a potential merging candidate exists. To be considered a candidate, the file:
    • Must be parseable.
    • Must be marked with the IDE class or classes in it, or
    • If there is a public class declared inside, only the public class marked with an ID is counted. IDs are of the form id=<an unique id value>, with no default and are used in the matching process.
  4. The merging process parses each each new file that does not have a pre-existing version and IDs of its marked classes.
  5. If a match is found, the file where the matching ID is defined is considered the pre-existing version and the one should be merged with the new file.

Flow: Searching for Marker Elements

The API searches for matching elements in each file pair:

  1. The API matches Elements (consisting of types, attributes, methods, or enum literals) of the new file against elements of the same type from the pre-existing file.
  2. The first attempt to match is done using marker IDs.The remainder of the non-matched elements are matched using names (for types, enum literals and attributes) and signatures for operations.
  3. The elements (types, attributes, methods, enum literals) of the new file are matched against the elements of the same type from the pre-existing version.

Regeneratable Elements

An element is regeneratable if it has a marker specifying that it is regeneratable.

Header and Body Regeneration

For purposes of source code modification, an element is a type, attribute, operation or enum literal declaration preceded by a single line comment or comments (including marker comments), and possibly javadoc comments.

The header of an element is the header of the element declaration plus any comments.

By default, the type and enum literal elements are only header-regeneratable: that is, when the type or enum elements are updated with a new version only the header of the element is updated. Such an update leaves the body of the declaration unmodified.

However, using a marker, the element can be explicity defined to be both header and body regeneratable.

By default, in the supplied templates, the body of a method is not regeneratable.

Replaced in Regeneration By Default

Each regeneratable old element for which a matching new element is found is replaced with the new element,.

The new element is made up of a header-only or header and header and body of the declaration.

Each regeneratable old element for which a matching "new" element was not found is deleted from the pre-existing source.

Each new element for which a matching old element was not found is added to the pre-existing source when the merging activity takes place.

Merge Process Console Output

The following represents typical console output when performing a merge, and indicates that source is being generated from the template.

Code Generation selected options:

Source Folder Location - C:\tmp\wrk\wss\NetBeansProjects\UMLBankAppSample24\src  
Backup Sources - true  
Generate Markers - true  
Show Generate Code Dialog - true  

Processing element 1 of 1: Class class3 ...  
Generating source from template "Java/CompilationUnit.java" ... Ok  
Existing Source File - C:\tmp\wrk\wss\NetBeansProjects\UMLBankAppSample24\src\Unnamed1.jav
Merging with the existing source file ... Ok  

Markers

Markers precede immediately an element and a single line comment (which might enclose a NetBeans Java Editor code-folding comment.)

Markers are of the form

 // #[(name=value(,name=value)*)?] 

Recognized Marker Parameters

The Template API recognizes a small set of parameters to indicate to the merging process if elements within a file should be regenerated.

  • regen=yes/no-- Specifieds whether the element is regeneratable default is no if the parameter isn't present
  • regenBody=yes/no-- Specifies if the element is header-regeneratable or header+body regeneratable. The default is no

Marker Example with Regeneratable Parameter

#[regen=yes,id=DCE.837531C6-88E2-92F9-401E-EC3D10886772] 

Examples

Markers Generated by Default Templates

When you use the NetBeans IDE UML Feature to generate code, you obtain code similar to the following, with comments set as included.

Note that the markers follow the form as indicated above, with regen set to yes, and with the marker ids set with specific identifiers.

        
/**
 *  cl2 class comment
 */
// #[regen=yes,id=DCE.837531C6-88E2-92F9-401E-EC3D10886772]
public class cl2 {

    // #[regen=yes,id=DCE.D113E820-6111-0ACD-3734-107284B942AC]
    private String Attr1;

    // #[regen=yes,id=DCE.A68261A9-6DCE-418D-3E81-7863E83C205B]
    public void op1 () {
    }

    // #[regen=yes,regenBody=yes,id=DCE.02E281C8-C473-EB3F-08A2-6967B09A4ACD]
    public String getAttr1 () {
        return Attr1;
    }

    // #[regen=yes,regenBody=yes,id=DCE.4D5F8CF3-9820-B029-5095-F03AA41EE94E]
    public void setAttr1 (String val) {
        this.Attr1 = val;
    }

    /**
     *  clas2  class comment
     */
    // #[regen=yes,id=DCE.53C71074-4D93-0C5F-82E1-ABE5DE2C30F1]
    class clas2 {

    }

}

Manually Adding Markers to Selectively Regenerate Code

You can reverse engineer existing source into a model. However, you might want only some parts of the code to be regenerated from the model.

To accomplish that, you need to manually add the markers as shown below for the attribute called Attr1.

/**
 *  cl2 comment
 */
public class cl2 {

    /**
     *  Attr1 comment
     */
    // #[regen=yes]
    private String Attr1;

    /**
     *  Attr2 comment
     */
    private String Attr2;

    /**
     *  clas2 comment
     */
    class clas2 {

    }

}
The next time you generate code from the model the Attr1 will be matched by name and updated with new version . That is because each regenerateable old element for which a matching new element is found is replaced with that new element when a marker is present.
/**
 *  cl2 comment
 */
public class cl2 {

    /**
     *  Attr1 comment modified in UML documentation property editor (???)
     */
    // #[regen=yes,id=DCE.6914EA88-3C15-40EE-7B14-2D28B9CA4FF3]
    private String Attr1;

    /**
     *  Attr2 comment
     */
    private String Attr2;

    /**
     *  clas2 comment
     */
    class clas2 {

    }

}

Renaming a Model's Attribute

Once the attribute has been marked with an ID, you can rename the attribute in the model and the IDE will still match it using its ID during the next code generation/merging, and thus renamed in the source code as well.


/**
 *  cl2 comment
 */
public class cl2 {

    /**
     *  Attr1 comment modified in UML documentation property editor
     */
    // #[regen=yes,id=DCE.6914EA88-3C15-40EE-7B14-2D28B9CA4FF3]
    private String[] Former_Attr1;

    /**
     *  Attr2 comment
     */
    private String Attr2;

    /**
     *  clas2 comment
     */
    class clas2 {

    }

}

Next Steps

  • To learn more about the UML feature, complete other Tutorials, including the Forward Engineering and Reverse Engineering tutorial.

  • To send comments and suggestions, obtain support, and stay informed of the latest changes to the NetBeans IDE development features, join the mailing list.


top