Posts Tagged ‘ztemplates’

ZTemplates email service

Friday, June 25th, 2010

Has been a while since I last blogged, but I have been rather busy lately. Today I have done what I wanted to be doing a long time ago. I wrote a ztemplates service for sending out emails, using the powers of the rendering engine to create HTML emails. So I came up with the following service (note that I wrote this for version 0.9.9.6):

public class ZEmailService implements ZIEmailService {
 
	@Override
	public void render(Object obj, final String from, final String[] recipients, final String subject) throws Exception {
		render(obj, from, recipients, subject, "text/html");
	}
 
	@Override
	public void render(Object obj, final String from, final String[] recipients, final String subject, String mimeType) throws Exception {
 
		if(obj.getClass().isAnnotationPresent(ZEmail.class) == false) {
			throw new Exception("@ZEmail annotation not present on " + obj.getClass().getCanonicalName());
		}
 
		final ZIRenderService renderService = ZTemplates.getRenderService();
		final ZEmail emailAnnotation = obj.getClass().getAnnotation(ZEmail.class);
		final Properties properties = new Properties();
		final String body = renderService.render(obj);
 
		properties.put("mail.smtp.host", emailAnnotation.host());
 
		if(emailAnnotation.username() != null) {
			properties.put("mail.user", emailAnnotation.username());
		}
		if(emailAnnotation.username() != null) {
			properties.put("mail.password", emailAnnotation.password());
		}
		sendMail(properties, from, recipients, subject, mimeType, body);
	}
 
	private static void sendMail(final Properties properties, final String from, final String[] recipients, final String subject, final String mimeType, final String body) throws MessagingException {
		final Session session = Session.getDefaultInstance(properties, null);
		final Message message = new MimeMessage(session);
		final InternetAddress addressFrom = new InternetAddress(from);
		final InternetAddress[] addressTo = new InternetAddress[recipients.length];
 
		for (int i = 0; i < recipients.length; i++) {
			addressTo[i] = new InternetAddress(recipients[i]);
		}
 
		message.setFrom(addressFrom);
		message.setRecipients(Message.RecipientType.TO, addressTo);
		message.setSubject(subject);
		message.setContent(body, mimeType);
 
		Transport.send(message);
	}
}

Here is the interface:

public interface ZIEmailService extends ZIService {
 
	  public void render(Object obj, final String from, final String[] recipients, final String subject) throws Exception;
	  public void render(Object obj, final String from, final String[] recipients, final String subject, String mimeType) throws Exception;
}

And the code for the @ZEmail annotation:

@Retention(RetentionPolicy.RUNTIME)
public @interface ZEmail {
	String host() default "localhost";
	String username();
	String password();
}

Let’s say we have a view like:

@ZRenderer(value = ZJspRenderer.class)
@ZEmail(password = "secret", host = "somehost", username = "admin")
public class SomeView {
 
    @ZExpose
    public String someValue() {
    }
}

As you can see the @ZEmail annotation makes it possible to set mail server settings. To actually send the mail using that view we only have to do the following:

new ZEmailService().render(new SomeView(), "from@example.org", new String[] { "to@example.org" }, "subject");

As you can see I’m not using the ServiceRepository in this example, I added the service to ztemplates myself, so I’m running a custom version. Just instantiating the service works as well.

There are of course a lot of improvements possible, but this version matches my needs. I hope someone will have some use of it.

Note: Will probably also work using other renderers, didn’t test it ;-)

Required external libraries:

  • mail.jar
  • activation.jar

Hope to be blogging some more soon.

ZTemplates 0.9.9.6 and custom content types

Wednesday, September 30th, 2009

Quite recently I have been in a situation where I wanted to expose some XML using ZTemplates. So I used the servlet serivce to get the HttpServletResponse instance:

final HttpServletResponse response = ZTemplates.getServletService().getResponse();
response.setCharacterEncoding("utf-8");
response.setContentType("application/xml");

Followed by rendering a view:

ZTemplates.getServletService().render(view);

When I inspected the HTTP traffic using wireshark I noticed that I saw:

Content-Type: text/html;charset=utf-8

Rather than the expected application/xml. So I started looking into the code of the ZServletService that is responsible for rendering:

public void render(Object obj) throws Exception {
    render(obj, "text/html");
}
 
public void render(Object obj, String mimeType) throws Exception {
    String html = renderService.render(obj);
    // response.setCharacterEncoding(UTF8);
    response.setContentType(mimeType);
    response.getWriter().print(html);
}

That explained a lot, so now you could go ahead and do:

ZTemplates.getServletService().render(view, "application/xml");

However that does not give you control on the encoding, so I decided to create a custom rendering method instead:

public static void render(Object view, String encoding, String contentType ) throws Exception {
    final HttpServletResponse response = ZTemplates.getServletService().getResponse();
    final String renderResponse = ZTemplates.getRenderService().render(view);
    response.setCharacterEncoding(encoding);
    response.setContentType(contentType);
    response.getWriter().print(renderResponse);
}

So to fix my problem I only have to do the following now:

ZRenderUtils.render(view, "utf-8", "application/xml");

p.s. If you are wondering in this example, view, is just a String containing XML.

[ztemplates] Form validation with regular expressions

Sunday, November 16th, 2008

Today I tried form validation with ZTemplates. For validating something I had to use a regular expression. In my view I created a pattern matching property like this:

private final ZStringProperty name = new ZStringProperty() {
@Override
  public ZError validate() {
 
  try {
 
    ZError error = super.validate();
 
    if (error != null) {				
      return error;
    }
 
    final Matcher matcher = Pattern.compile("[A-Z]+").matcher(getValue());
 
    if (matcher.matches() == false) {
      return new ZError("You didn't supply a valid identifier");
    }
 
    return null;
 
    }
    catch (Exception e) {
      return new ZError(e.getMessage());
    }
  }
};

