Monday, May 27, 2013

JEEConf - Kiev, 2013 - Report

The third JEEConf was superb. It was well organized, with friendly atmosphere and high-quality speakers. And I had a dilemma what topics/speaker I should visit. :-) 

So, I've selected the next speakers:
Unfortunately, there were other topics which went in parallel. Now, I'm waiting on video from organizer.

On the photo from left to right: 3) Venkat Subramaniam, 4) Mohamed Taman 5) me, 6) Jacek Laskowsk, 7) Reza Rahma and 8)Anton Keks.



See:
JEEConf - Kiev, 2012 - Report
JEEConf - Kiev, 2011 - Report

Thursday, May 23, 2013

Graphics Unit Conversion

Working with PDF files and with scanned images it always required to convert from point to millimeter, or from millimeter to pixel, and so on.

There is very interesting quote from iText in Action book:
What is the measurement unit in PDF documents? Most of the measurements in PDFs are expressed in user space units. ISO-32000-1 (section 8.3.2.3) tells us “the  default  for  the  size  of  the  unit  in  default  user  space  (1/72  inch)  is approximately  the  same  as  a  point  (pt),  a  unit  widely  used  in  the  printing industry. It is not exactly the same; there is no universal definition of a point.” In short, 1 in. = 25.4 mm = 72 user units (which roughly corresponds to 72 pt).

Of course,  you can easily write these utilities by yourself. But, sometimes it makes sense to look around in your project, maybe you've already had all required utils.

So, here are code snippets from several libraries

1. Barcode4j

package org.krysalis.barcode4j.tools;

/**
 * Utility class for unit conversions.
 * 
 * @author Jeremias Maerki
 * @version $Id: UnitConv.java,v 1.2 2004/09/04 20:25:56 jmaerki Exp $
 */
public class UnitConv {

    /**
     * Utility class: Constructor prevents instantiating when subclassed.
     */
    protected UnitConv() {
        throw new UnsupportedOperationException();
    }
    
    /**
     * Converts millimeters (mm) to points (pt)
     * @param mm the value in mm
     * @return the value in pt
     */
    public static double mm2pt(double mm) {
        return mm * 2.835;
    }

    /**
     * Converts points (pt) to millimeters (mm)
     * @param pt the value in pt
     * @return the value in mm
     */
    public static double pt2mm(double pt) {
        return pt / 2.835;
    }
    
    /**
     * Converts millimeters (mm) to inches (in)
     * @param mm the value in mm
     * @return the value in inches
     */
    public static double mm2in(double mm) {
        return mm / 25.4;
    }
    
    /**
     * Converts inches (in) to millimeters (mm)
     * @param in the value in inches
     * @return the value in mm
     */
    public static double in2mm(double in) {
        return in * 25.4;
    }
    
    /**
     * Converts millimeters (mm) to pixels (px)
     * @param mm the value in mm
     * @param resolution the resolution in dpi (dots per inch)
     * @return the value in pixels
     */
    public static int mm2px(double mm, int resolution) {
        return (int)Math.round(mm2in(mm) * resolution);
    }
}
2. iText v.4.2
package com.lowagie.text;

/**
 * A collection of convenience methods that were present in many different iText
 * classes.
 */

public class Utilities {

...
 
 /**
  * Measurement conversion from millimeters to points.
  * @param value a value in millimeters
  * @return a value in points
  * @since 2.1.2
  */
 public static final float millimetersToPoints(float value) {
     return inchesToPoints(millimetersToInches(value));
 }

 /**
  * Measurement conversion from millimeters to inches.
  * @param value a value in millimeters
  * @return a value in inches
  * @since 2.1.2
  */
 public static final float millimetersToInches(float value) {
     return value / 25.4f;
 }

 /**
  * Measurement conversion from points to millimeters.
  * @param value a value in points
  * @return a value in millimeters
  * @since 2.1.2
  */
 public static final float pointsToMillimeters(float value) {
     return inchesToMillimeters(pointsToInches(value));
 }

 /**
  * Measurement conversion from points to inches.
  * @param value a value in points
  * @return a value in inches
  * @since 2.1.2
  */
 public static final float pointsToInches(float value) {
     return value / 72f;
 }

 /**
  * Measurement conversion from inches to millimeters.
  * @param value a value in inches
  * @return a value in millimeters
  * @since 2.1.2
  */
 public static final float inchesToMillimeters(float value) {
     return value * 25.4f;
 }

 /**
  * Measurement conversion from inches to points.
  * @param value a value in inches
  * @return a value in points
  * @since 2.1.2
  */
 public static final float inchesToPoints(float value) {
     return value * 72f;
 }
    ...
}
3. FOP
package org.apache.fop.util;

import java.awt.geom.AffineTransform;

