niedziela, 13 stycznia 2013

Google guava presentation and guide to writing testable code

Below you can find very interesting links. One to google's guide to writing testable code. It can be treated as a nice checklist helping to keep code clean. Another, sent to me by a friend of mine, to a very nice project and presentation helping to learn guava

sobota, 12 stycznia 2013

XSLT Identity Transformation Overriding pattern and xsltproc - easy xml files manipulation (unix only)

Recently I faced the problem where I had to modify bunch of XML files scattered all over the file system. The modification was very small - move value of one XML tag into another, and remove the original tag.

The problem itself seems very simple, so writing a piece of software for that seems to be like killing a sparow with a bazooka.

Here is what I came up with

XSLT Identity Transformation Overriding pattern

Because our modification is very small, and we want to preserve most of our original document structure, we should start with XSLT Identity Transformation which looks like following

 
 
  
   
  
 

Now let's say, that we want to add another fridge to our kitchen in the following xml document, but only if the house is locked (house/isLocked element is set to true)

<house>
 <isLocked>true</isLocked>
 <kitchen>
  <cupboard>
   <capacity>8</capacity>
  </cupboard>
  <fridge>
   <boughtOn>2013-01-10T20:45:45.033+01:00</boughtOn>
   <innerTemperature>-4</innerTemperature>
  </fridge>
  <isLocked>true</isLocked>
 </kitchen>
 <livingRoom>
  <isLocked>true</isLocked>
 </livingRoom>
</house>

We can modify (override) our XLST Identity Transformation in following way:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <!--  Identity transform -->
 <xsl:template match="@*|node()">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
 </xsl:template>

 <!-- add a node fridge into our kitchen -->
 <xsl:template match="kitchen">
  <xsl:copy>
   <xsl:apply-templates/>
   <!-- only if house is locked -->
   <xsl:if test="/house/isLocked = 'true'">
   <fridge>
    <boughtOn>2013-01-10T20:45:45.033+01:00</boughtOn>
    <innerTemperature>-10</innerTemperature>
   </fridge>
   <!-- add new line -->
   <xsl:text>
   </xsl:text>
   </xsl:if>
  </xsl:copy>
 </xsl:template>    
 <!-- "unlock" the house (remove isLocked element) -->
 <xsl:template match="/house/isLocked">
 </xsl:template>
</xsl:stylesheet>

You can quickly see the result of transformation using xsltproc, which is a little unix commandline program for performing xslt transformations.

xsltproc newFridge.xslt kitchen.xml > kitchen.xml.out

Now, if you want to apply the same tranformation to a bunch of files selected from system with, say, find method, you can perform following

for f in `find -name "house*.xml"` ; do xsltproc xslt/newFridge.xslt "$f" > "$f.out"; done

If you don't care for the *.out files, you can always add mv so it will look like transformation was performed on on the original files:

for f in `find -name "house*.xml"` ; do xsltproc xslt/newFridge.xslt "$f" > "$f.out" ; mv "$f.out" "$f" ; done

These altoghether will give you a very easy, yet powerful, tool for mass xml manipulation. I run all of these commands on cygwin

czwartek, 10 stycznia 2013

JAXB - unmarshalling nested element

To fully benefit from this post I suggest visiting following tutorial on XSD and namespaces, and this one describing what is a globally declared element in XSD and why some of them get @XmlRootElement annotation and others have ObjectFactory with method annotated with @XmlElementDecl. The general rule is that if we have globally declared element (not type, element) which contains:
  1. Inline type declaration (anonymous type, as in case of kitchen element from rooms.xsd), it will be annotated with @XmlRootElement
  2. Reference to named type declaration (like houseObject element in houses.xsd), it will have corresponding ObjectFactory with createXXX method annotaded with @XmlElementDecl
As an intro to this post, let's create some xsd files on which we will work: house.xsd
<xs:schema xmlns:house="http://houses.service.jaxb.mpasinski/"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:rooms="http://rooms.houses.service.jaxb.mpasinski/"
           version="1.0"
           targetNamespace="http://houses.service.jaxb.mpasinski/">
    <xs:import namespace="http://rooms.houses.service.jaxb.mpasinski/" schemaLocation="rooms.xsd"/>

    <!-- globally defined element with named type -->
    <!-- it will result in XmlElementDecl annotation in ObjectFactory -->
    <xs:element name="houseObject" type="house:house"/>

    <!--globally defined elements with anonymous type (inline definition)-->
    <!--it will result in XmlElementRoot annotation to be added to generated class-->
    <xs:element name="houseRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="house:houseObject"/>
                <xs:element name="requestDateTime" type="xs:dateTime"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="houseLockedRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="house:houseObject"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="isHouseLockedResponse" type="xs:boolean"></xs:element>

    <!-- Type definition -->
    <xs:complexType name="house">
        <xs:sequence>
            <xs:element name="isLocked" type="xs:boolean" minOccurs="0"/>
            <xs:element ref="rooms:kitchen" minOccurs="0"/>
            <xs:element name="livingRoom" type="rooms:livingRoom" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
