Jostraca is Sponsored By:






 
    The Jostraca Code Generator

  How CodeWriters Work
 

Jostraca generates code by creating small external programs that produce the actual output. This makes Jostraca different from most other code generation tools, which tend to rely on special template languages. Instead, Jostraca is designed with the philosophy that template scripting should be done in an ordinary programming language that the developer is already familiar with.

To enable this approach, Jostraca has to compile the template into a small program in the template scripting language. In effect, all Jostraca does is turn the template into a big list of print statements. While this has the advantage of using a familiar language for template scripting, the downside is that the external program has to be compiled and executed by Jostraca.

The process of turning a template into generated code proceeds as follows:

Find and load the template file
Templates can specified as file paths, or referenced as library templates (the setting main.TemplatePath specifies the list of folders to search for library templates). Once the initial template file is loaded, the contents of the file are searched for a @conf directive (which is required), and any @include directives are resolved. Any settings in any @conf sections found are stored and assigned to the template. Template level settings override system settings, but are in turn overridden by command line options.

Determine template script
The programming language used for template scripting is determined by the main.TemplateScript setting. This is usually placed in the template @conf directive (the default is java). Once the template script is determined, the script specific settings are loaded from the conf folder. For example, Perl specific settings are in conf/perl.conf. The script specific settings determine the exact processing operations that will then be performed on the template.

Process template
The template is then processed by passing through a number of discrete steps. These steps are script language specific. The main ones are covered in the following items.

Prepare template
This processing step performs any special processing related to system properties and version compatibility.

Parse template
The hard work. The template contents are parsed into an internal data structure.

Merge template into WriterFormat
This is where the source code of the CodeWriter program is created. Jostraca uses special templates located in the format folder to specify the source code of the CodeWriter program. These CodeWriter templates are known as WriterFormats. The WriterFormat for the current template is specified by the main.CodeWriterFormat setting. Normally this is specified by the default configuration, but custom WriterFormats can be also be used. The WriterFormat templates use a special syntax and are independent from standard Jostraca templates. The template content is merged into the WriterFormat template by inserting template sections into marked positions in the WriterFormat. Of course, the actual source code (that big list of print statements) that is inserted is created by Jostraca before insertion.

Save template CodeWriter and other files
Once the CodeWriter program is created, the source text of the CodeWriter is saved to disk so that is can be compiled and executed. Other files may also be saved, such as template metadata properties files.

Compile CodeWriter program
Jostraca now attempts to compile the CodeWriter program. This is only necessary for compiled languages. If the template script is Perl, for example, this stage is not present. For languages other than Java, compilation involves running the compiler program externally as a separate process. This of course can lead to many types of error as the external compiler may have many types of dependency. In general, you should ensure that the Jostraca execution environment is also suitable for running the compiler. You can use the -v option to get verbose output from Jostraca. This output also shows the exact command used to execute the external compiler, which can be very useful for debugging. You can also use the main.ExternalCompilerOptions and main.ExternalCompiler settings to control this command. Note that in order to execute external compiler commands, the folders containing the external compiler programs should be in your PATH environment variable.

For Java, the are two ways of compiling the CodeWriter. Normally, Jostraca attempts to compile a Java CodeWriter by running the Sun compiler inside the Java process. This means that you need to put the rt.jar jar file from the Java JDK into your CLASSPATH. This option is usually much faster that running javac externally. If compilation is done internally, then you also need to ensure that the CLASSPATH used to run Jostraca includes all the classes that your template references. The standard jostraca execution scripts ( jostraca.bat and jostraca.sh ) include the contents of the CLASSPATH environment variable in the Jostraca classpath, so normally all you need to do to use additional classes in your template is to put them in your normal CLASSPATH. You can also construct your own jostraca execution scripts as a special case. When running Jostraca from Ant, this is not necessary as you can define the classpath used in the build.xml file.

If the Sun compiler cannot be found (because rt.jar is not in your CLASSPATH), then Jostraca will use javac to compile the CodeWriter. The classpath used in this case also includes the contents of the CLASSPATH environment variable, but you can also use java.ClassPath, java.ClassPathPrefix, and java.ClassPathSuffix to control this classpath. Again, use the -v option to see the full javac command if your CodeWriter does not compile due to ClassNotFound errors.

