34 Customizing Applications with MDS

The Oracle Metadata Services (MDS) framework allows you to create customizable applications. This chapter describes how to develop applications that can be customized and subsequently deployed by a customer. It also covers how to implement customizations on such applications.

This chapter includes the following sections:

For information on how to deploy customized applications, see Section 36.4, "Deploying the Application."

34.1 Introduction to Customization and MDS

Using the customization features provided by MDS, you can create applications that fall into the following customization patterns:

  • Seeded customization

    Seeded customization of an application is the process of taking a generalized application and making modifications to suit the needs of a particular group, such as a specific industry or site. Seeded customizations exist as part of the deployed application, and endure for the life of a given deployment. This chapter describes how to create a customizable application, and then customize the application using JDeveloper.

  • User customization (change persistence)

    User customization allows an end user to change the content of the application at runtime to suit individual preferences (for example, which columns are visible in a table), and have those changes "remembered" the next time the user opens the application. For information about user customization, see Chapter 35, "Allowing User Customizations at Runtime."

  • Design time at runtime

    Using the features of Oracle WebCenter, you can create applications that are customizable at runtime. This allows business analysts or administrators, using a Web browser interface, to customize the application for their end users. For information about runtime customization, refer to the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter.

For more information about the MDS architecture and metadata repositories (database and file-based) and archives (EAR, MAR), refer to the section about managing the MDS repository in the Oracle Fusion Middleware Administrator's Guide.

34.1.1 Customizations and Layers

A customized application contains a base application and one or more layers containing customizations. MDS stores the customizations in a metadata repository and retrieves them at runtime to merge the customizations with the base metadata to reveal the customized application. Since the customizations are saved separately from the base, the customizations are upgrade safe; a new patch to base can be applied without breaking customizations. When a customized application is launched, the customization content is applied over the base application.

For example, say you have a generalized payroll application with a validation rule that limits the salary field to 4000. Then you create a customization of that validation rule that limits the salary field to 3300. At runtime, the customization is applied to the base application and the validation rule for the salary field limits it to 3300.

A customizable application can have multiple customization layers. Examples of customization layers are industry and site. Each layer can have multiple customization layer values, but typically only one such layer value from each layer is applied at runtime. For example, the industry layer for a customizable application can contain values for healthcare and financial industries; but in the deployed customized application, only one of the values from this layer is used at a time.

Layer values from multiple customization layers can be applied, in a specified order of precedence, on top of the base metadata. For example, a customized application can contain customizations in the financial layer value of the industry layer and the Financial Company #1 layer value of the site layer. Each customization layer corresponds to a customization document that contains a set of instructions that change the underlying metadata.

The customization context of a customized application is defined by the set of customization layer values applied to it.

Figure 34-1 illustrates how layers are applied in a customized application.

Figure 34-1 Example of Layered Customization

Graphical example of layered customization

To support this, you use JDeveloper to create customization classes, define layers and values, and specify the order of precedence. These processes are described in Section 34.2, "Developing a Customizable Application."

34.1.2 Static and Dynamic Customization Content

Customizations can be categorized as either static or dynamic. Static customizations have only one layer value in effect for all executions of the application, while dynamic customizations can have values that vary based on the execution context of the application. If a customization can vary for different users executing the application, then it is dynamic. If a customization has the same value for all users executing the application then it is static.

When you implement customizations in ADF Business Components objects, the customizations remain the same for entire runtime of the application. This is because these objects are loaded only once for an application and reused for the duration of the application. For example, you can have a customized validation rule in the Healthcare Company #1 value of the site layer that limits salaries for that site to 3300. This is static customization content.

However, you can also implement customizations at the controller or view level that allow the layer value to be determined at runtime, based on user roles (responsibilities) or other application-specific criteria. For example, you can design an application so that users from different organizations see different sets of fields on a given screen. This is dynamic customization content.

The determination of whether a customization is static or dynamic is made in the customization class. In the customization class, if the getCacheHint() method returns ALL_USERS, then the customization layer is static. For more information about CacheHint values, see Section 34.2.2, "What You May Need to Know About Customization Classes."

All objects could have a static customization layer, depending on how the customization classes are implemented. But for ADF Business Components objects, customizations can only be static.

34.2 Developing a Customizable Application

To create a customizable application, create the base application and perform the following procedures:

To prepare an application for customization:

  1. Create the customization classes that will be used, as described in Section 34.2.1, "How to Create Customization Classes."

  2. Enable seeded customization in the application, as described in Section 34.2.4, "How to Enable Seeded Customizations for View Projects."

  3. Specify the customization classes in the adf-config.xml file, as described in Section 34.2.7, "How to Configure the adf-config.xml file."

  4. You can optionally restrict runtime customizations on the application, as described in Section 34.4.1, "How to Edit Extended Metadata Properties."

  5. After you have prepared the application for customization, you must prepare JDeveloper so you can use it to implement the customizations, as described in Section 34.3.4, "How to Configure Customization Layers."

34.2.1 How to Create Customization Classes

A customization class is the interface that MDS uses to define which customization applies to the base definition metadata. Each customization class defines a customization layer (for example, industry or site) and can contain multiple layer values. The customization classes that are used in the application must be available to JDeveloper when customizing the application, and included in the deployed application.

34.2.1.1 Customization Classes

A customization class evaluates the current context and returns a String result. This String result is used to locate the customization layer.

The customization class provides the following information:

  • A name, that represents the name of the layer.

  • An array of values, that represent the customization layer values. Typically, each layer returns a single value. If multiple values are returned, the customizations available in the MDS repository for those values are applied in the order in which they appear in the array. For more information, see Section 34.2.1.2, "Implementing the getValue() Method in Your Customization Class."

  • An IDPrefix, for objects created in the layer. When new objects are created in a customization layer they need a unique ID. The IDPrefix is added to the autogenerated identifier for the object to create an ID for the newly added object. Each layer needs a unique IDPrefix so that objects created at different customization layers will have unique IDs.

  • A cache hint, for the layer defined by the customization class. The cache hint defines whether a layer is static or dynamic. If the getCacheHint() method returns ALL_USERS, then the customization layer is static. For more information about dynamic customizations, see Section 34.1.2, "Static and Dynamic Customization Content." For more information about CacheHint values, see Section 34.2.2, "What You May Need to Know About Customization Classes."

Customizations can be used to tailor an application to suit a specific industry domain (verticalization). Each such domain denotes a customization layer and is depicted using a customization class.

To implement seeded customizations using your customization classes:

  • The cust-config section (under mds-config) in the adf-config.xml must contain a reference to the customization classes (as shown in Example 34-6).

    The customization configuration (cust-config) section provides the customization classes and their precedence for a customized application. See Section 34.2.7, "How to Configure the adf-config.xml file."

  • The customization classes must be available on JDeveloper's class path to support seeded customizations.

    After creating your customization classes, you can create an extension library that is included in JDeveloper's class path. (For more information, see Section 34.2.3.1, "Making Customization Classes Available to JDeveloper.") At runtime, your customization classes must be available in the EAR-level application class loader.

  • The layer values must be listed in the CustomizationLayerValues.xml file.

    This file is located in the jdev_install\jdev directory. The names of the layers in this file must be consistent with the customization classes. (For more information, see Section 34.3.4, "How to Configure Customization Layers.") JDeveloper uses this file to retrieve layer values at design time.

When JDeveloper is launched in the Customization Developer role, the Customization Context window displays the available customization layers and layer values. You can select the layer and value to which you want to apply customizations in the Customization Context window. For more information about working in the Customization Developer role, see Section 34.3.1, "Introducing the Customization Developer Role." The layer you choose to customize is called the tip layer. For more information, see Section 34.3.3, "Introducing the Tip Layer."

Example 34-1 shows a sample customization class. Note that all customization classes should have a single, no-argument constructor.

Example 34-1 Sample IndustryCC customization class in the mycompany package

package mycompany;
 
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import oracle.mds.core.MetadataObject;
import oracle.mds.core.RestrictedSession;
import oracle.mds.cust.CacheHint;
import oracle.mds.cust.CustomizationClass;

