Skip to content

A super lightweight MVC web framework built to leverage Java EE 6 CDI. Brew better software with better beans.

Notifications You must be signed in to change notification settings

bcowdery/darkroast-framework

Repository files navigation

DarkRoast

DarkRoast is a ultra fast and super lightweight MVC web framework built on top of Java EE 6 CDI. Inspired by Struts 2, Microsoft MVC and other easy to use frameworks, DarkRoast aims to be as simple as possible by building on standard Java libraries and established technology we all know and love.

CDI Extension

DarkRoast provides several convenient features for CDI applications, allowing easy access to servlet objects and important life cycle events from within your application.

Servlet Object Injection

Inject the ServletContext ServletRequest and ServletResponse into any managed bean. DarkRoast even allows injection of the typed HttpServletRequest and HttpServletResponse without requiring additional casting.

@Named
public class HelloWorldService {

    @Inject ServletContext servletContext;

    @Inject HttpServletRequest request;
    @Inject HttpServletResponse response;

    public String say() {
        return "Hello World!";
    }
}

Events

Observe important web application life cycle events in your application because why not.

  • ServletRequestEvent - Servlet request start and stop events.
  • ServerContextEvent - Web application servlet context startup and shutdown.
  • BootstrapEvent - DarkRoast startup and shutdown events.

Qualify your observers using @Initialized and @Destroyed annotations to observe start and stop events individually.

Bootstrap

Bootstrap your own application startup after DarkRoast has done it's thing. Observe the events you need to get your application up and running with minimal effort and without cryptic DSL's and convoluted configuration.

@Startup
@ApplicationScoped
public class ApplicationBootstrap {

    private static final Logger LOG = Logger.getLogger(ApplicationBootstrap.class.getName());

    protected void applicationStartup(@Observes @Initialized BootstrapEvent event) {
        LOG.info("Application is starting up!");
    }

    protected void applicationShutdown(@Observes @Destroyed BootstrapEvent event) {
        LOG.info("Application is shutting down");
    }
}

MVC

Controllers

DarkRoast is all about the beans. Take any POJO and annotate it with a @Path to turn it into a RequestScoped MVC controller. Action names are inferred from the URL, or can be explicitly mapped with another @Path.

Controller:

import com.darkroast.mvc.annotations.Path;
import com.darkroast.mvc.Controller;
import com.darkroast.mvc.results.Result;

import static com.darkroast.mvc.results.Results.*;

@Path("rythm")
public class HelloWorldController implements Controller {

    @Path("index")
    public Result index() {
        return view("index.html").add("what", "Rythm");
    }
}

index.html:

<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    @args String what

    <p>
        Got @what?
    </p>
</body>
</html>

Views are rendered using the Rythm Template Engine. Inspired by Microsoft's Razor and used by other frameworks like Play!, Rythm is easy to use, easy to extend and blazing fast.

View Models

Passing a Model to the View

View models can be passed to the view layer via the action Result object. Any result type that renders content will accept model parameters for rendering data back to the user. These results are also chainable, making it simple to add many model objects to the result.

@Path("index")
public Result index() {
    return view("index.html")
        .add("who", "Chuck Norris")
        .add("what", "a unicycle")
        .add("why", "his beard");
}

Declare the @args in your Rythm template.

@args String who
@args String what
@args String why

<p>
    @who, @what and @why.
</p>

Data Binding

Databinding is handled through a CDI extension that dynamically produces instances of objects for injectable fields annotated with @ViewModel, and attempts to populate them using request parameters.

Model view beans

  • A model bean must have a public default constructor
  • A model bean must follow JavaBean property naming conventions
  • Request parameters names must match the JavaBean property name as accessible from the Controller.

Model:

public class Person {
    private String name;

    public Person() {
    }

    public String getName() {
        return name;
    }

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

Controller:

import com.darkroast.mvc.annotations.Path;
import com.darkroast.mvc.annotations.ViewModel;
import com.darkroast.mvc.Controller;
import com.darkroast.mvc.results.Result;

import static com.darkroast.mvc.results.Results.*;

@Path("person")
public class PersonController implements Controller {

    @Inject @ViewModel Person person;

    @Path("index")
    public Result index() {
        return view("index.html").add("person", person);
    }

    @Path("hello")
    public Result hello() {
        System.out.println("Hello " + person.getName());
        return view("hello.html").add("person", person);
    }
}

View:

@args Person person

@if (person.getName() != null) {
   Hello @person.getName()!
}

<form action="/person/hello">
    <input type="text" name="person.name" value="@person.name"/>
</form>

Tag Reference

Darkroast has serveral bundled tags for rendering standard HTML controls, links, and other common elements. These tags fully support dynamic HTML attributes, meaning you can add your CSS classes, HTML5 data attributes, placeholder values and whatever else you may need.

For example, the following Rythm Template produces markup that is remarkably similar

@a(href= "/some/url", class="myclass", data-toggle="tooltip", title="A link with a Bootstrap style tooltip!") {
    <span>Hover over me</span>
}
<a href="/some/url" class="myclass" data-toggle="tooltip" title="A link with a Bootstrap style tooltip!">
    <span>Hover over me</span>
</a>

Tags

Tag Expected Attributes Example Usage
@a href, value or tag body @a("/some/url", "Link text")
@a(href: "/some/url", value: "Link text", class: "cssclass")
@a(href: "/some/url") { <span>Link text</span> }
@input name, value, optional type @input("person.name", "Bob Smith")
@input(name: "person.name", value: "Bob Smith, class: "cssclass")
@input(name: "person.email", value: @person.getEmail(), type: "email")

Note that even expected parameters can be omitted and the tag should still render correctly.

Custom Rythm Tags

Using Rythm you can easily create specific tags for your application. This is because Every template can be invoked as a tag. Templates are resolved from the template root (/WEB-INF/content by default), and mapped into a tag name by stripping off the file extension and converting path separators / into dots ..

For example suppose you have a template with the following content located at /WEB-INF/util/hello.html:

Hello from tag!

From the any other template or even the template itself you can invoke the template as a tag:

@util.hello()

Java Tag Interface

Rythm is so fast that there is very little performance benefit to writing a Java tag that produces output with StringBuilder or String concatenation.

However, Java tags are still very useful for third party developers wanting to package tags in jar files. DarkRoast provides a convenient mechanism for discovering and registering tags as managed beans through the use of the @RythmTag annotation.

import com.darkroast.rythm.annotations.RythmTag;
import org.rythmengine.template.ITag;
import org.rythmengine.template.JavaTagBase;

@RythmTag
public class Hello extends JavaTagBase {

    public Hello() {
    }

    @Override
    public String __getName() {
        return "hello";
    }

    @Override
    protected void call(ITag.__ParameterList params, __Body body) {
        Object o = params.getDefault();
        String name = o == null ? "who" : o.toString();
        p("Hello ").p(name);
    }
}
<body>
    <p>
        @hello("Darkroast")
    </p>
</body>

Inline Tags

TODO: Write this later... Reference https://github.com/greenlaw110/play-rythm/blob/master/documentation/manual/user_guide.textile

About

A super lightweight MVC web framework built to leverage Java EE 6 CDI. Brew better software with better beans.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages