Skip navigation header
Oracle ADF UIX Developer's Guide Go to Table of Contents
Contents
Go to previous page
Previous
Go to next page
Next

17. Configuration for ADF UIX

This chapter discusses the Oracle ADF UIX Configuration API, which is used for managing configuration information for all parts of a UIX application. The chapter contains the following sections:

The Configuration API

The UIX Configuration API is UIX's mechanism for passing global configuration information to all parts of the UIX framework. Configuration information consists of three types of information: URLs, file system paths, and a number of other properties. Both URLs and paths are used to indicate the location of UIX resources, such as images or style sheets used by the UIX framework. All configuration information is accessed via instances of the Configuration class, which is an immutable base class. The Configuration API also provides a companion mutable subclass, ConfigurationImpl, which applications can use to override default configuration values.

Configuration objects can be created from Java, but it's much easier to use the uix-config.xml file in your WEB-INF directory, which provides a simple XML format for creating configurations.

Configuration objects are passed throughout the UIX framework via the various project-specific contexts, such as the UIX Servlet's BajaContext, the Components' RenderingContext, the Images' ImageContext, and so forth. Unlike the other context objects, which are created to service a single HTTP request and are released upon completion of the response, Configuration objects exist for the lifetime of the application. This allows the application to perform configuration initialization once, and then reuse a single Configuration object (or a small number of Configuration objects) to service all requests.

UIX Resource Files

The UIX framework makes use of a variety of resource files, such as images and style sheets, which are required to be installed on a web server for use by UIX-generated web pages. In many cases, web applications require that application-specific resources be installed in a particular standard directory. For example, an application may require that its images be installed in the /images directory. The problem with this approach is that it introduces the potential for resource file name collisions between different applications. Imagine two different applications which refer to /images/logo.gif or styles.css. These two applications would not be able to co-exist on a single web server. The UIX framework avoids such resource file name collisions in two ways. First, the UIX framework partitions off its own resources by placing them in default resource directories under /cabo. Second, the UIX framework allows default resource locations to be overridden via the Configuration API.

The following table lists the name, default location, and contents for each of the UIX resource directories. The names are specified using the directory constants defined in the Configuration class. The default locations are specified as relative URLs.

Java Name XML Element Default Location Contents
BASE_DIRECTORY <base-directory> /cabo/ Contains all of the other UIX resource directories
IMAGES_DIRECTORY <images-directory> /cabo/images/ Contains static images used by UIX Components
STYLES_DIRECTORY <styles-directory> /cabo/styles/ Contains XML Style Sheet documents used by UIX
JSLIBS_DIRECTORY <jslibs-directory> /cabo/jsLibs/ Contains JavaScript library files used internally by UIX
JSPS_DIRECTORY <jsps-directory> /cabo/jsps/ Contains JSP files used internally by UIX
IMAGES_CACHE_DIRECTORY <images-cache-directory> /cabo/images/cache/ Contains application-specific images which are dynamically generated by UIX
STYLES_CACHE_DIRECTORY <styles-cache-directory> /cabo/styles/cache/ Contains Cascading Style Sheet files which are dynamically generated by UIX

The UIX resource directory structure is hierarchical. Changing the location of a parent directory also causes the location of child directories to be moved. For example, changing the IMAGES_DIRECTORY will implicitly change IMAGES_CACHE_DIRECTORY, and changing BASE_DIRECTORY will implicitly change all other directories.

All of the default locations defined above can be modified by using a ConfigurationImpl instance which has been configured with application-specific values or by adding elements to WEB-INF/uix-config.xml.

Editing uix-config.xml

UIX makes it easy to set up configuration objects with a single XML file. This file must be stored in a uix-config.xml file in your WEB-INF directory. This is the same WEB-INF directory where web.xml lists servlets and file mappings. (This directory only exists for Java Servlet 2.1 or later.)

