maandag 11 augustus 2014

From String to calculation

Introduction:

After the marshalling drill I have been thinking about how can we do small changes in xml without marshalling. The only other option I could come up with is xpath queries combined with element value changes. For primitive type changes this is a good idea but what if someone needs some complex calculations with a value from the xml file. Even this can be done.

The solution:

What I could think of was some kind of calculation template in a String something


//The numbers to calculate.
        int number1 = 40;
        int number2 = 2;

//Creating the javascript engine
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");

//The calculation template can be more complex
        String calcuationTemplate = "%d * %d";
        calcuationTemplate = String.format(calcuationTemplate, number1,number2);
        try {
//The actual calculation
            System.out.println(engine.eval(calcuationTemplate));
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

The conclusion:

After some googling and trying I found that yet again this is pretty simple. With this I can do as much math I like in a very simple way. The only thing I still have to take care of is a difference between the numbers that have been given and the numbers that are retrieved from the xml file.

have fun!

vrijdag 8 augustus 2014

replace diacritic characters

Introduction:

We had a request to remove all the diacritic  from a String. As usual Java has a nice solution for this.

Solution:


String str = "ÚÝâ";

String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD);
Pattern pattern = Pattern .compile("\\p{InCombiningDiacriticalMarks}+");

System.out.println(pattern.matcher(nfdNormalizedString).replaceAll(""));

result: UYa

The Normalizer class according to the javadoc:

 This class provides the method normalize which transforms Unicode
 text into an equivalent composed or decomposed form, allowing for easier
 sorting and searching of text.


Normalizer.Form.NFD
This is an Enum that tells the Normalizer class what kind of normalisation you want there are:

     /**
         * Canonical decomposition.
         */
        NFD,

        /**
         * Canonical decomposition, followed by canonical composition.
         */
        NFC,

        /**
         * Compatibility decomposition.
         */
        NFKD,

        /**
         * Compatibility decomposition, followed by canonical composition.
         */
        NFKC

The NFD variant decomposes the Ú in U and ' this makes it possible to do a regular expression like 
Pattern pattern = Pattern .compile("\\p{InCombiningDiacriticalMarks}+");

At last but not least the question we had was: what in heavens name is \\p{InCombiningDiacriticalMarks}
This answer we found at stackoverflow:

\p{InCombiningDiacriticalMarks} is a Unicode block property. In JDK7, you will be able to write it using the two-part notation \p{Block=CombiningDiacriticalMarks}, which may be clearer to the reader. It is documented here in UAX#44: “The Unicode Character Database”.

Conclusion:

The code we build today is just a tip of the iceberg. The functionality that the Normalizer can bring is much more. I hope in the future I can do some other stuff with this.

Have fun! 

dinsdag 5 augustus 2014

open closed Marshalling with Jaxb



Introduction

One of the things we had to tackle this week was some marshalling issue with a zillion small xml files. The feast of legacy. It was a very depressing thought to create separate marshalling objects for each of them. That Idea popped faster out of my head then in. After some thinking we came up with a component that could do all of the xml files

The solution

The idea I came up with is very simple it is base on Jaxb marshalling which is quit powerfull in the way that the code you need to write is very small. Also the speed of marshalling and unmarshalling is quit fast.

To get this to work you need the following dependencies:

<dependencies>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.1</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.1</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.14.4</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
    </dependency>
   //This one you only need when you want to use xpath queries
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.5.0</version>
    </dependency>
</dependencies>


The one and only class for marshalling and unmarshalling:

package nl.lostlemon.Marshal;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

//The Type is to make it possible to instanciate this class with different marshalling beans.
public class Marshalling<T> {

    // Notice that T is the return typed bean. The xm is an inputStream. Jaxb can deal with that. It improves       performance 
    public T unMarshall(final InputStream xmlStream, final Class clazz) {
        T value = null;
        try {
//create an unmarshaller
            Unmarshaller unmarshal = JAXBContext.newInstance(clazz).createUnmarshaller();
//read the xml input stream into Jaxb
            XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(xmlStream);
//marshall the xml file into a JavaBean
            value = (T)unmarshal.unmarshal(reader, clazz).getValue();
        } catch (JAXBException e) {
            e.printStackTrace();
        } catch (XMLStreamException e) {
            e.printStackTrace();
        }

        return value;
    }
//Notice that the parameter is also The T of type.
    public ByteArrayOutputStream marshal(final T type) {
//Create the return type for this method.
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
//Create a marshaller
            Marshaller marshaller = JAXBContext.newInstance(type.getClass()).createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//Create the xml in the form of an outputstream to boost performance
            marshaller.marshal(type, outputStream);
        } catch (PropertyException e1) {
            e1.printStackTrace();
        } catch (JAXBException e1) {
            e1.printStackTrace();
        }
        return  outputStream;
    }
}

