Showing posts with label Crash Course. Show all posts
Showing posts with label Crash Course. Show all posts

Wednesday, 15 August 2012

Pojomatic for Equals(), HashCode() and toString()

From the website itself: "Pojomatic provides configurable implementations of the equals(Object), hashCode() and toString() methods inherited from java.lang.Object"

This is best described with an example (available on Github, in the Introduction-To-Pojomatic directory):
@AutoProperty
public class Item {

    @Property(policy=PojomaticPolicy.EQUALS_TO_STRING)
    private long id = 0;

    private String description = "";

    @Property(policy=PojomaticPolicy.NONE)
    private transient int transientData;

    @Override
    public boolean equals(Object o) {
        return Pojomatic.equals(this, o);
    }

    @Override
    public int hashCode() {
        return Pojomatic.hashCode(this);
    }

    @Override
    public String toString() { 
        return Pojomatic.toString(this);
    }

    // Constructors, Setters & Getters...

}
Notice that equals(), hashCode() and toString() are overriden to call Pojomatic.

The @AutoProperty annotation enables Pojomatic on an class. It has two optional properties:
  • The auto detect policy indicates whether FIELDs or METHODs should be searched for properties to take into account. The search can also be disabled with NONE. By default, the FIELDs are searched for.
  • The default Pojomatic policy which indicates whether the properties are going to be included in equals(), hashCode() and toString(). By default, the policy is set to ALL. Other values are: EQUALS, EQUALS_TO_STRING, HASHCODE_EQUALS, NONE, TO_STRING.
The class level configuration can also be overridden at the field (or method) level with the @Property annotation. It also has two properties:
  • The name, which identifies the property in toString().
  • The policy, which is very similar to the default Pojomatic policy, but at the field/method level. It can take the same values, plus one: DEFAULT, which means 'the class level policy' (or ALL if none is defined).
The following:
Item item = new Item();
item.setDescription("Blue furniture");
item.setId(123456);
item.setTransientData(9999);

System.out.println("equals   : " + item.equals(new Object()));
System.out.println("hashCode : " + item.hashCode());
System.out.println("toString : " + item.toString());
Generates the following output:
equals   : false
hashCode : -2089463829
toString : Item{id: {123456}, description: {Blue furniture}}
Pojomatic also offers:
  • a feature to control formatting in toString()
  • a mean to prevent a subclass from overridding equals()
  • Assuming B extends A, but you don't want an instance of B to be equal to an instance of A ever, there is a mean to notify Pojomatic
  • Assuming B extends A, and you would like to retrieve the difference in terms of properties used to compute equals(), Pojomatic.diff(...) provides this information
  • One can retrieve the Pojomator used to compute equals(), hashCode() and toString(); it also contains an interesting isCompatibleForEquality() method to check whether another class can be used in equals()

Sunday, 12 August 2012

JPA Entity, Embeddable and Authorized Types

Introduction

JPA stands for Java Persistence API.  It is a mean by which developers can easily describe how to persist the data contained in Java objects using some annotations and a configuration file called persistence unit. This API is made available in the javax.persistence package. Typically, JPA is used in combination with an implementing framework (such as Hibernate for example).

This post is the first of a series introducing JPA with practical examples. It can be read like a reminder too. The code examples are are available from Github in the JPA directory. We will start with some basic annotations first.

@Entity

An entity creates a relationship between a Java class and (typically) a database table.
  • An entity class must have at least a public or protected constructor with no argument.
  • An entity class must have an @Id.
  • An entity class must not be final or have final variables.
  • The variables (or attributes) of an entity class to be persisted must be private, protected or package-private, and must be accessed via setter and getters from outside the class.
  • An entity class must implement Serializable in order to be transmittable in a detached status.

@Embeddable

An embeddable class is nearly an entity class, except that it cannot be persisted by itself alone. It can be used as a 'component' containing data to be persisted, in another entity.
Embeddable example:
@Embeddable
public class SomeEmbeddable implements Serializable {

    private String s;

    public SomeEmbeddable() { }

    public String getS() { return s; }
    public void setS(String s) { this.s = s; }

}

Authorized Types

The following entity example regroups the authorized types for persistence:
@Entity
public class AuthorizedTypes implements Serializable {

    @Id
    private long id;

    // Primitives

    private boolean bool;
    private Boolean bool2;
    private byte byt;
    private Byte byt2;
    private char c;
    private Character c2;
    private double dou;
    private Double dou2;
    private float floa;
    private Float floa2;
    private int i;
    private Integer i2;
    private long l;
    private Long l2;
    private short s;
    private Short s2;

    // Serializable types

    private String str;
    private BigInteger bi;
    private BigDecimal bd;
    private Serializable userDefined;
    private byte[] ba;
    private Byte[] ba2;
    private char[] ca;
    private Character[] ca2;

