No Preprocessor for Java
For a number of good reasons the preprocessor known from C and C++ was not adopted by the Java language. Looking at endlessly cascaded #includes with nested macros and tons of #ifdefs, you probably agree that it was a wise decision. However, there are also situations where it would be convenient to have at least a simple mechanism for conditional and/or included code. The following examples will demonstrate such cases and how they can be solved with the wurbelizer.Multiple Inheritance
Java does not support multiple inheritance. Again, for a number of reasons this is a good thing. However, consider the situation where some classes of an inheritance tree share the same functionality, which is defined by an interface and implemented by pretty much the same code in all those classes. While there are solutions to minimize copy and paste, there will always be some code left that has to be copied almost identically to those classes. Needless to say, that copy and paste generally is an unsatisfying solution. And what if the interface changes? Do we really need to manually modify all those classes?By using the wurbelizer, you don't! And this is how it works:
First, the interface gets a so-called here-document added, which is a wurbelizer feature very similar to that of the Unix shell. Here-documents (heredocs for short) can be viewed as documents contained in other documents. In order not to irritate the Java compiler, wurbelizer heredocs are stored within comments, while it doesn't matter whether line or block comments.
In our example, the heredoc .PrincipalDependable.impl contained in the interface PrincipalDependable describes the implementation of the interface:
As an additional feature, the wurbelizer supports wurblet anchors within heredocs, so the method isReferencingPrincipal is not manually coded, but will be generated -- more of such bells and whistles can be found in the wurbelizer documentation.
Next, in all classes implementing PrincipalDependable, all we have to do is to include the heredoc by means of an Include wurblet:
That's all! Now we can keep all the interface-related code in a single file. Whenever the interface changes, the code needs to be changed only at one single place. This is what's so cool about multiple inheritance and what has been achieved with wurblets and heredocs through the back door.
Build-Time Variants
Software configuration traditionally has always been a good candidate for conditional compiling. In Java, however, this isn't possible and so the configuration is usually implemented at runtime. While there are pros and cons for either approach, the reduction of dependencies and memory footprint sometimes is an issue which can be solved by conditional compiling in an elegant way.The wurbelizer provides a feature that can be used to describe conditional code at build time. It works via a so-called conditional wurblet anchor. For example:
The wurblet GenTheSuperCompanyLayer will only be invoked if the build-time variable $company equals TheSuperCompany. Build-time variables are usually declared as ant-properties.
Notes
- Heredocs are also a good candidate to hold model information.
- A conditional wurblet anchor in combination with the Include wurblet corresponds to #if ... #include ... #endif in C or C++.