Using T4 Toolbox To Generate Java Executables

Feb 27, 2013 at 7:48 PM
Our team has been asked to provide an LOE for a development effort that would build an Microsoft.Net Windows Client application that:
  1. Gets a subset of SAS macro
  2. Creates a platform independent Java executable that will be distributed to a client that will allow the user to execute and view these macros on a platform running a Java runtime.
Basically we envision this as the .NET component/Utility as a wrapper that packages up the SAS macros that a user selects in the UI and then packages and compiles those macros into a Java exe that is handed off to a client.

Does this sound like something that can be accomplished with the T4 Toolbox?

Thanks in advance.
Coordinator
Feb 28, 2013 at 1:50 AM
T4 Toolbox is a Visual Studio extension for generating text files.
Mar 2, 2013 at 1:10 PM
Edited Mar 2, 2013 at 1:11 PM
Ok I get that.

What I'm trying to do is generate some java code on the fly using these t4 templates

Here's where I am stuck:

I attempted to create a standard text template with an output type of .java, however I'm trying to figure out how to access properties from that template in order to set values at runtime.

IE:
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".java" #>
<#@ import namespace="System.IO"#>
public class macro {

    public string stringVal;
    public static void main(String[] args) {}
}
At runtime in my windows form I need to
  1. grab that stringVal variable and set it to some macro code
  2. wrap it up into a java class file.
I wasn't so sure that I could do it with a text template, so I attempted a preprocessed template:
<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>

public class preMacro{

    <# String stringVal= String.Empty;  #> 

        
} 
Now it seems i have access to this object in my windows form:
preMacro macro = new preMacro();
however I'm not sure how to access that stringVal in the template and set it at runtime

thanks
Coordinator
Mar 4, 2013 at 2:05 AM
Edited Mar 4, 2013 at 2:05 AM
In a Windows application, you can only use a preprocessed (a.k.a. runtime) template. Look at the .CS file the runtime template generates in your project to understand how to use it. You probably want to declare the "stringVal" as a property in a class feature block.
<#+ 
    public string StringVal;
#>
That way, you will be able to set it in your windows form like so:

preMacro macro = new preMacro();
macro.StringVal = "Value";

After that, you can save the generated code in a .java file:

File.WriteAllText("MyClass.java", macro.TransformText());

You may find the following articles helpful in understanding preprocessed templates: http://msdn.microsoft.com/en-us/library/ee844259.aspx
Mar 4, 2013 at 3:33 PM
Edited Mar 4, 2013 at 3:34 PM
Ok, So i set everything up like so in my form:
using (myStream = openFileDialog1.OpenFile())
{
string file = Path.GetFileName(openFileDialog1.InitialDirectory + openFileDialog1.FileName);
string text = File.ReadAllText(openFileDialog1.FileName);
    try
    {
        MacroTemplate mt = new MacroTemplate();
        mt.stringVal = text;
        File.WriteAllText("MyClass.java", mt.TransformText());
    }
    catch (Exception ex)
    {
       MessageBox.Show("An error occurred" + ex.GetBaseException());
    }
}            
Then in my template:
<#@ template language="C#" #>
<#@ template debug="true" #>

<#+
    public string stringVal;
    
#>
My java file is empty and I cannot figure out how to write output statement in the template file since each time I attempt to code a block following this line:
<#+
    public string stringVal;
    
#>
I get this error:
Error 1 A Statement cannot appear after the first class feature in the template. Only boilerplate, expressions and other class features are allowed after the first class feature block.

How do i write this variable out to the file?

Thanks

Doug
Mar 4, 2013 at 4:15 PM
Edited Mar 4, 2013 at 4:15 PM
Never mind.

I think I fixed it.

The variable declaration needed to be at the bottom
<#@ template language="C#" #>
<#@ template debug="true" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>

<#= stringVal #> 

<#+ public string stringVal;  #>