14 Developing a Server-Side Website

In the Oracle WebCenter Sites Model-View-Controller Framework, to code your organization’s data model, you, the Java developer, can write Templates for views in JSP and use Groovy to code business logic in Controllers, streamlined with WebCenter Sites Java APIs. Web developers can add presentation elements to views.

Topics:

14.1 About Developing a Server-Side Website

In the Oracle WebCenter Sites Model-View-Controller (MVC) Framework, the model is your data model. For the view, you create a Template or SiteEntry object. You can use an out-of-the-box Controller or create one to tie the model and view together.

The Oracle WebCenter Sites Model-View-Controller (MVC) Framework is described in Server-Side MVC Framework.

WebCenter Sites provides several Controllers already built with common patterns of use, like navigation for reading assets. For information about these out-of-the-box Controllers, see Controllers, or go to the Developer’s Samples Website and choose Out of the Box Controllers from the Getting Started menu.

14.2 Working with the Controller Interface

The Controller interface includes the handleRequest() method that lets you write an independent WebCenter Sites controller with independent tests.

The interface is as follows:

public interface Controller
{

    /**
     * Run the controller with all the information passed in from setters
     * @return a ModelAndView object
     * @throws ControllerException throws this Exception if errors occurred in processing
     */
    DependenciesAwareModelAndView handleRequest() throws ControllerException;
}

A new WCSController is created to provide a set of default WebCenter Sites-specific functions.

public interface WCSController extends Controller
{
    /**
     * setting an ics into the Controller, ICS is needed for retrieving information related to Controller
     * @param ics the ICS object
     */
    public void setICS( ICS ics );

    /**
     * Get the current device
     * @return the device object
     */
    public Device getDevice();

    /**
     * set the current device
     * @param device the device
     */
    public void setDevice(Device device);

    /**
     * get the query parameters specified for this request. For multi-valued query parameter, provide the
     * name=value for each parameter value. For eg. attributes=name&attributes=description&attributes=tag.
     * @return the query parameters map
     */
    public Map<String, List<String>> getQueryParams();

    /**
     * get the headers for this request
     * @return the headers map
     */
    public Map<String, List<String>> getHeaders();

    /**
     * get the template parameters specified in Site for this requested page
     * @return the template parameters map
     */
    public Map<String, String> getTemplateParams();

    /**
     * get the current view
     * @return the view information
     */
    public String getViewMarkup();

    /**
     * get the template map information
     * @return the template map
     */
    public List<Map<String, String>> getTemplateMap();

    /**
     * get the current session variables for the request
     * @return the session variables
     */
    public Map<String, String> getSessionVariables();

    /**
     * get the variables that were available in current ICS
     * @return the variables
     */
    public Map<String, String> getVariables();

    /**
     * get the element catalog parameters specified in Site for this requested page
     * @return the element catalog parameters map
     */
    public Map<String, String> getElementCatalogParameters();


    /**
     * setting the current view into the Controller
     * @param view the current view markup
     */
    void setViewMarkup(String view);

    /**
     * setting the the redirect view pagename into the Controller
     * @param redirectViewPagename the redirect view pagename
     */
    void setRedirectViewPagename(String redirectViewPagename);

    /**
     * Getting the redirect view pagename
     * @return the redreict view pagename
     */
    String getRedirectViewPagename();

    /**
     * Set all request parameters into Controller
     * @param queryParams the request parameters
     */
    void setQueryParams(Map<String, List<String>> queryParams);

    /**
     * Set all request headers into the view
     * @param headers the request headers
     */
    void setHeaders(Map<String, List<String>> headers);

    /**
     * Set all template parameters related to current view into Controller
     * @param templateParams the template parameters (SiteCatalog parameters)
     */
    void setTemplateParams(Map<String, String> templateParams);

    /**
     * Set all template map information into the Controller
     * @param templateMap the list of template map information for current page
     */
    void setTemplateMap(List<Map<String, String>> templateMap);

    /**
     * Set all ics session variables into the view
     * @param sessionVariables the current ics session variables
     */
    void setSessionVariables( Map<String, String> sessionVariables );

