Wednesday, 30 September 2009

Qi4j - First mixin

Qi4j LogoThis is my third post about Qi4j basics. In this post I'll show you how to implement behavior and wire it together with the code I already wrote for the previous post. As you probably remember Qi4j manages composites. Composite is defined as a composition of fragments. Fragment is a piece of code responsible for concrete functionality. Each fragment can be categorized either as a mixin or modifier. Mixin's role is to provide an implementation for composite's methods. At the moment Rational composite has only properties. So let's add some behavior methods. (Mixins are not limited only to provide behavior implementation, in fact properties are managed by predefined mixin too) Step 1. Extend Rational interface.
import org.qi4j.api.property.Property;
import org.qi4j.api.value.ValueComposite;

public interface Rational extends ValueComposite {

    Property<Integer> nominator();

    Property<Integer> denominator();

    Rational add(Rational toAdd);

    Rational mul(Rational toMultiply);
}
The highlighted lines show new behavior methods. If you try to run the application you will see the exception with the following message:
No implementation found for method public abstract com.blogspot.javasnippet.qi4j.Rational com.blogspot.javasnippet.qi4j.Rational.add(com.blogspot.javasnippet.qi4j.Rational) in com.blogspot.javasnippet.qi4j.Rational
That's because Qi4j doesn't see any implementation for these new methods. Step 2. Implement mixin.
public interface Rational extends ValueComposite {

    Property<Integer> nominator();

    Property<Integer> denominator();

    Rational add(Rational toAdd);

    Rational mul(Rational toMultiply);

    abstract class RationalMixin implements Rational {

        @Override
        public Rational add(Rational toAdd) {
            return null;
        }

        @Override
        public Rational mul(Rational toMultiply) {
            return null;
        }
    }
}
Things worth to be noted:
  • RationalMixin class is defined inside Rational interface - although it's not mandatory and is done here for simplicity there are cases (mainly for modifiers) where it makes sense to put implementation directly into declaring interface.
  • RationalMixin class is abstract - as I want to implement only behavior methods I have to make this class abstract. This way it's possible to even split single interface implementation into set of mixins. Qi4j proxies and reflection does the rest.
Qi4j still is not aware of this stub implementation and crashes by throwing this same exception as before. Step 3. Register mixin. To register mixin I have to annotate interface Rational with @Mixins annotation like below.
@Mixins(Rational.RationalMixin.class)
public interface Rational extends ValueComposite {
...
}
Now the application is running fine - Qi4j sees implementation for all declared methods. Step 4. Accessing composite state. UPDATE: It's no longer necessary to inject state to the mixin. See p.4.1 Rational extends ValueComposite which in turn extends Composite interface. If you look at source code of Composite interface then you will see it declares usage of PropertyMixin - that's the one which is responsible for properties state management. So our Rational is composed out of two fragments: PropertyMixin and RationalMixin. To implement methods inside the RationalMixin we need to access the state of this Rational composite instance. Qi4j solves this by dependency injection. See highlighted lines below.
    abstract class RationalMixin implements Rational {

        @This
        private Rational state;

        @Override
        public Rational add(Rational toAdd) {
            return null;
        }

        @Override
        public Rational mul(Rational toMultiply) {
            return null;
        }
    }
According to the JavaDoc, annotation @This "denotes the injection of a reference to the same Composite as the fragment is a part of". Then the method add() can be implemented as:
        public Rational add(Rational toAdd) {
            int n1 = state.nominator().get();
            int d1 = state.denominator().get();
            int n2 = toAdd.nominator().get();
            int d2 = toAdd.denominator().get();

            int d = d1 * d2;
            int n = n1 * d2 + n2 * d1;
            return null;
        }
Step 4.1. Accessing composite state without using @This. I wasn't aware of this feature when I was writing this post. Here is an update. Qi4j routes calls to the abstract methods (in other words - the methods which are not implemented by the mixin) to the composite. So the implementation of RationalMixin can be rewritten as follows:
    abstract class RationalMixin implements Rational {

        @Override
        public Rational add(Rational toAdd) {
            int n1 = this.nominator().get();
            int d1 = this.denominator().get();
            int n2 = toAdd.nominator().get();
            int d2 = toAdd.denominator().get();

            int d = d1 * d2;
            int n = n1 * d2 + n2 * d1;
            return null;
        }

        @Override
        public Rational mul(Rational toMultiply) {
            return null;
        }
    }
Step 5. Accessing module resources. Now it's time to create new Rational instance inside RationalMixin. To do this we need reference to the ValueBuilderFactory. This is solved by the dependency injection as well. Qi4j defines annotation @Structure which "denotes the injection of a resource specific for the module which the injected object/fragment is instantiated in".
    abstract class RationalMixin implements Rational {

        @Structure
        private ValueBuilderFactory builderFactory;

        @Override
        public Rational add(Rational toAdd) {
            int n1 = this.nominator().get();
            int d1 = this.denominator().get();
            int n2 = toAdd.nominator().get();
            int d2 = toAdd.denominator().get();

            int d = d1 * d2;
            int n = n1 * d2 + n2 * d1;

            ValueBuilder<Rational> builder = builderFactory.newValueBuilder(Rational.class);
            builder.prototype().nominator().set(n);
            builder.prototype().denominator().set(d);
            return builder.newInstance();
        }

        @Override
        public Rational mul(Rational toMultiply) {
            return null;
        }
    }