public class IndustryCC extends CustomizationClass {
  private static final String DEFAULT_LAYER_NAME = "industry";
  private String mLayerName = DEFAULT_LAYER_NAME;

  public IndustryCC() {
  }
  public CacheHint getCacheHint() {
    return CacheHint.ALL_USERS;
  }
  public String getName() {
    return mLayerName;
  }

  public String generateIDPrefix(RestrictedSession sess, MetadataObject mo) {
      return new String ("I");
  }

  public String[] getValue(RestrictedSession sess, MetadataObject mo) {
    // This needs to return the appropriate value at runtime. 
    return new String[] {"financial"};
  }
}

This example shows the four methods that define how the customization class will work: getCacheHint(), getName(), generateIDPrefix(), and getValue().

The return value for getCacheHint() indicates to MDS how widely visible a metadata object with this customization is, and therefore its likely duration in memory. It also defines whether or not a layer is static or dynamic. In this example, the getCacheHint() method returns ALL_USERS, which means the customization layer is static. For more information about CacheHint values, see Section 34.2.2, "What You May Need to Know About Customization Classes."

The getName() method returns the name of the customization layer. A SiteCC customization class, for example, might return "site." In this example, the getName() method returns "industry."

The generateIDPrefix() method creates an IDPrefix. The IDPrefix is a unique, abbreviated string that identifies the name and value of the layer. It is used as the prefix of the ID for objects created in the customization layer. The default implementation (if no IDPrefix is specified) returns name of the layer concatenated with customization value. For performance reasons, the IDPrefix should be kept short (4 characters or less). Therefore, the default implementation should be overridden. The related getIDPrefix() method returns the IDPrefix of the customization layer. In this example, the getIDPrefix() method would return "I" (for "industry").

The getValue() method returns the customization value (or values) for the customization class. In this example, the getValue() method returns a single value, "financial," that defines the customization context when combined with the layer name. There are additional techniques for using the getValue() method described in Section 34.2.1.2, "Implementing the getValue() Method in Your Customization Class."

Note:

The possible layer values corresponding to a layer name are retrieved by JDeveloper in the Customization Developer role from the CustomizationLayerValues.xml file. The precedence of layers is defined by the order of the customization classes specified in the adf-config.xml file. The names of the layers must be consistent in these files and in the customization classes.

34.2.1.2 Implementing the getValue() Method in Your Customization Class

The getValue() method is used to retrieve the layer value(s) of the customization class based on the application context and the metadata. For example, calling getValue() on a SiteCC customization class might return an array with single entry "headquarters." Typically, the getValue() method returns an array with a single value, as shown in Example 34-1.

You can also return multiple values from the getValue() method, as shown in Example 34-2.

Example 34-2 The getValue() Method Returning Multiple Values

public String[] getValue(RestrictedSession sess, MetadataObject mo) {
    return new String[]{"North America", "US", "CA"}
}

When multiple values are returned, customizations applicable to all values are applied. Customizations are applied in the order in which they appear in the array. In this example, North America customizations are applied over the base application, then US customizations are applied, and finally CA.

Note:

Returning multiple values for a customization layer is an advanced concept that is typically unnecessary.

The getValue() method can return a layer value based on the current execution context for the current user, pulled either from static or thread local state maintained by the client, or from properties set by the client on the MDS session and based on the metadata object name. Example 34-3 shows this type of implementation.

Example 34-3 The getValue() Method Returning a Layer Value Based on the Current Execution Context

public String[] getValue(RestrictedSession sess, MetadataObject mo) {
    if (mo.getName().equals("/sample/abc.jspx"))
    {
        return new String[]{"Headquarters"};
    }
     else
    {
        return new String[]{"RemoteSite"};
    }
}

In this example, the getValue() method uses the getName() method on the metadata object to determine if the name of the metadata document is "/sample/abc.jspx". If so, getValue() returns Headquarters to apply headquarters customizations. If not, it returns RemoteSite to apply customizations for remote sites.

Note:

Coding the getValue() method to return a value based on the metadata object is an advanced concept that is typically unnecessary. Customization context for dynamic layers is typically determined through facets of the application context, such as user name or responsibility.

An additional technique that can be useful during the development cycle is to use an external properties file to specify layer values. Example 34-4 references a properties file (customization.properties) that stores the layer values.

Example 34-4 The getValue() Method Using a Properties File to Specify Layer Values

public String[] getValue(RestrictedSession sess, MetadataObject mo) {
  Properties properties = new Properties();
    String configuredValue = null;
    Class clazz = IndustryCC.class;
    InputStream is = clazz.getResourceAsStream("/customization.properties");
    if (is != null){
      try {
        properties.load(is);
        String propValue = properties.getProperty(mLayerName);
        if (propValue != null){
          configuredValue = propValue;
        }
      } catch (IOException e) {
          e.printStackTrace();
      } 
      finally {
        try {
          is.close();
        } catch (IOException e) {
        e.printStackTrace();
        }
      }
    }
  return new String[] {configuredValue};
}

When an application using this technique is run in JDeveloper, you can change the layer value in the properties file and refresh the browser to see new customizations being applied. This customization class and properties file combination allows you to maintain the layer value in a separate file so you don't need to modify and recompile Java code to change it for a particular deployment. If you use a customization.properties file, it must be packaged with the customization classes so that they are loaded from the same class loader.

Example 34-5 shows a sample customization.properties file. When the IndustryCC class is loaded with this properties file, the layer value healthcare is applied.

Example 34-5 Sample Contents of a customization.properties File

#Configured values for the default layer values
industry=healthcare
site=headquarters

34.2.1.3 Creating a Customization Class

When creating customization classes, put them in a separate extension project. This allows you to deploy them to a JAR and import the JAR into your lowest level project (which is typically the model project). This approach increases modularity, making it easier to include them in multiple applications across your company, and easier to patch them centrally. For more information about this approach, see Section 34.2.3, "How to Consume Customization Classes."

Alternatively, if you are creating customization classes that will be used in a single application only, you can put the customization classes in the model project.

Make sure that there is only one copy of the customization classes in the application and that they are packaged in a JAR so that they are loaded at the EAR level application class loader. By default, adding project dependencies will add the customization classes to the WAR, which will not work correctly after the application is packaged and deployed. For more information about packaging your application for deployment, see Section 36.3.2, "How to Create Deployment Profiles."

Use the following procedure to create a customization class.

To create a customization class in an extension project:

  1. Launch JDeveloper using the Default role, and open (or create) the application that will hold the customization classes.

  2. From the File menu, choose New.

  3. In the New Gallery, select Projects and then Extension Project, and click OK.

    This opens the Create Extension Project dialog. For more information about the options in this dialog, see the online help.

    Note:

    If you don't see Extension Project, click the All Technologies tab.
  4. Specify the appropriate settings for your extension project, and click OK.

    Note:

    You should use a single extension project to hold all of your customization classes.
  5. In the Application Navigator, right-click your extension project and choose Project Properties.

  6. In the Project Properties dialog, click Libraries and Classpath, and then click Add Library.

  7. In the Add Library dialog, select MDS Runtime, and click OK.

  8. In the Application Navigator, right-click the extension project and choose New.

  9. In the New Gallery, expand General, select Java and then Java Class, and click OK.

  10. In the Create Java Class dialog, enter a name for the class and the appropriate package.

    Note:

    Customization classes are typically named for the layer name they return. For example, a customization class that returns the layer name industry would be named IndustryCC.
  11. In the Extends field, enter oracle.mds.cust.CustomizationClass.

  12. Make sure Implement Abstract Methods is checked and click OK.

  13. Replace the code in the generated file with code like that shown in Example 34-1.

  14. Save your changes and rebuild the project.

This creates the customization class. The sample code uses the package name mycompany and the class name IndustryCC. You will need to change these as appropriate for your application.

34.2.2 What You May Need to Know About Customization Classes

