[Insight-users] Correcting code conventions in Java wrappers

Jarek Sacha jarek at ieee.org
Sat, 06 Mar 2004 19:57:35 -0500


A great feature of ITK are wrappers. They enable faster prototyping and 
easier integration with application written in other languages. However, 
the wrappers tend to carry over coding conventions from the C++ ITK code 
that are either unnatural or alien in the destination language. I would 
like to share hare some suggestion that should make the Java wrapper 
code cleaner (in Java coding convention sense) and easier to use 
(eliminate constructs that are no longer required on the wrapping side)

The current version of ITK Java wrappers uses quite unusual code 
convention. In the Java community is very common to follow the standard 
coding convention defined in "Code Conventions for the Java Programming 
Language" http://java.sun.com/docs/codeconv/
It is very rare to find a Java project, in particular an open source 
project, that do not follow those general guidelines. The current ITK 
Java code is difficult to read for a Java coder, as it violates 
fundamental conventions. Many of those issues should be easy to resolve 
during wrapper generation (for instance items 1, 2, 3, and 5 below). 
Some may require extra wrapping setup, but should also be relatively 
easy to correct (for instance, 4 below).

Here are five ways in which Java wrappers can be improved:

1) In Java a package name is always written in all-lowercase ASCII 
letters and should be one of the top-level domain names.
Currently it is 'InsightToolkit', it should be rather 'itk' or 
'org.itk'. For instance, it should be
    import org.itk.*;
instead of
    import InsightToolkit.*;
It is also a bit strange that C++ code itself uses name space 'itk' but 
in the wrapper it is 'InsightToolkit'.

2) In Java class names start with uppercase letter, words in name are 
separated by capitalization (no underscores). For instance, it should be
    CannyEdgeDetectionImageFilter;
instead of
    cannyEdgeDetectionImageFilter;

3) In Java name prefixes are not used, package names are used instead 
(see also 1)). For instance, it should be
    org.itk.ImageFileReaderF2  or simply  ImageFileReaderF2
instead of
    itkImageFileReaderF2

4) There is no concept of a pointer in Java, so there is no need to 
carry over this concept from C++. For instance, it should be
    ImageFileReaderF2 reader = new ImageFileReaderF2();
instead of
    itkImageFileReaderF2_Pointer reader = 
itkImageFileReaderF2.itkImageFileReaderF2_New();
Note, that use of the factory method in the above is not applicable for 
Java wrappers. From Java point of view it does not make a difference if 
an object is created with a factory method or using a new operator. This 
makes a difference on C++ side (heap vs. stack) but is a needles 
complication on the Java side.

5) In Java method names start with a loser case letter. For instance, it 
should be
    canny.setInput(reader.getOutput());
instead of
    canny.SetInput(reader.GetOutput());

My current knowledge of CableSwig (I am working on it:) is nor 
sufficient to suggest actual fixes to wrapper generation code. I hope 
that somebody more proficient in CableSwig could easy fix this and post 
patches or give me some guidelines how this could be done and I will try 
to come out with actual patches.

Thanks,

Jarek

BTW: Here are examples of 'corrected' code and one using current version 
of Java wrappers. It should be:
-------------------
import org.itk.*;

public class CannyEdgeDetectionImageFilter {
  public static void main(String argv[])
  {
    ImageFileReaderF2 reader = new ImageFileReaderF2();
    CannyEdgeDetectionImageFilterF2F2 canny = new 
CannyEdgeDetectionImageFilterF2F2();
    RescaleIntensityImageFilterF2US2 rescaler  = new 
RescaleIntensityImageFilterF2US2();
    ImageFileWriterUS2 writer = new ImageFileWriterUS2();

    canny.setInput(reader.getOutput());
    rescaler.setInput(canny.getOutput());
    writer.setInput(rescaler.getOutput());
    rescaler.setOutputMinimum(0);
    rescaler.setOutputMaximum(65535);
    reader.setFileName("../../../../Testing/Data/Input/cthead1.png");
    writer.setFileName("./testout.png");
    writer.update();
  }
}
-------------------

instead of

-------------------
import InsightToolkit.*;

public class cannyEdgeDetectionImageFilter {
  public static void main(String argv[])
  {
    itkImageFileReaderF2_Pointer reader = 
itkImageFileReaderF2.itkImageFileReaderF2_New();

    itkCannyEdgeDetectionImageFilterF2F2_Pointer canny = 
itkCannyEdgeDetectionImageFilterF2F2.itkCannyEdgeDetectionImageFilterF2F2_New();

    itkRescaleIntensityImageFilterF2US2_Pointer rescaler  = 
itkRescaleIntensityImageFilterF2US2.itkRescaleIntensityImageFilterF2US2_New();

    itkImageFileWriterUS2_Pointer writer = 
itkImageFileWriterUS2.itkImageFileWriterUS2_New();

    canny.SetInput(reader.GetOutput());
    rescaler.SetInput(canny.GetOutput());
    writer.SetInput(rescaler.GetOutput());
    rescaler.SetOutputMinimum(0);
    rescaler.SetOutputMaximum(65535);
    reader.SetFileName("../../../../Testing/Data/Input/cthead1.png");
    writer.SetFileName("./testout.png");
    writer.Update();
  }
}
-------------------