The implementation of method add() is now finished. We can check if it works. Here is new body of method main() which computes 2/3 + 3/4 and prints the result to the console.
    public static void main(final String[] args) throws Exception {
        SingletonAssembler assembler = new SingletonAssembler() {

            @Override
            public void assemble(ModuleAssembly module) throws AssemblyException {
                module.addValues(Rational.class);
            }
        };

        ApplicationSPI application = assembler.application();

        Module module = assembler.module();
        ValueBuilder<Rational> rb;
        rb = module.valueBuilderFactory().newValueBuilder(Rational.class);
        rb.prototype().nominator().set(2);
        rb.prototype().denominator().set(3);
        Rational r1 = rb.newInstance();

        rb = module.valueBuilderFactory().newValueBuilder(Rational.class);
        rb.prototype().nominator().set(3);
        rb.prototype().denominator().set(4);
        Rational r2 = rb.newInstance();

        Rational r3 = r1.add(r2);

        System.out.println(r3.nominator().get() + "/" + r3.denominator().get());
    }
You should see:
17/12
Summary This is last post of my short series about Qi4j basics. Here is short list of things worth to be remembered:
  • Qi4j is composite oriented and manages composites rather than objects.
  • Qi4j aims to help us in easier DDD adoption.
  • Qi4j uses dependency injection.