As described in Section 34.2.1.1, "Customization Classes," the customization class defines a CacheHint which specifies the visibility of metadata objects in a customization layer, and therefore its likely duration in memory. This information is used by MDS to decide whether or not to cache a customization, and where to cache it. Any customization layers constructed using a given customization class have the same cache hint.

The following constants are supported values of CacheHint:

  • ALL_USERS -- The customization is applied globally (non-conditionally) for a given deployment. This constant is used for static customization layers.

  • MULTI_USER -- The customization is applied to multiple users.

  • REQUEST -- The customization is applied for the duration of the request only.

  • USER -- The customization is applied for a single user to documents which are accessed throughout the user's application session. (In web applications the application session is typically a servlet session.)

Note:

Customization classes can be executed frequently, once for each document being accessed to get the layer name and layer value, so take care to ensure their efficiency.

34.2.3 How to Consume Customization Classes

After you have created your customization classes, you can use them at design time in the Customization Developer role, and at run time in the application. To be consumed in an application or in JDeveloper, the classes must be packaged appropriately.

When you define the deployment profiles for your application, you will need to add the customization classes JAR to the EAR assembly, and to avoid duplication make sure the WAR does not include the customization classes JAR. For more information, see Section 36.3.2, "How to Create Deployment Profiles."

34.2.3.1 Making Customization Classes Available to JDeveloper

After you create the customization classes, you must make them available to JDeveloper so that you can use them when implementing customizations. When working in the Customization Developer role, your customization classes must be available on JDeveloper's class path.

Because the customization classes are reusable components, you can create a JDeveloper extension to contain them and make them available to JDeveloper. For information about creating and using JDeveloper extensions, see the Writing JDeveloper Extensions topic in JDeveloper Online Help.

However, when you package and deploy your customized application or run it from JDeveloper, the customization classes must be available at the application level on the application's class path. Therefore it is important to include them in the consuming application (for example, in the model project), and not just as a JDeveloper extension. For more information about making your customization classes available at runtime, see Section 34.2.3.2, "Consuming Customization Classes from an Extension Project."

To package your customization classes as a JDeveloper extension:

  1. Create your customization classes in the extension project, as described in Section 34.2.1.3, "Creating a Customization Class."

  2. In the Application Navigator, right-click your extension project and choose Rebuild project.jpr.

  3. In the Application Navigator, right-click your extension project and choose Deploy to Target Platform.

    This deploys the customization classes to JDeveloper, so they can be used in the Customization Developer role.

34.2.3.2 Consuming Customization Classes from an Extension Project

When you package and deploy your customized application or run it from JDeveloper, the customization classes must be available in the EAR level application classloader.

Note:

This procedure is not required if you created your customization classes in model project of the consuming application.

Before you begin:

With the application containing the customization classes open in JDeveloper in the Default role, create a JAR using the procedure described in Section 36.3.2.1, "Adding Customization Classes into a JAR."

Use the following procedure to make the customization classes visible to the application, and then add the customization classes to the cust-config section of the adf-config.xml file, as described in Section 34.2.7, "How to Configure the adf-config.xml file." This makes the customization classes available to the application when you run it locally from JDeveloper.

To use customization classes from an extension project:

  1. Open the application you want to customize in JDeveloper in the Default role.

  2. In the Application Navigator, right-click the model project and choose Project Properties.

  3. In the Project Properties dialog, click Libraries and Classpath.

  4. Click Add JAR/Directory.

  5. In the Add Archive or Directory dialog, select the JAR you created that contains the customization classes, and click Select.

  6. Click OK to close the Project Properties dialog.

    Now the customization classes are available if you are running your project locally in JDeveloper. However, if you are deploying your application remotely, you must also add the customization classes JAR to the EAR class path, as described in Section 36.3.2.4, "Creating an Application-Level EAR Deployment Profile."

34.2.4 How to Enable Seeded Customizations for View Projects

Like all customizable components, the XML elements of a customizable metadata object must be uniquely identifiable by MDS, and therefore must have a unique, non-null identifier. The component's identifier is used to refer to the element in the customization instructions in the customization layer. The ID property is the identifier for each type of component in an ADF Faces .jspx or .jsff file.

To allow for customizations on your JSF and JSP pages, you must enable seeded customizations in the application's view project, which drives some defaults for your pages. This is not necessary for your model and controller projects.

Note:

MDS requires that pages be XML-based to be customized. Therefore, customizations are not allowed on .jsp files; use .jspx files instead.

To enable seeded customizations in your view project:

  1. Launch JDeveloper using the Default role, and open the application that you want to make customizable.

  2. In the Application Navigator, right-click the view project and choose Project Properties.

  3. In the Project Properties dialog, click ADF View.

  4. Select the Enable Seeded Customizations checkbox, as shown in Figure 34-2.

  5. Click OK.

  6. Save the changes to your project.

Figure 34-2 Project Properties - Enable Seeded Customizations

Project Properties dialog with seeded customizations enabled

34.2.5 How to Enable Seeded Customizations in Existing Pages

If you have pages in your project that were created in an earlier version of JDeveloper, you must make sure that these pre-existing pages are also enabled for seeded customizations. This is only necessary if you migrated the application from an earlier version of JDeveloper and did not generate ids during migration.

To enable seeded customizations in an existing page:

  1. Launch JDeveloper using the Default role, and open the application that you want to make customizable.

  2. Create an audit profile to implement ID tokens for all XML objects in your page.

    1. From the Tools menu, choose Preferences.

    2. In the Preferences dialog, select Audit > Profiles.

    3. In the Rules tab on the Profiles page, deselect all rules.

    4. Select the rule ADF Faces > Component ID Rules > Check for ID When ADF Faces is Present.

    5. From the Default Fix dropdown list, select Generate a unique ID.

    6. Click Save As, then enter an identifiable name for the profile (such as Generate Unique IDs). and click Save.

    7. Click OK to close the Preferences dialog.

  3. In the Application Navigator, select the page for which you want to enable seeded customizations. Alternatively, you can select a project to run the audit on all the files it contains.

  4. From the Build menu, choose Audit filename.

  5. In the Audit dialog, select the profile you created to generate ids and click Run.

  6. Use the Log window to review issues and apply fixes.

  7. When the audit is complete, save your changes.

34.2.6 How to Enable Customizations in Resource Bundles

If you plan to create new resource keys when implementing customizations, you can specify the affected resource bundles using the Application Properties dialog.

To enable customizations in resource bundles:

  1. From the application context menu, choose Application Properties.

  2. In the Application Properties dialog, click Resource Bundles.

  3. Click Add.

  4. In the Select Resource Bundle dialog, navigate to and select the resource bundles for which you want to enable customization.

  5. Click Open.

  6. In the Application Properties dialog, select the checkbox in the Overridden column of the Bundle table.

  7. Click OK.

34.2.7 How to Configure the adf-config.xml file

The application's adf-config.xml file must have an appropriate cust-config element in the mds-config section. The cust-config element allows clients to define an ordered and named list of customization classes. You use the overview editor for the adf-config.xml file to add customization classes (see Figure 34-3).

To identify customization classes in the adf-config.xml file:

  1. With the application you want to customize open in JDeveloper, open the Application Resources panel in the Application Navigator.

  2. Expand Descriptors, then expand ADF META-INF.

  3. Right-click adf-config.xml, and choose Open.

  4. In the overview editor, click the MDS Configuration navigation tab, and then click the Add icon.

  5. In the Edit Customization Classes dialog, search for or navigate to the customization class you have already created.

  6. Select the appropriate class and click OK.

  7. After you have added all of the customization classes, you can use the arrow icons to put them in the appropriate order.

Figure 34-3 shows the overview editor for the adf-config.xml file with two customization classes added.

Figure 34-3 adf-config.xml Overview Editor

Overview editor for adf-config.xml

The order of the customization-class elements defines the precedence of customization layers. For example, in the code shown in Example 34-6, the IndustryCC class is listed before the SiteCC class. This means that customizations at the industry layer are applied to the base application, and then customizations at the site layer are applied.

Example 34-6 Customization Class Order in the adf-config.xml File