rooms.xsd
<xs:schema
        xmlns:furniture="http://furniture.service.jaxb.mpasinski/"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        version="1.0"
        targetNamespace="http://rooms.houses.service.jaxb.mpasinski/">
    <xs:import namespace="http://furniture.service.jaxb.mpasinski/" schemaLocation="furniture.xsd"/>

    <!--below is the globally defined element with anonymous type-->
    <!--jaxb will add XmlRoot annotation to the class-->

    <xs:element name="kitchen">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="cupboard" type="furniture:cupboard" minOccurs="0"/>
                <xs:element name="fridge" type="furniture:fridge" minOccurs="0"/>
                <xs:element name="isLocked" type="xs:boolean" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <!--type declaration-->
    <xs:complexType name="livingRoom">
        <xs:sequence>
            <xs:element name="isLocked" type="xs:boolean" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
furniture.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           version="1.0"
           targetNamespace="http://furniture.service.jaxb.mpasinski/"
           elementFormDefault="qualified">

    <!--contains only type declarations, no globally defined elements-->
    <xs:complexType name="cupboard">
        <xs:sequence>
            <xs:element name="capacity" type="xs:int" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="fridge">
        <xs:sequence>
            <xs:element name="boughtOn" type="xs:dateTime" minOccurs="0"/>
            <xs:element name="innerTemperature" type="xs:int" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
Now, let's say we received an xml request document with following format:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<houses:houseRequest xmlns:furniture="http://furniture.service.jaxb.mpasinski/" xmlns:houses="http://houses.service.jaxb.mpasinski/" xmlns:rooms="http://rooms.houses.service.jaxb.mpasinski/">
    <houses:houseObject>
        <isLocked>true</isLocked>
        <rooms:kitchen>
            <cupboard>
                <furniture:capacity>8</furniture:capacity>
            </cupboard>
            <fridge>
                <furniture:boughtOn>2013-01-10T20:45:45.033+01:00</furniture:boughtOn>
                <furniture:innerTemperature>-4</furniture:innerTemperature>
            </fridge>
            <isLocked>true</isLocked>
        </rooms:kitchen>
        <livingRoom>
            <isLocked>true</isLocked>
        </livingRoom>
    </houses:houseObject>
    <requestDateTime>2013-01-10T20:45:45.037+01:00</requestDateTime>
</houses:houseRequest>

We do not care for the for the whole request, but only for kitchen object. Our first attempt to get to the element might be like that:

        String houseRequest = TestUtils.readClasspathFile("houseRequest.xml");

        JAXBContext jaxbContext = JaxbUtils.getJAXBContext(Kitchen.class);
        JAXBElement<Kitchen> result = jaxbContext.createUnmarshaller().unmarshal(new StreamSource(new ByteArrayInputStream(houseRequest.getBytes())), Kitchen.class);
        Kitchen unmarshalledKitchen =  result.getValue();
But after inspecting the retreived kitchen object we find out that both cupboard and fridge are null:
Kitchen@5749b290[cupboard=<null>,fridge=<null>,isLocked=true]

The reason for that is simple. XML does not convey information about type, so JAXB does not know it should start searching for the kitchen element starting from kitchen tag. For the same reason, isLocked in our unmarshalled kitchen is set properly - JAXB found element isLocked (as it expected for kitchen object) and it does not care it that it belongs to houseObject (so different Java type). The reason why our unmarshalling faild becomes even more obvious when we look at result object (of JAXBElement type)