I then had to do 10 more, which annoyed me a bit. I decided to look at the in-built ZIntProperty type and then I built my own ‘ZPatternProperty’:

ZPatternProperty.java:

package org.ztemplates.property;
 
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
 
import org.ztemplates.property.ZProperty;
import org.ztemplates.web.ZTemplates;
 
public class ZPatternProperty extends ZProperty<String> {
 
  String pattern;
 
  public ZPatternProperty(String pattern, ZProperty<?>... dependsOn) {
 
    super(dependsOn);
    this.pattern = pattern;
  }
 
  public ZPatternProperty(String value, String pattern, ZProperty<?>... dependsOn) {
 
    super(dependsOn);
    this.pattern = pattern;
    setValue(value);
  }
 
  @Override
  public String parse(String formattedValue) throws Exception {
 
    if(formattedValue == null) {
      return null;
    }
 
    Pattern propertyPattern;
 
    try {
      propertyPattern = Pattern.compile(pattern);
    }
    catch(PatternSyntaxException e) {
 
    throw new Exception(ZTemplates.getMessageService().getMessage(ZPatternProperty.class.getName(), "PatternSyntaxException"));
    }
 
    // check if the value matches the pattern
    if(propertyPattern.matcher(formattedValue).matches() == false) {
      throw new Exception(ZTemplates.getMessageService().getMessage(ZPatternProperty.class.getName(), "NoMatchException"));
    }
 
    return formattedValue;
  }
 
  @Override
  public String format(String obj) {
    return obj;
  }
}

My first code example now becomes:

 
  private final ZPatternProperty name = new ZPatternProperty("[A-Z]+");

Isn’t that much more robust?!

I also had to supply a ZPatternProperties.properties file for getting the exception message:

ZPatternProperty.properties:

PatternSyntaxException=Invalid pattern
NoMatchException=Value does not match the pattern

It needs some better exception messages in the future, but for me it’s fine.

I’ve also sent an email to the creator of the ztemplates framework including the code. I hope that in a new version of ztemplates there will be support for pattern validation.

[ztemplates] ZJspRenderer and exposed fields - with JSTL

Saturday, November 15th, 2008

My previous article about ztemplates was about exposed values inside JSP code blocks. There is a also another possible approach and that is to use the JavaServer Pages Standard Tag Library. So let’s rewrite my last code example in the previous article.

Previous example:

<%
if(condition == true) {
 
  // notice the cast to the correct class type
  String message = (String)request.getAttribute("message");
 
  // When debugging it would be nice to check if the object is valid.
  if(message == null) {
 
    throw new Exception("DEBUG: message not exposed by render POJO.");
  }
 
  out.println(message);
}
%>

New example to see if the exposed ‘message’ field was set (with complete XHTML this time) :

<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 
<!-- NOTICE: load the tag library -->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Example</title>
  </head>
  <body>
    <c:choose>
      <c:when test="${message is null}">
        <p>You didn't provide a message!</p>
      </c:when>
      <c:otherwise>
        <p>Here is your message: ${message}</p>
      </c:otherwise>
    </c:choose>
  </body>
</html>

As you can see this is a much more robust way of doing things. Also take a look at this page for a more thorough introduction to JSTL.

[ztemplates] ZJspRenderer and exposed fields in JSP code blocks

Monday, November 3rd, 2008

Previously I worked with Apache Velocity as a rendering engine when using ZTemplates. However, I decided to use JSP instead.

Imagine having the following render POJO:

SampleView.java

@ZRenderer(ZJspRenderer.class)
public class SampleView {
 
  String message;
 
  @ZExpose
  public String getMessage() {
    return this.message;
  }
}

In the JSP template this could be used when doing something like:

SampleView.jsp

<html>
  <body>
    <h1>${message}</h1>
  </body>
</html>

However what would you do when having special conditions triggering the rendering of the message? You would try to do something like:

<%
if(condition == true) {
 
  out.println(${message});
}
%>

However since Java tries to compile the JSP it will give you an error saying there is a syntax error on the line where you print the ${message}. After having a look in the ZTemplates source code I discovered that ServletRequest.setAttribute() is being used for exposing values with a ZJspRenderer. This would mean JSP’s native request object would provide us all the exposed values for usage in our code blocks.

This would leave us with doing:

<%
if(condition == true) {
 
  // notice the cast to the correct class type
  String message = (String)request.getAttribute("message");
 
  // When debugging it would be nice to check if the object is valid.
  if(message == null) {
 
    throw new Exception("DEBUG: message not exposed by render POJO.");
  }
 
  out.println(message);
}
%>

It would be nice if ZTemplates would provide a wrapper for this, including a checker that throws an exception when the object is null. With this I mean a custom exception and not the normal NullPointerException, because most of the times it gives very big stack traces.

However this would also mean you’d have to import it in your JSP file as an import, because ZTemplates would have to provide a class for this. Not sure if this is what I would like to see.

Introduction to ztemplates

Wednesday, October 29th, 2008

Abstract

This article introduces ztemplates, a multi-tier open source web application framework for Java. ztemplates is licensed under the Apache 2.0 license. It uses Java annotations, thus meaning at least Java 1.5 or higher is required. ztemplates has a lot of features, but we will only introduce the basics in this post. This article will not describe how to set-up a project. Instead, it will explain the basics of the architecture of ztemplates.

ztemplates is a good framework. Its missing features are not critical issues nor will they cause problems in your day-to-day work.

public final Word = "See what ztemplates can do for you!";

Continue here