/**
 * Utility class for unit conversions.
 * @deprecated use org.apache.xmlgraphics.util.UnitConv instead.
 */
public final class UnitConv {

    /**
     * conversion factory from millimeters to inches.
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.IN2MM instead.
     */
    public static final float IN2MM = org.apache.xmlgraphics.util.UnitConv.IN2MM;

    /**
     * conversion factory from centimeters to inches.
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.IN2CM instead.
     */
    public static final float IN2CM = org.apache.xmlgraphics.util.UnitConv.IN2CM;

    /**
     * conversion factory from inches to points.
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.IN2PT instead.
     */
    public static final int IN2PT = org.apache.xmlgraphics.util.UnitConv.IN2PT;

    /**
     * Converts millimeters (mm) to points (pt)
     * @param mm the value in mm
     * @return the value in pt
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.mm2pt(mm) instead.
     */
    public static double mm2pt(double mm) {
        return org.apache.xmlgraphics.util.UnitConv.mm2pt(mm);
    }

    /**
     * Converts millimeters (mm) to millipoints (mpt)
     * @param mm the value in mm
     * @return the value in mpt
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.mm2mpt(mm) instead.
     */
    public static double mm2mpt(double mm) {
        return org.apache.xmlgraphics.util.UnitConv.mm2mpt(mm);
    }

    /**
     * Converts points (pt) to millimeters (mm)
     * @param pt the value in pt
     * @return the value in mm
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.pt2mm(pt) instead.
     */
    public static double pt2mm(double pt) {
        return org.apache.xmlgraphics.util.UnitConv.pt2mm(pt);
    }

    /**
     * Converts millimeters (mm) to inches (in)
     * @param mm the value in mm
     * @return the value in inches
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.pt2mm(pt) instead.
     */
    public static double mm2in(double mm) {
        return org.apache.xmlgraphics.util.UnitConv.mm2in(mm);
    }

    /**
     * Converts inches (in) to millimeters (mm)
     * @param in the value in inches
     * @return the value in mm
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.in2mm(in) instead.
     */
    public static double in2mm(double in) {
        return org.apache.xmlgraphics.util.UnitConv.in2mm(in);
    }

    /**
     * Converts inches (in) to millipoints (mpt)
     * @param in the value in inches
     * @return the value in mpt
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.in2mpt(in) instead.
     */
    public static double in2mpt(double in) {
        return org.apache.xmlgraphics.util.UnitConv.in2mpt(in);
    }

    /**
     * Converts inches (in) to points (pt)
     * @param in the value in inches
     * @return the value in pt
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.in2pt(in) instead.
     */
    public static double in2pt(double in) {
        return org.apache.xmlgraphics.util.UnitConv.in2pt(in);
    }

    /**
     * Converts millipoints (mpt) to inches (in)
     * @param mpt the value in mpt
     * @return the value in inches
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.mpt2in(mpt) instead.
     */
    public static double mpt2in(double mpt) {
        return org.apache.xmlgraphics.util.UnitConv.mpt2in(mpt);
    }

    /**
     * Converts millimeters (mm) to pixels (px)
     * @param mm the value in mm
     * @param resolution the resolution in dpi (dots per inch)
     * @return the value in pixels
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.mm2px(mm, resolution) instead.
     */
    public static double mm2px(double mm, int resolution) {
        return org.apache.xmlgraphics.util.UnitConv.mm2px(mm, resolution);
    }

    /**
     * Converts millipoints (mpt) to pixels (px)
     * @param mpt the value in mpt
     * @param resolution the resolution in dpi (dots per inch)
     * @return the value in pixels
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.mpt2px(mpt, resolution) instead.
     */
    public static double mpt2px(double mpt, int resolution) {
        return org.apache.xmlgraphics.util.UnitConv.mpt2px(mpt, resolution);
    }

    /**
     * Converts a millipoint-based transformation matrix to points.
     * @param at a millipoint-based transformation matrix
     * @return a point-based transformation matrix
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.mptToPt(at) instead.
     */
    public static AffineTransform mptToPt(AffineTransform at) {
        return org.apache.xmlgraphics.util.UnitConv.mptToPt(at);
    }

    /**
     * Converts a point-based transformation matrix to millipoints.
     * @param at a point-based transformation matrix
     * @return a millipoint-based transformation matrix
     * @deprecated use org.apache.xmlgraphics.util.UnitConv.ptToMpt(at) instead.
     */
    public static AffineTransform ptToMpt(AffineTransform at) {
        return org.apache.xmlgraphics.util.UnitConv.ptToMpt(at);
    }
}

Monday, May 20, 2013

Equals, HashCode and toString in Java

You probably know that equals, hashCode and toString methods are very important in Java. And they must be carefully implemented. Joshua Bloch has written about this in his famous book "Effective Java (2nd Edition)", items 8 and 9.

