Brutos Framework

Brutos Framework
Developer(s) Brandao
Initial release May 17, 2009
Stable release
2.0RC1 / 30 June 2015 (2015-06-30)
Development status Active
Written in Java
Operating system Cross-platform
Platform Java Virtual Machine
Type Application framework
License Apache License 2.0
Website www.brutosframework.com.br


The Brutos Application Framework is MVC controller written in Java. Designed to reduce the complexity of web development, with configurable mapping, view resolution as well as support for uploading and downloading files. Can be configured using XML, annotations and CoC.

The framework follows the below principles:

Release Bundle Downloads

The Brutos team provides release bundles hosted on the SourceForge File Release System, in ZIP.

Each release bundle contains JARs, documentation, source code, and other information.

You can download releases of Brutos, from the list at sourceforge.net/projects/brutos/files/brutos/.

Maven Repository Artifacts

They are produced a number of artifacts. All under the org.brandao groupId.

The official repository is www.brutosframework.com.br/maven/2.

How to configure?

Register the listener in web.xml

<listener>
    <listener-class>org.brandao.brutos.web.ContextLoaderListener</listener-class>
</listener>

Register the filter in web.xml

<filter>
        <filter-name>Brutos Framework Filter</filter-name>
        <filter-class>org.brandao.brutos.web.http.BrutosRequestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Brutos Framework Filter</filter-name>
        <url-pattern>*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>
</filter>

Attention: If you are using a container that supports the Servlet 3.0 specification, the registration of ContextLoadListener and DispatcherServlet or BrutosRequestFilter are not necessary. They will be automatically registered.

Register the artifacts in pom.xml

...
<dependencies>
  <dependency>
      <groupId>org.brandao</groupId>
      <artifactId>brutos-core</artifactId>
      <version>2.0-rc1</version>
  </dependency>
  <dependency>
     <groupId>org.brandao</groupId>
     <artifactId>brutos-web</artifactId>
     <version>2.0-rc1</version>
  </dependency>
  <dependency>
     <groupId>org.brandao</groupId>
     <artifactId>brutos-annotation</artifactId>
     <version>2.0-rc1</version>
  </dependency>
</dependencies>
...

Create the file brutos-config.xml in /WEB-INF.

<?xml version="1.0" encoding="UTF-8"?>
<controllers  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
              xmlns='http://www.brutosframework.com.br/schema/controllers'
              xmlns:context='http://www.brutosframework.com.br/schema/context'
              xsi:schemaLocation='
   http://www.brutosframework.com.br/schema/controllers 
http://www.brutosframework.com.br/schema/controllers/brutos-controllers-1.1.xsd
   http://www.brutosframework.com.br/schema/context 
http://www.brutosframework.com.br/schema/context/brutos-context-1.1.xsd'>

</controllers>


Examples

Creating a simple controller

URI mapping:

Controller/Action URI View
IndexController /Index /WEB-INF/index/index.jsp
IndexController.defaultAction() /Index/default /WEB-INF/index/defaultaction/index.jsp

Controller

public class IndexController{
  
   public void defaultAction(){
       ...
   }

}

Defining the controller path

URI mapping:

Controller/Action URI View
IndexController /mycontroller /WEB-INF/index/index.jsp
IndexController.defaultAction() /mycontroller/default /WEB-INF/index/defaultaction/index.jsp

Controller

@Controller("/mycontroller")
public class IndexController{
  
   public void defaultAction(){
       ...
   }

}

Defining the action path

URI mapping:

Controller/Action URI View
IndexController /mycontroller /WEB-INF/index/index.jsp
IndexController.defaultAction() /mycontroller/myaction /WEB-INF/index/defaultaction/index.jsp

Controller

@Controller("/mycontroller")
public class IndexController{
  
   @Action("/myaction")
   public void defaultAction(){
       ...
   }

}

Defining the action strategy

URI mapping:

Controller/Action URI View
IndexController /Index /WEB-INF/index/index.jsp
IndexController.defaultAction() /Index/default /WEB-INF/index/defaultaction/index.jsp

Controller

@ActionStrategy(ActionStrategyType.Hierarchy)
public class IndexController{
  
   public void defaultAction(){
   }

}

The Detached action strategy

URI mapping:

Controller/Action URI View
IndexController - -
IndexController.defaultAction() /default /WEB-INF/index/defaultaction/index.jsp

