Random

For an actual type parameter Person this factory generates a class PersonWithRandom that extends class Person. PersonWithRandom declares a public random() method that assigns random values to the primitive attributes of the PersonWithRandom object it is called upon.

This implementation of Random assigns only random values to attributes of types boolean, double, float,int or long. It could be enhanced, however, to work with a much wider range of types (e.g. also with class types like String).

Note that the factory works only for actual parameters that do not declare private attributes. The factory would generate code that would try to access these private attributes, and because Java forbids subclasses to access the private attributes of its superclasses and the generated class is a subclass of the actual type parameter this could not be compiled.

Factory/Java Source

The source can be found in the Factory/Java .zip-archive in factory/classes/examples/Random.factory:

<param> <var> T </var> </param>

package test;

import java.util.Random;

public class
<apply>
    <apply>
        <class> factory.Toolbox </class>
        <method> getRelativeName </method>
        <args>
            <var> T </var>
        </args>
    </apply>
    <method> concat </method>
    <args>
        <const> "WithRandom" </const>
    </args>
</apply>
extends <var> T </var>
{
    public void random() {
        Random r = new Random();
            
        // iterate over all attributes of T
        <for> <var> I </var>
        <apply>
            <class> factory.Toolbox </class>
            <method> getAllFields </method>
            <args> <var> T </var> </args>
        </apply>
        <body>
            <let> <var> CN </var>
            <apply>
                <apply>
                    <var> I </var> <method> getType </method>
                </apply>
                <method> getName </method>
            </apply>
            <body>
            <let> <var> FN </var>
            <apply>
                <var> I </var> <method> getName </method>
            </apply>
            <body>
                <if>
                <apply>
                    <var> CN </var>
                    <method> equals </method>
                    <args> <const> "boolean" </const> </args>
                </apply>
                <then>
                    this.<var> FN </var> = r.nextBoolean();
                </then> </if>
                <if>
                <apply>
                    <var> CN </var>
                    <method> equals </method>
                    <args> <const> "double" </const> </args>
                </apply>
                <then>
                    this.<var> FN </var> = (char) r.nextDouble();
                </then> </if>
                <if>
                <apply>
                    <var> CN </var>
                    <method> equals </method>
                    <args> <const> "float" </const> </args>
                </apply>
                <then>
                    this.<var> FN </var> = r.nextFloat();
                </then> </if>
                <if>
                <apply>
                    <var> CN </var>
                    <method> equals </method>
                    <args> <const> "int" </const> </args>
                </apply>
                <then>
                    this.<var> FN </var> = r.nextInt();
                </then> </if>
                <if>
                <apply>
                    <var> CN </var>
                    <method> equals </method>
                    <args> <const> "long" </const> </args>
                </apply>
                <then>
                    this.<var> FN </var> = r.nextLong();
                </then> </if>
            </body> </let>
            </body> </let>
        </body> </for>
    }
}

Test Program

The following unparameterized factory can be found in factory/src/test/RandomTest.factory in the Factory/Java .zip-archive. It applies factory Random to class Person, instantiates an object of the resulting class PersonWithRandom, calls its random() method and prints out its attributes.

package test;

public class RandomTest {
    public static void main(String argv[]) {
        <let> <var> T </var>
        <apply>
            <factory> examples/Random </factory>
            <args> <const> test.Person </const> </args>
        </apply>
        <body>
            <var> T </var> p = new <var> T </var>();

            p.random();
       
            System.out.println(p.name);
            System.out.println(p.plz);
            System.out.println(p.id);
        </body> </let>
    }
}

This factory can be compiled in the factory directory with
java -classpath classes factory.Factory -javad src -classd classes src/test/RandomTest
and run with
java -classpath classes test.RandomTest