ICE09 . playing with java, scala, groovy and spring .

Playing with Spring

Quick Tip: Extending WebDriver to react on stopwords

Posted by ice09 on July 18, 2010

The requirement

Happily using WebDriver for some time now, I realized that it makes sense to intercept each call that changes the page source in a way that certain “stopwords”, eg. “exception”, “error”, etc. cause an immediate exception. This is useful if you want to be sure that in a complex test case an exception will never occur. Otherwise, you would have to manually check for it each time the page source is altered.

The problem

I wanted to use the ProxyBeanFactory for this requirement, since it seemed the least compromising way of manipulating the calls to the actual WebDriver. However, I realized that I would have to use AspectJ for this, since calls to private/protected methods inside the bean itself cannot be intercepted by proxies. This is necessary to intercept the call to the method sendMessage, which is used by WebDriver and WebElement for methods which actually change the page source (which makes sense, since this method actually communicates with the plugin via Commands).

The solution

I decided not to use proxies, but just to subclass the FireFoxWebDriver with my own one, which just overwrites the “sendMessage” method. That’s it, the code is as follows.

The Spring config

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <context:annotation-config/>
    <context:component-scan base-package="de.demo.proxy"/>

	<util:list id="stopwords">
    	<value>exception</value>
    	<value>Comment</value>
	</util:list>
    
</beans>

The new WebDriver

package de.demo.proxy;

import java.util.List;

import javax.annotation.Resource;

import org.openqa.selenium.firefox.Command;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.springframework.stereotype.Component;

@Component
public class InterceptedFireFoxDriver extends FirefoxDriver {
	
	@Resource(name="stopwords")
	private List<String> stopwords;
	
	@Override
	protected String sendMessage(Class<? extends RuntimeException> throwOnFailure, Command command) {
		String result = super.sendMessage(throwOnFailure, command);
		// avoid endless recursion, sendMessage... is called by getPageSource as well
		if (command.getCommandName().equals("getPageSource")) {
	        return result;
		}
		String content = super.getPageSource();
		// might be null due to initialization issues (already called during spring context creation)
		if (stopwords != null) {
			for (String stopword : stopwords) {
				if (content.contains(stopword)) {
					throw new IllegalStateException("command [" + command.getCommandName() + "] causes page content with stopword: " + stopword);
				}
			}
		}
		return result;
	}

}

The sample class

package de.demo.proxy;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class MainClass {
	
    @Autowired
	private WebDriver driver;
    
    public void start() {
        driver.get("http://www.google.com");

        // Find the text input element by its name
        WebElement element = driver.findElement(By.name("q"));

        // Enter something to search for
        element.sendKeys("Hello");

        // Now submit the form. WebDriver will find the form for us from the element
        element.submit();

        // Check the title of the page
        System.out.println("Page title is: " + driver.getTitle());
        
        driver.findElement(By.xpath("//a")).click();
        
        driver.close();
    }
	
	public static void main(String[] args) {
			ApplicationContext appCtx = new ClassPathXmlApplicationContext("app.xml");
			MainClass mc = appCtx.getBean(MainClass.class);
			try {
				mc.start();
			} finally {
				mc.driver.close();
			}
	}

}

Posted in Uncategorized | Leave a Comment »

Spring 3, REST, XML – running on the Google App Engine

Posted by ice09 on March 15, 2010

Note: The complete sourcecode is available on Google Code here. The projects can be imported as Eclipse 3.5.x or SpringSource Tool Suite 2.3.x projects (the Google Eclipse Plugin has to be installed for the gae project).

Introduction

Having already used Spring 3 in combination with REST and JSON on the Google App Engine, I will sum it up once again to…

  1. …explore the changes between the Spring Milestones and the Release (3.0.1)
  2. …use a specified format (using XML Schema) for data exchange
  3. …experiment with XML, data persistence on the GAE and Spring 3 REST capabilities

Intention

We will create a simple REST service which takes User objects, which itself include Location and Buddy references. The format will be XML, since we want to specify the format explicitly with means of XML Schema. Usual REST mechanisms will be used, therefore HTTP-GET and HTTP-POST is supported.

The User Model

The User XML Schema

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/User"
	xmlns:tns="http://www.example.org/User" elementFormDefault="qualified">

	<element name="User">
		<complexType>
			<sequence>
				<element name="id" type="long" />
				<element name="firstName" type="string"></element>
				<element name="lastName" type="string"></element>
				<element name="birthday" type="dateTime"></element>
				<element name="buddies" type="tns:BuddyType" />
				<element name="locations" type="tns:LocationType" />
			</sequence>
		</complexType>
	</element>

	<complexType name="BuddyType">
		<sequence>
			<element name="id" type="long" />
			<element name="buddyid" type="long" minOccurs="0" maxOccurs="unbounded" />
		</sequence>
	</complexType>

	<complexType name="LocationType">
		<sequence>
			<element name="id" type="long" />
			<element name="location">
				<complexType>
					<sequence>
						<element name="longitude" type="int" minOccurs="1" maxOccurs="1" />
						<element name="latitude" type="int" minOccurs="1" maxOccurs="1" />
						<element name="timestamp" type="dateTime" minOccurs="1" maxOccurs="1" />
					</sequence>
				</complexType>
			</element>
		</sequence>
	</complexType>

</schema>

After a POST request has been sent, it will respond the submitted object, together with a Location attribute in the respond header, which identifies the new resource. It can be retrieved with a corresponding GET request.

The client will be using the RestTemplate. Furthermore, soapUI will be configured for client requests.
Finally, the generated project will be migrated to the Google App Engine.

Preparation

  1. Download either Eclipse IDE for Java EE Developers 3.5.2 or the SpringSource Tool Suite 2.3.1 (STS). Sample are done in STS, however the Eclipse JEE edition should be perfectly alright for these samples.
  2. Install the Google Plugin for Eclipse. This will enable Google App Engine (GAE) deployment later on.
  3. If you are not using the STS, you will have to install the m2eclipse plugin.

