Enhance Module Maven Archetype

Introduction :

The purpose of this is to speed up developer startup time when creating modules. Creating a module is currently a laborious process that includes a lot of file renaming and copy/pasting from other module templates. This maven wizard helps a user to  walk directly in creating the different types of modules and naming things correctly. This  would help to at least speed up the initial creation time.

Note that this is the project page that described the process leading to the original development of the archetype.

For instructions on using the archtype, see /wiki/spaces/docs/pages/25481039.

Creation of modules using module-wizard-plugin :

All moudules start with a basic folder structure:

  • Basic OpenMRS Module

At present the developer has 2 additional options:

  • Module with admin page link as well as a controller and a jsp page for that link.  
  • Module with a Service , HibernateDAO , POJO , Hibernate mapping , liquibase.xml and sqldiff.xml 

See the detail instructions for creating a customized module.

Developing a Module Maven Plugin

For developing a module maven plugin there were few limitations:

Maven archetype plugin is not flexible in:

  • Creation of wizard
  • Selecting necessary module templates
  • Overriding files

As a solution maven-plugin , archetype-plugin and velocity conditions are combined together.

Archetype Plugin : Creates modules from the templates , known as archetype's.
Maven Plugin       : Plays the role of being  wizard i.e asking wizard questions and parametrize them so that they are available for archetype generation mechanism.

Example for developing fully featured archetype:

Aim :

To make module-wizard-plugin compatible in adding a link to openmrs admin page. 

Procedure :

1) Create partial archetype which adds  AdminList.java  file to a module-api.
2) Combine archetype with the WizardMojo  of module-wizard-plugin. 
3) Add velocity condition in " openmrs-archetype-basicmodule-creation" config.xml.

Steps :

1) Create partial archetype which adds  AdminList.java  file to a module-api.       

   By using partial property of  archetype , we can add files to the existing basic module.

   a)Checkout : http://svn.openmrs.org/openmrs-contrib/maven/archetypes/openmrs-archetype-module/branches/openmrs-partial-archetype-module/

    This is the basic partial archetype structure.   
   
   b) Rename your parent project folder
       openmrs-partial-archetype-module to openmrs-archetype-adminpagelink-creation

   c) Change artifactId and name tag values in  pom.xml (Path : openmrs-archetype-adminpagelink-creation\ )     

<artifactId>openmrs-partial-archetype-module</artifactId>   to    <artifactId>openmrs-archetype-adminpagelink-creation</artifactId>
<name>openmrs-partial-archetype-module</name>           to    <name>OpenMrs AminPage Link Archetype </name>   

   d) Add required properties under <requiredProperties /> tag in archetype-metadata.xml (Path: openmrs-partial-archetype-module\src\main\resources\META-INF\maven\ )
      We use , module name(with and with out spaces) and admin page link as input parameter's.
      Syntax:  <requiredProperty key="" >
                          <defaultValue  ></defaultValue>   //with default value
                    </requiredProperty>
                                                      (  or  )
                    <requiredProperty key="" />              //with-out default value       

<requiredProperty key="module-name-no-spaces" />
  <requiredProperty key="module-name" />        
  <requiredProperty key="admin-page-link" />

    e) Add all the required source files in archetype-resources folder of project. Source files under archetype-resources folder act like prototypes.
        Add "AdminList.java" file to Path: openmrs-archetype-adminpagelink-creation\src\main\resources\archetype-resources\api\src\main\java\extension\html\  .  

/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
package ${package}.extension.html;

import java.util.HashMap;
import java.util.Map;

import org.openmrs.module.Extension;
import org.openmrs.module.web.extension.AdministrationSectionExt;

/**
 * This class defines the links that will appear on the administration page under the
 * "${parentArtifactId}.title" heading.
 */
public class AdminList extends AdministrationSectionExt {
    
    /**
     * @see ${groupId}.web.extension.AdministrationSectionExt#getMediaType()
     */
    public Extension.MEDIA_TYPE getMediaType() {
        return Extension.MEDIA_TYPE.html;
    }
    
    /**
     * @see ${groupId}.web.extension.AdministrationSectionExt#getTitle()
     */
    public String getTitle() {
        return "${module-name-no-spaces}";
    }
    
    /**
     * @see ${groupId}.web.extension.AdministrationSectionExt#getLinks()
     */
    public Map<String, String> getLinks() {
        
        Map<String, String> map = new HashMap<String, String>();
        
        map.put("#", "${admin-page-link}");
        
        return map;
    }
    
}

  

  f) Describe the list of all the files that are contained in the archetype-resources under <fileSets ></fileSets> tag , so that can be processed correctly by the archetype generation mechanism.

    <fileSet filtered="true" packaged="true"  encoding="UTF-8">
         <directory>api/src/main/java</directory>
             <includes>
                     <include>**/*.java</include>
             </includes>
    </fileSet>

      <directory />  - This tag points a location starting from archetype-resources folder.
      " **/*.java "       -  Implies that  all the .java file's in parent and its sub-folders should be included.
 
  g) Clean/Remove the archetype-metadata.xml and non-required files and folders from project. 

  • omod folder in archetype resources in not required.
  • filset tag describing omod folder in archetype-metadata.xml is also not required.