<adf-config xmlns="http://xmlns.oracle.com/adf/config"> 
  <adf-mds-config xmlns="http://xmlns.oracle.com/adf/mds/config"> 
    <mds-config xmlns="http://xmlns.oracle.com/mds/config" version="11.1.1.000">
      <cust-config> 
        <match path="/"> 
          <customization-class name="com.mycompany.IndustryCC"/> 
          <customization-class name="com.mycompany.SiteCC"/> 
        </match> 
      </cust-config> 
    </mds-config> 
  </adf-mds-config> 
</adf-config> 

34.2.8 What Happens When You Create a Customizable Application

When you create a customizable application, you have a base application that includes the pieces necessary for you or someone else to use as the basis for a customized application.

To perform the customization, you must open the application in JDeveloper using the Customization Developer role, as described in Section 34.3, "Customizing an Application."

34.2.9 What You May Need to Know About Customizable Objects and Applications

Oracle ADF components (such as controller, model, and business components objects) must have a unique identifier so that they can be customized. ADF components generated by JDeveloper are created with identifiers by default, with the exception of JSP and JSF pages in your view controller projects. To cause JDeveloper to generate identifiers for components on pages in your view controller projects, you must explicitly specify this at the project level (as explained in Section 34.2.4, "How to Enable Seeded Customizations for View Projects").

Before you implement customizations in an application, make sure that all objects that you intend to customize have the necessary identifiers. In many cases, you can run an audit rule to catch and fix any omissions (as explained in Section 34.2.5, "How to Enable Seeded Customizations in Existing Pages").

Also, take care to ensure the efficiency of your customization classes, because they can be executed frequently, once for each document being accessed to get the layer name and layer value.

34.3 Customizing an Application

Using the Customization Developer role, you can create customizations in a customizable application.

34.3.1 Introducing the Customization Developer Role

The Customization Developer role is used to customize the metadata in a project. Customization features are available only in this role. When you are in the Customization Developer role, you can do the following:

  • Create and update customizations

  • Select and edit the tip layer of a customized application

  • Remove existing customizations

When you are in the Customization Developer role, the source editor is read-only and the following JDeveloper features are disabled:

  • Workspace migration

  • Creation, deletion, and modification of application and IDE connections. You must configure connections in Default role before opening an application in Customization Developer role.

When working with an application in the Customization Developer role, new objects cannot be created, and noncustomizable objects cannot be modified. However, the following content types are customizable:

  • Portal modules

  • ADF modules, including ADF Faces, ADF Model, ADF Business Components, and ADF Controller

    Note:

    ADF Business Components objects are customizable only if a static customization class is selected in the Customization Context window. Otherwise, business components objects are read-only.

When working in the Customization Developer role, you cannot edit noncustomizable files, such as Java classes, resource bundles, security policies, deployment descriptors, and configuration files. Noncustomizable files are indicated by a lock icon when you are working in the Customization Developer role.

You are also restricted from modifying project settings and customizing certain ADF Business Components features, including service interfaces and business event definitions. Additionally, you cannot refactor, or make changes to customizable files that would, in turn, necessitate changes in noncustomizable files.

34.3.2 How to Switch to the Customization Developer Role in JDeveloper

The customization features of JDeveloper are available to you in the Customization Developer role. To work in this role, you can either choose it when you start JDeveloper or, if JDeveloper is already running, you can use the Preferences dialog to switch to the Customization Developer role.

To switch to the Customization Developer role in JDeveloper:

  1. From the Tools menu, choose Preferences.

  2. In the Preferences dialog, click the Roles node.

    The Roles page of the Preferences dialog displays the different roles that are available to you.

  3. Select Customization Developer, and click OK.

34.3.3 Introducing the Tip Layer

When working in the Customization Developer role, the layer and layer value combination that is selected in the Customization Context window is called the tip layer. The changes you make while in the Customization Developer role are applied to this layer.

The metadata displayed in the JDeveloper editors is a combination of the base metadata and the customization layers up to and including the tip layer, according to the precedence set in adf-config.xml, with the values specified in the Customization Context window for each layer.

When working in the Customization Developer role, you can also see the noncustomized state of the application. When you select View without Customizations in the Customization Context window, there is no current tip layer. Therefore, what you see is the noncustomized state. While you are in this view, all customizable files show the lock icon (in the Application Navigator), indicating that these files are read-only.

When you make customizations in a tip layer, these customizations are indicated by an orange icon in the Property Inspector. A green icon indicates non-tip layer customizations. When you see an orange icon beside a property, you have the option of deleting that customization by choosing Remove Customization from the dropdown menu for that property.

34.3.4 How to Configure Customization Layers

To customize an application, you must specify the customization layers and their values in the CustomizationLayerValues.xml file so that they are recognized by JDeveloper.

You can define the customization layers either globally for JDeveloper or in an application-specific file. If you use an application-specific file, it takes precedence over the global file. For more information on configuring layer values globally for JDeveloper, see Section 34.3.4.1, "Configuring Layer Values Globally." For more information on configuring application-specific layer values, see Section 34.3.4.2, "Configuring Workspace-Level Layer Values from the adf-config Editor."

When you open a customizable application in the Customization Developer role, JDeveloper reads the adf-config.xml file to determine the customization classes to use and their order of precedence. JDeveloper also reads the CustomizationLayerValues.xml file to determine the layer values to make available in the Customization Context window. If there are layers included in the CustomizationLayerValues.xml file that are not defined in the customization classes listed in the adf-config.xml file, they are not displayed in the Customization Context window.

Therefore, when you specify the customization layers globally for JDeveloper, you can have a comprehensive list of layer values for all of your customization applications in the CustomizationLayerValues.xml file, and only those appropriate for the current application are available in the Customization Context window. Conversely, you could have a comprehensive list of customization classes for an application in the adf-config.xml file, and only the subset of layer values that you will work on in your CustomizationLayerValues.xml file.

Note:

At design time, JDeveloper retrieves customization layer values from the CustomizationLayerValues.xml file. But at runtime, the layer values are retrieved from the customization class.

The names of the layers that you enter in the CustomizationLayerValues.xml file must be consistent with those specified in your customization classes. Section 34.3.4, "Layers and Layer Values Defined in CustomizationLayerValues.xml" shows the contents of a sample CustomizationLayerValues.xml file.

Example 34-7 Layers and Layer Values Defined in CustomizationLayerValues.xml

<cust-layers  xmlns="http://xmlns.oracle.com/mds/dt">
  <cust-layer name="industry" id-prefix="i">
    <cust-layer-value value="financial" display-name="Financial" id-prefix="f"/>
    <cust-layer-value value="healthcare" display-name="Healthcare" id-prefix="h"/>
  </cust-layer>
  <cust-layer name="site" id-prefix="s">
    <cust-layer-value value="headquarters" display-name="HQ" id-prefix="hq"/>
    <cust-layer-value value="remoteoffices" display-name="Remote" id-prefix="rm"/>
  </cust-layer>
</cust-layers>

For each layer and layer value, you can add an id-prefix token. This helps to ensure the uniqueness of the id, so that customizations are applied accurately. When you add a new element (such as a command button) to a page during customization, JDeveloper adds the id-prefix of the layer and layer value (determined by the selected tip layer) to the autogenerated identifier for the element to create an id for the newly added element in the customization metadata file. For example, in Example 34-7, the site layer has an id-prefix of "s" and the headquarters layer value has an id-prefix of "hq". So, when you select site/headquarters as the tip layer and add a command button to a page, the command button will have an id of "shqcb1" in the metadata customization file.

For each layer value, you can also add a display-name token to provide a human-readable name for the layer value. When you are working in the Customization Developer role, the value of the display-name token is shown in the Customization Context window for that layer value.

34.3.4.1 Configuring Layer Values Globally

The following procedure describes how to configure the CustomizationLayerValues.xml file globally for JDeveloper.