Setup

  1. If you want to use the Eclipse WTP features, like “Run on server…”, you will have to prepare your environment for a coexistence of Eclipse/WTP and Maven 2. Create a new project as described in this howto.
  2. Optionally:If you are having problems with Maven errors due to wring JRE settings, try setting the -vm argument in the eclipse.ini (or sts.ini) file as mentioned here.
  3. Depending on the setup of the maven-webapp-archetype, you might have to set the project compliance to Java 5 and create the src/main/java folder as well as add it to the classpath.

    The dependencies and plugin configurations in the main pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>org.example</groupId>
    	<artifactId>blogrestsample</artifactId>
    	<packaging>war</packaging>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>blogrestsample Maven Webapp</name>
    	<repositories>
    		<repository>
    			<id>maven2-repository.dev.java.net</id>
    			<name>Java.net Maven 2 Repository</name>
    			<url>http://download.java.net/maven/2</url>
    		</repository>
    		<repository>
    			<id>maven-repository.dev.java.net</id>
    			<name>Java.net Maven 1 Repository (legacy)</name>
    			<url>http://download.java.net/maven/1</url>
    			<layout>legacy</layout>
    		</repository>
    		<repository>
    			<id>springsource maven repo</id>
    			<url>http://maven.springframework.org/milestone</url>
    		</repository>
    	</repositories>
    	<pluginRepositories>
    		<pluginRepository>
    			<id>maven2-repository.dev.java.net</id>
    			<url>http://download.java.net/maven/2</url>
    		</pluginRepository>
    		<pluginRepository>
    			<id>maven-repository.dev.java.net</id>
    			<url>http://download.java.net/maven/1</url>
    			<layout>legacy</layout>
    		</pluginRepository>
    	</pluginRepositories>
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>org.springframework.web.servlet</artifactId>
    			<version>3.0.0.RC1</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>org.springframework.oxm</artifactId>
    			<version>3.0.0.RC1</version>
    		</dependency>
    		<dependency>
    			<groupId>commons-collections</groupId>
    			<artifactId>commons-collections</artifactId>
    			<version>3.2</version>
    		</dependency>
    		<dependency>
    			<groupId>javax.xml.bind</groupId>
    			<artifactId>jaxb-api</artifactId>
    			<version>2.0</version>
    		</dependency>
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>servlet-api</artifactId>
    			<version>2.5</version>
    			<scope>provided</scope>
    		</dependency>
    	</dependencies>
    	<build>
    		<plugins>
    			<plugin>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<configuration>
    					<source>1.5</source>
    					<target>1.5</target>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.mortbay.jetty</groupId>
    				<artifactId>maven-jetty-plugin</artifactId>
    				<version>6.1.10</version>
    				<configuration>
    					<scanIntervalSeconds>10</scanIntervalSeconds>
    					<stopKey>foo</stopKey>
    					<stopPort>9999</stopPort>
    				</configuration>
    				<executions>
    					<execution>
    						<id>start-jetty</id>
    						<phase>pre-integration-test</phase>
    						<goals>
    							<goal>run</goal>
    						</goals>
    						<configuration>
    							<scanIntervalSeconds>0</scanIntervalSeconds>
    							<daemon>true</daemon>
    						</configuration>
    					</execution>
    					<execution>
    						<id>stop-jetty</id>
    						<phase>post-integration-test</phase>
    						<goals>
    							<goal>stop</goal>
    						</goals>
    					</execution>
    				</executions>
    			</plugin>
    			<plugin>
    				<groupId>org.jvnet.jaxb2.maven2</groupId>
    				<artifactId>maven-jaxb2-plugin</artifactId>
    				<version>0.7.1</version>
    				<executions>
    					<execution>
    						<goals>
    							<goal>generate</goal>
    						</goals>
    					</execution>
    				</executions>
    				<configuration>
    					<schemaDirectory>${basedir}/src/main/resources</schemaDirectory>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    </project>
    
  4. Put the User.xsd into the /src/main/resources folder and generate the Java source code from the XML Schema with Maven.
  5. Add the generated sources in folder /target/generated-sources/xjc/ to the classpath.
  6. Add the web.xml to the /src/main/webapp/WEB-INF/.
  7. <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    	id="WebApp_ID" version="2.5">
    	<display-name>rest-blog-sample</display-name>
    	<servlet>
    		<servlet-name>rest</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>rest</servlet-name>
    		<url-pattern>/*</url-pattern>
    	</servlet-mapping>
    
    </web-app>
    
  8. In the web.xml the servlet-name is set to rest, ie. by CoC a config file rest-servlet.xml is included.
  9. <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:oxm="http://www.springframework.org/schema/oxm"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    		http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
    
    	<oxm:jaxb2-marshaller id="marshaller" contextPath="org.example.user"/>
    	
    	<context:annotation-config/>
    	<context:component-scan base-package="org.example.rest"/>
    	
    	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    		<property name="messageConverters">
    			<list>
    				<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
    					<constructor-arg ref="marshaller"/>
    				</bean>
    			</list>
    		</property>
    	</bean>
    	
    	<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
    	
    	<bean name="user" class="org.springframework.web.servlet.view.xml.MarshallingView">
    		<constructor-arg ref="marshaller"/>
    	</bean>
    	
    </beans>
    
  10. The application context file rest-servlet.xml is self-explanatory, a marshaller is created and registered in the BeanNameViewResolver as well as the AnnotationMethodHandlerAdapter. The corresponding Controller has to declare the to-be-unmarshalled object User with the @RequestBody annotation to use the AnnotationMethodHandlerAdapter:
    package org.example.rest.controller;
    
    import static org.springframework.web.bind.annotation.RequestMethod.GET;
    import static org.springframework.web.bind.annotation.RequestMethod.POST;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.example.user.ObjectFactory;
    import org.example.user.User;
    import org.springframework.http.HttpStatus;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseStatus;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    public class UserController {
    	
    	@RequestMapping(value="/post/", method=POST)
    	@ResponseStatus(HttpStatus.CREATED)
    	public ModelAndView post(@RequestBody User userRequest, HttpServletRequest request, HttpServletResponse response) {
    		User userResponse = new ObjectFactory().createUser();
    		response.addHeader("Location", determineLocationUri(request, "/user/" + userRequest.getId()));
    		return new ModelAndView("user").addObject(userResponse);
    	}
    
    	@RequestMapping(value="/user/{id}", method=GET)
    	@ResponseStatus(HttpStatus.CREATED)
    	public ModelAndView get(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
    		User userResponse = new ObjectFactory().createUser();
    		userResponse.setId(Long.valueOf(id));
    		return new ModelAndView("user").addObject(userResponse);
    	}
    	
    	String determineLocationUri(HttpServletRequest request,	String newPathInfo) {
    		StringBuffer url = request.getRequestURL();
    		url.replace(url.indexOf(request.getPathInfo()), url.length(), newPathInfo);
    		return url.toString();
    	}	
    
    }
    
  11. Depending on the project settings: “Web Project Settings”, the context root is set.

Migrating to a Google App Engine project

  1. Run the Maven goal mvn war:war in the project folder.
  2. From the generated war in folder target, copy the jars from the /WEB-INF/lib folder inside the jar.
  3. Copy the web.xml and rest-servlet.xml to the GAE project.
  4. Note:Use complex type as embedded XML Element, otherwise JAXBElement is used as marshalling type, which includes some string coupling where it does not have to be.
  5. Note:I wanted to use XMLBeans for this, however, I came across this “stream closed” error, which rendered XMLBeans useless for me.

Starting

You can start the application by either (1) running mvn jetty:run for the simple project, run out of eclipse (2) with “Run as…/Run on Server” or start the GAE project (3) with “Run as…/Web Application”. Depending on what way you choose, the URL changes (1: http://localhost:8080/post, 2: http://localhost:8080/…/post, 3: http://localhost:8888/post).

Testing

You can test the application in two ways:

  1. Using soapUI. It has REST support now, Using the sample project, you have to setup the project as follows:
  2. Using the RestTemplate. The pom.xml for the client project looks like this:
  3. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>org.examples</groupId>
    	<artifactId>resttemplate</artifactId>
    	<packaging>jar</packaging>
    	<version>1.0-SNAPSHOT</version>
    	<name>Spring 3 RestTemplate Sample</name>
    	<build>
    		<plugins>
    			<plugin>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<configuration>
    					<source>1.5</source>
    					<target>1.5</target>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.ws</groupId>
    			<artifactId>spring-xml</artifactId>
    			<version>2.0.0-M1</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-web</artifactId>
    			<version>3.0.1.RELEASE</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-oxm</artifactId>
    			<version>3.0.1.RELEASE</version>
    		</dependency>
    	</dependencies>
    </project>
    
    package org.example.rest.resttemplate;
    
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.StringReader;
    import java.net.URI;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.xml.transform.Source;
    import javax.xml.transform.stream.StreamSource;
    
    import org.example.user.User;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
    import org.springframework.http.converter.xml.SourceHttpMessageConverter;
    import org.springframework.oxm.XmlMappingException;
    import org.springframework.oxm.jaxb.Jaxb2Marshaller;
    import org.springframework.web.client.RestTemplate;
    
    public class UserClient {
    
        public static void main(String[] args) throws XmlMappingException, IOException {
        	for (int i=1; i<1000; i++) {
       			postForLocation(String.valueOf(i));
        	}
        }
    
    	private static void postForLocation(String id) throws IOException {
    		RestTemplate restTemplate = new RestTemplate();
        	List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
        	list.add(new SourceHttpMessageConverter<Source>());
        	restTemplate.setMessageConverters(list);
        	String content = readFileAsString("src/main/resources/user-instance.xml").replaceAll("ID", id);
        	URI resultUrl = 
        		restTemplate.postForLocation("http://localhost:8888/post/", 
        			new StreamSource(new StringReader(content)));
        	getObject(resultUrl);
    	}
    	
    	private static void getObject(URI resultUrl) {
    		RestTemplate restTemplate = new RestTemplate();
        	List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
        	Jaxb2Marshaller jaxb2 = new Jaxb2Marshaller();
        	jaxb2.setContextPath("org.example.user");
        	list.add(new MarshallingHttpMessageConverter(jaxb2));
        	restTemplate.setMessageConverters(list);
    		User user = restTemplate.getForObject(resultUrl, User.class);
    		System.out.println(user.getId());
    	}
    
    	private static String readFileAsString(String filePath) throws java.io.IOException{
    	    byte[] buffer = new byte[(int) new File(filePath).length()];
    	    BufferedInputStream f = new BufferedInputStream(new FileInputStream(filePath));
    	    f.read(buffer);
    	    return new String(buffer);
    	}	
    
    }
    

Posted in Google App Engine, Spring | Tagged: , | 6 Comments »

Spring Quicktip: Selecting beans during runtime

Posted by ice09 on February 13, 2010

Sometimes you want to select an actual bean implementation during runtime depending on the availability of other beans.

Example

You have a bean accessor which accesses some external component and is used in several beans all over your application in several application contexts.
Now lets assume you want to change the actual implementation of the accessor bean depending on the availability of some other bean extended-accessor, which might or might not be present during runtime. This selection should be transparent to the existing components, ie. if the bean extended-accessor is not available in the application context, the fallback is using accessor instead.

Implementation

There might be different solutions to this problem, to me the best one is using the magical BeanFactoryPostProcessor.

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class AccessorBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	
	protected String extendedTemplate;
	protected String accessorTemplate;
	protected String accessorTemplateFactory;
	
	public void setExtendedTemplate(String extendedTemplate) {
		this.extendedTemplate = extendedTemplate;
	}

	public void setAccessorTemplate(String accessorTemplate) {
		this.accessorTemplate = accessorTemplate;
	}

	public void setAccessorTemplateFactory(String accessorTemplateFactory) {
		this.accessorTemplateFactory = accessorTemplateFactory;
	}
	
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition(accessorTemplateFactory);
		MutablePropertyValues pvalues = beanDefinition.getPropertyValues();
		Template accessorClass = (Template) (beanFactory.containsBean(extendedTemplate) ? beanFactory.getBean(extendedTemplate) : (Template) beanFactory.getBean(accessorTemplate));   

                //Set the property (the selected bean implementation) now during runtime
		pvalues.addPropertyValue("accessorTemplate", accessorClass);
	}

Now, this bean must be instantiated – it will be passed the bean definition of all beans in the application context. It retrieves the factory bean first, which itself will be dynamically instantiated with the extendedTemplate if it exists and accessorTemplate otherwise.
Together with a factory bean, this looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

        <!-- Here the external definition can be imported (if it is, and the 
               bean extendedTemplate is defined, it will be passed to the factory bean) -->
	<import resource="classpath*:/extension.xml"/>
	
        <!-- Here the actual BeanFactoryPostProcessor is defined, the properties are 
               the Strings which identify the several beans -->
	<bean class="AccessorBeanFactoryPostProcessor">
		<property name="accessorTemplateFactory" value="accessorTemplateFactory"/>
		<property name="extendedTemplate" value="extendedTemplate"/>
		<property name="accessorTemplate" value="accessorTemplate"/>
	</bean>

        <!-- This is the actual bean which is used the the dependent beans - it is created 	
               by the factory bean, which is itself configured by BeanFactoryPostProcessor -->
        <bean id="actualTemplate" factory-bean="accessorTemplateFactory" factory-method="createAccessorTemplate" />

        <!-- This is the actual factory, which itself gets configured by the BeanFactoryPostProcessor -->
	<bean id="accessorTemplateFactory" class="AccessorTemplateFactory">
		<!-- will be modified during runtime -->
	</bean>

	<!-- This is the original accessor template bean, which is selected 
               if the extended bean is not present -->
        <bean id="accessorTemplate" class="AccessorTemplate" />

</beans>

Of course, the beans must implement the same interface. The included extension.xml is quite simple:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="extendedTemplate" class="ExtendedTemplate" />

</beans>

Finally, the factory bean is simple as well, it is used to have a single point of creation – the property accessorBean is set by the BeanFactoryPostProcessor during runtime:

public class AccessorTemplateFactory {

	public Template bean;

	public void setAccessorTemplate(Template arg0) {
		this.bean = arg0;
	}

	public Template createAccessorTemplate() {
		return bean;
	}

}

Posted in BeanFactoryPostProcessor, Spring | 2 Comments »

RESTing with JSON in Gaelyk

Posted by ice09 on February 1, 2010

Note: The complete sourcecode is available on github here (the subproject is ‘gaeloc’). For just downloading, unzipping and importing the project into Eclipse, press on the github site.

Doing REST is getting easier these days, however, there are still substantial differences between ease of usage between different REST frameworks.

A simple, concise approach is illustrated by the new REST support in Spring 3 as described in the previous post about this topic.
However, it can be even simpler. For some Android REST client, I wanted to choose the most intuitive and rapid way to implement a REST server prototype. Once again, I came up with Gaelyk, which I introduced here.

Technologies

  1. Gaelyk, a lightweight Groovy toolkit for the Google App Engine (Java)
  2. Groovy, namely the embeddable groovy-all-jar
  3. Jackson, an intuitive, nice & simple JSON processor
  4. the new Groovy Eclipse plugin

Setup

Currently, the best information about setup, installation and usage of Gaelyk is this post on developerworks.
I just updated the version numbers and changed the injected Google App Engine SDK element names (compare the version history). You will have to do the same if you want to get the downloadable post-project to work with Gaelyk 0.3.2.

The environment is a Eclipse 3.5.1 with the Google Plugin for Eclipse Plugin installed.

  1. Create new Web Application Project
  2. Add the Google App Engine SDK (for this project, GWT is not used)
  3. Add the Gaelyk and Groovy Jars
  4. Add the Jackson dependencies
  5. Add Groovy nature to the project to enable debugging
  6. For debugging, add the WEB-INF/groovy folder to the build path

Configuration

The important parts of the configuration are mentioned in the developerworks post. Just follow the instructions.
Afterwards, the routes for Gaelyk will be enabled and defined:

Changes to web.xml

<filter>
	<filter-name>RoutesFilter</filter-name>
	<filter-class>groovyx.gaelyk.routes.RoutesFilter</filter-class>
</filter>

<filter-mapping>
	<filter-name>RoutesFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

The routes.groovy file in WEB-INF

post "/new-user", forward: "/WEB-INF/groovy/post.groovy"
get "/user/@name", forward: "/WEB-INF/groovy/get.groovy?name=@name"

The post.groovy file called by POST on /new-user

import com.google.appengine.api.datastore.Entity 
import java.text.SimpleDateFormat 
import org.codehaus.jackson.map.ObjectMapper

def requestComplete = new StringBuilder();
while ((line = request.getReader().readLine()) != null) {
	requestComplete.append(line);
}
ObjectMapper mapper = new ObjectMapper(); 
Map map = mapper.readValue(requestComplete.toString(), Map.class);

def user = new Entity("user")
user.name = map.key
user.save()

The get.groovy file called by GET on /user/{ID}

import org.codehaus.jackson.map.ObjectMapper
import com.google.appengine.api.datastore.KeyFactory

if (params["id"]) {
	def id = Long.parseLong(params["id"])
	try {
		def key = KeyFactory.createKey("user", id)
		def user = datastore.get(key)
		ObjectMapper mapper = new ObjectMapper();
		response.contentType = "application/json"
		StringWriter sw = new StringWriter();
		mapper.writeValue(out, user);
	} catch (Throwable t) {
	}
} else {
	forward "index.html"
}

Starting and using the Google App Engine

You can start the Google App Engine locally by choosing “Run As…/Web Application”.

It helps a lot to be able to browse the datastore – this is now possible locally as well by visiting http://localhost:8888/_ah/admin/datastore

Posted in Gaelyk, REST | 2 Comments »

File monitoring with Groovy, JMX and Vaadin

Posted by ice09 on December 1, 2009

Note: The complete sourcecode is available on github here. For just downloading, unzipping and importing the project into Eclipse, press on the github site (detailed instructions below).

Besides the Google Web Toolkit (GWT), there is a nice web application framework for Java-only users called Vaadin.
Out-of-the-box, it has a more polished interface and prettier components than GWT.
I used it in a small application, my experience was very positive, even though I used Vaadin in a non-standard way (periodic asynchronous updating of a component by a infinitely running process), it works very well and there was really good support by the Vaadin team.
Note: This post is not an introduction to Vaadin, I hardly know it myself. A great developer-friendly entry are the sample applications. For more info, there is a step-by-step tutorial and a book for deeper understanding.

Intention

Automated testing of a web application is used in a Continuous Integration Environment. Furthermore, load/stress testing of the web application takes place in a Performance Test setting. A process should monitor logfiles in these test environments and report errors in a web-based report.

Technically, a thread must monitor several logfiles, aggregate these errors in a managed component which must be analyzed by a visualizing component (eg. a automatically refreshing table), which must be accessible from several clients.

So, now with technological annotations…

Technically, a thread must monitor several logfiles (Groovy), aggregate these errors in a managed component (Groovy, JMX) which must be analyzed by a visualizing component (eg. a automatically refreshing table), which must be accessible from several clients (web based, Vaadin).

Ok, lets go.

The “server side components”

The server side just consists of a simple Groovy script:

import javax.management.remote.*
import javax.management.*
import groovy.jmx.builder.*
import java.rmi.registry.LocateRegistry

class ServerState implements Serializable {
    def list=[]
}
def jmxbean = new ServerState()

Thread.start {
    def jmx = new JmxBuilder()
    def beans = jmx.export {
        bean(name: "jmx.builder:type=ExportedObject", jmxbean)
    }
    LocateRegistry.createRegistry(9000)
    jmx.connectorServer(port: 9000).start()
}

def worker = { logfile ->
    println "analyzing ${logfile}"
    logfile.withReader { reader -> 
        reader.skip(logfile.length())
        while (true) {
            def line = reader.readLine();
            if (!line) { 
                Thread.sleep(1000); 
            } else {
                def inner = [:]
                inner["server"] = logfile.name
                inner["ts"]= new Date().toString()
                inner["error"] = line
                jmxbean.getList().add(inner)
            }
        }
    }
}

new File("c:/temp/").eachFileMatch(~/^log.txt.*/) { file ->
    Thread.start worker.curry(file)
}

