Rendering

The rendering stage of provisioning is driven by application of Velocity Templates.  However, in some cases, there may be additional processing applied to the resulting text:

·         Merge processing.  This processing stage merges generated content with existing target artifact content, subject to various merge control options specified in the generated content.

·         Formatting.  Depending upon content type, eclipse content formatting utilities will be applied to the result.

·         Conditional commit.  If the result is the same as the existing target artifact content, no output will occur.  This will preserve file time-stamp for unaltered target artifacts, enabling expected behavior for incremental project builds and repository updates.

·         Post processing actions.  Depending upon content/file type, actions may be invoked to process the result, such as construction of an eclipse project in the workspace when a “.project” file is rendered.

 

Merge Processing

The following forms of merge processing are implemented:

·         Java merge

·         model merge

Java merge

A specialized generation mechanism provides for user override of generated java code.

 

 The implementation utilizes tag values in the javadoc comment block preceding a method, plus blocks demarcated by specific string patterns.  The following tags are currently defined:

 

Within a method body, the following pattern is used:

Text Box:                 // begin-user-code
                …………….any user code
                // end-user-code

 

Within a javadoc comment, the following pattern is used:

Text Box: <!--begin-user-doc -->
                …………….any user documentation
 <!--end-user-doc -->

 

 


Example:

Assume following code is generated initially (for new Target)

Text Box: /**
 * test case for unmodifiable 
 *<!--begin-user-doc -->
 <!--end-user-doc -->
 * @unmodifiable
 */
public void testSimpleUnmodifiable() {
      // because of the @unmodifiable tag,
      // any generated code in this method can notl be overridden
      // begin-user-code
      // end-user-code  
}
 
      /**
 * test case for modifiable 
 *<!--begin-user-doc -->
 <!--end-user-doc -->
 * @modifiable
 */
public void testSimpleModifiable() {
      // because of the @modifiable tag,
      // generated code in this method will be overridden only within following block, plus comments in the user-doc block
      // begin-user-code
      // end-user-code  
}
 
      /**
 * test case for generated 
 *<!--begin-user-doc -->
 <!--end-user-doc -->
 * @generated
 */
public void testSimpleGenerated() {
      // because of the @generated tag,
      // any code in this method will be overridden by generated code
      // begin-user-code
      // end-user-code  
}
 
      /**
 * test case for untagged 
 *<!--begin-user-doc -->
 <!--end-user-doc -->
 */
public void testSimpleUntagged() {
      // because of no recognized tag,
      // all  code in this method can be overridden by user
      // begin-user-code
      // end-user-code  
}


Assume user modifies above so that he sees:

Text Box: /**
 * test case for unmodifiable 
 * user comment 1
 *<!--begin-user-doc -->
 * user comment 2
 <!--end-user-doc -->
 * user comment 3
 * @unmodifiable
 */
public void testSimpleUnmodifiable() {
      // because of the @unmodifiable tag,
      // any generated code in this method can not be overridden
      // user-code 1
      // begin-user-code
      // user-code 2
      // end-user-code  
      // user-code 3
}
 
      /**
 * test case for modifiable 
* user comment 1
 *<!--begin-user-doc -->
 * user comment 2
 <!--end-user-doc -->
 * user comment 3
 * @modifiable
 */
public void testSimpleModifiable() {
      // because of the @modifiable tag,
      // generated code in this method will be overridden only within following block, plus comments in the user-doc block
      // user-code 1
      // begin-user-code
      // user-code 2
      // end-user-code  
      // user-code 3
}
 
      /**
 * test case for generated 
* user comment 1
 *<!--begin-user-doc -->
 * user comment 2
 <!--end-user-doc -->
 * user comment 3
 * @generated
 */
public void testSimpleGenerated() {
      // because of the @generated tag,
      // any code in this method will be overridden by generated code
      // user-code 1
      // begin-user-code
      // user-code 2
      // end-user-code  
      // user-code 3
}
 
      /**
 * test case for untagged 
* user comment 1
 *<!--begin-user-doc -->
 * user comment 2
 <!--end-user-doc -->
 * user comment 3
 */
public void testSimpleUntagged() {
      // because of no recognized tag,
      // all  code in this method can be overridden by user
      // user-code 1
      // begin-user-code
      // user-code 2
      // end-user-code  
      // user-code 3
}
 
/**
 * test case for user added method 
 * my comment 1
 *<!--begin-user-doc -->
 * my comment 2
 <!--end-user-doc -->
 * my comment 3
 */
public void testSimpleUserAddedMethod() {
      // because of no recognized tag,
      // all  code in this method can be overridden by user
      // my mod will happen
      // begin-user-code
      // my mod will happen 2
      // end-user-code  
      // my mod will happen 3
}


 

Result of re-running ModelPro would be:

Text Box:  /**
 * test case for unmodifiable 
 *<!--begin-user-doc -->
 <!--end-user-doc -->
 * @unmodifiable
 */