Execute CodeWriter to generate code
This stage, finally, is where your template (that is, the CodeWriter created from the template) is executed to actually produce output. This stage is similar to the compilation stage, in that for many template script languages such as Perl or Python, an external command must be executed to run the CodeWriter. Once again, you can use the -v option to see the actual execution command.

For Java, the same issues (in particular, the CLASSPATH issues) apply as for compilation. In the normal case, Jostraca will attempt to dynamically load the CodeWriter class and execute it within the Jostraca process. If you wish to execute the CodeWriter externally as a separate process, then you you have to specify the setting:
main.process.Controller = org.jostraca.process.ExternalJavaController
Jython templates are special case. Since Jython runs under the JVM, the location of the Jython installation folder must be specified manually, so that the Jython libraries can be found. Thus, Jython templates require the jython.home setting to be present and set to the absolute folder path of the Jython installation. This setting can be placed in the template @conf section, or specified on the command line:
jostraca -Djython.home=JYTHON_HOME jython-template.jtm
Jython CodeWriters are normally executed internally using the PythonInterpreter class. To execute the CodeWriter externally using the jython execution script, use the setting
main.process.Controller = org.jostraca.process.ExternalJythonController
The standard CodeWriter for all languages also performs some actions when creating the output files. First, any output files that already exist are backed up to a .jostraca folder in the current folder. You can stop this backup action by using the -B command line option. The CodeWriter also outputs the names of any files that are created. This information is used by Jostraca to create the metadata properties file. Note that if you prevent the creation of the metadata properties file (using -M for example), then the template service method _getProperty will not return any values.

Controlling the CodeWriter

Jostraca attempts to do the least amount of work necessary to create the generated output files. In the default case, Jostraca will use previously saved template metadata to compare the modification times of the output files and the template to see if generation is actually necessary. If not, the CodeWriter is not compiled or executed and Jostraca exits. Jostraca also checks to see if CodeWriter compilation is necessary, and if not, will only execute the existing CodeWriter. This case occurs when resource files specified on the command line as template arguments have changed, but the template itself has not changed. To see how Jostraca determines the required actions, use the -v command line option.

Sometimes you will need to force Jostraca to perform certain operations. The command line options controlling CodeWriter compilation are -c: always compile CodeWriter, and -C: do not compile CodeWriter. You may need to force recompilation if the file modification times are out of synchronisation.

You can also control whether Jostraca executes the CodeWriter. You may not always actually want the CodeWriter to run directly. In the case where you are creating the CodeWriter from the template, so that you can use it later in your own programs, all you want to do is compile the CodeWriter program, but not execute it. You can use the -G option to prevent Jostraca from executing the CodeWriter. Conversely, -g will force Jostraca to execute the CodeWriter.

Generating Multiple Templates

You can generate more than one template at a time using Jostraca. You can specify a list of templates on the command line. For example:

jostraca  foo.jtm  bar.jtm  baz.jtm   resources.xml

All arguments to Jostraca that end in .jtm are assumed to be templates. You can also use the -l option to force Jostraca to consider all arguments to be template files. If you have a long list of templates, you can put them in a file, one per line, and reference the file using the -t command line option. When using Jostraca from Ant, multiple templates can be specified using the templateList attribute, or by inserting multiple template sub-elements.

When generating multiple templates, all resource files (that is, non-template files, like resources.xml in the example above) that are specified on the command line are assumed to apply to all templates. This can cause all templates to be regenerated when file modification times are changed.

When generating multiple templates, Jostraca processes the template by performing each processing stage on all templates in turn. That means that all templates are first parsed, and then all CodeWriters are created, and so on. This approach is taken so that the CodeWriters can all be compiled together in one compilation phase, which greatly speeds up code generation.





home |  download |  documentation |  resources  |  contact |  SourceForge Logo  |  Copyright © 2000-2002 Richard Rodger. Site License.