DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Automated Bug Fixing: From Templates to AI Agents
  • Dynamic File Upload Component in Salesforce LWC
  • Safeguarding Web Applications With Cloud Service Providers: Anti-CSRF Tokenization Best Practices
  • Make Your Backstage Templates Resilient

Trending

  • Recurrent Workflows With Cloud Native Dapr Jobs
  • Create Your Own AI-Powered Virtual Tutor: An Easy Tutorial
  • Subtitles: The Good, the Bad, and the Resource-Heavy
  • While Performing Dependency Selection, I Avoid the Loss Of Sleep From Node.js Libraries' Dangers

Using StringTemplate: Part 1 'An Introduction to StringTemplate'

By 
Collin Fagan user avatar
Collin Fagan
·
May. 26, 10 · Interview
Likes (2)
Comment
Save
Tweet
Share
28.5K Views

Join the DZone community and get the full member experience.

Join For Free

Please note: I put forth SQL examples because they can be short and are easy to understand. As other have pointed out it is not advisable to build SQL with Strings, regardless of the technique used.

To quote the StringTemplate home page: “StringTemplate is a Java template engine for generating source code, web pages, emails, or any other formatted text output.”

Great, but what is a “template engine”?
          A template engine (also known as a template processor or a template parser) is a software component that is designed to combine one or more templates with a data model to produce one or more result documents (Wikipedia). To you and me that means that a template engine is an alternate way to generate complicated text. One that I feel is particularity useful. Before we dive into that, lets take a look at a few examples of traditional String construction in Java.

First we have the trusty old “+” operator.

String message = "Hello" + " World"; 

While convenient for small concatenations. It becomes a real pain when the embedded variable count of the amount of text increases.   

    String strSQL = "UPDATE customers SET customerName='" + name
+ "', customerAddress='" + address
+ "', customerEmail = '”+ email + "
+ "customerNumber = " + phone
+ " customerPurchase = " + purchase
+ "' WHERE id=" + 12;

String new419 = "Hello "
+ "Dear, " + name + ", \n"
+ "Permit me to inform you of my desire of "
+ "going into business relationship with you. "
+ "I have the believe you are a reputable "
+ "and responsible and trustworthy person \n"
+ "I can do business with from the little"
+ "information so far I gathered about you "
+ "during my search for a partner and by matter "
+ "of trust I must not hesitate to confide "
+ "in you for this simple and sincere business. ";

Next we have StringBuilder. In general it's considered a better practice to use StringBuilder because of it's performance profile.

    StringBuilder sqlBuilder = new StringBuilder(
"UPDATE customers SET customerName='").append(name).append(
"', customerAddress='").append(address).append(
"', customerEmail = '").append(email).append(
"', customerNumber = '").append(phone).append(
"', customerPurchase = '").append(purchase).append(
"' WHERE id=").append(12);

Unfortunately it doesn't make building up a string significantly easier. 

Finally we have formatted text.

// Explicit argument indices may be used to re-order output.
String.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d");
>> d c b a

// Optional locale as the first argument can be used to get
// locale-specific formatting of numbers. The precision and width can be given
// to round and align the value.

String.format(Locale.FRANCE, "e = %+10.4f", Math.E);

>> e = +2,7183

// The '(' numeric flag may be used to format negative numbers with
// parentheses rather than a minus sign. Group separators are
// automatically inserted.

String.format("Amount gained or lost since last statement: $ %(,.2f",balanceDelta);

>> Amount gained or lost since last statement: $ (6,217.58)

Format is powerful but only scales up to, at most, a handful of parameters. This is not because there is some programmatic limit to the Format class, but more one of practicality. Tracking a hundred parameters by their index would be quite challenging.

Templates, a better way.

A template is simply a document with “placeholders” in it. These “placeholders” are expressions that tell the template engine where to put data.  All (okay most) white space and line feed characters are respected. This also has the nice benefit of separating the formatting (view) from the data. Here is a simple single line example :

 

     StringTemplate query = new StringTemplate(
"UPDATE customers SET customerName='$customer$'," +
" customerAddress='$address$' WHERE id=$id$");

query.setAttribute("customer", "Frank");
query.setAttribute("address", "1313 Mocking Bird Lane");
query.setAttribute("id", "4453");

System.out.println(query);

Output:


    UPDATE customers SET customerName='Frank', customerAddress='1313 Mocking Bird Lane' WHERE id=4453 

As you can see “placeholders” are delimited by $...$ (or <...> if you so choose). In this way it is reminiscent of variable substitution in languages like PHP or bash. The name inside the delimiters is used to look up the correct piece of data. Having names is important for maintaining readability. It also allows data to be pushed into the template in any order. This was a single line example. When you get to multi-line text you will probably want to use a template file. A template file is a plain text document that contains the fully formatted version of your desired output. $...$ attributes are placed thought the document to indicate parts you want replaced later by StringTemplate.

Example template file (spam-419.st):

From Address $from_addr$
To Address $to_addr$
Dear $to$,
    Permit me to inform you of my desire of going into business relationship with you. I have
    the believe you are a reputable and responsible and trustworthy person I can do business
    with from the little information so far I gathered about you during my search for a partner
    and by matter of trust I must not hesitate to confide in you for this simple and sincere business
.
...
Best Regards, $from$

Populating this template involves loading a StringTemplateGroup and using that to create an instance of your StringTemplate.

 

    StringTemplateGroup templateGroup = new StringTemplateGroup("spam group", "templates");
StringTemplate spam419 = templateGroup.getInstanceOf("spam419");
spam419.setAttribute("to", "Collin");
spam419.setAttribute("to_addr", "collin@bugmenot.com");
spam419.setAttribute("from", "Ima Spammer");
spam419.setAttribute("from_addr", "ima.spammer@spammers-paradise.com");

System.out.println(spam419.toString());

The StringTemplateGroup constructor in the code above takes two parameters. The first is a "group name". In this example it is not really important, feel free to use anything you like. The second is very important. This is the location of a directory (folder) that contains the template files you wish to load. In this example I am using a relative path. Relative to where I'm executing this code I expect to see a directory called "templates". The getInstanceOf() method takes the name (without the .st extension) of the that template file to be loaded. In this case I'm attempting to load "spam419.st".

From Address ima.spammer@spammers-paradise.com
To Address collin@bugmenot.com
Dear Collin,
    Permit me to inform you of my desire of going into business relationship with you. I have
    the believe you are a reputable and responsible and trustworthy person I can do business
    with from the little information so far I gathered about you during my search for a partner
    and by matter of trust I must not hesitate to confide in you for this simple and sincere business
.
...
Best Regards, Ima Spammer

I encourage you to experiment with this template. I think you will find adding or removing lines is trivial. Changing white space in the template is trivial. Even adding new attributes (placeholders) is straight forward. StringTemplate is a powerful tool that I can't hope to cover in just one blog post. For those who are chomping at the bit to learn more I'd recommend reading the official StringTemplate documentation which is a fantastic resource. 

Have fun,
Collin

 

From http://weblogs.java.net/blog/aberrant/archive/2010/05/25/using-stringtemplate-part-1-introduction-stringtemplate

Template

Opinions expressed by DZone contributors are their own.

Related

  • Automated Bug Fixing: From Templates to AI Agents
  • Dynamic File Upload Component in Salesforce LWC
  • Safeguarding Web Applications With Cloud Service Providers: Anti-CSRF Tokenization Best Practices
  • Make Your Backstage Templates Resilient

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!