The WEB-INF/uix-config.xml file always begins (and ends) with the same element, <configurations>. Inside that element it contains a series of elements that will configure UIX. For example:

  <?xml version="1.0" encoding="ISO-8859-1"?>
  <configurations xmlns="http://xmlns.oracle.com/uix/config">

    <!-- A series of properties global to your application -->
    <application-configuration>
      <uix-path>c:\yourDirectory\uixFiles\</uix-path>
      <check-modified>true</check-modified>
      <ui-extensions>
        <template-library>templates/library.uit</template-library>
      </ui-extensions>
    </application-configuration>

    <!-- A set of default properties -->
    <default-configuration>
      <base-path>
        <context-uri>uixInst</context-uri>
      </base-path>

      <help-provider>
        <ohw-servlet-url>http://yourserver.com/ohw</ohw-servlet-url>
      </help-provider>
    </default-configuration>

    <!-- An alternate configuration that disables accessibility features  -->
    <configuration name="noAccessibility">
      <accessibility-mode>inaccessible</accessibility-mode>
    </configuration>

    <!-- And another configuration that maxes out accessibility features -->
    <configuration name="maxAccessibility">
      <accessibility-mode>screenReader</accessibility-mode>
      <style-sheet-name>myBigStyleSheet.xss</style-sheet-name>
    </configuration>

  </configurations>

We'll shortly talk about all of the elements you can use in a configuration file, but a quick run-through of this example should give you a lay of the land.

Each uix-config.xml file contains three sections, each of which is optional:

  1. First, an <application-configuration> section defines properties that will be global to an entire web application.
  2. Second, a <default-configuration> section defines properties that will be used as defaults - but can be overridden.
  3. Finally, any number of <configuration> elements let you define named overrides of the <default-configuration>.