To configure design time customization layer values globally for JDeveloper:

  1. Locate and open the CustomizationLayerValues.xml file.

    You can find this file in the jdev subdirectory of your JDeveloper installation directory (jdev_install\jdev\CustomizationLayerValues.xml).

  2. For each layer, enter a cust-layer element, as shown in Example 34-7.

  3. For each layer value, enter a cust-layer-value element, as shown in Example 34-7.

  4. Save and close the CustomizationLayerValues.xml file.

  5. Make sure that the customization class JARs (created in Section 34.2.3.1, "Making Customization Classes Available to JDeveloper") are available in the JDeveloper class path.

  6. After you have made changes to the global CustomizationLayerValues.xml file, you must restart JDeveloper.

34.3.4.2 Configuring Workspace-Level Layer Values from the adf-config Editor

When configuring layer values for an application, you can use either the adf-config editor (in the Default role or the Customization Developer role) or the Customization Context window (in the Customization Developer role). For information on how to do this from the Customization Context window, see Section 34.3.4.3, "Configuring Workspace-Level Layer Values from the Customization Context Window."

When you create an application-specific CustomizationLayerValues.xml file, JDeveloper stores it in an application-level directory (for example, workspace-directory\.mds\dt\customizationLayerValues\CustomizationLayerValues.xml). You can access this file in the Application Resources section of the Application Navigator, under the MDS DT folder.

The following procedure describes how to configure the CustomizationLayerValues.xml file for a specific application from the adf-config editor.

To configure design time customization layer values at the workspace level from the adf-config editor:

  1. In the Application Navigator, double-click the adf-config.xml file.

    The adf-config.xml file is in the Application Resources panel of the Application Navigator, under ADF META-INF in the Descriptors node.

  2. In the overview editor, click the MDS Configuration tab.

  3. Below the table of customization classes, click the Configure Design Time Customization Layer Values link to open the workspace-level CustomizationLayerValues.xml file.

    When you click the link, JDeveloper opens the file in the editor. If the workspace-level CustomizationLayerValues.xml file doesn't already exist, JDeveloper displays a confirmation dialog. Click yes to create and open a copy of the global file.

  4. Specify layer values as necessary, as described in Section 34.3.4, "How to Configure Customization Layers."

  5. Save your changes.

Unlike the global CustomizationLayerValues.xml file, the layer values of workspace-level CustomizationLayerValues.xml file can be changed in Customization Developer role. Additionally, when you save your changes, the modified values are reflected in the Customization Context window without restarting the JDeveloper. If the customization context that was active prior to modifying the file becomes invalid with the modified customization layer values, the customization context is deselected. You will need to select the customization context from the updated customization layer values.

34.3.4.3 Configuring Workspace-Level Layer Values from the Customization Context Window

When configuring layer values for an application, you can use either the Customization Context window (in the Customization Developer role) or the adf-config editor (in the Default role or the Customization Developer role). For information on how to do this from the adf-config editor, see Section 34.3.4.2, "Configuring Workspace-Level Layer Values from the adf-config Editor."

When you create an application-specific CustomizationLayerValues.xml file, JDeveloper stores it in an application-level directory (for example, workspace-directory\.mds\dt\customizationLayerValues\CustomizationLayerValues.xml). You can access this file in the Application Resources section of the Application Navigator, under the MDS DT folder.

The following procedure describes how to configure the CustomizationLayerValues.xml file for a specific application from the Customization Context window in the Customization Developer role.

To configure design time customization layer values at the workspace level from the Customization Context window:

  1. Click the Override global layer values link in the Customizations window.

    When you click the link, JDeveloper opens the CustomizationLayerValues.xml file in the overview editor. If the workspace-level CustomizationLayerValues.xml file doesn't already exist, JDeveloper displays a confirmation dialog. Click yes to create and open a copy of the global file.

  2. Specify layer values as necessary, as described in Section 34.3.4, "How to Configure Customization Layers."

  3. Save your changes.

Unlike the global CustomizationLayerValues.xml file, the layer values of workspace-level CustomizationLayerValues.xml file can be changed in Customization Developer role. Additionally, when you save your changes, the modified values are reflected in the Customization Context window without restarting the JDeveloper. If the customization context that was active prior to modifying the file becomes invalid with the modified customization layer values, the customization context is deselected. You will need to select the customization context from the updated customization layer values.

34.3.5 How to Customize Metadata in JDeveloper

You use the same development procedures and techniques to customize metadata that you use when developing the base application. To implement customizations, however, you must be working in the Customization Developer role and specify the customization context by selecting a tip layer and layer value before editing the metadata. For an application to be customizable, customizations must be enabled in your project. For more information, see Section 34.2, "Developing a Customizable Application."

To customize metadata in JDeveloper:

  1. Launch JDeveloper using the Customization Developer role.

  2. Open the customizable application.

  3. In the Customization Context window, select the layer and value for which you want to implement customizations.

    The Customization Context (displayed at the bottom of the Customization Context window) changes to reflect your selection, as shown in Figure 34-4.

    Figure 34-4 Customization Context Window with site/headquarters Selected as the Tip Layer

    Customization context window with selected tip layer

    Note:

    The selection you make in the Customization Context window indicates the context for the customizations that you will implement in JDeveloper. This selection does not directly impact the runtime for the application. At runtime, the customization context is returned from your customization classes. For more information, see Section 34.2.1, "How to Create Customization Classes."
  4. Edit the metadata as you typically would during development. For example, right-click an entity object and choose Open. Then edit the object using the overview editor.

    While you use the same techniques for editing metadata during customization that you would during development, certain restrictions apply. For example, some string properties, such as button labels, cannot be edited directly in the Property Inspector: they must be edited using the Select Text Resource dialog or the Expression Builder. For more information about restrictions to editing during customization, see Section 34.3.1, "Introducing the Customization Developer Role." For information about using the Expression Builder, see Section 12.7.1.1, "Opening the Expression Builder from the Property Inspector."

    Even though you use the overview editor to implement customizations, you do not make changes to the base metadata file. Your changes are stored separately in a customization metadata file.

    Note:

    To see the uncustomized base metadata, you can select View without Customizations in the Customization Context window.
  5. You can optionally choose Remove Customization from the dropdown menu for a property (in the Property Inspector) to clear the existing customization.

    Note:

    In the Property Inspector, tip layer customizations are indicated by an orange icon, while non-tip layer changes are indicated by a green icon. Remove customization can only be performed in the context in which the customization was added. So you can remove only those customizations that have an orange indicator in the Property Inspector.
  6. Choose Save from the File menu to save your changes.

After you have completed your customizations, you can run and test the customized application.

34.3.6 How to Fix Incongruencies Between the Tip Layer and Base Metadata

If a base metadata document is upgraded or if the base document type definition is changed (for backward compatibility, type definition changes should be avoided), it is possible for customizations on that document to become invalid.

For example, say an element in the XSD has minOccurs=0, maxOccurs=1 and the base document initially has no occurrences of the element. So you insert an occurrence of the element as a customization. Then the base document is upgraded to add an occurrence of the same element. In this situation, applying the customization results in two occurrences of the element, violating the maxOccurs rule of the XSD.

If this happens, JDeveloper alerts you to such tip customization issues in Structure window when you open the document in the Customization Developer role. When a document is opened in JDeveloper, any errors (for example, errors due to schema validation) are displayed in the Structure window. For some error conditions, audit fix actions are provided. You can double-click the error to go to the source of the problem in the document. Note that the Structure window reports only the validation errors introduced by customizations in the current tip layer. If there are validation errors in layers other than the tip layer, they are not reported.

To fix tip layer customization errors, the JDeveloper Customization Developer role provides a default audit action named Fix all tip customization validation errors. This action fixes validation violations on the merged document by removing the tip layer customizations.

34.3.7 What Happens When You Customize an Application

When you implement customizations in an application, JDeveloper creates a metadata file for the customizations and a subpackage to store them in.

The metadata file contains the customizations for the customized object, which are applied over the base metadata at runtime. The new metadata file is named the same as the base file for the object with an additional .xml extension. For example, if you implement customizations for the browseOrders.jsff page, the customization metadata file is named browseOrders.jsff.xml. Or if you implement customizations on the OrderItems entity object, the base metadata file is named OrderItems.xml and the customization metadata file is named OrderItems.xml.xml.