    public enum Color { WHITE, BLACK, RED; }
    private Color col;

    // Other entities and embeddables

    @OneToOne
    private OtherEntity otherEntity;

    private SomeEmbeddable someEmbeddable;

    @ElementCollection
    private Collection<SomeEmbeddable> coll;

    @ElementCollection
    private Set<SomeEmbeddable> st;

    @ElementCollection
    private List<SomeEmbeddable> list;

    @ElementCollection
    private Map<String, Serializable> mpp;

    // Time-related

    // Keeps date only
    @Temporal(TemporalType.DATE)
    private java.util.Date MyDate;

    // Keeps time only
    @Temporal(TemporalType.TIME)
    private java.util.Date MyTime;

    // Keeps date and time
    @Temporal(TemporalType.TIMESTAMP)
    private java.util.Date MyTimestamp;

    @Temporal(TemporalType.TIMESTAMP)
    private java.util.Calendar cal;

    // Keeps date only
    private java.sql.Date sqlDate;

    // Keeps time only
    private java.sql.Time sqlTime;

    // Keeps date and time
    private java.sql.Timestamp sqlTimeStamp;

    // Setters & Getters....

}
These are the basic persistence elements one can use and combine in entities. The above needs more configuration to be fully operational. It is only an illustration of concepts.

Monday, 6 August 2012

JAXB Annotation - Basic Annotations, Inheritance

JAXB (Java Architecture for XML Binding) enables the mapping of Java object into XML documents back and forth. This post is an introduction, tutorial and summary of JAXB annotations. It proceeds with operational code examples to describe each feature.

The code examples are available from Github in the JAXB-JSON-XML-Marshalling directory. Most examples rely on the following piece of code to create XML files from annotated Java objects:
    public static void createXML(Object o) throws JAXBException {
        
        // Creating a Marshaller
        JAXBContext jaxbContext = JAXBContext.newInstance(o.getClass());
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
 
        StringWriter result = new StringWriter();
        jaxbMarshaller.marshal(o, result);

        // Printing XML
        String xml = result.toString();
        System.out.println(xml);
        
    } 
In order to generate such XML documents, a JAXB context must be created. More details on this in part II.

@XmlRootElement