    /**
     * Set all ics variables into the view
     * @param variables the current ics variables
     */
    void setVariables( Map<String, String> variables );

    /**
     * Set all ElementCatalog parameters into the view
     * @param elementCatalogParameters the ElementCatalog parameters
     */
    void setElementCatalogParameters( Map<String, String> elementCatalogParameters);
}
     

The default BaseController implements WCSController to provide default WebCenter Sites functionalities to customers who have implemented Controllers that do not provide. WCSController makes the access to assets and other WebCenter Sites data easy. A new set of annotations allows customers to inject certain WebCenter Sites-specific properties into the Controller. Specifically, Oracle has added annotations to inject these properties: AssetReader, NavigationReader, ics variables, ics session variables, headers, query parameters, and ControllerInvoker (allows customers to pass a Controller name. It invokes the passed-in Controller in the current Controller). Sample Controllers that use annotations to provide basic common functionalites are as follows:

Hello World Controller

package oracle.webcenter.sites.controller

import COM.FutureTense.Common.ControllerException
import COM.FutureTense.Interfaces.Controller
import COM.FutureTense.Interfaces.DependenciesAwareModelAndView
import COM.FutureTense.Interfaces.IItem
import COM.FutureTense.Cache.AccessedItem
import COM.FutureTense.Interfaces.ModelAndViewInstance
import com.fatwire.assetapi.data.*
import com.fatwire.assetapi.site.NavigationReader
import com.openmarket.xcelerate.asset.*
import com.fatwire.assetapi.fragment.*

public class FSIIHelloWorld implements Controller
{
  private Map models = new HashMap();
  public Map getModels()
  {
    return models;
  }

  public DependenciesAwareModelAndView handleRequest() throws ControllerException
  {
    models.put("text", "Hello World");

    return new ModelAndViewInstance( models );
  }
}

This Controller implements the Controller interface and only sets a “Hello World” message into the Model as a simple demonstration.

AssetReader Controller

package oracle.webcenter.sites.controller

import COM.FutureTense.Common.ControllerException
import COM.FutureTense.Interfaces.Controller
import COM.FutureTense.Interfaces.DependenciesAwareModelAndView
import COM.FutureTense.Interfaces.ModelAndViewInstance
import com.fatwire.assetapi.data.*
import com.fatwire.assetapi.site.NavigationReader
import com.openmarket.xcelerate.asset.*
import com.fatwire.assetapi.fragment.*

public class FSIIAssetReader implements Controller
{
  @InitAssetReader (assetType="AVIArticle", assetId=1328196047241 )
  private AssetReader assetReader;

  @InitAssetReader ( select="name,description" )
  private AssetReader assetReaderWithoutId;

  @InitRequestValuesMap (type=RequestValuesType.VARIABLES)
  private Map<String, Object> icsVariables;

  private Map models = new HashMap();
  public Map getModels()
  {
    return models;
  }

  public DependenciesAwareModelAndView handleRequest() throws ControllerException
  {
    models.put("assetReader", assetReader.read());
    models.put("assetReaderWithoutId",assetReaderWithoutId.forAsset( (String)icsVariables.get("c"), Long.parseLong((String)icsVariables.get("cid"))).read());
    return new ModelAndViewInstance(models);

  }
}

AssetReader Controller uses three annotations to initialize two AssetReaders to enable them for use in the Controller. The first AssetReader is initialized with assetType and assetId passed in through annotation parameters. The second one initializes the AssetReader assetType/assetId inside the handleRequest method using the values from icsVariables. Each AssetReader reads the specified asset and puts the results into the Model for display.

NavigationReader Controller

package oracle.webcenter.sites.controller

import COM.FutureTense.Common.ControllerException
import COM.FutureTense.Interfaces.Controller
import COM.FutureTense.Interfaces.DependenciesAwareModelAndView
import COM.FutureTense.Interfaces.ModelAndViewInstance
import com.fatwire.assetapi.data.*
import com.fatwire.assetapi.site.NavigationReader
import com.openmarket.xcelerate.asset.*
import com.fatwire.assetapi.fragment.*

