2. workflow
•All conventions are applied
with blocks of
transformations for each
source file.
•Transformations may
update the same sources or
creating/updating another
ones.
2
3. overview
• reader: reads the sources. i.e retrieves all files from a directory
recursively.
• walker: executes a chain of transformations for each source.
• transformation: updates or creates sources for the following
transformation.Transformations are connected like a pipe through a
shared context.
• writer: writes the sources. i.e using the eclipse formatter.
3
4. reader
• Reads the sources. By default, reads the folder src/main/java.
• Works with multiple include/exclude rules.
• Creates a resource object, whose content is iterated from the walker.
• Works for sources of any programming language.The resource object
could be a source folder, a parsed json file, etc..
• Is extensible. You only need to implement the reader and resource
interfaces.
4
5. reader configuration
<reader path="src/main/java" >
</reader>
type="walkmod:commons:file-reader"
<param name="my1stparam">my1stvalue</param>
<param name="my2ndparam">my2ndvalue</param>
<include wildcard="com/my_company/**" ></include>
<exclude wildcard="com/my_company/utils/**"></exclude>
the exclude and
include rules [optional]
the reader bean
[default]
the custom
params
[optional]
5
6. walker
• Executes a chain of transformations for each object allocated in a
resource. i.e all java source files of an specific folder.
• merges the output produced by transformations with existent
resources.
• invokes the writer with the final (and merged) output.
• analyzes and reports which changes have been produced by the chain
of transformations in each object.
• Is extensible. You only need to implement the walker interface.
6
7. walker configuration
<walker root-namespace="" >
<transformations>
<transformation >
</transformation>
</transformations>
</walker>
type="walkmod:commons:java-walker"
<param name="myparam">myvalue</param>
type="walkmod:commons:license-generator"
<param name="licenseFile">src/main/license-header.txt</param>
<transformation type=”walkmod:commons:import-cleaner” />
the walker
bean [default]
at least one
transformation must
be specified
the custom
params
[optional]
7
8. transformations
• modifies or creates objects that will be written.
• There are three ways to design a transformation. Using:
templates,
scripts,
or visitors.
8
10. why templates?
• Using templates is a well known practice in code generation, specially
in the backend of web applications (Velocity, JSP, freemarker..).
• Templates should be used to add code in source files.
• groovy is the default template engine.
• A set of interfaces must be implemented to work with your favorite
template engine.
10
11. template configuration
<!DOCTYPE walkmod PUBLIC "-//WALKMOD//DTD" "http://www.walkmod.com/dtd/walkmod-1.0.dtd">
<walkmod>
...
<transformation type="walkmod:commons:template" >
<param name="templates">
[ “src/main/groovy/dao.groovy”,
“src/main/groovy/web-services.groovy” ]
</param>
</transformation>
...
</walkmod>
<param name="templateEngine">walkmod:commons:groovy</param>
the template
engine[default]
the list of applied
templates
11
12. script transformations
import org.walkmod.lang.ast.body.ModifierSet;
import java.lang.reflect.Modifier;
import org.walkmod.lang.ast.body.FieldDeclaration;
for(type in node.types){
def fields = type.members.findAll({it instanceof FieldDeclaration});
for (field in fields){
int modifiers = ModifierSet.addModifier(field.modifiers, Modifier.PRIVATE);
modifiers = ModifierSet.removeModifier(modifiers, Modifier.PROTECTED);
modifiers = ModifierSet.removeModifier(modifiers, Modifier.PUBLIC);
field.setModifiers(modifiers);
}
}
groovy script to force private fields
12
13. why scripts?
• Scripts allow the design of inline transformations.
• Scripts should be used to apply simple modifications in source files.
• Support for multiple languages.Those which implement the standard
Java scripting interface. i.e. groovy, javascript, python..
13
15. visitor transformations
public class HelloVisitor extends VoidVisitor<VisitorContext>{
...
@Overwrite
public void visit(MethodDeclaration md, VisitorContext ctx){
//TODO
}
@Overwrite
public void visit(FieldDeclaration fd, VisitorContext ctx){
//TODO
}
...
}
15
16. why visitors?
• Visitors are developed and compiled in java.They allow the creation of
complex and efficient transformations.
• To include transformations as plugins to be shared inside the
community.
• Visitors should be used to apply complex modifications in source files.
16
17. visitor configuration
<!DOCTYPE walkmod PUBLIC "-//WALKMOD//DTD" "http://www.walkmod.com/dtd/walkmod-1.0.dtd">
<walkmod>
<plugins>
<plugin groupId="mygroupId" artifactId="myartifactId" version="versionNumber">
</plugin>
</plugins>
...
<transformation type="mygroupId:myartifactId:my-visitor" >
<param name="param1">
value1
</param>
<param name="paramN">
valueN
</param>
</transformation>
...
</walkmod>
the bean name of
the visitor
the visitor
setteable values
17
18. writer
• writes each object allocated in a resource. i.e all java source files of a
specific folder.
• Has include/exclude rules.
• Is extensible. You only need to implement the writer interface.
• There are useful writer implementations, such as the storage of the
contents of a toString() object method or the eclipse formatter.
18