The customization metadata files are stored in a subpackage hierarchy that is created at the same level as the object you customize. The first-level package is named mdssys, and it contains a package named cust. The cust package contains a package for each customization layer for which you have implemented customizations.

For example, say you have a base application that has a package called oracle.fod.model containing your entity objects, and you have a customization layer named site with two layer values: headquarters and remoteoffices. Then you implement customizations for the OrderItems entity object at the headquarters layer value. When you implement these customizations, JDeveloper creates the subpackage hierarchy oracle.fod.model.mdssys.cust.site.headquarters and stores the customization metadata files there.

Similarly, for pages in your view controller project, JDeveloper creates a directory structure to store the customization metadata files. For example, if you customize the BrowseOrders.jsff page in the Web Content folder of your view controller project, JDeveloper creates the directory structure mdssys/cust/site/headquarters under Web Content and stores the customization metadata file there.

34.3.8 How to Customize ADF Library Artifacts in JDeveloper

In the Customization Developer role, you can use JDeveloper to customize artifacts in an ADF library. This need can arise when, for example, one development team produces task flows as part of a framework service and makes them available to other teams as an ADF library. Then another development team uses one of the task flows in a consuming application, and needs to fine-tune it to fit the requirements of the application.

You can add an ADF library to your project in the Customization Developer role just as you would add it in the Default role. However, in the Customization Developer role, content from an ADF library appears as editable to allow you to implement customizations, whereas in the Default role it is read-only. For more information about working with ADF libraries, see Chapter 33, "Reusing Application Components."

To customize an ADF library artifact:

  1. Open your customizable application in the Customization Developer role.

  2. In the Application Navigator, click the Navigator Display Options icon and choose Show Libraries.

    This displays the libraries in the Application Navigator, so that you can explore them and access their artifacts.

  3. Add the desired library to your project if it is not already shown among the libraries in the Application Navigator.

    For information about how to do this, see Section 33.3, "Adding ADF Library Components into Projects."

  4. Customize the artifacts just as you would customize other content in your project.

    For example, you can drag and drop taskflows from a library to .jspx or .jsff pages in a consuming project, drag and drop taskflows from a library to a page or fragment in another library, drag and drop library content or taskflows from the Resource catalog, drag and drop data controls from Data Controls panel to .jspx or .jsff pages in a library, edit business components, and drag and drop a data control from a library to the Data Controls panel and then drop to a page in another palette. All these actions would result in customizations of the library.

34.3.8.1 Specifying a Location for ADF Library Customizations

The location where ADF library customizations are stored is project-dir\libraryCustomizations by default. If your workspace contains multiple projects, you should change this to an workspace-level location for each project (for example, workspace-dir\.mds\ADFLibraryCustomizations).

You can change the location of ADF library customizations on the Project Source Paths > ADF Library Customizations page of the Project Properties dialog. If you change this location after you have implemented customizations on an ADF library, you must move the customization metadata files to the new location. To do this, use the file system to move the customization metadata (XML) files from the old directory to the new one.

If you have more than one project in the workspace with existing ADF library customizations that need to be moved to the common location, move the customizations to the new location one project at a time. For each project, change the location of ADF library customizations in the Project Properties dialog, and then move the customization metadata files from the old location to the new location. To mitigate conflicts where an ADF library artifact has customizations in more than one project, you have following options:

  • From both projects, open the ADF Library artifact for which there are conflicting customizations, and decide upon which customizations you want. Preserve the customizations you want to keep and delete the others.

  • If both customizations are important, open the ADF library artifact from the first project and implement the customizations that were previously done in second project. Then save the customizations in the first project and remove the customizations from the second project.

Do not open ADF library customization metadata files from multiple projects in a text editor and merge their contents. This can corrupt the customization metadata file.

Additionally, the location where ADF library customizations are stored is automatically included when you create a MAR deployment profile. If you change this location after you have created a MAR profile, you must also change the corresponding entry in the contributors list on the User Metadata file group page of the Edit MAR Deployment Profile Properties dialog before packaging. Alternatively, you can re-create the MAR profile to pick up this change. For more information about creating a MAR deployment profile, see Section 36.3.2, "How to Create Deployment Profiles."

34.3.8.2 Viewing ADF Library Runtime Customizations from Exported JARs

When working in the JDeveloper Customization Developer role, you can view runtime customizations implemented on ADF library artifacts contained in an exported JAR.

To make runtime customizations viewable from JDeveloper:

  1. Open the customized application in the Customization Developer role.

  2. From the Application Navigator popup menu, choose Application Properties.

  3. In the Application Properties dialog, click Customization Libraries.

  4. Click Browse, and navigate to the location of the exported JAR.

  5. Select the JAR file and click Select.

  6. Click OK to close the Application Properties dialog.

Now the JAR is available so that JDeveloper can look up customizations on ADF library artifacts. When you open an object that contains ADF library artifacts, JDeveloper looks for customizations in this JAR and displays them if appropriate. JDeveloper decides what to display for a given artifact in a given customization context as follows:

  • If the artifact has no runtime customizations or seeded customizations associated with it, the artifact from the ADF library is displayed.

  • If the artifact has only runtime customizations or seeded customizations associated with it (but not both), the customized artifact is displayed.

  • If the artifact has both runtime customizations and seeded customizations associated with it, the seeded customization takes precedence and is displayed.

Additionally, when you run the application locally from JDeveloper, the runtime customizations are displayed. However, the runtime customizations are not included in any packaging of the application for deployment.

34.3.9 What Happens When You Customize ADF Library Artifacts

During the development of enterprise applications, there might be artifacts (such as task flows) that can be reused in multiple applications. To facilitate reuse of these common artifacts they are usually packaged into an ADF library and distributed. This allows you to add the ADF library to the list of libraries on which the consuming application depends on. Then when the application is packaged, the customizations from all such ADF libraries are included in the MAR, which is later deployed to the MDS repository.

Note:

The ADF library provider should take care to ensure that no name conflicts arise due to customizations in the library. In the event that name conflicts arise between customizations packaged in an ADF library and the customizations from the consuming project, the customizations from the ADF library are ignored.

When you implement customizations on objects from an ADF library, the customization metadata is stored by default in a subdirectory of the project called libraryCustomizations. And although you create ADF library customizations at the project level, they are merged together during packaging to be available at the application level at runtime. Essentially, ADF libraries are JARs that are added at the project level, which map to library customizations being created at the project level. However, although projects map to web applications at runtime, the MAR (which contains the library customizations) is at the EAR level, so the library customizations are seen from all web applications.

Therefore, you can customize an ADF library artifact in only one place in an application for a given customization context (customization layer and layer value). Customizing the same library content in different projects for the same customization context would result in duplication in MAR packaging. To avoid duplicates that would cause packaging to fail, implement customizations for a given library in only one project in your application.

For example, say the ADF library you are using contains a page fragment text.jsff. In the consuming application, customize this library page in only one project. By doing so, customizations are available for all projects in the application that consume this library at runtime.

You are also restricted from customizing an object from an ADF library when your project already contains an object with the same name. In case of duplication, you must fix the projects by deleting one of the duplicate documents or deleting one and merging the differences into the other.

Similarly, if the ADF library contains seeded customizations for an artifact within a given customization context (customization layer and layer value), you cannot implement customizations for that artifact within the same customization context. In this situation, the ADF library artifact is read-only. You can, however, implement customizations for the artifact within other customization contexts.

For example, say the ADF library you are using contains seeded customizations for the Headquarters layer value in the Site layer. When you select this as your tip layer in the Customization Context window, the customized objects in that ADF library are read-only. However, if you select Site/Remote Site 1 as your tip layer, then the objects are customizable.

Note:

When the consuming application implements customizations on content from an ADF library, the customizations are written to the local project directories, but they are not automatically injected with the web-app-root during packaging. For more information, see Section 36.3.2.3, "Creating a MAR Deployment Profile."

