Ant Patterns – Continued

This is a follow up post of the previous one about the build tool Apache Ant and usage patterns called Ant Patterns.

Converting a Path to a Property

You can use Ant to gather a list of files from a fileset and convert this using pathconvert to a property with each file on a separate line. The property ${line.separator} is a JVM and OS dependent system property which is automatically available for every ant script.

<fileset id="my.files" dir="." includes="**/*.php">
      <!-- any condition, etc. ... -->
</fileset>
<!-- joins all files together into one string -->
<pathconvert pathsep="${line.separator}" property="my.files.flattend" refid="my.files"/>

The resulting property can then by piped to a program which receives the list on its standard input (STDIN) adhereing to the Unix principles. An example is shown below which uses a ruby script.

<fileset id="my.files" dir="." includes="**/*.php">
      <!-- any condition, etc. ... -->
</fileset>
<!-- joins all files together into one string -->
<pathconvert pathsep="${line.separator}" property="my.files.flattend" refid="my.files"/>
<!-- pipes the list of all files seperated by new lines to a script -->
<exec executable="ruby.exe" inputstring="${my.files.flattend}">
      <arg value="${my.script.name}"/>
</exec>

Note: Usage of the Ant Pattern Executing Platform Independent from the previous post in conjunction with this pattern is strongly recommended.

Ant as a Template System

Ant can use its property resolution mechanism for evaluating templates. This is useful if you need to generate files using templates. The templates can be read from any file while the properties can be stated within the ant file directly, read from a property file, xml file or requested from the user. An example is given below with leverages the copy task with its filterchain which can provide additional operations for the files to be copied, in this case the expansion of the properties. The filterchain basically implements the Unix pipes the Ant way.

<!-- make sure properties are set using the property, propertyfile, xmlproperty or input task -->
<property name="name" value="World" />

<!-- apply template by copying -->
<copy file="${template}" tofile="${target}"> 
  <filterchain> 
    <!-- fill the blanks with values -->
    <expandproperties/> 
  </filterchain> 
</copy>

Given the contents of the template.tt are Hello ${name}, the contents of the ${target} file will be Hello World.

This approach gives only simple property expansion as loops, conditions or any other mechanism normally used in templates does not work. However, this may suffice for some use cases.

Formatting XML Files Resulting from XSLT Transformations

Ant can use xslt stylesheets in the xslt task to transform a XML file to another XML file or simple text. In many cases, the result is another XML file which should look formatted well. However, Ant uses by default Apache Xalan as its XSL engine which contains a bug ignoring the indent attribute of the ouput tag. The listing below shows such the stub of a stylesheet which results in unindented XML code.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
    <!-- templates and stuff -->
</xsl:stylesheet>

This can be solved by adding the special indent-amount attribute to the output element with the namespace http://xml.apache.org/xslt and set it, for example, to 4 spaces.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
    <xsl:output method="xml" indent="yes" encoding="UTF-8" xalan:indent-amount="4"/>
    <!-- templates and stuff -->
</xsl:stylesheet>

More information about this can be found here.

Additional Links

The Java Initializers

In Java, the concepts of classes and instances are the core concepts. A class as well as each instance has variables and methods. To differentiate, the variables and methods corresponding to the class have to be marked static while variables and methods default to the instance (if not marked static). In the following, I focus only on the variables.

The following example shows the declaration for class and instance variables:

public class Variables {
  static String classVariable; // initialized with default value null

  String instanceVariable; // initialized with default value null
}

Class Variables

Class variables are interpreted in the order they appear in the file. I can directly assign values to a class variable (direct initialization) or call a static method which initialises the variable through its return value. This, however, can lead to problems as shown in the next listing:

public class Variables {
  static String directlyInitialized = "class variable";
  static String directlyInitializedWithMethod = init();
  static String anotherDirectlyInitialized = "test";

  private static String init() {
    return anotherDirectlyInitialized;
  }