public class FSIINavigationReader implements Controller
{
  @InitNavigationReader (assetType = "Page", assetId = 1346043544347)
  private NavigationReader navigationReader;

  private Map models = new HashMap();
  public Map getModels()
  {
    return models;
  }

  public DependenciesAwareModelAndView handleRequest() throws ControllerException
  {
    models.put("navigationReader", navigationReader.read());
     return new ModelAndViewInstance(models);
 }
}

Like the AssetReader Controller, the NavigationReader Controller uses annotations to initialize a NavigationReader in the Controller so it can be used by users to access the Navigation information from WebCenter Sites.

Variables, Headers, Session Variables and Request Parameters

package oracle.webcenter.sites.controller

import COM.FutureTense.Common.ControllerException
import COM.FutureTense.Interfaces.Controller
import COM.FutureTense.Interfaces.DependenciesAwareModelAndView
import COM.FutureTense.Interfaces.ModelAndViewInstance
import com.fatwire.assetapi.data.*
import com.fatwire.assetapi.site.NavigationReader
import com.openmarket.xcelerate.asset.*
import com.fatwire.assetapi.fragment.*

public class FSIIVariablesAnnotations implements Controller
{
  @InitRequestValuesMap (type=RequestValuesType.HEADERS)
  private Map<String, Object> headers;

  @InitRequestValuesMap (type=RequestValuesType.VARIABLES)
  private Map<String, Object> icsVariables;

  @InitRequestValuesMap (type=RequestValuesType.QUERY_PARAMS)
  private Map<String, Object> params;

  @InitRequestValuesMap (type=RequestValuesType.SESSION_VARIABLES)
  private Map<String, Object> icsSessionVariables;

  private Map models = new HashMap();
  public Map getModels()
  {
    return models;
  }

  public DependenciesAwareModelAndView handleRequest() throws ControllerException
  {
    models.put("headers", headers);
    models.put("variables", icsVariables);
    models.put("sessionVariables",  icsSessionVariables);
    models.put("queryParams", params);
    return new ModelAndViewInstance(models);
  }
}

These annotations populate a set of variables in the Controller from headers, ics variables, ics session variables and request parameters to be used in the Controller.

Logging a Dependency from Controller

package oracle.webcenter.sites.controller

import COM.FutureTense.Common.ControllerException
import COM.FutureTense.Interfaces.Controller
import COM.FutureTense.Interfaces.DependenciesAwareModelAndView
import COM.FutureTense.Interfaces.IItem
import COM.FutureTense.Cache.AccessedItem
import COM.FutureTense.Interfaces.ModelAndViewInstance
import com.fatwire.assetapi.data.*
import com.fatwire.assetapi.site.NavigationReader
import com.openmarket.xcelerate.asset.*
import com.fatwire.assetapi.fragment.*

public class FSIILogDeps implements Controller
{
  private Map models = new HashMap();
  public Map getModels()
  {
    return models;
  }

  public DependenciesAwareModelAndView handleRequest() throws ControllerException
  {
    models.put("text", "Log Controller Deps");

    List<IItem> items = new ArrayList<IItem>();
    items.add( new AccessedItem("Deps logged from Controller"));
    return new ModelAndViewInstance(models, items);
  }
}

This Controller demonstrates how a user-defined dependency could be logged from Controller.

Displaying a View Markup from Controller

package oracle.webcenter.sites.controller

import COM.FutureTense.Common.ControllerException
import COM.FutureTense.Interfaces.Controller
import COM.FutureTense.Interfaces.DependenciesAwareModelAndView
import COM.FutureTense.Interfaces.ModelAndViewInstance
import com.fatwire.assetapi.data.*
import com.fatwire.assetapi.site.NavigationReader
import com.openmarket.xcelerate.asset.*
import com.fatwire.assetapi.fragment.*

public class FSIIViewMarkup implements Controller
{
  private Map models = new HashMap();
  public Map getModels()
  {
    return models;
  }

  public DependenciesAwareModelAndView handleRequest() throws ControllerException
  {
    models.put("text", "Some Text");
    return new ModelAndViewInstance(models, null, "Display this view markup text from Controller", null);
  }
}