Controller

@ActionStrategy(ActionStrategyType.Detached)
public class IndexController{
  
   @Action("/default")
   public void defaultAction(){
       ...
   }

}

The Hierarchy action strategy

URI mapping:

Controller/Action URI View
IndexController /Index /WEB-INF/index/index.jsp
IndexController.defaultAction() /Index/default /WEB-INF/index/defaultaction/index.jsp

Controller

@ActionStrategy(ActionStrategyType.Hierarchy)
public class IndexController{
  
   public void defaultAction(){
       ...
   }

}

The Parameter action strategy

URI mapping:

Controller/Action URI View
IndexController /Index /WEB-INF/index/index.jsp
IndexController.defaultAction() /Index?invoke=default /WEB-INF/index/defaultaction/index.jsp

Controller

@ActionStrategy(ActionStrategyType.Parameter)
public class IndexController{
  
   public void defaultAction(){
      ...
   }

}

Defining the default action

URI mapping:

Controller/Action URI View
IndexController.defaultAction() /Index /WEB-INF/index/index.jsp
IndexController.defaultAction() /Index/default /WEB-INF/index/defaultaction/index.jsp

Controller

@Controller(defaultActionName="/default")
public class IndexController{
  
   public void defaultAction(){
       ...
   }

}

Defining the abstract action

URI mapping:

Controller/Action URI View
IndexController /Index /WEB-INF/index/index.jsp
IndexController /Index/abstractAction /WEB-INF/index/view.jsp
IndexController.defaultAction() /Index/default /WEB-INF/index/defaultaction/index.jsp

Controller

@Action(value="/abstractAction", view=@View("view"))
public class IndexController{
  
   public void defaultAction(){
   }

}

Using URI template

URI mapping:

Controller/Action URI View
IndexController /mycontroller/{user} /WEB-INF/index/index.jsp
IndexController.defaultAction() /mycontroller/{user}/default /WEB-INF/index/defaultaction/index.jsp

Controller

@Controller("/mycontroller/{user}")
public class IndexController{
  
   private String user;

   public void defaultAction(){
       ...
   }

}

File upload

Form

<form method="POST" enctype="multipart/form-data" action="/Index/default">
  <input type="file" name="image"/>
</form>

Controller

public class IndexController{
  
   //@Identify version before 2.0 rc1
   public void defaultAction(@Basic(bean="image") File image){
       //the parameter image is a temporary file
       ...
   }

}

File download

Controller

public class IndexController{
  
   public File downloadAction(){
       return new File("/path/file.ext");
   }

}

Mounting the result action

Controller

public class IndexController{
  
   public ResultAction action1Action(ResultAction result){
      result.addInfo("Content-Type", "text/html; charset=utf-8")
            .setContentType(String.class)
            .setContent("<html><body>test</body></html>");
      return result;
   }

    public ResultAction action2Action (ResultAction result){
        result.addInfo("Content-Type", "text/html; charset=utf-8")
            .setView("myView")
            .add("value1", BigDecimal.ONE);
        return result;
    }

}

Creating a simple interceptor

Interceptor

public class MyInterceptorController implements InterceptorController{
  
    private Map props;

    public void setProperties( Map props ){
       this.props = props;
    }

    public boolean isConfigured(){
        return this.props != null;
    }

    public void intercepted( InterceptorStack stack, InterceptorHandler handler ) throws          
           InterceptedException{
        //code before action
        stack.next(handler);
        //code after action
    }
    
    public boolean accept(InterceptorHandler handler){
        return true;
    }

}

Controller

@InterceptedBy(@Intercept(interceptor=MyInterceptorController.class))
public class IndexController{
  
    ...

}

Creating a simple interceptor stack

Interceptor A

@InterceptsStack(name="stackA")
public class MyInterceptorAInterceptorController implements InterceptorController{
    ...
}

Interceptor B

@InterceptsStack(name="stackA", executeAfter=MyInterceptorAInterceptorController.class)
public class MyInterceptorBInterceptorController implements InterceptorController{
    ...
}

Controller

@InterceptedBy(@Intercept(name="stackA"))
public class IndexController{
    ...
}

Handling exceptions

URI mapping

Controller/Action URI View
IndexController /Index /WEB-INF/index/index.jsp
IndexController.defaultAction() /Index/default /WEB-INF/index/defaultaction/index.jsp
throw NullPointerException /Index/default /WEB-INF/index/defaultaction/nullpointerexception.jsp