34.3.10 How to Package and Deploy Customized Applications

After you customize the application, you will want to deploy it. Before you deploy the customized application, you must follow the configuration procedures for setting up your MDS repository, as described in the Oracle Fusion Middleware Administrator's Guide.

An enterprise application can contain model and user interface projects, and both types of projects can contain customized metadata. The customized metadata is packaged into a MAR for deployment. By default, the customizations from both types of projects are added to a single MAR. For information about how to create a MAR profile, see Section 36.3.2.3, "Creating a MAR Deployment Profile."

34.3.10.1 Implicitly Creating a MAR

When you use JDeveloper to package an ADF application, JDeveloper creates an auto-MAR that includes default metadata (such as customizations), when either of the following conditions are met.

  • The Enable User Customizations > Across Sessions using MDS checkbox is selected on the ADF View settings page of the Project Properties dialog for the user interface project.

  • The MDS configuration section of the adf-config.xml file contains a <metadata-store-usage> element that is marked as deploy-target="true", as shown in Example 34-8.

Example 34-8 metadata-store-usage Element in adf-config.xml

< . . . >
  <persistence-config>
    <metadata-namespaces>
      <namespace path="/oracle/apps" metadata-store-usage="repos1"/>
    </metadata-namespaces>
    <metadata-store-usages>
      <metadata-store-usage id="repos1" deploy-target="true">
      . . .
      </metadata-store-usage>
    </metadata-store-usages>
  </persistence-config>
< . . . >

34.3.10.2 Explicitly Creating a MAR

For customizations created in JDeveloper to take effect in the application when it is deployed, these customizations need to be made available to the application at runtime. There are two techniques you can use to accomplish this:

  • Package the customizations along with the application using a MAR.

    Create a MAR profile that includes the customization metadata. The MAR profile should be included in the deployed EAR to ensure that the customizations are available at runtime. Your customization classes must be packaged in the EAR file such that they are in the application-level class loader.

    Note:

    If you have seeded customizations only, you do not need to create a MAR to import them into the MDS repository unless you also want to support runtime customizations. If you have seeded customizations and do not have cross-session persistence enabled, the seeded customizations will be packaged in the EAR, by default, and loaded from the class path.
  • Import the customizations to the runtime repository used by the application.

    You typically use this approach if customizations to library metadata need to be applied to an application that is deployed separately. Using this approach, you package the customizations into a JAR and then use the importMetadata WLST command to import them to the MDS runtime repository. For more information about this and other WLST commands, see the Oracle Fusion Middleware WebLogic Scripting Tool Command Reference.

If your application has customizations on objects from an ADF library, the customization metadata is implicitly included when you create the MAR profile. If you change the location of ADF library customizations in the Project Properties dialog, you must re-create the MAR profile before packaging.

If you plan to use design time at runtime capabilities to add or edit resource keys in the override bundle at runtime, the override bundle must be packaged as part of the MAR. By default, the override bundle is packaged as part of the autogenerated MAR if the application contains seeded customizations. However, if the application doesn't contain seeded customizations, you must explicitly create the MAR deployment profile to package the override bundle. When the MAR profile is created explicitly, the override bundle is added and included by default as part of the user metadata.

When you package and deploy the completed customized application, you should do so from the Default role, rather than from the Customization Developer role. For information about how to create a MAR profile, see Section 36.3.2, "How to Create Deployment Profiles."

34.3.11 What Happens at Runtime in a Customized Application

At runtime, the application applies the customization metadata files over the base application in the order of precedence defined in the cust-config section of the adf-config.xml file.

The layer value is retrieved from the customization class at runtime and evaluated in the context the application is running, and the appropriate customizations for that layer value are applied.

34.3.12 What You May Need to Know About Customized Applications

When you are customizing an application, you might be using integrated source control or customizing resource strings. When you use these features, there is additional information you need to know.

34.3.12.1 Customization and Integrated Source Control

When working in the Customization Developer role, your source control integration complements the process of customization. If JDeveloper is configured to automatically check out and add new files to source control and you attempt to customize a base document that is available from a source control system, JDeveloper behaves in the following way:

  • If the corresponding customization file is not already available, then a new customization file is created in source control and the customizations are written to it.

  • If the corresponding customization file exists, it is checked out and customizations are written to it.

  • If the corresponding customization file exists and it is already checked out or not yet in version control, customizations are written to it without any further version control operation.

Since the base document is not modified in the Customization Developer role, the base document is not checked out.

If JDeveloper is not configured to automatically check out or add new files to source control, you must manually make the customization files editable and check in newly created customization files to source control. For more information about using source control in JDeveloper, see section Section 1.4.2, "Using a Source Control System."

34.3.12.2 Editing Resource Bundles in Customized Applications

During the course of customizing your application, you might want to customize the content to use different resource bundle keys or define and use new resource keys.

You can open a customizable application in the Customization Developer role and use the Property Inspector to customize the usages of resource bundle strings. You can change a document to use another already existing resource key in a resource bundle, or create a new resource. For more information about resource bundles, see Section 4.7, "Working with Resource Bundles."

New resource keys (created in the Customization Developer role) are saved to an application-level override bundle (in XLIFF format), and JDeveloper adds an entry to the adf-config.xml file like the one shown in Example 34-9 to configure the application-level override bundle.

Example 34-9 adf-resourcebundle-config Section in adf-config.xml

<adf-resourcebundle-config xmlns="http://xmlns.oracle.com/adf/resourcebundle/config">
  <applicationBundleName>
    path-to-resource-bundle/bundle-name
  </applicationBundleName>
  <bundleList>
    <bundleId>
      package.BundleID
    </bundleId>
  </bundleList>
</adf-resourcebundle-config>

Note:

If an application is not configured for customization, you can open it in the Customization Developer role and define new resource keys by choosing Edit Resource Bundles from the Application menu. However, you cannot change a document to use the new resource keys if it is not configured for customization.

34.4 Extended Metadata Properties

Extended metadata is data that describes the metadata content. The extended metadata file contains additional information about the metadata file. One use of this extended information is to identify which parts of the metadata can be customized at runtime (design time at runtime customizations) and who can customize them. For more information about this use of extended metadata properties, see Section 34.4.2, "How to Enable Customization for Design Time at Runtime."

You can open a metadata file (such as a .jspx file) in JDeveloper and use the Property Inspector to view and edit its extended metadata properties. When you open a metadata file, its extended metadata properties are displayed in the Property Inspector. These properties can be edited to add metadata information at either of the following levels:

  • File-level: These properties are displayed in the Property Inspector when the root element is selected in the Structure window.

  • Element-level: These properties are displayed in the Property Inspector when an element is selected in the Structure window. The selected element should have a non-null identifier.

Extended metadata properties are supported for file types that support customizations and can be packaged in a MAR, such as .jsff and .jspx files.

Extended metadata for a metadata document is stored in an associated resource description framework (RDF) file. RDF is a W3C standard used to define an XML framework for defining metadata. The RDF file associated with the metadata document is created when the first property value is specified using the Property Inspector. Extended metadata properties are editable only when JDeveloper is in the Default role. RDF files are read-only in the Customization Developer role.

The RDF file is stored in the mdssys directory. For example, if the metadata being described is stored in the file system as /myapp/data/page1.jspx, the corresponding extended metadata document would be stored as /myapp/data/mdssys/mdx/page1.jspx.rdf. The extended metadata document must then be packaged with the corresponding metadata base file and added to the same deployment profile. For more information about creating a MAR deployment profile, see Section 36.3.2, "How to Create Deployment Profiles."

Note:

Don't edit the extended metadata documents directly. Use the Property Inspector.

34.4.1 How to Edit Extended Metadata Properties

You can use extended metadata properties to provide additional metadata information that is not covered in the metadata file (such as a .jspx file). When you open the metadata file in JDeveloper, extended metadata properties are displayed in the Property Inspector, which you can use to edit these properties when you are using JDeveloper in the Default role.