Defines the root element of the XML document. If not name is specified (like this for example: @XmlRootElement(name = "MyRootName"), the name of the element is taken from the class name.

This annotation can be used on a Class or on an enum. A Class does need a no parameter constructor or a factory method (more details in the @XmlType section).

For example:
@XmlRootElement(name="MyRootName")
public class A {

    private int a1 = 0;

    @XmlElement
    public int getA1() {
        return a1;
    }

    public void setA1(int a1) {
       this.a1 = a1;
    }

}
generates the following XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyRootName>
   <a1>28</a1>
</MyRootName>
One can also specify a namespace name for the XML element or a local name for the XML element.

Inheritance

When a class inherits of another annotated class, the root name is taken from the inheriting class:
@XmlRootElement
public class InheritsA extends A {

    private int b1 = 0;

    @XmlElement
    public int getB1() {
        return b1;
    }

    public void setB1(int b1) {
        this.b1 = b1;
    }

}
The generated XML is:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<inheritsA>
    <a1>33</a1>
    <b1>66</b1>
</inheritsA>

@XmlElement / @XmlTransient

The @XmlElement indicates which element should be included in the XML conversion. If you want to annotate fields instead of getter methods, use the @XmlAccessorType(XmlAccessType.FIELD).

If you need to exclude a field from the generated XML, use the @XmlTransient annotation.
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class FieldAnnotation {

    @XmlElement
    private int a1 = 45;

    @XmlTransient
    private long a2 = 0;

    @XmlElement(nillable=true)
    private String xxx = null;

    @XmlElement(required=true)
    private String req;

    public int getA1() {
        return a1;
    }

    public void setA1(int a1) {
        this.a1 = a1;
    }

    public long getA2() {
        return a2;
    }

    public void setA2(long a2) {
        this.a2 = a2;
    }

    public String getXxx() {
        return xxx;
    }

    public void setXxx(String xxx) {
        this.xxx = xxx;
    }

    public String getReq() {
        return req;
    }

    public void setReq(String req) {
        this.req = req;
    }

} 
Assuming the following class creation:
FieldAnnotation fa = new FieldAnnotation();
fa.setA2(28);
fa.setReq("Some value");
generates:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<fieldAnnotation>
    <a1>45</a1>
    <xxx xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
    <req>Some value</req>
</fieldAnnotation>
One can also set a default string value, or set the XML Schema element name and the target namespace of the XML element via the @XmlElement annotation.

@XmlType

This annotation allows one to specify the order of items in the generated XML document. It can also be used to specify a factory class and/or a factory method (with no arguments) to create instances of the annotated class:
@XmlRootElement
@XmlType(propOrder={"a2", "a1"},
  factoryClass=OrderFactory.class,
  factoryMethod="myConstructor")
public class Order {

    private int a1 = 0;
    private int a2 = 0;

    @XmlElement
    public int getA1() {
        return a1;
    }

    public void setA1(int a1) {
        this.a1 = a1;
    }

    @XmlElement
    public int getA2() {
        return a2;
    }

    public void setA2(int a2) {
        this.a2 = a2;
    }

}
The factory class:
public class OrderFactory {
    public static Order myConstructor() {
        return new Order();
    }
}
The generated XML:
<order>
  <a2>99</a2>
  <a1>28</a1>
</order>
One can also set the XML Schema type and the target namespace of the XML Schema type with the @XmlType annotation.

@XmlSeeAlso

This annotation allows one to refer to other classes to include in the XML generation. In other words, if a referred class is not in the JAXB context, it will be taken into account anyway and won't trigger a runtime error. This annotation can be used as a safeguard when marshalling and unmarshalling.

This is best described with an example:
@XmlRootElement
public class Document {

    private String content = "";

    @XmlElement
    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}
@XmlRootElement
public class Image {

    private String name = "";

    @XmlElement
    public String getName() {
        return name;
    }

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

}
@XmlRootElement
@XmlSeeAlso({Document.class,Image.class})
public class Folder {

    private Document document = null;
    private Image image = null;

    @XmlElement
    public Document getDocument() {
        return document;
    }

    public void setDocument(Document document) {
        this.document = document;
    }

    @XmlElement
    public Image getImage() {
        return image;
    }

    public void setImage(Image image) {
        this.image = image;
    }

}
The generated output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<folder>
    <document>
        <content>My content</content>
    </document>
    <image>
        <name>My image</name>
    </image>
</folder>

Next

JAXB to XMLJAXB to JSONJAXB Annotations Tutorial Table Of Content

Thursday, 10 May 2012

Introduction To Maven Concepts (Crash Course)

This is the post I wish someone had written to connect dots in 2007, when Maven documentation was scarce. This Maven tutorial is a starting point for those who have no experience with Maven, or who are willing to improve their global understanding of Maven concepts. It explains what Maven is, what you can do with it, but not how to do it. I will also give pointers to additional documentation.

What is Maven?

Maven is a software project implementation tool, but not a project management tool. In a factory, it would be the complete assembly line, taking in raw materials and producing finished products ready for use. It is mostly used by Java programmers, but it can be configured for other programming languages too.

If ever you have to work on a large Java project, you will most probably have to learn either about Maven or Ant (another project implementation tool). Otherwise, your project will quickly become unmanageable as it grows in size. Ant requires you to configure all your requirements from top to bottom. You have to build the whole assembly line for a given project. On the other side, Maven comes with default behaviors. If there is something you don't like in the assembly line, you can reconfigure it or extends parts to meet your specific needs.

There has been some religious wars between Ant users and Maven in the past. But today, they coexists in peace. In fact, it is pretty common for a Maven project to call Ant as a module to perform tasks it cannot perform itself.

Both Maven and Ant are functionally interchangeable. If an existing project works fine with Ant, you should not convert it to Maven. However, if you start a project from scratch, you may want to consider Maven, because of the very large support community and an incredible number of mature modules available for free under an open source license.

What Is The Form Factor?

Maven is a package you download and install on your PC. You just need to unzip it in a directory and make sure it is accessible from the command line (i.e., it has to be 'in the path'). Maven is a command line product with no graphic user interface (GUI). However, it is well integrated in free software development applications such as NetBeans or Eclipse. Most often, you will never need to run Maven from the command line. If you plan to use Ant with Maven, you will need to install it on your PC too.

How Does It Work?

When you start using Maven, it will first create a local repository on your PC. As you compile your software projects, all the results are posted in this local repository. The produced items are called artifacts. You can configure Maven to post those artifacts in other remote repositories or locations too, if necessary.

In addition to this local repository, there is what is called the central repository. It is a huge online repository containing tons of free artifacts contributed under an open source license over many years by thousands of developers. When Maven needs one of these artifacts to build a project and can't find it the local repository, it tries to fetch it from the central repository, if the local PC is connected to the Internet. Maven can be configured to search those artifacts in other public or private repositories too.

As a consequence, the first time Maven builds a project, it will download many artifacts from the central repository. It is a one time operation. You are not allowed to post something directly to the central repository. If you want to contribute your own artifacts, you need to read this.

There are three main types of repositories, the central repository, your local repository and public or private proprietary repositories.

What Is A Maven Project?

Contrary to many other software implementation tools, Maven projects operate according to a standard directory structure where different items (code files, test files, etc...) are expected to be found in well-known directories. It is part of the delivered assembly line.

It is not a good idea to try to reconfigure this directory structure to fit your karma. If another software engineer gets to work on your project, he will be confused. On the other side, if you get to work on another Maven project, you will be happy to find what you are looking for where it is supposed to be. Learn about Maven directory structures. Don't be a baby, open your mouth and do take the pill (lol)!

Another key project item is the Project Object Model XML file often called 'pom' or 'pom.xml'. Each project has its own directory structure with a pom.xml located at its root. Here is one the simplest possible 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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>


  <groupId>com.mycompany</groupId>
  <artifactId>SimpleMavenProject</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

</project>

It contains the 4 items making the coordinates of the project. Basically, it is the location of the project in repositories; a concatenation of the group id, the artifact id, and the project version (for a definition of SNAPSHOT, see (*) below) together with directory separators. The packaging explains how and which default artifacts will be bundled into the repository. You can organize and identify your projects as you wish using the coordinates you want. The packaging depends of the type of project your want to create.

The POM is where you will configure the different parts of the assembly line to meet your needs if default configuration is not enough.

Typically, under the hood, all Maven projects are created using an archetype. It is a kind of template used to create the default content of POMs and the default directory structure of Maven projects. You can create your own archetypes if you need to, but existing ones will cover most of your needs.

How Does The Compile Process Work?

The compile process is called the build process in Maven. It can be configured to perform much more than a simple compilation. Therefore, you should avoid mentioning a 'compile process' when talking about Maven, because it is only one of the phases of one of Maven's build processes (one step in the assembly line).

When a build process is executed, it goes through a life cycle using the information contained in the POM. Each life cycle is made of phases. Plugins are attached to phases. A phase can contain multiple plugins. A plugin is basically a set of operations of a given type which may be executed during a build cycle. Each possible plugin operation is called a goal. When a plugin is attached to a phase, a goal is specified (or else the default goal is executed).

The life cycle goes through each phase, sequentially, and executes each default (or configured in the POM) plugin goal, sequentially, until the end or until one of the plugin goal fails to execute. A Maven goal (as opposed to a plugin goal) is a step in the life cycle of a build process. By default, a build process will go the whole way through, unless a specific Maven goal is specified. In this case, Maven stops at this life cycle step, even if it is executed successfully.

By default, some plugins are attached to phases. Each plugin has a default goal which will be invoked unless it is configured differently in the POM. This is the default assembly line. You can also attach additional plugins to the phases of your build cycles. These will be downloaded from the central repository if necessary. You can also write your own plugins if you need to and use them in your build cycles.

Think about all this in terms of Lego's attached to a structural frame.

What About Maven Dependencies?

Large projects often use existing pieces of code (libraries) by making an explicit reference to them. In Maven projects, such dependencies to existing artifacts are specified in the POM, using their coordinates. Sometimes, these dependencies are just required for the build process (for the testing phase for example). Sometimes, they need to be shipped as part of the delivered artifacts. The type of use of the dependency is called a scope. It is specified in the POM

What About Profiles?

In order to cover complex situations (for example) when you need to create different types of artifacts for different target platforms, it would be tedious to maintain multiple POMs for the same project. The solution is called build profiles in Maven.

This is a mean to set additional configuration if the build process is to be executed for a specific platform (building for Windows or for Linux for example). In this case, corresponding plugins are only executed if they have been defined in the corresponding platform profile in the POM. A POM can be executed by specifying (or not) a build profile. This determines the set of plugins which will be executed on top of the default configuration.

Conclusion

There are many other features available in Maven. We have only mentioned the basics. If you want to learn more about Maven, including how to use it, the best resource available on the net is the Maven Complete Reference online guide.

After reading this guide, you should explore existing Maven modules. Learn what they can do for you. If you need help, type your question in Google followed by the word 'StackOverflow'. It most probably has already been answered. If not, go to StackOverflow.com and ask your question there.

-----

(*) SNAPSHOT versions can be confusing at the beginning. Let's assume you are working on a project and have released version 1.0.0. You are now working on version 1.1.0, but it has not been released and won't be released until you are done. Version 1.1.0 is work in progress. Yet, with Maven's build process, you are creating temporary work in progress artifacts. In order to differentiate these from production ready artifacts, you can add -SNAPSHOT to the work in progress version of your project (i.e.,  <version>1.1.0-SNAPSHOT</version>).

When you create Maven projects with dependencies to other artifacts/libraries, by default, maven ignores SNAPSHOT versions of those dependencies. Yet, if you want to access a specific SNAPSHOT version of a dependency, you can explicitly specify it in your pom.xml. This is often necessary during the development phase of a project.

For Maven parent projects, see here • More about Maven tips and tricks here.