A few Java snippets I keep reinventing

I write them here so that I’ll have a place to find them again.

How to convert a String into an InputStream:

new ByteArrayInputStream(input.getBytes())

How to capture in a String an OutputStream

OutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
ps.println("bla bla");
...
String out = ps.toString();

How to find the temporary directory

protected String getTempDir() throws Exception {
    if (null == tempDir) {
        File temp = File.createTempFile("aaa", "b");
        temp.deleteOnExit();
        tempDir = temp.getParent();
    }
    return tempDir;
}

How to provide a simple Log4j configuration for tests

@BeforeClass 
public static void configureLogging() {
    System.setProperty("log4j.defaultInitOverride", "true");
    Properties p = new Properties();
    p.setProperty("log4j.appender.stdout", "org.apache.log4j.ConsoleAppender");
    p.setProperty("log4j.appender.stdout.Target", "System.out");
    p.setProperty("log4j.appender.stdout.layout", "org.apache.log4j.PatternLayout");
    p.setProperty("log4j.appender.stdout.layout.ConversionPattern", "%5p %c{1}:%L - %m%n");
    p.setProperty("log4j.rootLogger", "INFO, stdout");
    PropertyConfigurator.configure(p);
}

How to parse an XML document and find nodes with XPath. And test a StringTemplate template!

import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.antlr.stringtemplate.StringTemplate;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class XpathTest {

    @Test
    public void testXpath() throws Exception {
        Document doc = documentFromString("<a><b><c>foo</c></b></a>");
        assertEquals(0, getNodeList(doc, "//foo").getLength());
        assertEquals(1, getNodeList(doc, "//c").getLength());
        assertEquals("foo", getNodeContent(doc, "/a/b/c"));
    }

    private String getNodeContent(Document doc, String xpath) throws XPathExpressionException {
        NodeList nodes = getNodeList(doc, xpath);
        assertEquals("expected exactly 1 node at xpath " + xpath, 1, nodes.getLength());
        return nodes.item(0).getTextContent();
    }

    private NodeList getNodeList(Document doc, String xpath) throws XPathExpressionException {
        // see http://www.ibm.com/developerworks/library/x-javaxpathapi.html
        XPathFactory factory = XPathFactory.newInstance();
        XPath xp = factory.newXPath();
        return (NodeList) xp.evaluate(xpath, doc, XPathConstants.NODESET);
    }

    private Document documentFromString(String string) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(false);
        factory.setNamespaceAware(true);
        return factory.newDocumentBuilder().parse(new ByteArrayInputStream(string.getBytes()));
    }

    @Test
    public void testTemplate() throws Exception {
        StringTemplate template = new StringTemplate("Hello, $name$!");
        template.setAttribute("name", "world");
        assertEquals("Hello, world!", template.toString());
    }
}  

How to easily create, parse and format a date.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

public class DateUtil {
	private static final Locale LOCALE = Locale.ITALY;
	private static final String FORMAT_STRING = "dd MMMM yyyy";

	public static Date create(int year, int month, int day, int hours, int minutes, int seconds) {
		return new GregorianCalendar(year, month-1, day, hours, minutes, seconds).getTime();
	}

	public static Date parse(String s) throws ParseException {
		return format().parse(s);
	}

	public String toFormattedString(Date date) {
		return format().format(date);
	}

	private static SimpleDateFormat format() {
                // update: (thanks Mirko!)
		// can't use a static instance as SimpleDateFormat is not thread-safe
		return new SimpleDateFormat(FORMAT_STRING, LOCALE);
	}
}

A simple but workable servlet web.xml configuration file.

<?xml version = '1.0' encoding = 'utf-8'?>
<web-app>
   <description>Sample Simple Web App</description>

   <servlet>
      <servlet-name>helloworld</servlet-name>
      <servlet-class>essap.sample.helloworld.HelloWorldServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>helloworld</servlet-name>
      <url-pattern>/hello</url-pattern>
   </servlet-mapping>
</web-app>  

And finally, a simple but complete Ant build.xml for a web application.