Qi4j offers much more features than I know about (I'm still learning). If you want to learn more go to its website. I encourage you to give it a try.

Wednesday, 23 September 2009

Qi4j - First application

Qi4j LogoIn the previous post I've shown how to set up Qi4j project with maven. In this post I'll show how to create application which will slowly evolve into basic rational number calculator in the future. I realize that using Qi4j in such simple application is an overkill but I think it's suitable for showing the basics. Qi4j derives many concepts from the famous Domain Driven Design. According to DDD principles an application should be comprised of layers. Each layer can have one or more modules. Qi4j uses assemblers to define application structure, layers, modules and dependencies between them. Assemblers are classes derived from interface org.qi4j.bootstrap.Assembler. In this simple application we'll use SingletonAssembler which instantiates one layer with one module inside. Step 1. Create application class. Create new class SimpleQi4jApplication in the package com.blogspot.javasnippet.qi4j which is located under directory src/main/java.
package com.blogspot.javasnippet.qi4j;

public class SimpleQi4jApplication {

    public static void main(final String[] args) {


    }

}
Step 2. Add SingletonAssembler.
public class SimpleQi4jApplication {

    public static void main(final String[] args) {
        SingletonAssembler assembler = new SingletonAssembler() {

            @Override
            public void assemble(ModuleAssembly module) throws AssemblyException {

            }
        };

    }
}
SingletonAssembler is an abstract class with abstract method assemble left to be implemented. I don't have anything to be assembled at the moment so I'm leaving it empty. Step 3. Activate application. Qi4j application has simple life-cycle. It can be activated and deactivated.
public class SimpleQi4jApplication {

    public static void main(final String[] args) throws Exception {
        SingletonAssembler assembler = new SingletonAssembler() {

            @Override
            public void assemble(ModuleAssembly module) throws AssemblyException {

            }
        };

        ApplicationSPI application = assembler.application();
    }
}
Now we can start this doing-nothing application. (I've added throws Exception to main() method for the sake of simplicity). We don't have to activate application explicitly because SingletonAssembler does this automatically. Step 3. Create composite. Let's model the rational number. Each rational number can be expressed as a ratio nominator/denominator, where both nominator and denominator are integers. Here is Rational interface created with Qi4j goodies.
import org.qi4j.api.property.Property;
import org.qi4j.api.value.ValueComposite;

public interface Rational extends ValueComposite {

    Property<Integer> nominator();

    Property<Integer> denominator();

}
Several new features come with this code snippet:
  • The properties are declared as methods with result type Property<Integer>. Qi4j deprecates classic POJO model and replaces it with this simple and powerful concept.
  • Interface Rational extends ValueComposite - this declaration makes Rational a Qi4j composite. In general Qi4j favours composites over objects (in Java meaning) and everything it manages is rather a composite than an object. There are several types of composites supported like value, entity, service and transient. In this example I choose to use value composite - an equivalent of DDD value object.
  • Interface Rational defines only properties - there is no behavior. One of the greatest features of Qi4j is its ability to manage composite state automatically (through generic mixins). That means we don't need to provide any implementation at the moment.
Now we can add Rational composite to the Qi4j runtime.
    public static void main(final String[] args) throws Exception {
        SingletonAssembler assembler = new SingletonAssembler() {

            @Override
            public void assemble(ModuleAssembly module) throws AssemblyException {
                module.addValues(Rational.class);
            }
        };

        ApplicationSPI application = assembler.application();
        application.activate();

        Module module = assembler.module();
        ValueBuilder<Rational> rb;
        rb = module.valueBuilderFactory().newValueBuilder(Rational.class);
        rb.prototype().nominator().set(2);
        rb.prototype().denominator().set(3);
        Rational r1 = rb.newInstance();

        System.out.println(r1.nominator().get() + "/" + r1.denominator().get());
    }
This program prints:
2/3
A lot of code for such easy task, hm? But remember that's just an example :-). There are several things worth to be noted:
  • No constructors - As we don't provide implementation for Rational we can't use constructor. With Qi4j we have to use builders to create new instances.
  • When rb.prototype is mutable the r1 is immutable - that's built-in property of value composites.
In the next post I'll finally implement behavior - operations add and multiply.

Friday, 18 September 2009

Qi4j - Project setup with Maven and Eclipse

Qi4j LogoQi4j is an implementation of composite oriented programming paradigm written in pure Java. As I'm just taking my first steps with Qi4j I've decided to write down some notes about that. In this post I'll show you how to setup your first Qi4j project with maven and eclipse. So, let's go. Step 1. Create project skeleton. With maven's archetype plugin we can get the skeleton really quickly.
mvn archetype:generate
Use the default project archetype (number 15) Maven asks for the groupId and artifactId.
Define value for groupId: : com.blogspot.javasnippet.qi4j Define value for artifactId: : qi4j-example
The skeleton has been created with the following pom.xml file
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.blogspot.javasnippet.qi4j</groupId>
    <artifactId>qi4j-example</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>qi4j-example</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
Step 2. Add Qi4j maven repository. To download Qi4j artifacts we must configure appropriate repository in the pom.xml. To do that add the following section to your pom.xml file
<repositories>
    <repository>
       <id>ops4j-repository</id>
       <url>http://repository.ops4j.org/maven2</url>
    </repository>
</repositories>
Step 3. Add Qi4j dependecies. Qi4j is not a single heavyweight jar but rather a set of small libraries. Then we can take only these we really need.
<dependencies>
    <dependency>
        <groupId>org.qi4j.core</groupId>
        <artifactId>qi4j-core-api</artifactId>
        <version>${version.qi4j-core}</version>
    </dependency>
    <dependency>
        <groupId>org.qi4j.core</groupId>
        <artifactId>qi4j-core-spi</artifactId>
        <version>${version.qi4j-core}</version>
    </dependency>
    <dependency>
        <groupId>org.qi4j.core</groupId>
        <artifactId>qi4j-core-bootstrap</artifactId>
        <version>${version.qi4j-core}</version>
    </dependency>
    <dependency>
        <groupId>org.qi4j.core</groupId>
        <artifactId>qi4j-core-runtime</artifactId>
        <version>${version.qi4j-core}</version>
        <scope>runtime</scope>
    </dependency>
    ...
As you can see the Qi4j version number is set as a property so we must define it (when I'm writing this the latest version is 1.0-RC1).
<properties>
    <version.qi4j-core>1.0-RC1</version.qi4j-core>
</properties>
Busy people can find final pom.xml below.
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.blogspot.javasnippet.qi4j</groupId>
    <artifactId>qi4j-example</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>qi4j-example</name>
    <url>http://maven.apache.org</url>

    <properties>
        <version.qi4j-core>1.0-RC1</version.qi4j-core>
    </properties>

    <repositories>
        <repository>
            <id>ops4j-repository</id>
            <url>http://repository.ops4j.org/maven2</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.qi4j.core</groupId>
            <artifactId>qi4j-core-api</artifactId>
            <version>${version.qi4j-core}</version>
        </dependency>
        <dependency>
            <groupId>org.qi4j.core</groupId>
            <artifactId>qi4j-core-spi</artifactId>
            <version>${version.qi4j-core}</version>
        </dependency>
        <dependency>
            <groupId>org.qi4j.core</groupId>
            <artifactId>qi4j-core-bootstrap</artifactId>
            <version>${version.qi4j-core}</version>
        </dependency>
        <dependency>
            <groupId>org.qi4j.core</groupId>
            <artifactId>qi4j-core-runtime</artifactId>
            <version>${version.qi4j-core}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
Step 4. Build the application. Now it's time to download Qi4j dependencies and build the application for the first time.
mvn install
Step 5. Import project to the eclipse workspace. As Eclipse is my favorite IDE I call maven to generate eclipse project files.
mvn eclipse:eclipse -DdownloadSources -DdownloadJavadocs
Start Eclipse and import your fresh project into your workspace. Now you can remove generated files App.java and AppTest.java That's it. In the next post I'll show you how to start up your first Qi4j application.

Tuesday, 8 September 2009

Collection Literals in Java 7

Today I read the final list of the Project Coins - the accepted list of Java language enhancement proposals for Java 7. The goal of one of them is to introduce collection literals for List, Set and Map. Probably it will be more convenient to build simple collections with them, but why to bind Java language (through JLS) with java.util.List and its friends? One may say that java.util.* is part of the JDK anyway. For me it's not enough justification for that step which looks more like an attempt to patch Java deficiencies with more or less weak solution. Unfortunately, the backward compatibility requirement doesn't allow to take a better one. I would be happy if I never saw this in Java language.