Controller

From JRapid

(Redirected from MainController)
Jump to: navigation, search

Contents

Description

JRapid applications are generated with a single main controller class that handles every CRUD (Create/Retrieve/Update/Delete) request and other operations performed on the model classes, that is, on every entity. This controller, the MainController, maps every operation to the corresponding Services class according to the target resource.

As it happens with every other component of JRapid generated applications, the controller is created in two layers, allowing for customization. Both files are created in the controller subpackage of the default package for the application. The MainController class extends MainControllerAbstract class, where all the automatically generated code is placed. The abstract class should not be edited as any changes will later be overwritten.

The controller exposes your internal service methods in <Entity>Services.class so that they can be accessed via GET and POST methods. In Ruby on Rails this type of exposed method is referred to as a "route". Spring also contains similar functionality. In Spring parlance, they are referred to as paths, and the Spring scaffolding even creates their own type of controller to expose the service. JRapid applications create and expose many of these methods automatically for the front end to access services in addition to easily allowing developers to add their own custom methods and have these services made available through the controller.

Controller Servlet

Every JRapid application defines the controller servlet in their web.xml mapped to the DefaultController class, part of the jrapid-ntier library.

        ...
	<servlet>
		<servlet-name>controller</servlet-name>
		<servlet-class>com.jrapid.controller.DefaultController</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>controller</servlet-name>
		<url-pattern>/xml/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>controller</servlet-name>
		<url-pattern>/xmlrpc/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>controller</servlet-name>
		<url-pattern>/upload/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>controller</servlet-name>
		<url-pattern>/report/*</url-pattern>
	</servlet-mapping>
        ...


Hierarchy

The DefaultController class extends the FrontController class, a servlet included as part of the jrapid-ntier library that acts as the only entry point for the application, as long as no customizations are added, of course.

DefaultController loads every controller defined in the project's /JavaSource/controllers.cfgs configuration file. The MainController included in the controller subpackage of every project is included in the controllers.cfgs file when this is created.

The automatically generated MainControllerAbstract class extends FrontController as well.

Every generated service is registered in the MainController Abstract file. For each entity the following lines are included in the controller, inside the init method where "Entity" is your particular entity.

	@Override
	protected void init(FrontController controller) {
			
			// main for Entity
			controller.registerXmlRpcService(EntityServices.class, "removeMany", "Entity.remove");
			controller.registerXmlService(GET, "/Entity", EntityServices.class, "findPage", new DefaultMarshaller(), true);
			controller.registerXmlService(GET, "/Entity/([0-9,]+)" , EntityServices.class, "find", new DefaultMarshaller(true), false);
			controller.registerXmlService(POST, "/Entity/([0-9,]+)", EntityServices.class, "store", new DefaultMarshaller(true, "com/beta20101222/xml/EntityFull.xml"), false);
		
			...
	}

Services

These registered services map to methods generated in the classes of the services package, as shown below. Note the servlet mapping url patterns defined in the deployment descriptor. Each type of service adds a segment to the URL: xml and xmlrpc are worth noting in this case.

GET /xml/Entity/{params}
List entities. Maps to EntityServices.findPage() method.
GET /xml/Entity/{id}
Get an entity record. Maps to EntityServices.find() method.
POST /xml/Entity/{id}
Create or Update an entity record. Maps to EntityServices.store() method.
XML-RPC "Entity.remove" with ids as parameter
Delete entity records. Maps to EntityServices.removeMany() method.

Subsets

If a subset is created for the entity, the following service is added.

      controller.registerXmlService(GET, "/Entity/<SubsetName>", EntityServices.class, "<SubsetName>", new DefaultMarshaller(), true);
GET /xml/Entity/<SubsetName>/{params}
Lists active entities. Maps to the EntityServices.find<SubsetName>() method.

Defaultsets

For every defaultset defined for an entity, a couple of services are registered:

      controller.registerXmlService(GET, "/Entity/<DefaultSetName>/(?:([^/&&[^;]]*))?", EntityServices.class, "<DefaultSetName>", new DefaultMarshaller(true), false);
      controller.registerXmlService(POST, "/Entity/<DefaultSetName>/(?:([^/&&[^;]]*))?", EntityServices.class, "store<DefaultSetName>", new DefaultMarshaller(true, "com/beta20110103/xml/EntityFull.xml"), false);
GET /xml/Entity/<DefaultSetName>/{params}
Get an entity record using defaultset. Maps to EntityServices.find<DefaultSetName>() method.
POST /xml/Entity/<DefaultSetName>/{params}
Create or Update an entity record using defaultset. Maps to EntityServices.store<DefaultSetName>() method.

Auto-Suggest

If your user interface provides a suggestion capability the following will be added with <Property> being the name of the field for which the suggestions are being provided:

       controller.registerXmlService(GET, "/Entity/suggest<Property>/(.*)", EntityServices.class, "suggest<Property>", new DefaultMarshaller());
GET /xml/Entity/suggest<Property>/{params}
Get a list of suggestions for possible values like the parameter.

Unique

If any of the properties of an entity is unique you will have the following:

      controller.registerXmlRpcService(<Entity>Services.class, 
				"checkUniqueFor<Property>", 
				"Entity.checkUniqueFor<Property>");
XML-RPC "<Entity>.checkUniqueFor<Property>"
Verify uniqueness of property value.

Example

    <entity label="Company" menu="menu" name="Company">
        <subset name="byActiveNotExpired">
            <param name="companyActive" type="boolean"/>
            <condition field="active" value="companyActive"/>
            <condition field="expiration" ge="now()"/>
        </subset>

        <defaultset name="defaultCompanies">
            <default name="active" value="true"/>
        </defaultset>

        <property display="primary" label="Name" name="name" required="required" type="string" unique="unique">
        <suggest expr="SELECT c.name FROM Company as c WHERE c.name LIKE concat('%', ?, '%')"/>
        </property>
        <property label="Address" name="address" type="text"/>
        <property label="Expiration" name="expiration" type="date"/>
        <property label="Active" name="active" type="boolean"/>

        <filter display="primary" label="Active Filter" name="activeFilter" property="active"/>
    </entity>

This entity containing a filter, subset and defaultset auto creates the following:

public class MainControllerAbstract extends FrontController {

	@Override
	public void init(ServletConfig config) throws ServletException ...
		
	@Override
	protected void init(FrontController controller) {
			/* Find, store, remove basic operations */
			controller.registerXmlRpcService(CompanyServices.class, "removeMany", "Company.remove");
			controller.registerXmlService(GET, "/Company", CompanyServices.class, "findPage", new DefaultMarshaller(), true);
			controller.registerXmlService(GET, "/Company/([0-9,]+)" , CompanyServices.class, "find", new DefaultMarshaller(true), false);
			controller.registerXmlService(POST, "/Company/([0-9,]+)", CompanyServices.class, "store", new DefaultMarshaller(true, "com/libraryproject/xml/CompanyFull.xml"), false);
			
                        /* For subset "byActiveNotExpired" */
			controller.registerXmlService(GET, "/Company/byActiveNotExpired/(?:([^/&&[^;]]*))?", CompanyServices.class, "findSubsetByActiveNotExpired", new DefaultMarshaller(), true);

                        /* For defaultset "byActiveNotExpired" */
			controller.registerXmlService(GET, "/Company/defaultCompanies", CompanyServices.class, "findDefaultCompanies", new DefaultMarshaller(true), false);
			controller.registerXmlService(POST, "/Company/defaultCompanies", CompanyServices.class, "storeDefaultCompanies", new DefaultMarshaller(true, "com/libraryproject/xml/CompanyFull.xml"), false);
			
                        /* For auto-suggest */
                        controller.registerXmlService(GET, "/Company/suggestname/(.*)", CompanyServices.class, "suggestName", new DefaultMarshaller());
			
                        /* For verifying uniqueness of company name */
                        controller.registerXmlRpcService(CompanyServices.class, 
				"checkUniqueForName", 
				"Company.checkUniqueForName");
	}

}

See also

Personal tools