public void testSimpleUnmodifiable() {
      // because of the @unmodifiable tag,
      // any generated code in this method can not be overridden
      // begin-user-code
      // end-user-code  
}
 
      /**
 * test case for modifiable 
 *<!--begin-user-doc -->
 * user comment 2
 <!--end-user-doc -->
 * @modifiable
 */
public void testSimpleModifiable() {
      // because of the @modifiable tag,
      // generated code in this method will be overridden only within following block, plus comments in the user-doc block
      // begin-user-code
      // user-code 2
      // end-user-code  
}
 
      /**
 * test case for generated 
 *<!--begin-user-doc -->
 <!--end-user-doc -->
 * @generated
 */
public void testSimpleGenerated() {
      // because of the @generated tag,
      // any code in this method will be overridden by generated code
      // begin-user-code
      // end-user-code  
}
 
      /**
 * test case for untagged 
 * user comment 1
 *<!--begin-user-doc -->
 * user comment 2
 <!--end-user-doc -->
 * user comment 3
 */
public void testSimpleUntagged() {
      // because of no recognized tag,
      // all  code in this method can be overridden by user
      // user-code 1
      // begin-user-code
      // user-code 2
      // end-user-code  
      // user-code 3
}
 
/**
 * test case for user added method 
 * my comment 1
 *<!--begin-user-doc -->
 * my comment 2
 <!--end-user-doc -->
 * my comment 3
 */
public void testSimpleUserAddedMethod() {
      // because of no recognized tag,
      // all  code in this method can be overridden by user
      // my mod will happen
      // begin-user-code
      // my mod will happen 2
      // end-user-code  
      // my mod will happen 3
}

 


Additional variations:

User removes tags, producing following in target:

Text Box: /**
 * test case for unmodifiable 
 * user comment 1
 *<!--begin-user-doc -->
 * user comment 2
 <!--end-user-doc -->
 * user comment 3
 */
public void testSimpleUnmodifiable() {
      // because of the @unmodifiable tag,
      // any generated code in this method can not be overridden
      // user-code 1
      // begin-user-code
      // user-code 2
      // end-user-code  
      // user-code 3
}
 
      /**
 * test case for modifiable 
 * user comment 1
 *<!--begin-user-doc -->
 * user comment 2
 <!--end-user-doc -->
 * user comment 3
 */
public void testSimpleModifiable() {
      // because of the @modifiable tag,
      // generated code in this method will be overridden only within following block, plus comments in the user-doc block
      // user-code 1
      // begin-user-code
      // user-code 2
      // end-user-code  
      // user-code 3
}
 
      /**
 * test case for generated 
       * user comment 1
       *<!--begin-user-doc -->
       * user comment 2
       <!--end-user-doc -->
       * user comment 3
 */
public void testSimpleGenerated() {
      // because of the @generated tag,
      // any code in this method will be overridden by generated code
      // user-code 1
      // begin-user-code
      // user-code 2
      // end-user-code  
      // user-code 3
}

 

 


 

Regeneration via ModelPro produces:

 Text Box: Note:user can not change @unmodifiable
/**
 * test case for unmodifiable 
 *<!--begin-user-doc -->
 <!--end-user-doc -->
 * @unmodifiable
 */
public void testSimpleUnmodifiable() {
      // because of the @unmodifiable tag,
      // any generated code in this method can notl be overridden
      // begin-user-code
      // end-user-code  
}
 
Note:user can not change @modifiable
      /**
 * test case for modifiable 
 *<!--begin-user-doc -->
 * user comment 2
 <!--end-user-doc -->
 * @modifiable
 */
public void testSimpleModifiable() {
      // because of the @modifiable tag,
      // generated code in this method will be overridden only within following block, plus comments in the user-doc block
      // begin-user-code
      // user-code 2
      // end-user-code  
}
 
Note:user can remove @generated and replace all body code and comments
      /**
 * test case for generated 
       * user comment 1
       *<!--begin-user-doc -->
       * user comment 2
       <!--end-user-doc -->
       * user comment 3
 */
public void testSimpleGenerated() {
      // because of the @generated tag,
      // any code in this method will be overridden by generated code
      // user-code 1
      // begin-user-code
      // user-code 2
      // end-user-code  
      // user-code 3
}

  


Model merge

A specialized generation mechanism provides for fine-grained user override of model-backed target artifacts.

 

 

The implementation utilizes tag values associated with a model element.  The mechanism for associating tags with model elements depends on the serialization form for the target artifacts plus any underlying model constraints.  The following tags are currently used:

 

The default behavior for override in absence of tags is that source model elements override “matching” target model elements.  Target model elements which do not appear in source will be included in resulting target.   A “match” determination is model-specific.

 

For xsd and wsdl, tags are specified as attributes on the serialized document element.  The namespace for these override attributes  is http://modelDriven.org/schema/modelPro/override.   Thus a xsd/wsdl document may have the form:

 