In the example, <application-configuration> has informed UIX that it should search for its .uix files in the c:\yourDirectory\uixFiles\ directory. (This doesn't affect where UIX looks for images, Javascript libraries, etc. - just the UIX files). We've also asked that UIX pay attention to when files are modified so it can drop the cached version and reload the file; this makes debugging much easier, but carries a small performance hit. Finally, we've registered a single template library, which means UIX users won't need to manually import the library on each page.

Next, <default-configuration> sets up two more properties. First, it changes <base-path>, which is the root directory where UIX installables live. Then, it points UIX at an instance of the Oracle Help for the Web (OHW) servlet; with just these few lines, all your UIX pages will support context-sensitive help. (Oracle Help for the Web is a powerful web-based help solution that is available for free from Oracle. Visit the Oracle Technology Network (http://otn.oracle.com) for more information.)

Finally, we add two named <configuration> options to adjust the level of accessibility support. One option disables accessibility features, and the other enhances accessibility from its default. These configurations would let us tailor our output to the specific user, though it's still up to an application to decide which user gets which setting (with a preferences page, for example). Both of these <configuration> choices also inherit both of the values set in <default-configuration>, so there's no need to re-specify the OHW server or the base path.

Editing <application-configuration>

The <application-configuration> element supports several children. The order of these children does matter. They must be included in the order they're described here.

Enabling Debugging Functionality

UIX offers several features that can be turned on while debugging, but should not be used when deploying an application (unless you need to debug problems on a deployed application). To turn on "debug" mode in UIX, set the debug attribute of <application-configuration> to "true": For example:

   <application-configuration debug="true">
     <debug-indent-output>true</debug-indent-output>
   </application-configuration>

All the elements whose name starts with debug- are considered debug-mode-only settings, and will be ignored unless debugging is explicitly turned on. This lets developers pick a set of debugging features and rapidly turn them on and off.

In addition to features that can be individually turned on and off, UIX will enable some functionality automatically when in debug mode:

Editing <default-configuration> and <configuration> Elements

The <default-configuration> and <configuration> elements support several children. The order of these children does not matter, but if you include a <default-configuration>, it must come before all <configuration> elements.

The resource directory elements

A configuration file can set any of seven different UIX resource directories; these directories are listed and described above in UIX Resource Files, and the use of these elements is described below in Modifying UIX Resource Locations.

Using A Non-default Configuration

Applications may use the default configuration by simply not specifying a Configuration instance at render time. Alternatively, an application may use a single application-specific Configuration instance for all page renders, or it may choose from a small number of instances on a per-render basis. For example, a different Configuration instance may be used depending on the target content type (HTML vs. WML) or to provide custom configurations for different customers in a hosted application environment.

When using the UIX Servlet, a Configuration can be specified for each request by overriding the UIXPageBroker.getConfigurationName method.


  protected String getConfigurationName(
    BajaContext context,
    Page page)
  {
    if (_doIWantMyOtherConfig(...))
      return "MyOtherConfig";
    return "MyConfig";
  }

For developers not using the UIX Servlet, once the Configuration instance has been configured and registered - either in uix-config.xml or in Java , it can be used at render time by calling setConfiguration() on the UIX Components RenderingContext. UIX Components's BaseRenderingContext provides two overloads of setConfiguration(): one which takes the Configuration instance, and another which takes the Configuration name.

Creating ConfigurationImpl Instances

Applications which need to override the default configuration values from Java can do so by creating their own ConfigurationImpl instances. Creating a configuration involves a three step process:

  1. Create a new ConfigurationImpl instance
  2. Set the application-specific URLs, paths, and properties on this instance
  3. Register the instance

These steps are performed one time only. The following example demonstrates how to create and register application-specific ConfigurationImpl instance.

// Create the ConfigurationImpl instance, specifying a unique name
ConfigurationImpl config = new ConfigurationImpl("iProductConfig");

// Configure the instance with application-specific values
config.putRelativeURI(Configuration.BASE_DIRECTORY, "/iProduct/cabo/");

ServletContext context = _getAServletContext();
// Register the instance
config.register(context);

Every ConfigurationImpl instance must have a unique name and must be registered by calling the Configuration.register(ServletContext) method. (UIX also supports registering configurations globally with a register() method, but this is deprecated.) These requirements are necessary to allow configuration settings to survive round trips to and from the browser when UIX's private JSPs are used.

Modifying UIX Resource Locations

Although the default location of the UIX resource files protects against name collisions with resource files from other applications, it may be useful to move the UIX resources to some other location altogether. For example, in environments where multiple UIX applications may be installed, it may be useful for each application to have its own copy of the UIX resources. That way, if one application upgrades to a new version of UIX, the UIX resource files used by other applications would not be affected. (This is particularly important for applications which are not partitioned by some other means, for example, applications which are not installed into their own Servlet context.)

The simplest way to modify the UIX resource directory locations is to use the ConfigurationImpl.putRelativeURI() method or <context-uri> XML element. This method takes the key constant of the directory to move, and the new relative URL for the directory. The following code demonstrates how to move a single resource directory.


<!-- in UIX XML -->
<jsps-directory>
  <context-uri>/iProduct/cabo/jsps/</context-uri>
<jsps-directory>

// In Java:
config.putRelativeURI(Configuration.JSPS_DIRECTORY, "/iProduct/cabo/jsps/");

As a result of this change, UIX Components will generate URLs of the form <context path>/iProduct/cabo/jsps/ when referring to the UIX Components JSP files. The application is required to have the UIX Components JSPs installed in the corresponding directory on the file system.

The UIX resource directory structure is hierarchical. Changing the location of a parent directory also causes the location of child directories to be moved. For example, the following code changes both the IMAGES_DIRECTORY and the child IMAGES_CACHE_DIRECTORY.


<!-- in UIX XML: -->
<images-directory>
  <context-uri>/iProduct/images/</context-uri>
</images-directory>

// In Java:
config.putRelativeURI(Configuration.IMAGES_DIRECTORY, "/iProduct/images/");

As a result, the UIX Components images should be installed in the directory corresponding to /iProduct/images/. If the IMAGES_CACHE_DIRECTORY is not explicitly specified, UIX Dynamic Images-generated images are created in the the subdirectory corresponding to /iProduct/images/cache.

Similarly, all of the UIX resource directories can be moved with a single call to putRelativeURI() by modifying the BASE_DIRECTORY value (or using the <base-directory> element).

Working with Full Paths

All of the previous examples make use of relative URLs, which are resolved relative to the context path of the Servlet. An alternate approach is to use ConfigurationImpl.putFullURIAndPath(), or both of the <full-uri> and <full-path> elements to specify absolute locations. Absolute locations can be useful for sharing UIX resources across machines or for offloading work to other web servers. For example, the following sample demonstrates how to configure UIX to allow the images to be served by a secondary web server.


<!-- in UIX XML -->
<images-directory>
  <full-path>/net/images/private/httpd/htdocs/cabo/images/</full-path>
  <full-uri>http://images.example.com/cabo/images/</full-uri>
</images-directory>

// In Java:
// The full URI to the images directory on the image server
String fullURI = "http://images.example.com/cabo/images/";

// The full file system path to the auto-mounted images directory
String fullPath = "/net/images/private/httpd/htdocs/cabo/images/";

config.putFullURIAndPath(config.IMAGES_DIRECTORY, fullURI, fullPath);

Using this configuration, all URLs refering to UIX Components images will start with the URL http://images.example.com/cabo/images/, and thus will be served by the web server at images.example.com. Offloading the work of serving up image files to a second web server reduces the amount of work that needs to be done by the primary server, and can result in improved response times. However, keep in mind that longer URLs can result in larger page sizes, as the full URL must be generated for each image referenced by UIX Components.

Applications should never use hardcoded absolute file system paths, as the actual paths may vary from machine to machine. File system paths should be configurable at deployment time. This can be achieved by allowing the paths to be specified as part of the installation process. Or, full paths can be retrieved from a configuration file (like uix-config.xml) or via Servlet initialization parameters.

Apache Aliased Directories

Another case in which a custom configuration with full URLs/paths may be necessary is when the application's JSP files and the UIX resources are located in a aliased directory on an Apache web server. Apache allows URLs to be aliased to directories outside of the web server's document root. For example, the following entry in the Apache httpd.conf configuration file creates an alias for the URL /HTML/.

Alias /HTML/ "/private/html/"

As a result of this alias, any URLs starting with /HTML/ will be translated to paths under the /private/html/ directory. In order to move the UIX resources into the aliased directory, under /private/html/cabo, the following configuration should be sufficient:


<!-- In XML: -->
<base-directory>
  <context-uri>/HTML/cabo/</context-uri>
</base-directory>

// In Java:
config.putRelativeURI(Configuration.BASE_DIRECTORY, "/HTML/cabo/");

In the case where /HTML/ is not aliased, this configuration will work correctly. However, when /HTML/ is aliased as described above, this configuration does not produce the desired results. Apache's aliasing mechanism affects the way file system paths are reported by the servlet engine. So, although any HTML generated by UIX Components will contain the correct URLs, starting with /HTML/cabo/, images and style sheets which are dynamically generated by UIX are not created in the correct locations on the file system. For example, in this particular case, the IMAGES_CACHE_DIRECTORY, which should be created at "/private/html/cabo/images/cache", is actually created at "/private/html/HTML/cabo/images/cache". The end result is that the URLs for generated images and style sheets do not match the locations in the aliased directory, and broken images and missing styles result.

This problem can be avoided by configuring UIX with the actual full path of the aliased UIX resource location. The following call to putFullURIAndPath() shows the required configuration for this particular case.


<!-- in UIX XML -->
<base-directory>
  <full-uri>/HTML/cabo/>/full-uri>
  <full-path>/private/html/cabo/</full-path>
</base-directory>

// In Java:
config.putFullURIAndPath(Configuration.BASE_DIRECTORY,
                       "/HTML/cabo/",
                       "/private/html/cabo/");

When using this full URL configuration instead of the relative URL configuration proposed above, UIX will correctly place dynamically generated resources in the aliased directory under /private/html/cabo/. Of course, the full path /private/html/cabo/ should not be hardcoded, as the actual path may vary from machine to machine. Instead, the full path of the aliased directory can be derived dynamically using the Servlet API's ServletContext.getRealPath(). getRealPath() translates URLs to file system paths. The following code, when called from a JSP in the aliased /private/html/ directory, will produce the correct configuration:

// The call to getRealPath("/") will return the root directory of the
// alias, which is "/private/html".
String realPath = servletContext.getRealPath("/");

config.putFullURIAndPath(Configuration.BASE_DIRECTORY,
                       "/HTML/cabo/",
                       realPath + "/cabo/");

Using the UIX Cookie

UIX contains support for using a cookie to maintain the pieces of a user's profile that affect UIX. We take privacy and security seriously: the cookie is small and tightly scoped to the originating server only, and contains no information that needs to be encrypted. The cookie currently contains only two pieces of information:

Clients that need to set and get properties from the cookie do so with the oracle.cabo.share.config.UIXCookie Java class. To get the cookie, you'll need the HttpServletRequest and HttpServletResponse:


  HttpServletRequest request = ...;
  HttpServletResponse response = ...;

  // Get the UIX cookie, creating it if it hasn't been set already
  UIXCookie cookie = UIXCookie.getUIXCookie(request, response);
  cookie.setAccessibilityMode(AccessibilityMode.SCREEN_READER_MODE);
  cookie.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));

UIX will automatically default its accessibility mode and time zone based on the values set on the cookie. You can still explicitly set these values explicitly (on the Configuration and LocaleContext respectively) if you wish. But the UIX cookie provides a much easier way for applications to add basic UIX preferences to their login screens without any recoding of their other pages, or any support for persisting those preferences from one login to the next (as the UIX Cookie is very long-lived.) As an example, you can add the following component to your login page to add full support for setting the accessibility level of an application:



   <messageChoice name="access" prompt="Accessibility: ">
     <contents>
       <option text="(None)" value=""/>
       <option text="Default" value="D"/>
       <option text="Disabled" value="I"/>
       <option text="Enhanced" value="S"/>
     </contents>
   </messageChoice>


... and the following code to your login event handler:



  ...
    AccessibilityMode mode = _decodeAccessibilityMode(
                                       event.getParameter("access"));
    UIXCookie cookie = UIXCookie.getUIXCookie(context.getServletRequest(),
                                              context.getServletResponse());
    cookie.setAccessibilityMode(mode);
  ...


  //
  // Utility for decoding a string value into an AccessibilityMode
  //
  static private AccessibilityMode _decodeAccessibilityMode(String value)
  {
    if ("".equals(value))
      return null;
    else if ("D".equals(value))
      return AccessibilityMode.DEFAULT_MODE;
    else if ("I".equals(value))
      return AccessibilityMode.INACCESSIBLE_MODE;
    else if ("S".equals(value))
      return AccessibilityMode.SCREEN_READER_MODE;

    return null;
  }
}

(For extra credit, you'd want to databind the "selectedValue" of the <messageChoice> to default to the last-chosen value of accessibility mode.)

In addition, to Java access, UIX includes automatic support for defaulting the time zone of the client using Javascript in the browser, which solves an obscure but important problem. The HTTP protocol sends headers that provide a lot of information about the user, including the user's language and browser type. Unfortunately, it does not include the user's time zone. However, that information is accessible from Javascript. UIX takes advantage of this by pushing the information available from Javascript into the UIX Cookie (unless the time zone has already been explicitly specified.) The cookie will be sent the server on the next request, so the server can report correct times to the user. (The cookie won't have the time zone until the second request - so the time zone will be wrong on the very first page a user sees.) If this support is not wanted, it can be disabled using the <disable-uix-cookie> element in WEB-INF/uix-config.xml; see above.