  public static void main(String[] args) {
    System.out.println(directlyInitializedWithMethod); // prints null
  }
}

This will print out null as the variable anotherDirectlyInitialized is initialized after the directlyInitializedWithMethod is initialized. The compiler does not detect it, it is the responsibility of the programmer to avoid such situations. We could solve this issue by reordering the statements, however, this is an area where we can do errors easily.

There is another alternative, namely, class initializers. These initializers are executed after all static variables have been initialized.

public class Variables {
  static String directlyInitialized = "class variable";
  static String directlyInitializedWithMethod;
  static String anotherDirectlyInitialized = "test";

  static {
    directlyInitializedWithMethod = anotherDirectlyInitialized;
  }

  public static void main(String[] args) {
    System.out.println(directlyInitializedWithMethod); // prints test
  }
}

This static block can contain any complex setup logic. It is executed after all static variables are initialised but before any method call to the class is issued. Good use cases are the computation of constants or preinitialization of other instances which require more than a simple constructor or method call.

Instance Variables

The approach of initializing static variables is also applied to instance variables. I can directly assign values to an instance variable (direct initialization) or call a method which initialises the variable through its return value. This, however, can lead to the same initialization problems.

public class Variables {
  String directlyInitialized = "class variable";
  String directlyInitializedWithMethod = init();
  String anotherDirectlyInitialized = "test";

  private String init() {
    return anotherDirectlyInitialized;
  }

  public static void main(String[] args) {
    InstanceVariables object = new InstanceVariables();
    System.out.println(object.directlyInitializedWithMethod); // prints null
  }
}

However, there is also an initializer construct for instance variables. This construct is called before any constructor is called and allows to initialize instance variables regardless of their ordering.

public class Variables {
  String directlyInitialized = "class variable";
  String directlyInitializedWithMethod;
  String anotherDirectlyInitialized = "test";

  {
    directlyInitializedWithMethod = anotherDirectlyInitialized;
  }

  public static void main(String[] args) {
    InstanceVariables object = new InstanceVariables();
    System.out.println(object.directlyInitializedWithMethod); // prints test
  }
}

Another real use case of these instance initializers is to add values to a HashMap on creation as seen in the next code snippet:

// regular approach
Map<String, String> myMap = new HashMap<>();
myMap.put("DE", "German");
myMap.put("EN", "English");
		
		
Map<String, String> otherMap = new HashMap<String, String>() {
	// anonymous subclass of HashMap

	{
		// instance initializer setting specific values
		this.put("DE", "German");
		this.put("EN", "English");
	}

};

The advantage is, that the latter can be used to initialize a field in a class directly with specific values.

The most useful eclipse plugins

I will not explain in detail the eclipse plugins you obviously try to get like subclipse, or other eclipse plugins that helps you with your current language like PHPclipse for php, etc.

I focus on the eclipse plugins that helps you with small problems and make your like easier on a day to day basis.

  1. FindBugs for static code analysis in Java. Reviews the code and shows problems with solutions how to fix them.
    Update Site: http://findbugs.cs.umd.edu/eclipse/
  2. QuickREx for evaluating regular expressions as you type. This helps to create these expressions in quite some way.
    Update Site: http://www.bastian-bergerhoff.com/eclipse/features
  3. OpenExtern for opening a folder or file using the shell or the explorer
    Update Site: http://openextern.googlecode.com/svn/trunk/openextern_update/

Maybe this also helps you during your development of your solutions.

XText and Eclipse – FeatureMap

I wanted to convert my EMF model to an XText Grammar to generate an editor for my model. However, the feature maps are not supported in XText. Therefore, it is best to remove them. As an XSD is the source of my EMF, i just annotated the xsd:choice constructs with ecore:featureMap=””. Then, XText can create the language.

Other problems arise due to datatypes. For the XML Datatypes, specific IValueConverters have to be registered.