Controller

public class IndexController{
  
   public void defaultAction() throw NullPointerException{
       ...
   }

}

Specifying handling exception

URI mapping

Controller/Action URI View
IndexController /Index /WEB-INF/index/index.jsp
IndexController.defaultAction() /Index/default /WEB-INF/index/defaultaction/index.jsp
throw NullPointerException /Index/default /WEB-INF/index/defaultaction/npe.jsp

Controller

@ThrowSafe(target=NullPointerException.class, view="npe")
public class IndexController{
  
   public void defaultAction() throw NullPointerException{
       ...
   }

}
Action

URI mapping

Controller/Action URI View
IndexController /Index /WEB-INF/index/index.jsp
IndexController.defaultAction() /Index/default /WEB-INF/index/defaultaction/index.jsp
throw NullPointerException /Index/default /WEB-INF/index/defaultaction/npe.jsp

Controller

public class IndexController{
  
   @ThrowSafe(target=NullPointerException.class, view="npe")
   public void defaultAction() throw NullPointerException{
       ...
   }

}

Simple bean mapping

Form

<form method="POST" action="/Index">
  <input type="hidden" name="invoke" value="default">
  <input type="text" name="myBean.id">
</form>

Bean

@Bean
public class MyBean{
  
    private Integer id;

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

    public Integer getId(){
        return this.id;
    }

}

Controller

public class IndexController{
  
   //@Identify version before 2.0 rc1
   public void defaultAction(@Basic(bean="myBean") MyBean bean) {
       ...
   }

}

Defining the property scope

Bean

@Bean
public class MyBean{
  
    private Integer id;

    //@Identify version before 2.0 rc1
    @Basic(scope=ScopeType.SESSION)
    private User user;
    
    ...
}

Defining the property name

Form

<form method="post" ... > 
    <input type="text" name="paramName.my_id"> 
</form>

Bean

@Bean
public class MyBean{
  
    //@Identify version before 2.0 rc1
    @Basic(bean="my_id")
    private Integer id;
    
    ...
}

Defining the bean constructor

Bean

@Bean
public class MyBean{

    public MyBean(){...}

    @Constructor
    public MyBean(Integer id){...}

}

Defining the target class

Controller

public class MyController{

    @Target(LinkedHashMap.class)
    private Map property;
    ...
}

Collection mapping

Form

<form method="post" action="...">
    <input type="text" name="person.name">
    <input type="text" name="person.address.element[0].type">
    <input type="text" name="person.address.element[0].street">
    <input type="text" name="person.address.element[0].city">
    <input type="text" name="person.address.element[0].state">
</form>

Bean

@Bean
public class Person {
    private String name;

    private List<Address> address;

    ...
}

Bean

@Bean
public class Address {

    private String type;
    private String street;
    private String city;
    private String state;
    ...
}

Map

Form

<form method="post" action="/person/save"> 
    <input type="text" name="person.name"> 
    <input type="text" name="person.address.key[0]"> 
    <input type="text" name="person.address.element[0].type"> 
    <input type="text" name="person.address.element[0].street"> 
    <input type="text" name="person.address.element[0].city"> 
    <input type="text" name="person.address.element[0].state"> 
</form>

Bean

@Bean
public class Person {
    private String name;

    private Map<String, Address> address;

    ...
}

Defining tha action view

URI mapping

Controller/Action URI View
IndexController /Index /WEB-INF/index/controllerView.jsp
IndexController.defaultAction() /Index/default /jsp/index.jsp

Controller

@View("controllerView")
public class IndexController{
  
   @View(value="/jsp/index.jsp", resolved=true)
   public void defaultAction(){
   }

}

Using Bean Validator

Action

public class IndexController{
  
   public void defaultAction(@NotNull Integer arg1){
       ...
   }

}

Action

public class IndexController{
   
   @NotNull
   public Integer defaultAction(){
       ...
       return result;
   }

}

Controller

public class IndexController{
  
   @NotNull
   private Integer value;

   public void defaultAction(){
       ...
   }

}

Controller

public class IndexController{
  
   private Integer value;

   public void setValue(@NotNull Integer value){
       this.value = value;
   }
   ...
}

Bean

@Bean
public class MyBean{
  
   @NotNull
   private Integer value;

   ...

}