First, a thread is started that exports the aggregating bean via JMX (it’s so easy in Groovy).
After calling jmx.connectorServer(port: 9000).start(), the bean is available under the JNDI-Name service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi to client processes (using the name jmx.builder:type=ExportedObject).
Afterwards, a worker closure is created. Nothing special in there, just the reader.skip(logfile.length()) makes sure the end of the file is used at the beginning (before the monitoring process starts).
The last three lines are quite dense, though. Here, all files matching the pattern (eg, log.txt, log.txt1, log.txt2) are used to create threads which monitor these files. This is easily achieved by using currying, which is described in detail here.
In this case, file is applied and the rest (the partially applicated closure) is submitted to Thread.start, which takes a closure (now with an already defined logfile) as the argument.

Tip: Using the Groovy script

All information necessary to run Groovy in any environment is stated here.
However, there is a really cool way of testing Groovy scripts without any settings, etc. Just JAVA_HOME must be set correctly.

  1. Download Groovy, unzip or install to some directory (eg. c:\dev\groovy)
  2. Set your JAVA_HOME environment variable to your Java installation (eg. set JAVA_HOME=c:\java\jdk1.6.0_17).
  3. Start groovyConsole.exe (in \$GROOVY_HOME\bin). Paste the script there. Run it.

Located in GROOVY_HOME\bin: groovyConsole

