📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (176K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
1. Create a Simple Maven Project
<!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
2. Create a Velocity Template - class.vm
- Create a vtemplates folder under /resources directory.
- Create a template called class.vm file under vtemplates folder add the following code to it:
package ${packagename};
public ${className} implements Serializable {
/** Serial Version UID. */
private static final long serialVersionUID = 1L;
#foreach( $property in $properties )
private $property.fieldType $property.fieldName;
#end
#foreach( $property in $properties )
public ${property.fieldType} get${property.getGetterAndSetterField()}() {
return this.${property.fieldName};
}
public void set${property.getGetterAndSetterField()}(${property.fieldType} ${property.fieldName}) {
this.${property.fieldName} = ${property.fieldName};
}
#end
}
3. Create a Velocity Template Writer
package net.guides.codegenerator.beans;
public class Field {
private String fieldName;
private String fieldType;
public Field(String fieldName, String fieldType) {
super();
this.fieldName = fieldName;
this.fieldType = fieldType;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getFieldType() {
return fieldType;
}
public void setFieldType(String fieldType) {
this.fieldType = fieldType;
}
}
- Initialize the Velocity engine
- Read the template
- Put the data model in a context object
- Merge the template with context data and render the view
package net.guides.codegenerator.util;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import net.guides.codegenerator.beans.Field;
public class VelocityWriter {
static String modelName = "User";
static String packageName = "com.companyname.projectname";
public static void main(String[] args) {
VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.init();
Template t = velocityEngine.getTemplate("vtemplates/class.vm");
VelocityContext context = new VelocityContext();
if(packageName != null) {
context.put("packagename", packageName);
}
List<Field> properties = new ArrayList<>();
properties.add(new Field("id", "int"));
properties.add(new Field("firstName", "String"));
properties.add(new Field("lastName", "String"));
properties.add(new Field("dob", "LocalDate"));
context.put("className", modelName);
context.put("properties", properties);
StringWriter writer = new StringWriter();
t.merge( context, writer );
System.out.println(writer.toString());
}
}
4. Demo
19:26:28.268 [main] DEBUG org.apache.velocity - CommonsLogLogChute name is 'org.apache.velocity'
19:26:28.271 [main] DEBUG org.apache.velocity - Initializing Velocity, Calling init()...
19:26:28.271 [main] DEBUG org.apache.velocity - Starting Apache Velocity v1.7 (compiled: 2010-11-19 12:14:37)
19:26:28.271 [main] DEBUG org.apache.velocity - Default Properties File: org\apache\velocity\runtime\defaults\velocity.properties
19:26:28.271 [main] DEBUG org.apache.velocity - Trying to use logger class org.apache.velocity.runtime.log.AvalonLogChute
19:26:28.271 [main] DEBUG org.apache.velocity - Target log system for org.apache.velocity.runtime.log.AvalonLogChute is not available (java.lang.NoClassDefFoundError: org/apache/log/format/Formatter). Falling back to next log system...
19:26:28.271 [main] DEBUG org.apache.velocity - Trying to use logger class org.apache.velocity.runtime.log.Log4JLogChute
19:26:28.271 [main] DEBUG org.apache.velocity - Target log system for org.apache.velocity.runtime.log.Log4JLogChute is not available (java.lang.NoClassDefFoundError: org/apache/log4j/Layout). Falling back to next log system...
19:26:28.271 [main] DEBUG org.apache.velocity - Trying to use logger class org.apache.velocity.runtime.log.CommonsLogLogChute
19:26:28.271 [main] DEBUG org.apache.velocity - Using logger class org.apache.velocity.runtime.log.CommonsLogLogChute
19:26:28.276 [main] DEBUG org.apache.velocity - ResourceLoader instantiated: org.apache.velocity.runtime.resource.loader.FileResourceLoader
19:26:28.276 [main] DEBUG org.apache.velocity - Do unicode file recognition: false
19:26:28.276 [main] DEBUG org.apache.velocity - FileResourceLoader : adding path '.'
19:26:28.285 [main] DEBUG org.apache.velocity - ResourceCache: initialized (class org.apache.velocity.runtime.resource.ResourceCacheImpl) with class java.util.Collections$SynchronizedMap cache map.
19:26:28.286 [main] DEBUG org.apache.velocity - Loaded System Directive: org.apache.velocity.runtime.directive.Stop
19:26:28.287 [main] DEBUG org.apache.velocity - Loaded System Directive: org.apache.velocity.runtime.directive.Define
19:26:28.287 [main] DEBUG org.apache.velocity - Loaded System Directive: org.apache.velocity.runtime.directive.Break
19:26:28.288 [main] DEBUG org.apache.velocity - Loaded System Directive: org.apache.velocity.runtime.directive.Evaluate
19:26:28.289 [main] DEBUG org.apache.velocity - Loaded System Directive: org.apache.velocity.runtime.directive.Literal
19:26:28.289 [main] DEBUG org.apache.velocity - Loaded System Directive: org.apache.velocity.runtime.directive.Macro
19:26:28.290 [main] DEBUG org.apache.velocity - Loaded System Directive: org.apache.velocity.runtime.directive.Parse
19:26:28.291 [main] DEBUG org.apache.velocity - Loaded System Directive: org.apache.velocity.runtime.directive.Include
19:26:28.292 [main] DEBUG org.apache.velocity - Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
19:26:28.316 [main] DEBUG org.apache.velocity - Created '20' parsers.
19:26:28.325 [main] DEBUG org.apache.velocity - Velocimacro : "velocimacro.library" is not set. Trying default library: VM_global_library.vm
19:26:28.325 [main] DEBUG org.apache.velocity - Velocimacro : Default library not found.
19:26:28.325 [main] DEBUG org.apache.velocity - Velocimacro : allowInline = true : VMs can be defined inline in templates
19:26:28.325 [main] DEBUG org.apache.velocity - Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions
19:26:28.325 [main] DEBUG org.apache.velocity - Velocimacro : allowInlineLocal = false : VMs defined inline will be global in scope if allowed.
19:26:28.325 [main] DEBUG org.apache.velocity - Velocimacro : autoload off : VM system will not automatically reload global library macros
19:26:28.348 [main] DEBUG org.apache.velocity - ResourceManager : found vtemplates/class.vm with loader org.apache.velocity.runtime.resource.loader.FileResourceLoader
package com.companyname.projectname;
public User implements Serializable {
/** Serial Version UID. */
private static final long serialVersionUID = 1L;
private int id;
private String firstName;
private String lastName;
private LocalDate dob;
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public LocalDate getDob() {
return this.dob;
}
public void setDob(LocalDate dob) {
this.dob = dob;
}
}
5. Generated Source Code
package com.companyname.projectname;
public User implements Serializable {
/** Serial Version UID. */
private static final long serialVersionUID = 1L;
private int id;
private String firstName;
private String lastName;
private LocalDate dob;
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public LocalDate getDob() {
return this.dob;
}
public void setDob(LocalDate dob) {
this.dob = dob;
}
}
Definition of net.guides.codegenerator.beans.Field; is missing in the example
ReplyDeleteAdded, thanks for informing!
DeleteIt is not replacing values for methods name.
ReplyDeletepublic void $property.getGetterAndSetterField()(LocalDate dob) {
this.dob = dob;
vs
public void setDob(LocalDate dob) {
this.dob = dob;
how is it that $property.getGetterAndSetterField() is automatically fetching the fieldName instead of fieldType?
ReplyDeleteIs it that the first variable in Field model will be fetched?