Running the following tests:

//This test uses the BookBean with an xml containing a single book.
    @Test
    public void testUnmarshallingXpath() {
        InputStream inputStream = this.getClass().getResourceAsStream("testSingle.xml");
        Marshalling<SingleBookBean> marshalling = new Marshalling<SingleBookBean>();
        SingleBookBean bookBean = marshalling.unMarshall(inputStream,SingleBookBean.class);
        Assert.assertTrue(bookBean.getTitle() != null);
    }

// The BookBean the @Getter and @Setter is from Lombok.
// Take care of the 
@XmlRootElement(name = "book")
@XmlAccessorType(XmlAccessType.FIELD) These are the identifiers to tell JaxB what to do. The XmlRootElement refers to the xml rootelement in the xml file.

@Getter
@Setter
@XmlRootElement(name = "book")
@XmlAccessorType(XmlAccessType.FIELD)
public class BookBean {
  // These are the exact same names as the xml Elements
    private String author;
    private String title;
}

//The single xml file:
<book>
    <title>witches abroad</title>
    <author>Terry Pratchet</author>
</book>

//This test is using the books bean with an xml containing multiple books.
    @Test
    public void testUnmarshallingList() {
        long start = Calendar.getInstance().getTimeInMillis();
        InputStream inputStream = this.getClass().getResourceAsStream("test.xml");
        Marshalling<Books> marshalling = new Marshalling();
        Books books = marshalling.unMarshall(inputStream,Books.class);
        //Assert.assertTrue(books.getBookBeans().size() == 3);
        long stop = Calendar.getInstance().getTimeInMillis();
        long elapsedTime = (stop-start);
        System.out.println("number of elements " + books.getBookBeans().size() + " elapsed time " + elapsedTime + " ms");

    }

// The Books bean based on the same principle as the BookBean.
@XmlRootElement(name = "catalog")
@XmlAccessorType(XmlAccessType.FIELD)
public class Books {

    @Getter
    @Setter
    @XmlElement(name = "book", type = BookBean.class)
    private List<BookBean> bookBeans;
}

//the multiple books xml file:
<catalog>
    <book id="bk101">
        <author>Gambardella, Matthew</author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
        <description>An in-depth look at creating applications
            with XML.</description>
    </book>
    <book id="bk102">
        <author>Ralls, Kim</author>
        <title>Midnight Rain</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-12-16</publish_date>
        <description>A former architect battles corporate zombies,
            an evil sorceress, and her own childhood to become queen
            of the world.</description>
    </book>
    <book id="bk103">
        <author>Corets, Eva</author>
        <title>Maeve Ascendant</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-11-17</publish_date>
        <description>After the collapse of a nanotechnology
            society in England, the young survivors lay the
            foundation for a new society.</description>

    </book>
</catalog>

//The marshalling test with the books bean:

    @Test
    public void testMarshallingList() {
        Books books = new Books();
        List<BookBean> bookBeans = new ArrayList<BookBean>();
        for(int i=0;i<100000;i++) {
            BookBean bookBean = new BookBean();
            bookBean.setAuthor("J.R.R Tolkien");
            bookBean.setTitle("The hobbit");
            bookBeans.add(bookBean);
        }
        books.setBookBeans(bookBeans);
        long start = Calendar.getInstance().getTimeInMillis();
        Marshalling<Books> marshalling = new Marshalling<Books>();
}

// The marshalling test with the BookBean.
   @Test
    public void testMarshalling() {
        BookBean bookBean = new BookBean();
        bookBean.setAuthor("Terry Pratchet");
        bookBean.setTitle("Witches abroad");
        Marshalling<BookBean> marshalling = new Marshalling<BookBean>();
        String xml = marshalling.marshal(bookBean).toString();
    }

Conclusion: 

Using Java typing in combination with a usefull library in the open closed principal, saves you a lot of code writing and maintainance. I had real pleassure to write in such a small piece of code so much power. 

Have fun!