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