This Controller informs Webcenter Sites that original page is not displayed, instead, the text in the viewMarkupText returned from Controller is returned.

Redirecting the View to Another WebCenter Sites Page

package oracle.webcenter.sites.controller

import COM.FutureTense.Common.ControllerException
import COM.FutureTense.Interfaces.Controller
import COM.FutureTense.Interfaces.DependenciesAwareModelAndView
import COM.FutureTense.Interfaces.ModelAndViewInstance
import com.fatwire.assetapi.data.*
import com.fatwire.assetapi.site.NavigationReader
import com.openmarket.xcelerate.asset.*
import com.fatwire.assetapi.fragment.*

public class FSIIRedirectView implements Controller
{
  private Map models = new HashMap();
  public Map getModels()
  {
    return models;
  }

  public DependenciesAwareModelAndView handleRequest() throws ControllerException
  {
    return new ModelAndViewInstance(models, null, null, "FirstSiteII/FSIIRedirectedView");
  }
}

This Controller instructs WebCenter Sites to redirect a page to another WebCenter Sites page content.

Calling Another Controller

package oracle.webcenter.sites.controller

import COM.FutureTense.Common.ControllerException
import COM.FutureTense.Interfaces.Controller
import COM.FutureTense.Interfaces.DependenciesAwareModelAndView
import COM.FutureTense.Interfaces.IItem
import COM.FutureTense.Cache.AccessedItem
import COM.FutureTense.Interfaces.ModelAndView
import COM.FutureTense.Interfaces.ModelAndViewInstance
import com.fatwire.assetapi.data.*
import com.fatwire.assetapi.site.NavigationReader
import com.openmarket.xcelerate.asset.*
import com.fatwire.assetapi.fragment.*

public class FSIICallAnotherController implements Controller
{
  @InjectControllerInvoker (controllerName = "FSIIHelloWorld", pagename = "FirstSiteII/FSIIHelloWorld")
  private ControllerInvoker controllerInvoker;
  
  private Map models = new HashMap();
  public Map getModels()
  {
    return models;
  }

  public DependenciesAwareModelAndView handleRequest() throws ControllerException
  {
    ModelAndView modelAndView = controllerInvoker.invoke(new HashMap());
    
    models.putAll(modelAndView.getModel());
    
    return new ModelAndViewInstance( models);
  }
}


This Controller uses annotations to initialize a ControllerInvoker with the Controller name so that the passed-in Controller could be invoked inside this Controller.

14.3 Creating a Controller

Creating a Controllerwith the Create New Controller wizard in the Admin interface of Oracle WebCenter Sites is quick and easy. All you need to do is give your Controller a name and add its business logic to the wizard.

In a similar way, you can create Controllers with Oracle Developer Tools in an Eclipse IDE. See Managing WebCenter Sites Resources in Eclipse.

To create a Controller through the Admin interface:

  1. On the New page of the WebCenter Sites Admin interface, click New Controller in the asset type table.

    The Create New Controller wizard opens.

    Description of newcontroller.gif follows
    Description of the illustration newcontroller.gif
  2. In the Name field, enter a name for the new Controller.

  3. (Optional) In the Description field, enter a description of the new Controller.

  4. In the Controller Logic field, add your business logic code.

  5. Click the Save icon.

For more information about developing Controllers, go to the Developer’s Samples Website and choose Controller from the Site Rendering menu.

14.4 Creating a Template

The WebCenter Sites Admin interface’s easy-to-use template form lets you can create a Template asset quickly.

To create a Template using the Admin interface:

  1. Click New.

  2. In the table on the right, click the New Template link next to Template.

  3. Fill in the Template form.

  4. Save the Template.

See Creating Template Assets.

14.5 Setting Up the Home Page

Design a modular home page for your website that uses common elements. You can use the common code of those elements in several locations or contexts.

For information about setting up a home page for your website, see these topics:

14.6 Adding Site Navigation

Oracle WebCenter Sites provides Navigation Reader, Link Builder, and Bob Link Builder Java APIs that you can use to create a site navigation for your website.

You can add site navigation for your website with the following Java APIs:

For more information about these Java APIs, go to the Rendering API menu on the Developer’s Samples Website.