Let's create simple bean object and implement the mentioned above methods:
package org.halyph;

import java.util.List;

public class StandardBean {
    private String name;
    private int id;
    private List<StandardBean> references;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public List<StandardBean> getReferences() {
        return references;
    }

    public void setReferences(List<StandardBean> references) {
        this.references = references;
    }

    @Override
    public String toString() {
        return "StandardBean{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", references=" + references +
                "} " + super.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        StandardBean that = (StandardBean) o;

        if (id != that.id) return false;
        if (name != null ? !name.equals(that.name) : that.name != null) return false;
        if (references != null ? !references.equals(that.references) : that.references != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + id;
        result = 31 * result + (references != null ? references.hashCode() : 0);
        return result;
    }
}

These three methods (equals, hashCode and toString) were generated by IDE. But, we have one drawback - their maintenance, i.e. we should carefully regenerate/update them. Also, readability is not very good. There are several alternative ways to solve this issue.

1. Apache Commons Lang
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class ApacheCommonsBean {
    
    ...

    @Override
    public String toString() {
        return new ToStringBuilder(this)
                .append("name", name)
                .append("id", id)
                .append("references", references)
                .toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ApacheCommonsBean that = (ApacheCommonsBean) o;

        return new EqualsBuilder()
                .appendSuper(super.equals(o))
                .append(name, that.name)
                .append(id, that.id)
                .append(references, that.references)
                .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(31, 17)
                .appendSuper(super.hashCode())
                .append(name)
                .append(id)
                .append(references)
                .toHashCode();
    }

}
2. Google Guave
import com.google.common.base.Objects;

public class GuavaBean {

    ...

    @Override
    public String toString() {
        return Objects.toStringHelper(this)
                .add("name", name)
                .add("id", id)
                .add("references", references)
                .toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null) return false;

        if (o instanceof GuavaBean) {
            final GuavaBean other = (GuavaBean) o;
            return Objects.equal(name, other.name)
                    && Objects.equal(id, other.id)
                    && Objects.equal(references, other.references);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(name, id, references);
    }

}
3. Java 7 Utils
import java.util.Objects;

public class JavaSevenBean {
   
    ...

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        JavaSevenBean that = (JavaSevenBean) o;

        return Objects.equals(name, that.name)
                &&  Objects.equals(id, that.id)
                && Objects.equals(references, that.references);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, id, references);
    }
}
 
Summary


Both Apache Commons Lang and Google Guava are additional jars in you project. So, when should we use these libraries:
  • I prefer to avoid using additional libraries if I need only small amount of library functionality. I.e. don't add Apache Commons/Guava into your project if you need equals, hashCode and toString only.
  • Use full power of existent projects libraries. Don't reinvent the wheel. Almost all mid-size project has Apache Commons or Guava (or both).
  • Use modern Java 7 feature if it's possible in your current environment.
  • I can't make preference between Guava and Apache Commons. Just stick to the current project state and select library which will be more useful. Don't be dogmatic.
IDE generated equals, hashCode and toString methods are not readable. And  in general cases they are boilerplate and hard to maintain. It's very easy to forget re-generate/update them.

Links:

Saturday, May 18, 2013

Short article review about JSP

Recently, I've read interesting Bozho's post Templating For Java Web Applications. Bozho mentioned and shared two stackoverflow flows which are really useful if you'd like to compare JSP with other template engines.

  1. Why would I use a templating engine? jsp include and jstl vs tiles, freemarker, velocity, sitemesh - here he provoked discussion a la "JSP vs X".
  2. JSP tricks to make templating easier? - it's short and very descriptive tutorial "how we can use JSP 2.0 Tag Files to build composable layout JSP page". Highly recommended!
There is no rocket science, but it's a nice trigger to think about:
  • when to use standard template engines
  • when to use bloated engines
  • what is the value of standard vs 3d party engine

Monday, May 13, 2013

iText Useful Resources

Recently I've begun using iText PDF generation library due to my work needs. I must admit that this library is quite powerful, but for really quick start I needed several resources with nice working samples. Here is the list:
  1. iText in Action, Second Edition, by Bruno Lowagie book is a must have if you really need to dive into library details. Also, it's very important to work in parallel with book samples https://itext.svn.sourceforge.net/svnroot/itext/book. I've reviewed the 1st edition of this book and must admit that the 2d is much better. I.e. don't waste your time and stick to 2d edition only.
  2.  iText and iTextSharp are very similar libraries. I.e. you can use iTextSharp code snippets as samples for iText. For this purpose I've selected the next two blogs:
  3. RoseIndia iText Examples - nice and basic iText samples.
  4. And the last item is iText forum
In general item 1 can solve almost all your needs.