javax.xml.bind.JAXBElement@276a38b5[name={http://houses.service.jaxb.mpasinski/}houseRequest,
declaredType=class mpasinski.jaxb.service.houses.rooms.Kitchen,
scope=class javax.xml.bind.JAXBElement$GlobalScope,
value=mpasinski.jaxb.service.houses.rooms.Kitchen@6765f738,
nil=false]

Unmarshalling nested element with StAX and XMLReader

First we need to tell JAXB where to start unmarshalling our object:

String houseRequest = TestUtils.readClasspathFile("houseRequest.xml");
String nodeName = "kitchen";
Kitchen unmarshalledKitchen = null;

//create XMLStreamReader (StAX)
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xmlReader = xif.createXMLStreamReader(new StringReader(houseRequest));

int event = 0;
//here we advance to next tag untill we find node called "kitchen"
for (event = xmlReader.next(); event != XMLStreamReader.END_DOCUMENT; event = xmlReader.next()) {
    if (event == XMLStreamReader.START_ELEMENT) {
        if (xmlReader.getLocalName() == nodeName) {
            break;
        }
    }
}

Now all we need to do is just unmarshalling

        if (event != XMLStreamReader.END_DOCUMENT) {
            JAXBContext jaxbContext = JaxbUtils.getJAXBContext(Kitchen.class);
            JAXBElement<Kitchen> result = jaxbContext.createUnmarshaller().unmarshal(xmlReader, Kitchen.class);
            unmarshalledKitchen = result.getValue();
        }

If we analyze our unmarshalled object now, we get following form:

mpasinski.jaxb.service.houses.rooms.Kitchen@4b00ebec
 [cupboard=mpasinski.jaxb.service.furniture.Cupboard@2980f96c,
  fridge=mpasinski.jaxb.service.furniture.Fridge@527736bd,
  isLocked=true]
//cupboard
mpasinski.jaxb.service.furniture.Cupboard@2980f96c[capacity=8]
//fridge
mpasinski.jaxb.service.furniture.Fridge@527736bd
 [boughtOn=java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT+01:00",offset=3600000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2013,MONTH=0,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=10,DAY_OF_YEAR=1,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=20,MINUTE=45,SECOND=45,MILLISECOND=33,ZONE_OFFSET=3600000,DST_OFFSET=0],
  innerTemperature=-4]

On my github repo you can find JaxbUtils class which has method doUnmsarshallNestedElement being refactored version of the code above. You can find there also the complete code used in this post.

Of course the definite flaw of this method is that it will try to unmarshall first element with specified name. A better way to perform unmarshalling nested element may be to use EclipseLink MOXy jaxb implementation and the @XmlPath extension. However, there are times where you cannot change the jaxb implementation or you cannot alter generated classes (therefore you cannot add @XmlPath annotation)

wtorek, 8 stycznia 2013

Using guava cache to avoid expensive JAXBContext recreation

Creating JAXBContext is very expensive, especially when many classes are "known" to this context (just as a side note, a class is known to JAXBContext when it is in the package which name was passed to newInstance method or in the same package as class passed to newInstance method). Using guava's cache can be a very nice way of acheiving JAXBContext caching

private static final LoadingCache<String, JAXBContext> jaxbContextsCache = CacheBuilder.newBuilder()
            .build(
                    new CacheLoader<String, JAXBContext>() {
                        @Override
                        public JAXBContext load(String packageName) throws Exception {
                            return JAXBContext.newInstance(packageName);
                        }
                    }
            );

    public static JAXBContext getJAXBContext(Class clazz) {
        String packageName = clazz.getPackage().getName();
        try {
            return jaxbContextsCache.get(packageName);
        } catch (ExecutionException e) {
            throw new JaxbUtilsException("Error when getting JAXBContext from cache", e);
        }
    }

It is worth noting, that JAXBContext is thread safe, but Marshaller and Unmarshaller objects are not (at least by JAXB specification contract) and therefore should not be shared. You can implement some pooling if you need critical performance. This article explains marshaller/unmarshaller pooling and shows example code

Source code related to this post can be found on my git repository

More granural exceptions testing with JUnit 4 and ExpectedException

It took me quite long time to finally get myself together and write my first post. To be honest, I was inspired by a friend I work together on a project who started blogging some time ago. You can find his blog here

I decided to blog on something simple yet useful first, before I start a series of articles related to JAXB

When I moved from JUnit 3 to JUnit 4 it hit me how elegant it is to verify whether exceptions get thrown from your code. The expected argument of @Test annotation is just so nice, but it allows you only to test whether an exception of desired class has been thrown. But what if you require more granual control?

ExpectedException to the rescue!!!.

On the Expected exception you can setup simple expectations (like when using mocks) and JUnit framework will verify them automatically

    private static final String EXCEPTION_MESSAGE = "Test exception message";

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void testNullPointerExceptionSimpleMessageCheck() {
        thrown.expect(NullPointerException.class);
        thrown.expectMessage(EXCEPTION_MESSAGE);

        throw new NullPointerException(EXCEPTION_MESSAGE);
    }

What is really cool, is that you can pass Hamcrest matcher to the expect method, which gives you absolute control on how you would like to verify, whether proper exception has been thrown

    @Test
    public void testExceptionWithHamcrestMatcher() {
        thrown.expect(isNullPointerWithTestExceptionMessage());

        throw new NullPointerException(EXCEPTION_MESSAGE);
    }

    private static Matcher<Throwable> isNullPointerWithTestExceptionMessage() {
        return new BaseMatcher<Throwable>() {
            @Override
            public boolean matches(Object o) {
                if (o instanceof NullPointerException) {
                    NullPointerException npe = (NullPointerException) o;
                    return EXCEPTION_MESSAGE.equals(npe.getMessage());
                }
                return false;
            }

            @Override
            public void describeTo(Description description) {
            }
        };
    }

You can find full sourcecode on my git repository

Just a small update. A friend of mine, sent me this link about catch-exception library. The definite advantage of this solution is that, apart from verifying whether appropriate exception has been thrown, you can add, say, verification of some of your mocks. You can for instance verify, that because of an exception being thrown, no other method in the flow has been called.