For example, suppose you want to deliver a metadata file in some form to external customers. Along with metadata file, you need to provide additional information about the file, such as the creator, subject, description, format, and rights. You can accomplish this by creating an extended metadata property file for your metadata file.

To edit extended metadata properties:

  1. Launch JDeveloper using the Default role.

  2. In JDeveloper, open the appropriate application and project.

  3. In the Application Navigator, select the object for which you want to edit extended metadata properties.

  4. In the Structure window, select the appropriate element (typically the root element).

  5. In the Property Inspector, expand the appropriate node to edit the properties.

    To display the Property Inspector with the values for the selected component, choose Property Inspector from the View menu.

  6. Edit the value for the desired property and press Enter.

  7. Choose Save from the File menu to save your work.

If you have edited extended metadata properties for a metadata file, you must package your extended metadata (or RDF) files with the metadata files when you deploy the application.

34.4.2 How to Enable Customization for Design Time at Runtime

You can also use extended metadata properties to provide information about which parts of the metadata can be customized at runtime and who can customize the metadata content.

By default, many components (such as tables and panelSplitters) that you can add to a .jspx page are preconfigured to allow runtime customization to support implicit user personalization (such as changing the order of columns in a table). Some WebCenter components (such as panelCustomizable) also allow customization in their type definition. For more information about user customization, see Chapter 35, "Allowing User Customizations at Runtime." For more information about WebCenter components, see the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter.

Components that are preconfigured to allow customization need no further modification to enable design time at runtime customizations. If you use them in a .jspx page, then they are customizable by default. However, the root elements of metadata objects (such as .jspx pages and page definition files) and other components (such as buttons) that you can add to a .jspx page are not preconfigured to be customizable at runtime, and must be explicitly configured to allow runtime customizations.

Therefore, depending on the requirements of your application, you will need to modify Customization properties in the following situations:

  • For components that are preconfigured to allow customization, you can override the default settings to disallow customization.

  • For components that are not preconfigured to allow customization and metadata objects (such as .jspx pages), you can override the default settings to allow customization.

  • For components that are configured to allow customization, you can optionally restrict who is allowed to perform customizations at runtime.

In the Customization group in the Property Inspector, there are two properties that allow you to specify whether customizations for an object are permitted at runtime and who is permitted to do them. The CustomizationAllowed property can be set on any element to specify whether or not it can be customized. The CustomizationAllowedBy property controls which users can customize the element. These settings are not enforced when implementing seeded customizations using JDeveloper, but are instead enforced when customizing the application at runtime (design time at runtime customizations).

For example, say you have a .jspx page with a form that contains two panels, and you need to allow runtime customization for content in Panel1, but not Panel2. You would set CustomizationAllowed to true for Panel1, and set it to false for Panel2. If you need to allow runtime customization on an entire page, you would set CustomizationAllowed to true for the .jspx page root.

To edit customization properties:

  1. Launch JDeveloper using the Default role.

  2. In JDeveloper, open the appropriate application and project.

  3. In the Application Navigator, select the object for which you want to edit customization properties.

  4. In the Structure window, select the appropriate element.

  5. In the Property Inspector, expand the Customization node to edit the customization properties.

    To display the Property Inspector with the values for the selected component, choose Property Inspector from the View menu.

  6. Edit the property value and press Enter.

    For example, to allow runtime customizations on a .jspx file, select the file and set the CustomizationAllowed property to true.

  7. Choose Save from the File menu to save your work.

If you have edited customization properties, you must package your extended metadata (RDF) files with the metadata files when you deploy the application.

34.5 Enabling Runtime Modification of Customization Configuration

You can prepare your customized application to accept overrides to the customization configuration (the cust-config section of the adf-config.xml file) at runtime on a per-session basis, thus allowing the user to change the way customizations are applied for a given session (or web request).

Consider a scenario where an application is configured with a site layer and a user layer and you want to make design time at runtime customizations to the site layer. If you use the application's customization configuration (defined in the adf-config.xml file), any customizations that you implement are applied to the user layer. So, you need to be able to adjust the customization configuration for a given session to allow your customizations to be applied to the site layer.

Or you have a requirement that an administrator wants to see the base metadata document with the site layer customizations alone. For cases like this, you need to specify a modified customization configuration, other than what was originally specified in application's adf-config.xml file.

For each web request, Oracle ADF creates an MDS session. For any MDS customization configuration modifications that apply to a session (web request), the user could programmatically provide modified MDS session options with a new customization configuration to Oracle ADF that would be applied on top of the original MDS configuration while creating a MDS session.

To implement this functionality, use the following ADF interfaces for sessionOptionsFactory:

  • oracle.adf.share.mds.SessionOptionsFactory is the interface you use to specify modified MDS session options for a web request in an ADF application.

    SessionOptionsFactory :: oracle.mds.core.SessionOptions createSessionOptions(oracle.mds.core.SessionOptions defaultOptions)
    

    You implement this method to return the modified MDS sessionOptions to ADF.

  • oracle.adf.share.config.ConfigUtils is the public class you can use to register your session options factory with ADF.

    ConfigUtils :: public static void setSessionOptionsFactory(ADFContext context, SessionOptionsFactory factory)
    

See your ADF API documentation for further detail on these interfaces.

Note:

If you are using Oracle Composer components, you can use the ComposerSessionOptionsFactory interface to specify modified MDS session options with Composer.
ComposerSessionOptionsFactory :: public SessionOptions createSessionOptions(SessionOptions defaultOptions, String mode);

oracle.adf.view.page.editor.webapp.WebCenterComposerFilter loads your ComposerSessionOptionsFactory implementation from the current thread context class loader. See the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter for more information.

You register your sessionOptionsFactory with ADF or Composer in a filter implementation so that ADF can get modified session options from your implementation before the MDS session is created in request lifecycle.

Example 34-10 shows how you can implement sessionOptionsFactory. This example sets a modified customization configuration for the session to use the site customization layer alone regardless of the customization configuration specified in the adf-config.xml file. See the Javadoc for oracle.mds for more information.

Example 34-10 Sample sessionOptionsFactory Class

package mycompany;

import oracle.adf.share.mds.SessionOptionsFactory;
import oracle.mds.config.CustClassListMapping;
import oracle.mds.config.CustConfig;
import oracle.mds.config.MDSConfigurationException;
import oracle.mds.core.SessionOptions;
import oracle.mds.cust.CustClassList;
import oracle.mds.cust.CustomizationClass;

public class MySessionOptionsFactory implements SessionOptionsFactory {
  public MySessionOptionsFactory() {
    super();
  }
  /**
   * Called to allow the application code to create a new SessionOptions object.
   * The application code should make sure to read the values from the
   * defaultOptions object as part of contruction of their new object and make
   * sure they only override the intended values.
   * @param defaultOptions
   * @return modified MDS session options
   */
  public SessionOptions createSessionOptions(SessionOptions defaultOptions) {
    // create new mds Customization configuration
    CustConfig custconfig = null;
 
    // create customization class array. Just put SiteCC implementation as we 
    // wish to apply site customizations alone.
    CustomizationClass[] custclassarray = new CustomizationClass[] {new SiteCC()};
 
    CustClassList custclasslist = new CustClassList(custclassarray);
 
    // specify the base metdata package namespace mapping on which site
    // customizations would apply
    CustClassListMapping[] mappings = 
        new CustClassListMapping[] {new CustClassListMapping("mycompany/package",
                                                     null, null, custclasslist)};
    // create new customization configuration
    try{
      custconfig = new CustConfig(mappings);
    }
    catch (Exception ex){
      //do nothing
    }
    
    // now return modified sessionOptions to ADF with new mds customization
    // configuration. Only use newly created customization configuration in here.
    // For rest of option, use whatever available in defaultOptions.
    return new SessionOptions(defaultOptions.getIsolationLevel(),
                              defaultOptions.getLocale(),
                              custconfig,
                              defaultOptions.getVersionContext(),
                              defaultOptions.getVersionCreatorName(),
                              defaultOptions.getCustomizationPolicy(),
                              defaultOptions.getServletContextAsObject()); 
}
}