Basic Templates
[Previous]  [Next] 
|
User Manual [Previous]  [Next] Basic TemplatesGenerating string output is a very common task for programs. Common types of output include html, xml and executable code. Umple has a special capability for this, as do many other technogies (it is central to PhP, for example). The advantage of Umple's approach is that it adds generation templates in a uniform manner to C++, Java, PhP and other languages that Umple supports. The same templates can be reused. The Umple generation templates are essentially a readable way to generate special methods that emit Strings (and also in Java's case StringBuilders). Two basic elements are needed to use generation templates: Templates The first essential element is the templates themselves. These are shown as a name followed by arbitrary text in <<! !>> brackets. The text in the brackets can contain anything you want. See the examples below to understand how these are used.
<<!output this!>> will build the string 'output this' when specified in an emit method (below). Emit method specifications: The second essential element is one or more 'emit' statements. These specify the methods to be generated. As with any method there can be a set of arbitrary parameters. Following this, in a second set of parameters is comma-separated list of templates to emit. For example, the following says to generate a method with signature String printRow(intTimes, intCount); that will emit a string containing the contents of the row and cr templates:
emit printRow(int times, int count)(row, cr); Optional elements in templates are: Expression blocks: Inside the template, programmers can specify arbitrary expressions in <<= >> brackets. These can refer to attributes of the class, parameters to the emit method, states and so on. The result of the expression will be substituted every time the template method is called. This appears in all examples below. Code blocks: Also inside the template program logic can be embedded in <<# #>> brackets. This enables conditional emission of parts of a template, or looping within the template. This appears in the second example below. Comment blocks: Comments in templates can be shown within <</* */>> The first two examples below show how simple templates can be used to output strings, in this case a one-column multiplication table. The first example uses two template methods, the second being called in a loop. The second example generates the same output, but all the looping logic is enclosed in the template itself. The third example shows a more substantial template with a lot of 'boilerplate' text that is easy to read and edit in the Umple source. Manually writing the generated would be substantially more awkward. Umple's mixin capability allows templates to be kept in separate files. This can faciliatate reuse. Example 1// Simple example to demonstrate umple's template // base string generation mechanism. // In this approach there is an iterative call // to the emit function class MathExample { // A simple template to inject a platform // specific newline cr <<! !>> // Two templates for different lines of output header <<!Print out a <<=times>> times table!>> row <<! <<=times>> times <<=count>> is <<=times*count>>!>> // Specification for two methods to be generated // to output parts of the text // Method arguments are in the first parentheses // Templates to output are in the second set emit printHeader(int times)(header, cr); emit printRow(int times, int count)(row, cr); // Main program to run the above and generate // the output public static void main(String[] argv) { int times = 10; // default MathExample m = new MathExample(); if(argv.length > 0) { times=Integer.parseInt(argv[0]); } // Print the header System.out.print(m.printHeader(times)); // Print one row for each element for (int i=0; i <= times; i++) { System.out.print(m.printRow(times,i)); } } } Load the above code into UmpleOnline Example 2// Simple example to demonstrate umple's template // base string generation mechanism. // In this approach iteration is embedded in the // rows template and there is a single emitter // function generated called result class MathExample { // A simple template to inject a platform // specific newline cr <<! !>> // A template for the header lines header <<!Print out a <<=times>> times table!>> // A template that generates all the rows by // iterating rows <<!<<# for (int i=0; i <= times; i++) {#>> <<=times>> times <<=i>> is <<=times*i>><<#}#>>!>> // Specification of a single method to emit // the result emit result(int times)(header, rows, cr); public static void main(String[] argv) { int times = 10; // default if(argv.length > 0) { times=Integer.parseInt(argv[0]); } // Output the entire result System.out.print( new MathExample().result(times)); } } Load the above code into UmpleOnline Example 3// Example of creating a lengthy output in Umple // from a template. Note this is plain text. // See the next page for html generation. // The company is, of course, fictitious. class RefLetterRequest { // Attributes used to construct the instance String fileno; String recipient; String applicant; String sender; String senderTitle; // Letter template letterTemplate <<! Subject: Reference request for <<=applicant>>, File #<<=fileno>> Dear <<=recipient>>, Our company, Umple Enterprises, is hiring talented software engineers. We have received an application from <<=applicant>> who named you as an individual who could provide a letter of reference. Would you please reply to this letter, answering the following questions: * In what capacity do you know <<=applicant>> * For how long have you known <<=applicant>> * Describe the abilities of <<=applicant>> in software development * What his or her strengths and weaknesses? * Please provide your phone number and suitable times to call in case we need to follow up Yours sincerely, <<=sender>> <<=senderTitle>> !>> // Specification of the method to generate emit letterTemplate()(letterTemplate); // Main program to generate the letter public static void main(String[] argv) { if(argv.length < 5) { System.err.println("You must specify arguments for fileno, recipient, applicant, sender, sendertitle"); } // Output the entire result else System.out.print(new RefLetterRequest( argv[0], argv[1],argv[2], argv[3], argv[4] ).letterTemplate()); } } Load the above code into UmpleOnline SyntaxtemplateAttributeDefinition : [[templateName]] [[templateAttribute]] templateName :  ( [~classname] .  )? [name] [[templateParameters]]? emitMethod : [=modifier:public  |protected  |private]? [=static]? [type]? [=emit] [[methodDeclarator]] [[templateList]]?; templateList- : (  ( [[templateName]]  ( , [[templateName]]  )*  )? ) templateAttribute# : <<! [[templateAttributeContent]]* !>> templateAttributeContent- : [[templateExpression]]  | [[templateComment]]  | [[templateCodeBlock]]  | [[templateExactSpaces]]  | [[templateInclude]]  | [[templateText]] templateText# : [**templateTextContent:<<(=|#|/[*]|$|@)] templateComment# : <</* [**templateCommentContent] */>> templateExpression# : <<=  ( [[templateExpression]]  | [**templateExpressionContent:<<  (=|#|/[*]|$|@  )]  )+ >> templateCodeBlock# : <<#  ( [[templateExpression]] | [**templateLanguageCode:<<  (=|#|/[*]|$|@  )]  )* #>> |