groovyConsole in action

The “client side”

Testing with jconsole

jconsole is included in the Java SDK (JAVA_HOME\bin)

The JMX-URL is determined by the Groovy script

Result of calling the exported operation getList()

Creating a web app client with Vaadin

  1. Download the Vaadin Eclipse plugin.
  2. Download the zipped files (click on ). It’s subproject Vaadin.
  3. Create new Vaadin project, choose Vaadin jar (cmp. image) – this post was tested with vaadin-6.2.nightly-20091016-c9216.jar.
  4. Delete generated src and Webcontent (!! except WEB-INF/lib !!) directores and copy from downloaded zip.

Structure and Functioning

The JMX-component to connect to Groovy-JMX-server

public class JmxService {

	private JMXServiceURL url;
	private JMXConnector jmxc;
	private MBeanServerConnection mbsc;
	private ObjectName mbeanName;
	
	private static JmxService INSTANCE;
	
	private JmxService() {
		try {
			url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi");
			jmxc = JMXConnectorFactory.connect(url, null);
			mbsc = jmxc.getMBeanServerConnection();
			mbeanName = new ObjectName("jmx.builder:type=ExportedObject");
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (MalformedObjectNameException e) {
			e.printStackTrace();
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
	}
	
	public static JmxService getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new JmxService(); 
		}
		return INSTANCE; 
	}
	