Bean

@Bean
public class MyBean{
  
   private Integer value;

   public void setValue(@NotNull Integer value){
       this.value = value;
   }

   ...

}

Bean

@Bean
public class MyBean{
  
   
   private Integer value;

   public voud setValue(@NotNull Integer value){
       this.value = value;
   }

   ...

}

Complex form and mixing form and session.

Form

<form method="post" action="/Person/save"> 
    Person: <br>
    <input type="hidden" name="person.id"> 
    <input type="text" name="person.firstName"> 
    <input type="text" name="person.lastName">
    <input type="text" name="person.birthday">
    <input type="radio" name="person.gender" value="MALE"> Male
    <input type="radio" name="person.gender" value="FEMALE"> Female

    Childs <br>
    <!-- Child 1 -->
    <input type="text" name="person.childs.element[0].firstName"> 
    <input type="text" name="person.childs.element[0].lastName">
    <input type="text" name="person.childs.element[0].birthday">
    <input type="radio" name="person.childs.element[0].gender" value="MALE"> Male
    <input type="radio" name="person.childs.element[0].gender" value="FEMALE"> Female
    <!-- Child 2 -->
    <input type="text" name="person.childs.element[1].firstName"> 
    <input type="text" name="person.childs.element[1].lastName">
    <input type="text" name="person.childs.element[1].birthday">
    <input type="radio" name="person.childs.element[1].gender" value="MALE"> Male
    <input type="radio" name="person.childs.element[1].gender" value="FEMALE"> Female
    <!-- Child 3 -->
    <input type="text" name="person.childs.element[2].firstName"> 
    <input type="text" name="person.childs.element[2].lastName">
    <input type="text" name="person.childs.element[2].birthday">
    <input type="radio" name="person.childs.element[2].gender" value="MALE"> Male
    <input type="radio" name="person.childs.element[2].gender" value="FEMALE"> Female
</form>

Bean

public enum Gender{

   MALE,

   FEMALE;

}

Bean

@Bean
public class Person{

   private Integer id;

   private String firstName;

   private String lastName;

   private Date birthday;

   //@Enumerated(EnumerationType.STRING)
   private Gender gender;

   private List<Person> childs;

   ...

}

Controller

public class PersonController{

   //or inject logged user here
   //@Identify(scope="session") 
   //private User loggerdUser;

    public void saveAction(@Basic(scope="session") User loggerdUser, 
            @Basic(bean="person") Person person){
        ...
    }
}

Polymorphic Mapping

Mapping a polymorphic action parameter

@Controller("/property")
public class PropertyController{

    @Action("/save")
    public void saveProperty(
        @Basic(bean="property")
        @Any(
            metaBean=@Basic(bean="property_type")
            metaValues={
                @MetaValue(name="Decimal", target=DecimalProperty.class),
                @MetaValue(name="Set", target=SetProperty.class)
            }
        )
        Property property){
            ...
    }
}

Mapping a polymorphic collection

@Controller("/property")
public class PropertyController{

    @Action("/save")
    public void saveProperty(
        @Basic(bean="properties")
        @ElementCollection(
            any=
                @Any(
                     metaBean=@Basic(bean="property_type")
                     metaValues={
                         @MetaValue(name="Decimal", target=DecimalProperty.class),
                         @MetaValue(name="Set", target=SetProperty.class)
                     }
                 )
        )
        List<Property> properties){
            ...
    }
}

Mapping a polymorphic map

@Controller("/property")
public class PropertyController{

    @Action("/save")
    public void saveProperty(
        @Basic(bean="properties")
        @KeyCollection(
            any=
                @Any(
                     metaBean=@Basic(bean="property_type")
                     metaValues={
                         @MetaValue(name="Decimal", target=DecimalProperty.class),
                         @MetaValue(name="Set", target=SetProperty.class)
                     }
                 )
        )
        Map<Property,String> properties){
            ...
    }
}

Mapping a polymorphic property

@Controller("/property")
public class PropertyController{

    @Basic(bean="property")
    @Any(
        metaBean=@Basic(bean="property_type")
        metaValues={
            @MetaValue(name="Decimal", target=DecimalProperty.class),
            @MetaValue(name="Set", target=SetProperty.class)
        }
    )
    private Property property;

    @Action("/save")
    public void saveProperty(){
            ...
    }
}

See also

Tutorials

Book

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.