Text Box:       <…  xmlns:mpo=”http://modelDriven.org/schema/modelPro/override”…>
            …
            <…   mpo:generated=”” …>
            …
      </…>

  

Example:

Assume following is generated initially (for new Target xsd)

 

Text Box: <xsd:complexType name="UnmodifiableSolicitation" mpo:unmodifiable="" mpo:doc="user can not modify any part of this">
      <xsd:sequence>
        <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
        <xsd:element name="testNameChange" type="xsd:string"/>
        <xsd:element name="testEmbeddedChange" type="xsd:string"/>
        <xsd:element name="testRemoval" type="xsd:string"/>
        <xsd:element name="testInsertEnd" type="xsd:string"/>
    </xsd:sequence>
</xsd:complexType>
                        
<xsd:complexType name="ModifiableSolicitation" mpo:modifiable="" mpo:doc="user completely overrides this element">
      <xsd:sequence>
        <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
        <xsd:element name="testNameChange" type="xsd:string"/>
        <xsd:element name="testEmbeddedChange" type="xsd:string"/>
        <xsd:element name="testRemoval" type="xsd:string"/>
        <xsd:element name="testInsertEnd" type="xsd:string"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="GeneratedSolicitation" mpo:generated=""  mpo:doc="this element is generated">
      <xsd:sequence>
        <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
        <xsd:element name="testNameChange" type="xsd:string"/>
        <xsd:element name="testEmbeddedChange" type="xsd:string"/>
        <xsd:element name="testRemoval" type="xsd:string"/>
        <xsd:element name="testInsertEnd" type="xsd:string"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="GeneratedNotSolicitation" mpo:generated=""   mpo:doc="user completely overrides this element if generated tag removed">
      <xsd:sequence>
        <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
        <xsd:element name="testNameChange" type="xsd:string"/>
        <xsd:element name="testEmbeddedChange" type="xsd:string"/>
        <xsd:element name="testRemoval" type="xsd:string"/>
        <xsd:element name="testInsertEnd" type="xsd:string"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="DefaultSolicitation" mpo:doc="user can add elements but not override generated elements">
      <xsd:sequence>
        <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
        <xsd:element name="testNameChange" type="xsd:string"/>
        <xsd:element name="testEmbeddedChange" type="xsd:string"/>
        <xsd:element name="testRemoval" type="xsd:string"/>
        <xsd:element name="testInsertEnd" type="xsd:string"/>
        <xsd:element name="testEmbeddedDefault" >
                <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
                          <xsd:element name="testNameChange" type="xsd:string"/>
                          <xsd:element name="testEmbeddedChange" type="xsd:string"/>
                          <xsd:element name="testRemoval" type="xsd:string"/>
                          <xsd:element name="testInsertEnd" type="xsd:string"/>
                      </xsd:sequence>    
                </xsd:complexType>
            </xsd:element>        
        <xsd:element name="testEmbeddedUnmodifiable" mpo:unmodifiable="">
                <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
                          <xsd:element name="testNameChange" type="xsd:string"/>
                          <xsd:element name="testEmbeddedChange" type="xsd:string"/>
                          <xsd:element name="testRemoval" type="xsd:string"/>
                          <xsd:element name="testInsertEnd" type="xsd:string"/>
                      </xsd:sequence>    
                </xsd:complexType>
            </xsd:element>        
        <xsd:element name="testEmbeddedModifiable" mpo:modifiable="">
                <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
                          <xsd:element name="testNameChange" type="xsd:string"/>
                          <xsd:element name="testEmbeddedChange" type="xsd:string"/>
                          <xsd:element name="testRemoval" type="xsd:string"/>
                          <xsd:element name="testInsertEnd" type="xsd:string"/>
                      </xsd:sequence>    
                </xsd:complexType>
            </xsd:element>        
        <xsd:element name="testEmbeddedGenerated" mpo:generated="">
                <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
                          <xsd:element name="testNameChange" type="xsd:string"/>
                          <xsd:element name="testEmbeddedChange" type="xsd:string"/>
                          <xsd:element name="testRemoval" type="xsd:string"/>
                          <xsd:element name="testInsertEnd" type="xsd:string"/>
                      </xsd:sequence>    
                </xsd:complexType>
            </xsd:element>        
        <xsd:element name="testEmbeddedGeneratedNot" mpo:generated="">
                <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="testInsertBeforeAfter" type="xsd:string"/>
                          <xsd:element name="testNameChange" type="xsd:string"/>
                          <xsd:element name="testEmbeddedChange" type="xsd:string"/>
                          <xsd:element name="testRemoval" type="xsd:string"/>
                          <xsd:element name="testInsertEnd" type="xsd:string"/>
                      </xsd:sequence>    
                </xsd:complexType>
            </xsd:element>        
        
    </xsd:sequence>
</xsd:complexType>


 Assume user modifies above so that he sees: