Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Tigerstripe Advanced Plugin Tutorial"

(Artifact Filters)
(Velocity Macros)
Line 217: Line 217:
 
=Velocity Macros=
 
=Velocity Macros=
  
In addition to models and utilities, Velocity supports the use of Velocimacros to simplify repetitive template functions. You can find out more about these macros on the Velocity website (http://jakarta.apache.ort/velocity/index.html). If your template needs the macros, you must add a reference to them in your rule definition.
+
'''[[Tigerstripe_Glossary#Velocity|Velocity]]''' supports the use of '''Velocimacros''' to simplify repetitive '''[[Tigerstripe_Glossary#Velocity Template|template]]''' functions. You can find out more about these macros on the Velocity website.
 +
 
 +
'''Velocimacros''' are added to a '''[[Tigerstripe_Glossary#Rule|rule]]''' defintion in a very similar manner to'''[[Tigerstripe_Glossary#Velocity Context Defintion|Velocity Context Defintions]]'''. Simply navigate to the '''Velocity Macro''' section of the rule editor and click on "Add".
 +
 
 +
Note: '''[[Tigerstripe_Glossary#Tigerstripe|Tigerstripe]]''' does not support the definition of "''in-line'' macros.
  
 
=Plug-in Reports=
 
=Plug-in Reports=

Revision as of 09:14, 11 January 2008

< To: Tigerstripe_Tutorials

This tutorial builds upon the concepts discussed in the Simple Plugin Tutorial. It introduces different rule types, shows how to incorporate more information into your templates and develop java helper classes to simplify template writing.

Defining Global Rules

In the Simple Plugin Tutorial we created a simple Artifact Rule. These rules are run once per artifact (for the the relevant Artifact Type) in the project, and produce a single file for each artifact.

In some situations, you may desire or need to create a file that contains information about multiple artifacts. For example, a single XML file that contains information about all of the artifacts in a project or an HTML index page that provides links to pages about each entity. In this case you would define a Global Rule.

Global Rules are executed once per generation of a project. There are a few differences from Artifact Rules: Creating a Global Rule follows the same process as creating an Artifact Rule, however there is less information to enter upon creation.

In the following example you will create a very simplistic XML schema that has elements for each Entity in the model. Note: The validity of this schema is questionable; it is intended purely as an example of a Global Rule.

To create a Global Rule:

1. Create a template in the templates directory of your Plugin Project. Name this template globalTemplate.vm and save the template. The template should include the following content:

     ## This is globalTemplate.vm
     <?xml version="1.0" encoding="UTF-8"?>
     <schema>
     #foreach ($entity in $entities)
         <complexType name="$entity.Name" >
               <complexContent>
                     <sequence>
     #foreach ($attribute in $entity.IextFields)
                         <element name="$attribute.Name" type="$attribute.Type.Name" />
     #end
                     </sequence>
             </complexContent>
         </complexType>
     #end
     </schema>

Take look at a few key lines in this template:

  • #foreach ($entity in $entities) ...... #end - This line defines the enclosed template elements and ensures that they are iterated for each entity in the model.
    • $entities is one of a number of possible collections.
    • $enumerations, $datatypes etc, contain all instances of a particular artifact type.
    • $artifacts is the complete set of artifacts in the model.
  • #foreach ($attribute in $entity.IextFields)..... #end - This line defines the enclosed template elements and ensures that they are iterated for each attribute defined in the entity.
    • Attributes are of type IextField - more details can be found in the API documentation in the on-line Help.
    • Other useful collections are IextLabels for Constantsand IextMethods for Methods'.
  • type="$attribute.Type.Name" - Scans the model to obtain the name of the attribute type.

Note: You can obtain a more complete picture of the model structure by looking at the javaDoc for the Tigerstripe external API.

2. Create a Global rule that points to the template you created. You accomplish this in the same way you created an Artifact Rule. Refer to Define a Plug-in Rule for more information. There are actually two types of Global Rule - for this rule, select the "Simple Run Rule" from the drop-down list - this should be the default.

3. Click Save to save your changes.

The next time you generate a Project with this plugin enabled, you should get a schema file (schema.xsd) with content similar to the following:

<?xml version="1.0" encoding="UTF-8"?>
<schema>
   <complexType name="Order" >
         <complexContent>
               <sequence>
                   <element name="details" type="String" />
               </sequence>
       </complexContent>
   </complexType>
   <complexType name="Service" >
         <complexContent>
               <sequence>
                   <element name="Counter" type="int" />
                   <element name="ServiceName" type="String" />
               </sequence>
       </complexContent>
   </complexType>
</schema>

In this example, you have two entities named, Order and Service. The Service entity has two attributes, Counter and ServiceName.

It is important to realize that in a real model, you will see different content in the schema file but the structure will be the same and will be repeated for each entity.

Important: Both Global and Artifact Rules can exist in the same plugin. Be careful to choose unique output file names.

Using Java Models

(You can only specify a Model within an Artifact Rule definition.)

A Modelis a Java class that implements the IArtifactModel interface (or one of its subclasses) specified in the Tigerstripe External API. Appropriate use of a Model Class can greatly simplify templates and enhance their readability.

In the Model Class' you define methods to manipulate the information available from the artifact, project etc, or look-up additional data. Some examples of method usage within a model are:

  • Reformat data - You may want to translate a package name to a directory path name. For example, com.mycompany.models could become com/mycompany/models.
  • Look up data in other related artifacts- eg If the type of an attributeis an enumeration, you can examine the Base Type of that enumeration(ie int or string).
  • Read additional data from a configuration file in the project or plugin.
  • Perform complex manipulations that would be difficult in Velocity.


The artifact' that is to be processed is passed to the Model Classusing the setIArtifact method.


To create a new Model Class:

  1. Create a new Java Class in the src directory of your plugin project.
  2. The Class must implement the IArtifactModel interface (or one of its subclasses)
    • For this tutorial Name your model EntityModel in the com.mycompany.plugins.models package
  3. Add the methods as outlined in the following example:


public class EntityModel implements IArtifactModel {
   private IArtifact artifact;   
   public void setIArtifact(IArtifact artifact) {
       this.artifact = artifact;
   }
   public IArtifact getArtifact(){
       return artifact;
   }
   public String getName(){
       return getArtifact().getName()+"Value";
   }
   public String getKeyName(){
       return getArtifact().getName()+"Key";
   }
   public String getOutPath(){
       String packageName = getArtifact().getPackage();
       String path = packageName.replaceAll("\\.", "/");
       return path;
   }

}

Note: You will need to "import" the IArtifactModel and IArtifact interfaces for the Tigerstripe External API.

In this example, you will specify the type of your artifact to be IArtifact. This allows the model to be used for any artifact type. In many cases however, you may wish to create a more specific type of artifact, such as IManagedEntityArtifact. This allows access to methods on a particular artifact type. It is also possible to create a generic model and inherit from that model each specific artifact type.

Having created your model, you will need to refer to it in a template and then set up a rule to pass the model to the template.

To reference your model in a template:

1. Create your template. This procedure is the same as previously outlined, but within the template you will make reference to methods on the Model Class.

## This is modelTemplate.vm
##
// This file was generated using $templateName.
##
// In this case the artifact Name ($artifact.Name) ,
// is not the same as the model Name ($model.Name).
public interface ${model.Name} {
   public String get${model.KeyName};
} 


2. Create a new rule as described in the Simple Plugin Tutorial. However, in the Model Class field, browse to the Model Class that you created above. In the Model Class Name text box, enter the name by which the model will be referred to within your template.

  • In this tutorial, name your model class model. Hence the use of $model in the above template example.
  • Note: The Output File definition can contain references to model methods by using the ${model.xxx} syntax.

3. Click Save to save your plug-in project. 4. Generate against your Tigerstripe project.

The generated file for the Order entity will be in a directory based on it's package name, and will have the name OrderValue.out. It will contain a method called getOrderKey.

You could have easily achieved this result by using template functions, but as your processing becomes more and more complex, models will become an essential part of your plug-ins.

Artifact Filters

(This feature only applies to Artifact Rules)

Sometimes you may need to run through a subset of artifacts of a given Artifact type. Rather than code a rule into your template, you can specify an Artifact Filter that will limit the artifacts that are processed in the template. This will keep your templates simple and easy to understand.

Artifact Filters are defined in a similar manner to [[Tigerstripe_Glossary#Model Class|Models]. That is, Artifact Filters are Java classes in the src directory of your plugin that implement the IArtifactModel interface. The filter needs to implement a single select method and any artifact that returns a result of true, is passed to the template engine for further processing.

In the following filter, only artifacts that have a Annotation of name Version are accepted and all other artifacts are rejected. For a detailed discussion of Annotations see the Advanced Annotations to Tigerstripe Models tutorial.


public class VersionFilter implements IArtifactFilter {
   public boolean select(IArtifact artifact) {    
       IextStereotypeInstance[] stereos = artifact.getStereotypeInstances();
       for (IextStereotypeInstance instance: stereos){
           if (instance.getName().equals("Version")){
               return true;
           }
       }
       return false;
   }
}

Once you have defined a filter, you can apply that filter to an artifact rule by clicking on Browse next to the Artifact Filter field in the plugin descriptor editor, Rules tab.

Note: Remember to deploy your plug-in when you change a rule definition.

Velocity Context Definitions

Another way to simplify templates is to create a Utility class. A Utility class contains commonly used methods; a typical case might be a set of String manipulation utilities. These could be third party utilities or your own.

To write your own utility:

1. Create a class in the src directory of your plugin project.

  • For this tutorial, name your class 'MyUtils'.

2. Add methods as appropriate to your class. You can add as many methods as you like, but for this example you will create a single method (shown below):

public class MyUtils {  
   public String capitalize(String inString){
       return inString.substring(0,1).toUpperCase() +
              inString.substring(1);    
   }
}

3. Add Utility classes to your rule by adding them to the list of Velocity Context Definitions. Each definition (either your own or a reference to a .jar containing utilities) must have an entry with a name and a path . The name is used in the template to identify the specific utility class.

In your template, you can then use these methods with the $utilName.methodName(arg) syntax. For example, using the utility as defined above, which has been added with the name myUtils:

public $attribute.Type.Name get${myUtils.capitalize($attribute.Name)}();

Note: In this case the ${ } syntax for Velocity can help when your utility function is adjacent to other text.

If you call a method that does not exist, Velocity will simply leave the reference in place. For example, if you mistype the above function name and run your plugin, you may find a line (such as the one outlined below) in your output file:

public String get${myUtils.capitulate(Details)}();

Velocity Macros

Velocity supports the use of Velocimacros to simplify repetitive template functions. You can find out more about these macros on the Velocity website.

Velocimacros are added to a rule defintion in a very similar manner toVelocity Context Defintions. Simply navigate to the Velocity Macro section of the rule editor and click on "Add".

Note: Tigerstripe does not support the definition of "in-line macros.

Plug-in Reports

Obtaining a plug-in report upon generation.

Each time you click Generate in a Tigerstripe project, you may get a Tigerstripe Report in the output directory of your project. You can enable or disable this feature though the Advanced pane of the Project Editor.

If you enable this feature, the plug-in report will appear as TigerstripeReport.xml, and will include (in addition to other information about the project) a section for each plug-in rule. These reports can be useful at runtime to determine what has been handled, filtered, and generated. An example extract from a single Artifact Rule plug-in is shown below:

<pluginReports>

           <pluginReport    group     = ""
                           id        = "SimplePluginProject()"
                           version = "" >
                   <property directoryName = "default" />
                   <property flag = "false" />
           <childReports>
               <childReport
                   ruleName = "modelRule"
                   ruleType = "Artifact Model Run Rule"  >
                   <matchedArtifacts>
                       <matchedArtifact name = "com.mycompany.Order"/>
                       <matchedArtifact name = "com.mycompany.Service"/>
                   </matchedArtifacts>    
                   <generatedFiles>
                       <file name = "com/mycompany/OrderValue.out"/>
                       <file name = "com/mycompany/ServiceValue.out"/>
                   </generatedFiles>
               </childReport>
           </childReports>
           </pluginReport>
   </pluginReports>

In this example, the initial section display information about the plug-in, and the value of the plug-in properties that have been set for this Tigerstripe project. As a result, a childReport is created for each Rule in the plug-in.

   * <matchedArtifacts> lists the qualified name for the artifacts that were passed to this rule based on their Artifact Type and passed any defined filter.
   * <generatedFiles> lists the files generated relative to the output directory for your project.

Back to the top