This plugin ties a Qi4j Application to a Play! >=2.1 Application providing a tight integration between the two.
The Play framework makes it easier to build web applications with Java & Scala.
Play is based on a lightweight, stateless, web-friendly architecture and features predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications - thanks to its reactive model, based on Iteratee IO.
Official Site
http://playframework.org/
Questions & Answers
[http://stackoverflow.com/questions/tagged/playframework-2.0]
(http://stackoverflow.com/questions/tagged/playframework-2.0)
Discussion
[http://groups.google.com/group/play-framework]
(http://groups.google.com/group/play-framework)
The short answer is that Qi4j is a framework for domain centric application development, including evolved concepts from AOP, DI and DDD.
Qi4j is an implementation of Composite Oriented Programming, using the standard Java 5 platform, without the use of any pre-processors or new language elements. Everything you know from Java 5 still applies and you can leverage both your experience and toolkits to become more productive with Composite Oriented Programming today.
Moreover, Qi4j enables Composite Oriented Programming on the Java platform, including both Java and Scala as primary languages as well as many of the plethora of languages running on the JVM as bridged languages.
Official Site
http://qi4j.org/
Questions & Answers
[http://stackoverflow.com/questions/tagged/qi4j]
(http://stackoverflow.com/questions/tagged/qi4j)
Discussion
http://groups.google.com/group/qi4j-dev
As Qi4j itself is written in the Java language, this Play plugin is too. Sample code you'll find below is Java code but most of this works in Play Scala applications.
You can use Qi4j for a small part of your application where Composite Oriented Programming fits or go for a bigger DDD stack using Qi4j Libraries and Extensions. In development mode the Qi4j Tools can come in handy.
Qi4j is pronounced "chee for jay", so PlayQi is pronouced "play chee".
- Add
https://oss.sonatype.org/content/repositories/snapshots/
andhttps://repository-qi4j.forge.cloudbees.com/snapshot/
repositories as resolvers to yourproject/Build.scala
; - add
"org.codeartisans" %% "playqi" % "1.1"
and"org.qi4j.core" %% "org.qi4j.core.runtime" % "2.0"
to your dependencies inproject/Build.scala
; - add
1500:org.codeartisans.playqi.PlayQiPlugin
to yourconf/play.plugins
.
The plugin request that you set the qi4j.app-assembler
parameter in conf/application.conf
.
A Qi4j application is assembled using an ApplicationAssembler, set qi4j.app-assembler
to the fully qualified name of yours class.
As a quick start and for a simple Qi4j application you can extend SingletonAssembler ;
public class MyAppAssembler extends SingletonAssembler {
public void assemble(ModuleAssembly ma) throws AssemblyException {
ma.values( Comment.class, Tagline.class );
ma.entities( Post.class, Page.class );
ma.services( Blog.class
MemoryEntityStoreService.class,
UuidIdentityGeneratorService.class );
}
}
and use qi4j.app-assembler=bootstrap.MyAppAssembler
.
See this tutorial on [how to assemble a more complete Qi4j application] (http://qi4j.org/latest/howto-assemble-application.html).
Play and Qi4j Applications are started / activated and passivated / stopped together.
Moreover, Play DEV / TEST / PROD modes and Qi4j development / test / production modes are synched.
Depending on your Qi4j Application assembly you can use two APIs:
PlayQiSingle
for a simple Qi4j Application based on SingletonAssembler ;PlayQi
for a Qi4j Application using layers and modules.
PlayQiSingle
is provided as an easy way to prototype or to integrate a small Qi4j application in a Play application. We recommend to use a true application assembly using layers and modules and the PlayQi
API.
PlayQiSingle
When using a SingletonAssembler the single Module of the Qi4j Application is considered as the Module used by Play controllers, thus you don't need to set qi4j.controllers-layer
nor qi4j.controllers-module
in your configuration.
Application app = PlayQiSingle.application();
Layer layer = PlayQiSingle.layer();
Module module = PlayQiSingle.module();
Blog blog = PlayQiSingle.service( Blog.class );
Here is a simple exemple:
public class BlogController extends Controller {
public static Result index() {
return ok( template.render( PlayQiSingle.service( Blog.class ).homepage() ) );
}
}
PlayQi
When using a complete Qi4j Application assembly you need to set qi4j.controllers-layer
and qi4j.controllers-module
in your configuration to point the Module of your Qi4j Application the Play controllers will use. Once done, PlayQi
provide utility methods to quickly get handles on Qi4j composites:
Application app = PlayQi.application();
Layer controllersLayer = PlayQi.controllersLayer();
Module controllersModule = PlayQi.controllersModule();
Blog blog = PlayQi.service( Blog.class ); // From the controllers module
Besides, you can also get a handle on any layer/modules of your Qi4j Application:
Layer layer = PlayQi.layer( "Presentation" );
Module module = PlayQi.module( "Presentation", "Contexts" );
Blog blog = PlayQi.service( "Presentation", "Contexts", Blog.class );
Qi4j Structure and Service injections scopes are supported in controllers.
WARNING Controllers injection only work on Play! 2 Java Applications for now, we need help from Scala developers to implement this in Scala, any volunteers?
To use this facility you must set both qi4j.controllers-layer
and qi4j.controllers-module
parameters in your application.conf
to define the Module from where the injections
will be done ;
qi4j.controllers-layer=Presentation
qi4j.controllers-module=Contexts
and then in your controllers:
@Structure public static Application application;
@Structure public static Layer layer;
@Structure public static Module module;
@Service public static Iterable<ServiceReference<Blog>> blogReferences;
@Service public static ServiceReference<Blog> blogReference;
@Service public static Blog blogService;
By default, only classes in the controllers
package are injection candidates.
You can set the qi4j.controllers-packages
parameter to change this behaviour with a
column separated list of package names.
Limitations: @Tagged services are not supported yet.
Play 2.1 bring the possibility to use non-static Java controllers. This plugin allow you to manage your controllers inside your Qi4j application.
This is available using PlayQiSingle
and PlayQi
, see above.
Object Controllers
Let's start with a simple controller ;
public class MyController extends Controller {
@Service Blog blog;
public Result index() {
return ok( index.render( blog.homepage() ) );
}
}
assemble it in your Qi4j application as an Object;
moduleAssembly.objects( MyController.class );
and then use the PlayQi API in your GlobalSettings ;
public class Global extends GlobalSettings {
@Override
public <T> T getControllerInstance( Class<T> clazz ) {
return PlayQi.newControllerInstance( clazz );
}
}
Transient Composite Controllers
Here is a sample Controller as a TransientComposite (meaning you get Qi4j fragments support):
public interface MyController {
@MyConcern
@MySideEffect
Result index();
}
public class MyControllerMixin {
@Service Blog blog;
@Override
public Result index() {
return ok( index.render( blog.homepage() );
}
}
assemble it in your Qi4j application as an Object;
moduleAssembly.transients( MyController.class ).withMixins( MyControllerMixin.class );
and then use the PlayQi API in your GlobalSettings ;
public class Global extends GlobalSettings {
@Override
public <T> T getControllerInstance( Class<T> clazz ) {
return PlayQi.newTransientControllerInstance( clazz );
}
}
This plugin provides the annotations and to wrap Qi4j UnitsOfWork around Play Actions and Callable<?> wrappers for you to go async.
A Qi4j UnitOfWork takes place in a Module, so depending on your Application assembly you may use different Action composition annotations or Callable<?> wrappers.
When using SingletonAssembler
import org.codeartisans.playqi.*;
public class MyController {
@PlayQiSingleUnitOfWorkConcern
public static Result action() {
:
return ok( .. );
}
}
If you go async, you can use the PlayQiSingleUnitOfWorkCallable
to wrap a UoW around another Callable.
When using a full Qi4j Application assembly
import org.codeartisans.playqi.*;
public class MyController {
// UoW taking place in the configured controllers module
@ControllersModuleUnitOfWorkConcern
public static Result action() {
:
return ok( .. );
}
// UoW taking place in a module of your choice
@PlayQiUnitOfWorkConcern( "Presentation", "Contexts" )
public static Result anotherAction() {
:
return ok( .. );
}
}
If you go async, you can use either the ControllersModuleUnitOfWorkCallable
or the PlayQiUnitOfWorkCallable
to wrap a UoW around another Callable.
Theses tools work in DEV mode only. Their configuration is ignored in TEST and PROD modes.
By setting qi4j.envisage=enabled
in your application.conf
the Envisage Qi4j Tool
is started/reloaded/stopped alongside your application.
Envisage is a Swing based visualization tool for the Qi4j Application model, it allows you to browse your Application Assembly. Visualizations can be printed to PDFs.
By setting qi4j.entity-viewer=enabled
in your application.conf
the Entity Viewer Qi4j Tool
is started/reloaded/stopped alongside your application.
EntityViewer is a Swing based Entities browser. It allows you to browse Entities persisted in EntityStores.
Note that to use the EntityViewer your Qi4j Application Assembly must contains both EntityStore and Index/Query services.
This software is licensed under the Apache 2 license, quoted below.
Copyright 2012 Paul Merlin.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.