	public ServerState getServerState() {
		return JMX.newMBeanProxy(mbsc, mbeanName, ServerState.class, true);
	}

}

The table with its on-click-listener is created in pure Java

	private Table initTable(final IndexedContainer container) {
		final Table table = new Table();
		table.setContainerDataSource(container);
		table.setWidth("100%");
		table.setPageLength(PAGE_LENGTH);
		table.setColumnExpandRatio("error", 1);
		table.setSelectable(true);
		final Application self = this;
		table.addListener(new Table.ValueChangeListener() {
			@Override
            public void valueChange(ValueChangeEvent event) {
				Object o = table.getValue();
                if (o != null) {
                	preformattedText = new Label("Here can be sources");
                    preformattedText.setContentMode(Label.CONTENT_PREFORMATTED);
                    self.getMainWindow().addComponent(preformattedText);                
            	} else {
                    self.getMainWindow().removeComponent(preformattedText);                
                }
          	}
        });
		return table;
	}

The Refresher”pattern” is explained here, the sources are in the repository. All necessary sources are also included in the github sources to this post.

Running the project

You can just start the server-side Groovy script (after configuring the file matching loop at the end of the script corresponding to your system). Afterwards, just start the Vaadin project with “Run on Server”.
Now, you have to change a monitored file (eg. add a line and save the file). If you have chosen “Aktualisierung starten” (ie. start polling for new JMX events) the changed line should appear in the table. You can choose the line (details view is not implemented yet) to display more information. The table scrolls accordingly (the last item is always displayed at the bottom of the table).
The refresh mechanism necessary for polling the JMX state is copied from here.
Note: for real usage, it would be much better to use JMX notification for this use case.

Posted in Groovy, Vaadin | Leave a Comment »

Spring 3 on the Google App Engine: REST in Peace

Posted by ice09 on November 19, 2009

Note: The complete source and necessary jars are available in github here. For just downloading, unzipping and importing the project into Eclipse, press on the github site.
Important: this is a collection of projects, the relevant project for this post is gae-rest-sample and spring3-resttemplate.

Finally I succeeded in getting REST (with the new REST support in Spring 3) done in the Google App Engine.
It wouldn’t be an easy task, but thanks to one brilliant blog post, a forum post and a very helpful JIRA issue, it can be resolved just by searching.

  1. The brilliant blog post about Spring REST in general by Eyal Lupu.
    This post is just a rewrite of that one, just adding the GAE-related stuff.
    All details about REST content negotiation and how the Spring MVC works with REST is explained there.
  2. The forum post about problems with GAE and XStream.
    This helps to unterstand the reason for the sun.reflect.ReflectionFactory is a restricted class exception when using XStream on GAE.
  3. The JIRA issue 566, which investigates the problem in more detail and provides a solution which is valid for at least the usage in this context (note the last entry).

I finally took the snapshot jar attached to the JIRA issue, which works well for the samples in this post. Nevertheless, there might still be difficulties with XStream on the GAE, so be aware.

The client

Eyal Lupu also provides a JSON-Client in his post. The client itself is straightforward – it uses the Spring RestTemplate. The JsonHttpMessageConverter uses Spring’s FileCopyUtils for InputStream String conversion which is quite cool.