<?xml version="1.0"?>
<project name="my-project" default="compile" basedir=".">

    <property name="build.dir"      location="target" />
    <property name="build.prod.dir" location="${build.dir}/prod"/>
    <property name="build.test.dir" location="${build.dir}/test"/>
    <property name="src.dir"        location="src"/>
    <property name="test.dir"       location="unit"/>
    <property name="test.lib.dir"   location="lib/test" />
    <property name="war.file"       location="${build.dir}/my-project.war"/>
    <property name="conf.dir"       location="conf/development" />

    <path id="project.classpath">
        <pathelement location="${build.prod.dir}" />
        <pathelement location="${build.test.dir}" />
        <fileset dir="${test.lib.dir}">
            <include name="*.jar"/>
        </fileset>
    </path>

    <target name="prepare">
        <mkdir dir="${build.prod.dir}"/>
        <mkdir dir="${build.test.dir}"/>
    </target>

    <target name="compile" depends="prepare">
        <javac source="1.5" target="1.5" destdir="${build.prod.dir}" debug="true" encoding="utf-8">
            <src path="${src.dir}" />
            <classpath refid="project.classpath" />
        </javac>
    </target>

    <target name="compile-tests" depends="compile">
        <javac source="1.5" target="1.5" destdir="${build.test.dir}" encoding="utf-8">
            <src path="${test.dir}" />
            <classpath refid="project.classpath" />
        </javac>
    </target>

    <target name="test" depends="compile-tests">
        <junit haltonfailure="true" haltonerror="true" 
      outputtoformatters="yes" fork="yes" forkmode="perBatch" maxmemory="256m" dir="${basedir}">
            <classpath refid="project.classpath" />
            <classpath location="${src.dir}" />
            <classpath location="${test.dir}" />
            <formatter type="brief" usefile="no" />
            <batchtest>
                <fileset dir="${build.test.dir}" includes="**/*Test.class" />
            </batchtest>
        </junit>
    </target>

    <target name="clean">
        <delete dir="${build.dir}" />
    </target>

    <target name="war" depends="compile">
        <war destfile="${war.file}" webxml="${conf.dir}/web.xml">
            <classes dir="${build.prod.dir}" />
            <classes dir="${src.dir}" includes="**/*.html" />
            <classes dir="${src.dir}" includes="**/*.properties" />
            <classes dir="${src.dir}" includes="**/config.yml" />
            <fileset dir="web" />
            <classes dir="${conf.dir}" includes="log4j.*" />
        </war>
    </target>  
</project>

6 Responses to “A few Java snippets I keep reinventing”

  1. fabiobeta Says:

    Matteo…grazie!!!

  2. matteo Says:

    You’re welcome! Some of this stuff is from the old Milano-XPUG projects…

  3. riffraff Says:

    interesting, I used items #1 and #2 yesterday and #5 is already in the codebase, albeit I prefer to transform the NodeList into a List :)

  4. Mirko Says:

    Only a little thing:
    SimpleDateFormat is not thread-safe, so need to be instantiated every time.

  5. matteo Says:

    Mirko: you’re right. I corrected the error. Although a better fix would be to use Joda Time (http://joda-time.sourceforge.net/)!

  6. matteo Says:

    How to transform a SOAP response from XML to Java object:

    protected <T> T unmarshal(Class<T> klass, String fileName) throws JAXBException
    {
        JAXBContext context = JAXBContext.newInstance(klass.getPackage().getName());
        Unmarshaller unmarshaller = context.createUnmarshaller();
        InputStream stream = this.getClass().getResourceAsStream(fileName);
        JAXBElement jaxbElement = (JAXBElement) unmarshaller.unmarshal(stream);
        return (T) jaxbElement.getValue();
    }
    

    How to do the reverse:

    // See http://stackoverflow.com/questions/2472155/i-want-to-convert-an-output-stream-into-string-object
    public <T> String marshal(Class <T> klass, T object) throws JAXBException
    {
      StringWriter writer = new StringWriter();
      JAXBContext context = JAXBContext.newInstance(klass);
      Marshaller marshaller = context.createMarshaller();
      marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      JAXBElement jaxbElement = new JAXBElement<T>(new QName("","rootTag"), klass, object);
      marshaller.marshal(jaxbElement, writer);
      return writer.toString();
    }
    

Leave a Reply