Dashboard > WebWork 1 > WebWork CookBook > Writing a ViewMapping
  WebWork 1 Log In View a printable version of the current page.  
  Writing a ViewMapping
Added by jwzrd, last edited by Hani Suleiman on Apr 25, 2004  (view change)
Labels: 
(None)

Sometimes, it is useful to write a custom view mapping. One of the reasons for this would be, for example, to allow for different mechanisms for looking up views, or different behaviour for determining what constitutes a view for a particular action.

The example below illustrates how a custom view mapping can be plugged in to allow for commands specified as parameters to be treated as regular command URL's in terms of views. The desired functionality is to be able to specify myaction!mycommand=foo.jsp in the view properties/XML file, and then have foo.jsp be used as the view when request /myaction.action?command=mycommand

Writing your own ViewMapping involves implementing the webwork.dispatcher.ViewMapping interface.

ViewMappingImpl.java:

public class ViewMappingImpl implements ViewMapping {
  public Object getView( String anActionName, String aViewName ) {
    return ...;
  }
}

WebWork internally uses the webwork.dispatcher.DefaultViewMapping class. A recommended practice is to have your class extend it, and overriding getView() to hook in your behaviour. This means, however, that your class will be first in the default sequence of ViewMapping delegation that WebWork uses. This sequence is:

  • ConfigurationViewMapping (which is the class in front of views.properties/actions.xml)
  • CachingViewMapping (caches view results to avoid a potentially expensive lookup)
  • DynamicViewMapping (Allows for resolving variables in views like ${foo})

Since CachingViewMapping and DynamicViewMapping are wrappers around another ViewMapping, they can easily be used to produce a different order of delegation.

Back to the example at hand. We'd like to specify a view mapping that is command aware with regards to commands specified as parameters. The implementation would be something like this:

CommandAwareViewMapping.java:

public class CommandAwareViewMapping implements ViewMapping {
  private ViewMapping delegate;

  public CommandAwareViewMapping( ViewMapping delegate ) {
    this.delegate = delegate;
  }

  public Object getView( String actionName, String viewName ) {
    if (
      //check if the current action on the stack is CommandDriven
      ActionContext.getValueStack().findValue( "." ) instanceof CommandDriven
       && ActionContext.getParameters().containsKey( "command" ) &&
            actionName.indexOf( '!' ) == -1
    ) {
      //it's a command driven action, and we have a command parameter but no
      //standard command delimiter '!'
      String command = ((String[]) ActionContext.getParameters().get(
         "command" ))[0];
      //Replace the lookup with a command-specific lookup
      return delegate.getView( actionName + '!' + command, viewName );
    } else {
      return delegate.getView( actionName, viewName );
    }
  }
}

Here is an example of how to implement a seamless redirection mechanism. It works by re-writing the url to views named redirect with a call to the standard redirect action. The code looks like the following:

RedirectViewMapping.java:

public class RedirectViewMapping implements ViewMapping {
  private ViewMapping delegate;
  private String redirectionPrefix;

  public RedirectViewMapping( ViewMapping delegate ) {
    this.delegate = delegate;

    /* this implies that the WebWork ServletDispatcher is mapped to *.jspa
       and that action suffix is "jspa"
       and that webwork.properties declares the standard redirect action
       Ideally this is read from some property store */
    redirectionPrefix = "/redirect.jspa?url=";
  }

  public Object getView( String anActionName, String aViewName ) {
    Object view = delegate.getView( anActionName, aViewName );
    if ("redirect".equals( aViewName )) {
      view = redirectionPrefix + view;
    }
    return view;
  }
}

Using it involves binding your redirection targets to your actions using the redirect view name like the following (using views.properties):

views.properties:

foo.CreateFoo.redirect = /foo/list.jsp

or (using actions.xml):
actions.xml:

<action name="foo.CreateFoo">
  <view name="redirect>/foo/list.jsp</view>
</action>

In both cases, we would also like to modify the delegation order, so the ViewMapping looks something like this:

MyDefaultViewMapping.java:

public class MyDefaultViewMapping implements ViewMapping {
  private ViewMapping delegate;

  public DefaultViewMapping() {
    delegate = new ConfigurationViewMapping();
    delegate = new CachingViewMapping( delegate );

    // to "attach" the command-parameter ViewMapping
    delegate = new CommandAwareViewMapping( delegate );

    // to "attach" the seamless redirect ViewMapping
    delegate = new RedirectViewMapping( delegate );
  }

  public Object getView( String actionName, String viewName ) {
    return delegate.getView( actionName, viewName );
  }
}

This is then easily hooked into WebWork by adding the following line to webwork.properties:

webwork.properties:

webwork.viewmapping=MyDefaultViewMapping
redirect.jspa=webwork.action.standard.Redirect

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.9 Build:#527 Sep 07, 2006) - Bug/feature request - Contact Administrators