Spring RestTemplate:

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setMessageConverters(new HttpMessageConverter[]{new JsonHttpMessageConverter()});

    JSONObject result = restTemplate.getForObject("http://localhost:8080/users/.js", JSONObject.class);

    JSONArray aresult = result.getJSONArray("payload");
    for (int x=0; x<aresult.length(); ++x) {
        JSONObject currResult = (JSONObject) aresult.get(x);
        System.out.format("%-100s | %s%n", currResult.get("name"), currResult.get("lastLoggedInAt"));
    }

JSON-Unmarshaller:

	@Override
	protected JSONObject readInternal(Class<JSONObject> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
                MediaType contentType = inputMessage.getHeaders().getContentType();
		Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : Charset.forName("utf-8");
		String stringResult =  FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));

		JSONObject jObject;
		try {
			jObject = new JSONObject(stringResult);
		} catch (JSONException e) {
			throw new IOException (e);
		}
		return jObject;
	}

Annoyances

Here are some things I don’t understand and I had to work around.
Please comment if you know more about the problem.

  1. In the web.xml, the url-pattern has to be / instead of /* (or /rest in the original sample) to get it working in the GAE
  2. Usually, I would prefer having the jsp-views in /WEB-INF/*. However, this does not work in GAE (doesn’t find WEB-INF or anything below WEB-INF)

Posted in Google App Engine, REST | 4 Comments »

Scala Mashup Series: The Template Method in Java, Spring and Scala

Posted by ice09 on November 9, 2009

Continuing the Scala Mashup Series, this post is about a quite important, often used, but also controversial pattern: The Template Method.

In general, there are great explanations of the pattern in Wikipedia and of course in Head First Design Patterns.

Criticism

A very good summary of the Template Method pattern especially in comparison to the Strategy pattern is on stackoverflow.com:

The Template pattern does compile-time algorithm selection by subclassing.
The Strategy pattern does run-time algorithm selection by containment.

Example

Imagine you want to arrange a dinner. The entire algorithm for arranging a dinner is predefined:

  1. Invite your guests
  2. Go shopping
  3. Clean your fridge to provide enough space
  4. Prepare the meal
  5. Server the meal
  6. Wash the dishes

Now, some parts of this algorithm (which in its entirety is called arrange) are fixed (invariant parts). Other parts are highly dependant on the meal you want to prepare (variant parts).
In Template Method, the algorithm itself is described in a public accessible method, eg. arrange(), which combines and calls the variant and invariant methods. The invariant methods are implemented in the abstract super class. The variant parts are implemented in the concrete classes, eg. BratwurstDinner, which implements the concrete way to do shopping for the BratwurstDinner, as well as the preparation of the Bratwurst itself.
The important part is the compile-time binding – the implementing, concrete classes cannot change their implementation during runtime.
This makes the Template Method almost ideal for framework creation, when you want to provide abstract algorithms with certain concrete implementations (think of abstract database layers, with an algorithm which cares for opening & establishing connections, handles exceptions and cleans up nicely after doing … the variant part, which is implemented in the concrete classes).

Here is the dinner example using the Template Method pattern

Here is the dinner example using the Strategy pattern

There are two clever blog posts, one about disadvantages of the Template Method pattern, and one mentioning a possible alternative in languages with first class functions like Scala.

Language comparison: Java, Scala, Spring

We will happily leave out the Java example, since it is just too obvious. In the Wikipedia article a sample is given, together with the class diagram it should be pretty obvious how Template Method is implemented in Java. The only thing to keep in mind is to set the super class abstract, as well as the variant methods – which are then implemented (using @Override) in the concrete classes.

Scala

In Scala there are is the intuitive way of implemeting the Template Method, analogous to Java:

abstract class DinnerEvent {

  def arrange(): Unit = {
    makeGuestList
    doShopping
    cleanFridge
    prepareMeal
    serveMeal
    washDishes
  }

  def prepareMeal(): Unit
  def doShopping(): Unit

  def makeGuestList(): Unit = {
    println("making guest list...")
  }

  def cleanFridge(): Unit = {
    println("cleaning fridge...")
  }

  def serveMeal(): Unit = {
    println("serving meal...")
  }

  def washDishes(): Unit = {
    println("washing dishes...")
  }

}

trait TurkeyDinner {

  def doShopping(): Unit =  {
    println("...buying turkey")
  }

  def prepareMeal(): Unit =  {
    println("...preparing turkey")
  }

}

object TemplateMethod {

  def main(args:Array[String]) = {
    val dinner = new DinnerEvent with TurkeyDinner
    dinner.arrange()
  }

}

However, in languages with first class functions, it is too tempting to use the Strategy pattern:

class DinnerEventWithStrategy(shoppingStrategy: () => Unit, preparingStrategy: () => Unit) {

  def arrange(): Unit = {
    makeGuestList()
    shoppingStrategy()
    cleanFridge()
    preparingStrategy()
    serveMeal()
    washDishes()
  }

  def makeGuestList(): Unit = {
    println("making guest list...")
  }

  def cleanFridge(): Unit = {
    println("cleaning fridge...")
  }

  def serveMeal(): Unit = {
    println("serving meal...")
  }

  def washDishes(): Unit = {
    println("washing dishes...")
  }

}

object Closure {

  def turkeyShoppingStrategy(): Unit = {
    println ("...shopping turkey strategy")
  }

  def turkeyPreparationStrategy(): Unit = {
    println ("...preparing turkey strategy")
  }

  def main(args:Array[String]) = {
    val dinner = new DinnerEventWithStrategy(turkeyShoppingStrategy, turkeyPreparationStrategy)
    dinner.arrange()
  }

}

So, you should choose wisely, both patterns definitely have their scope of application – just keep in mind that Strategy also uses composition over inheritance, which is always a good advise.

…and what about Spring?

This is interesting, Spring uses the Template Method a lot – and many think it is one of their greatest strengths.
But wait … the Template Method pattern? Not really. The Spring Framework templates in fact are not implementing the Template Method pattern, even if it feels this way.
Let’s examine a small usage example of Spring’s JdbcTemplate:

package com.commons.sample.dao;

import java.util.List;

import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;

public class JdbcSimpleDao extends SimpleJdbcDaoSupport implements SimpleDao {

	final static String single	= "select id, name from test where id = ?"; 
	final static String list 	= "select id, name from test"; 

	public Simple getSimpleById(int id) {
		return getSimpleJdbcTemplate().queryForObject(single, 
				ParameterizedBeanPropertyRowMapper.newInstance(Simple.class), id);
	}

	public List<Simple> getSimples() {
		return getSimpleJdbcTemplate().query(list, 
				ParameterizedBeanPropertyRowMapper.newInstance(Simple.class));
	}

}

What is happening here? Even though the class extends SimpleJdbcDaoSupport, it would not have to.
The Method query(…) takes the SQL and a ParameterizedBeanPropertyRowMapper.newInstance(Simple.class), which defines a row mapper that creates an object of class Simple – this certainly describes a strategy. So, even the so-called Spring Templates actually uses the Strategy pattern.

Summary

The Template Method is a powerful pattern. Use it if you create a framework, since you can inject certain functionality in the implementing classes at compile time, which let the user of your framework extend it easily, but in a controlled and “traceable” way. For Java, it is a natural way to enable users of your classes to extends the functionality at certain points.
In languages with first-order functions (or closures), like Scala, it might feel more natural to use the Strategy pattern instead. However, keep in mind that the patterns are not completely identical.

Posted in Patterns, Scala | 2 Comments »

Simple Performancetesting with Grinder

Posted by ice09 on November 4, 2009

In the last post, I created a prototype with some technologies which were new to me, especially Gaelyk.

As it turned out, the prototype behaved quite differently in my local system and when deployed in the Google App Engine. What seems really strange to me is that even after all five number series had been cached, every 3-4th request took quite long, at least locally. In the deployed version, this seemed to be different and not too slow (even though I suppose a pure Java version would be significantly faster).

Now, how can I test without too much trouble if the deployed site is “just fast enough”?
Having looked around quite some time, Grinder looked most promising to me, with respect to easy of usage and features.

Preparation

Download Grinder and Jython 2.2.1 – it must be this version, not the current 2.5.x – this just does not work.

Install Jython.

Create grinder.properties and grinder.py – they can go in any directory, the most simple usage will be in the grinder/lib directory:

grinder.properties (change directory accordingly):

grinder.runs=0
grinder.threads=10
grinder.processes=1
grinder.jvm.arguments=-Dpython.home=/dev/jython2.2.1

grinder.py

# A simple example using the HTTP plugin that shows the retrieval of a
# single page via HTTP. The resulting page is written to a file.
#
# More complex HTTP scripts are best created with the TCPProxy.
import string
from net.grinder.script.Grinder import grinder
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest

test1 = Test(1, "Request resource")
request1 = test1.wrap(HTTPRequest())
log = grinder.logger.output

class TestRunner:
    def __call__(self):
	grinder.statistics.setDelayReports(1)
        result = request1.GET("http://localhost:8080/data.groovy")
	log(result.getText())
	if string.find(result.getText(), "counter") < 1:
	    grinder.statistics.forLastTest.setSuccess(0)
        # result is a HTTPClient.HTTPResult. We get the message body
        # using the getText() method.

Usage

Now you can start the Grinder console with:
java -cp grinder.jar net.grinder.Console

Afterwards, start the Grinder agent with:
java -cp grinder.jar net.grinder.Console

Now, you must sync the data first, as shown in the screenshot. Afterwards, just start the tests.

grinder

According to the config, the agent runs indefinitely in 10 Threads. The site in the Jython script is called and in the resulting page, the expression counter is searched. If it is not present, the test fails. You can verify this by stopping the server, it will start increasing the failure counter immediately.

All in all, we have a very easy load test with very few lines of code.

As a result, the remote Google App Engine runs much more stable, so I just presume that the memcache implementation of the local Google App Engine server is not as good/stable as the remote one. But this is just a guess.

However, be careful with Gaelyk besides from using it for prototypes, because if the site is not called continuously, it kind of fells asleep really fast (some minutes) and needs its time for wakeup, which is quite annoying. I just don’t know what causes this, Gaelyk or the GAE.
You can verify this by just loading the Gaelyk home page. The first call often really feels kind of slow.

Posted in Grinder, Performance testing | 1 Comment »

Google Chart API with Gaelyk on the Google App Engine

Posted by ice09 on November 4, 2009

Note: Github available here. It works best with the current SpringSource Tool Suite.

Having had evening to spare, together with a colleague I came up with the following nano-project:

Write a prototype for creating a chart from some series of numbers, which is hosted in a cheap cloud.

So this brings me to: “Write a prototype (Groovy) for creating a chart (Google Chart API) from some series of numbers (taken from spreadsheets of Google Docs), which is hosted in a cheap cloud (Google App Engine).”
Some day, I will have to fix this Google addiction – however, Groovy is not affiliated to Google at all.

Evaluation of Frameworks

Wanting to combine Groovy and the Google App Engine, I immediately came across two different frameworks, the almighty and ubiquitous Grails and the much more pragmatic Gaelyk.
Since for this purpose Gaelyk is more than enough and because I wanted to try it, I used this for prototyping. By downloading the sources from Github, the typical Gaelyk project setup can be concluded if analyzed together with the information given in the Gaelyk tutorial – it’s quite easy.

The data (about 100-1000 random numbers between 5000 to 6000) should come from a web based, private (authorization-based) available data source – even though many possibilities exist, I chose Google Docs for two reasons:

  1. Easy creation of “some” random numbers
  2. Authorization based on Google Authorization
  3. Access class already exists (cmp. this post)

The last important feature should be the creation of a chart. Here, really a lot compelling solutions exist. Mainly, there are three different ways to realize Chart creation:

  1. Java based, eg. JFreeChart
  2. Javascript based, eg. JQuery plugin flot
  3. Pure Web based, eg. Google Chart API

Since I want to have it simple & easy, the third option is really great for this use case. A chart can very easily be created, compare this, which is rendered dynamically:

which is:

http://chart.apis.google.com/chart?chxl=0:||1:|&cht=lc&chxt=x,y&chs=500x150&chco=0077CC&chm=B,E6F2FA,0,0,0&chd=t:5563.0,5807.0,5096.0,5898.0,5306.0,5944.0,5932.0,5510.0,5088.0,5791.0,5039.0,5145.0,5459.0,5395.0,5997.0,5075.0,5587.0,5760.0,5561.0,5719.0,5108.0,5339.0,5321.0,5686.0,5213.0,5987.0,5228.0,5670.0,5594.0,5292.0,5909.0,5616.0,5978.0,5375.0,5504.0,5558.0,5840.0,5233.0,5947.0,5028.0,5592.0,5992.0,5020.0,5991.0,5953.0,5471.0,5243.0,5784.0,5472.0,5801.0,5652.0,5700.0,5183.0,5949.0,5809.0,5426.0,5130.0,5394.0,5919.0,5741.0,5134.0,5402.0,5801.0,5567.0,5478.0,5740.0,5563.0,5677.0,5346.0,5020.0,5243.0,5137.0,5787.0,5241.0,5351.0,5834.0,5630.0,5542.0,5238.0,5242.0,5312.0,5642.0,5424.0,5988.0,5796.0,5912.0,5599.0,5567.0,5832.0,5559.0,5760.0,5061.0,5629.0,5951.0,5095.0,5585.0,5602.0,5686.0,5562.0,5700.0,5267.0,5656.0,5757.0,5023.0,5498.0,5935.0,5650.0,5807.0,5345.0,5080.0,5919.0,5308.0,5316.0,5076.0,5154.0,5399.0,5537.0,5923.0,5968.0,5973.0,5528.0,5640.0,5097.0,5369.0,5374.0,5248.0,5955.0,5243.0,5949.0,5126.0,5659.0,5010.0,5473.0,5012.0,5536.0,5274.0,5115.0,5809.0,5212.0,5400.0,5550.0,5274.0,5931.0,5762.0,5343.0,5655.0,5434.0,5981.0,5844.0,5277.0,5823.0,5905.0,5741.0,5168.0,5057.0,5956.0,5841.0,5804.0,5421.0,5933.0,5667.0,5171.0,5083.0,5322.0,5410.0,5459.0,5092.0,5678.0,5401.0,5817.0,5526.0,5663.0,5753.0,5802.0,5289.0,5917.0,5020.0,5372.0,5993.0,5023.0,5773.0,5469.0,5681.0,5442.0,5736.0,5552.0,5678.0,5493.0,5758.0,5726.0,5713.0,5103.0,5201.0,5435.0,5583.0,5318.0,5501.0,5076.0,5004.0&chds=4000,7000

Now, was this easy?

Preparation/Implementation

First, the Groovy file which dispatches the request is as follows (must go to the groovy folder):

import java.net.URLConnection;

def labels = ["A", "B", "C", "D", "E"]
int ivalue = new Random().nextInt(5);

String link;
if (memcacheService.get(labels.get(ivalue)) == null) {
	def ts = new com.commons.gse.TestSheets();
	link = ts.getData(labels.get(ivalue)); 
	memcacheService.put(labels.get(ivalue), link)
} else {
	link = memcacheService.get(labels.get(ivalue))
}
request.setAttribute ('counter', com.commons.gse.TestSheets.counter++)
request.setAttribute ('appendix', link)
forward '/data.gtpl'

The interesting part is the usage of the predefined object memcacheService which makes it possible to just use Google App Engine’s memcache without having to deal with creation, exception handling, etc.
One of five (“A-E”) cached number series is used. If no cache for the character is found, the number is extracted from a speadsheet called data in Google Docs (see screenshots below).
After having calculated or retrieved the numerb series from the cache, the values (which is the complete link with the numbers included) are put into the ServletRequest (in this case the predefined object request). Finally, the request is dispatched to the view, a Groovy template (data.tgpl).

<html>
<head/>
<body>
  <span>counter:<%= request.getAttribute('counter') %></span>
  <form>
    <input type="button" value="Reload" onClick="window.location='/data.groovy'">
  </form>
  <img src='<%= request.getAttribute('appendix') %>'/>
</body>
</html>

A final note: if you want to use this from Github, you will have to change the Google authorization data in TestSheets.java (which is completely left out here, but is described here).

Here is the setup of the Google Docs spreadsheets:

namespreadsheet
randomnumbers

Running

If you have installed the SpringSource Tool Suite, you can just import the Eclipse project and choose “Run as…/Web Application”. The local server should be startet. Afterwards, you can call http://localhost:8080/data.groovy.

Note: Be sure to change the username/password combination in TestSheets.java

Posted in Gaelyk, Google App Engine, Google Spreadsheet API | 2 Comments »

Scala Mashup Series: Simple Factory, Factory Method and Abstract Factory

Posted by ice09 on September 15, 2009

Up to now, I identified three different kinds of factory patterns, which are similar to each other.

Simple, but powerful: The Simple Factory

The simple factory in Java is implemented as a static method, which returns a object of a certain type. This object can be newly created or a singleton (in contrast to object creation with constructors, which create new objects always).

Advantages [taken from Effective Java (2nd Edition)]

  1. Factory methods have names
  2. Constructors differ only by signature. With factory methods, the method itself can describe the kind of object created.

  3. Factory methods decide what kind of objects are created
  4. With factory methods, newly created objects can be returned as well as singletons.

  5. Factory methods can return objects of any subtype
  6. Depending on the submitted arguments, the method can decide to return subtypes of the return type (see example below).

  7. Verbosity of creating parameterized type instances is reduced
  8. Redundant specification of the form Map map = new HashMap() is not necessary with factory methods, since the compiler is able to infer the type by type inference.

Disadvantages:

  1. Factory methods do not favor inheritance
  2. Returned (non-public) types of factory methods cannot be subclasses (if they have no public or protected constructors).

  3. Factory methods cannot be identified as creational methods as easy as constructors
  4. This can be leveled by using conventions, eg. valueOf, getInstance, of depending on the context.

public class Factory {

    public static Item createItem( Object decideUpon ) {
        
        int itemType = figureOutItemType( decideUpon );

        switch( itemType ) {
            case Constants.Type1:
                return new Type1();
            case Constants.Type2:
                return new Type2();
            // etc.
        }
    }
}

And now in Scala:

object Factory {

  def createItem( decideUpon:String ):Item = decideUpon match {
    case "type1" => new Item1Type
    case "type2" => new Item2Type
    case _ => error("Unknown option.")	  
  }

}

The real Factory Method

The Factory Method is used to create several concrete objects of one abstract class.
In contrast to the Simple Factory described above, the factory itself is subclassed, therefore a concrete factory which creates concrete classes can be created depending on the context.

public abstract class Factory {

    public abstract Item createItem();

}
public class Item1Factory extends Factory {

    public Item createItem() {
        return new Type1();
    }

}
public class Item2Factory extends Factory {

    public Item createItem() {
        return new Type2();
    }

}

In Scala, the code is almost the same, is might just be simplyfied by the use of pattern matching (not equal to the Java version).

trait Factory {  
 
  def create( decideUpon:String ): Item
 
}
object Item1Factory extends Factory {
 
  def create(): Item = instanceType match {
    case "type1" => new Type1Item
    case _ => error("Unknown option.")	  
  }
 
}

Last, not least: Abstract Factory

In short, an Abstract Factory is used to create families of related objects.
The creation methods inside the Abstract Factories are usually implemented as Factory Methods.

Posted in Patterns | Comments Off on Scala Mashup Series: Simple Factory, Factory Method and Abstract Factory