Final project structure -
  h) Run mvn install on archetype-project to check whether it builds correctly or not.
    If " Build Success Full " message comes,  then your archetype is working and installed into your local maven repository .m2 .

2) Combine archetype with the WizardMojo  of module-wizard-plugin.

   a)Check out module-wizard-plugin
      URL: http://svn.openmrs.org/openmrs-contrib/maven/plugins/module-wizard-plugin/trunk/

   b)Add the required parameter's to WizardMojo.java
   

/**
  * The generated project's admin page link.
  *
  * @parameter expression="${adminPageLink}" default-value="Link Name"
  */
  private String adminPageLink;

 /**
  * Holds the condition for the generated project's to include a admin link or not.
  *
  * @parameter default-value="n"
  */
  private String adminLinkReply;

       -adminPageLink value can be  manipulated from command line.

       -adminLinkReply value cannot be manipulated with command line.

     c) Add the related question to wizard 
    Maven plugin uses plexus prompter for prompting questions in maven wizard.   

 /**
   * The Plexus CommandLine prompt component.
   * @component
   * @required
   */
private Prompter prompter;

 We can prompt text in two patterns and it returns string
 String parameter1=prompter.prompt(  <command line prompting text >  );    //With out default value    
 String parameter2=prompter.prompt(  <command line prompting text >  , <default value is user enters null >);  //With default value  
Patient Name::             <returns null value>    
Patient Name: John : :  <on entering null ,it returns default value " John " >   

d)Adding question to WizardMojo.java
       -Asking  whether a user want a admin link or not , format (Y/N) .

//archetype selective questions 
  adminLinkReply=prompter.prompt("Do you want admin page link :  (Y/N) ",adminLinkReply);

       -Asking parameter values if admin link question is yes.

//parameters based on reply of archetype selective questions
       if("y".equalsIgnoreCase(adminLinkReply))
              adminPageLink=prompter.prompt("admin-page-link:",adminPageLink);

      e) Add the values as properties to maven session so that they are available for openmrs-archetype-adminpagelink-creation archetype
         As "module-name " , "module-name-no-spaces " are already set for basic basic module creation , we need to add admin-page-link to WizardMojo properties.
         Syntax   :  properties.setProperty( <property-name> , <value> );

     //Adding to maven session so that they are available for archetype-mechanism     
        properties.setProperty( "admin-page-link", adminPageLink );

          Note:  <property-name> is case sensitive

       f)Add the created archetype artifactId to archetypeIds of WizardMojo.java to execute the archetype.                  
        Note: openmrs-archetype-basicmodule-creation should be added first to parameter ' archetypeIds ' as parent archetype should be executed first before partial archetype executes.
        Run command "mvn install" on  module-wizard-plugin.
        It should give "Build Success Full" message.
 

3)Add velocity condition to " openmrs-archetype-basicmodule-creation " config.xml

       To add link to admin page ,we have to add extension tag in config.xml but archetype doesnot allow over-writing of files so by using velocity conditions we have to write them in basicmodule-archetype.
       a)Check out openmrs-archetype-basicmodule-creation
          URL : http://svn.openmrs.org/openmrs-contrib/maven/archetypes/openmrs-archetype-basicmodule-creation/trunk/

      b)Add condition property to archetype-metadata.xml <requiredProperties /> tag of " openmrs-archetype-basicmodule-creation " so that it is available for velocity condition
         Path : openmrs-archetype-basicmodule-creation\src\main\resources\META-INF\maven\

<requiredProperties>
               .
               . 
               <requiredProperty key="adminLinkReply" />
    </requiredProperties>

    c) Add adminList extension with velocity condition to " openmrs-archetype-basicmodule-creation " config.xml

   
    #* If the value of wizard question: " Do you want admin page link "
    is 'y' then below lines will get added to config file
    *#
    #if( $adminLinkReply == 'y' || $adminLinkReply== 'Y' )
    <!-- Add's link to admin page -->
     <extension>
      <point>org.openmrs.admin.list</point>
      <class>${package}.extension.html.AdminList</class>
     </extension>   
    #end      

     d) Run mvn install on openmrs-archetype-basicmodule-creation
        

To run the plugin:

1) Locate your command line to a empty directory.
2) Run maven command
    Syntax   : mvn <groupId>:<artifactid>:<version>:<goal>
    Example : mvn org.openmrs.maven.plugins:module-wizard-plugin:1.0-SNAPSHOT:generate
3) Follow the wizard (Build Success message must be seen)   

All the new archetypes should be committed inhttp://svn.openmrs.org/openmrs-contrib/maven/archetypes/$\{artifactId\}/trunk/