Oracle Configurator Extensions and Interface Object Developer’s Guide Release 12.1 for Part Number E14321-03 | ![]() Contents | ![]() Previous | ![]() Next |
This appendix contains code examples illustrating the use of Configurator Extensions and the CIO.
This appendix covers the following topics:
This appendix contains code examples illustrating the use of Configurator Extensions and the CIO. These examples are fuller and longer than the examples provided in the rest of this document, which are often fragments. For each example, see the cited background sections for explanatory details.
This Configurator Extension produces an HTML representation of the runtime Model tree, beginning at a node specified in the Configurator Extension binding.
For the detailed procedure for creating a Configurator Extension Rule, see Building Configurator Extensions and the Oracle Configurator Developer User’s Guide. For specific information on building a Configurator Extension for generating custom output, see Generating Custom Output.
Here is a summary of the tasks specific to this example:
Use the Java source code in Generating Output with a Configurator Extension (ShowStructureCX.java) for your Java archive file and Configurator Extension Archive.
When you define your Configurator Extension rule, use the options listed in the following table:
Option | Choose ... |
---|---|
Model Node | The node of your Model on which you want the button for the command event to be placed by Oracle Configurator. This node is independent of the node in the Model tree from which the Configurator Extension begins showing structure. |
Java Class | ShowStructureCX, from your Configurator Extension Archive |
Java Class Instantiation | With Model Node Instance |
When you define your event binding, use the options listed in the following table:
Option | Choose ... |
---|---|
Event | onCommand |
Command Name | A string that you choose as a command. For example: Show Structure. Do not enclose the string in quotation marks. The string can contain spaces. |
Event Scope | Your choice of scope. Try repeating the example with different scopes to see the effect when you test it. |
Method Name | showModelStructure |
When you define your argument bindings, use the options listed in the following tables:
Option | Choose ... |
---|---|
Argument Type | javax.servlet.http.HttpServletResponse |
Argument Specification | Event Parameter |
Binding | HttpServletResponse |
Option | Choose ... |
---|---|
Argument Type | oracle.apps.cz.cio.IRuntimeNode |
Argument Specification | Model Node or Property |
Binding | The node of your Model from which you want to begin showing hierarchical Model structure. |
The example first calls the response.setContentType() method of the HttpServletResponse class, passing "text/html" as the output type.
The following line is required for compatibility with Microsoft Internet Explorer:
response.setHeader ("Expires", "-1");
Then the example calls response.getWriter() to get an output stream to which the Configurator Extension can write HTML.
You can also write non-HTML output by setting a different content type (a MIME type) and writing appropriate data to the output stream.
In the private method generateNode(), you can call either IRuntimeNode.getCaption(), as shown, or IRuntimeNode.getName(). However, getCaption() reflects changes to the name of a component instance made with Component.setInstanceName(), as described in Renaming Instances of Components, while getName() does not.
Generating Output with a Configurator Extension (ShowStructureCX.java)
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import com.sun.java.util.collections.Iterator;
import oracle.apps.cz.cio.IRuntimeNode;
/**
* Displays a textual rendition of the model structure tree.
*
*/
public class ShowStructureCX {
/**
* Bind node parameter to the node from which to start rendering model structure.
*/
public void showModelStructure(HttpServletResponse response, IRuntimeNode node) throws IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Runtime Model Structure</title>");
out.println("</head>");
out.println("<body>");
out.println("<h3>Runtime Model Structure</h3>");
generateNode(out, node, 0);
out.println("</body>");
out.println("</html>");
}
private static void generateNode(PrintWriter out, IRuntimeNode node, int level) throws IOException {
for (int i = 0; i < level; ++i) {
out.print("--");
}
// out.println(node.getName() + " <br> "); // doesn't get changed instance names
out.println(node.getCaption() + " <br> ");
for (Iterator i = node.getChildren().iterator(); i.hasNext(); ) {
IRuntimeNode childNode = (IRuntimeNode)i.next();
generateNode(out, childNode, (level + 1));
}
}
}
For background, see Using Requests.
This example shows how to designate a group of requests as nonoverridable requests, by using ConfigTransaction.useNonOverridableRequests(). For background, see Nonoverridable Requests.
Setting Nonoverridable Requests (NonOverridableTest.java)
import oracle.apps.cz.cio.BooleanFeature;
import oracle.apps.cz.cio.Component;
import oracle.apps.cz.cio.ComponentSet;
import oracle.apps.cz.cio.ConfigTransaction;
import oracle.apps.cz.cio.Configuration;
import oracle.apps.cz.cio.IInteger;
import oracle.apps.cz.cio.IOption;
import oracle.apps.cz.cio.IRuntimeNode;
import oracle.apps.cz.cio.IState;
import oracle.apps.cz.cio.IText;
import oracle.apps.cz.cio.LogicalException;
import oracle.apps.cz.cio.LogicalOverridableException;
import oracle.apps.cz.cio.NoSuchChildException;
import com.sun.java.util.collections.Iterator;
/**
* Demonstrates the use of nonoverridable requests.
*/
public class NonOverridableTest {
/**
* Makes requests while in "nonoverridable request mode".
* @param config in a CX, bind to the System Parameter "Configuration"
* @param comp a Component whose structure reflects this example code
*/
public void testOverride(Configuration config, IRuntimeNode comp) throws LogicalException {
ConfigTransaction itr = null;
try {
// Begin a transaction that uses nonoverridable requests
// ---------------------------------------------------
itr = config.beginConfigTransaction();
itr.useNonOverridableRequests();
// Try setting an Option Feature with mutually exclusive Options.
IRuntimeNode of1 = comp.getChildByName("option_feature_1");
// Select option_1
ConfigTransaction tr = config.beginConfigTransaction();
((IOption)of1.getChildByName("option_1")).select();
config.commitConfigTransaction(tr);
// Select option_2
tr = config.beginConfigTransaction();
((IOption)of1.getChildByName("option_2")).select();
config.commitConfigTransaction(tr);
// Try setting a value for an Integer Feature.
tr = config.beginConfigTransaction();
((IInteger)comp.getChildByName("integer_feature_1")).setIntValue(33);
config.commitConfigTransaction(tr);
// Try overriding a Boolean value.
// Assume that boolean_feature_1 NEGATES boolean_feature_2. This should produce a contradiction.
tr = config.beginConfigTransaction();
try {
((BooleanFeature)comp.getChildByName("boolean_feature_1")).setState(IState.TRUE);
((BooleanFeature)comp.getChildByName("boolean_feature_2")).setState(IState.TRUE);
} catch (LogicalOverridableException loe) {
loe.override();
}
config.commitConfigTransaction(tr);
// Get next Component in Component set.
ComponentSet cset = (ComponentSet)comp.getParent().getChildByName("component_set_1");
Component cset_comp_1 = null;
Iterator iter = cset.getChildren().iterator();
if (iter.hasNext()) {
cset_comp_1 = ((Component)iter.next());
}
// Try deleting a Component from a Component set.
// This is not allowed, and should produce a contradiction.
try {
tr = config.beginConfigTransaction();
cset.delete(cset_comp_1);
config.commitConfigTransaction(tr);
} catch (LogicalException le) { // for cset.delete()
config.rollbackConfigTransaction(tr);
System.out.println("Expected exception in deleting component " + le);
}
// Try adding a Component to a Component set.
// This is not allowed, and should produce a contradiction.
try {
tr = config.beginConfigTransaction();
cset.add();
config.commitConfigTransaction(tr);
} catch (LogicalException le) { // for cset.add()
config.rollbackConfigTransaction(tr);
System.out.println("Expected exception in adding component " + le);
}
try {
// Try setting value of a Text Feature of Component in Component set
tr = config.beginConfigTransaction();
IRuntimeNode featText = cset_comp_1.getChildByName("text_feature_1");
((IText)featText).setTextValue("any_text");
config.commitConfigTransaction(tr);
// Try overriding default value of an Integer Feature of Component in Component set
IRuntimeNode intFeatDef = comp.getParent().getChildByName("integer_feature_default");
tr = config.beginConfigTransaction();
((IInteger)intFeatDef).setIntValue(50); // Default value was 25
config.commitConfigTransaction(tr);
// Commit the transaction that used nonoverridable requests,
// thus canceling "nonoverridable request mode"
config.commitConfigTransaction(itr);
// ------------------------------------------------------------------
// Make an ordinary user request:
tr = config.beginConfigTransaction();
((IState)comp.getChildByName("boolean_feature_3")).setState(IState.TRUE);
config.commitConfigTransaction(tr);
/* */
} catch (LogicalException le) { // for setTextValue(), setIntValue(), setState()
le.printStackTrace();
// here, you should log the exception and stack trace to a file
} catch (NoSuchChildException nsce) { // for getChildByName()
nsce.printStackTrace();
// here, you should log the exception and stack trace to a file
}
} catch (LogicalException le) { // for select(), setIntValue(),
le.printStackTrace();
// here, you should log the exception and stack trace to a file
} catch (NoSuchChildException nsce) { // for getChildByName()
nsce.printStackTrace();
// here, you should log the exception and stack trace to a file
}
}
}
This example shows how to use LogicalOverridableException.override() to override a logical contradiction and return a List of Request objects that represent all the previously asserted user requests that failed due to the override that you are performing. For background, see Failed Requests.
Getting a List of Failed Requests (OverrideTest.java)
import oracle.apps.cz.cio.*;
import oracle.apps.cz.common.*;
import oracle.apps.fnd.common.*;
import oracle.apps.cz.utilities.*;
import java.util.*;
import com.sun.java.util.collections.List;
import com.sun.java.util.collections.Iterator;
public class OverrideTest
{
public static void main(String[] args)
{
ConfigTransaction tr = null;
Configuration config = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
CZWebAppsContext ctx = new CZWebAppsContext("/jdevhome/users/dbc_files/secure/server01_sid02.dbc"); // Use DBC file for context
CIO cio = new CIO();
int modelId = 5005; // hypothetical model ID
ConfigParameters cp = new ConfigParameters(modelId);
java.util.Calendar modelLookupDate = Calendar.getInstance(); // current date and time
cp.setModelLookupDate(modelLookupDate);
config = cio.startConfiguration(cp, ctx);
try {
OptionFeature of = (OptionFeature)config.getRootComponent().getChildByName("Feature1");
Option o1 = (Option) of.getChildByName("Option1");
Option o2 = (Option) of.getChildByName("Option2");
try {
tr = config.beginConfigTransaction();
o1.select();
o2.deselect();
config.commitConfigTransaction(tr);
} catch (LogicalOverridableException loe) {
try {
// Get list of failed requests, if any
List list = loe.override();
System.out.println("Option1: " + o1+ " State: " + o1.getState());
System.out.println("Option2: " + o2+ " State: " + o2.getState());
printList(list);
config.commitConfigTransaction(tr);
} catch (LogicalException le) {
le.printStackTrace();
// here, you should log the exception and stack trace to a file
config.rollbackConfigTransaction(tr);
}
} catch (LogicalException le) {
le.printStackTrace();
// here, you should log the exception and stack trace to a file
config.rollbackConfigTransaction(tr);
}
} catch (LogicalException le) {
le.printStackTrace();
// here, you should log the exception and stack trace to a file
} catch (NoSuchChildException nsce) {
// Perform exception handling here
}
} catch (LogicalException le) {
le.printStackTrace();
// here, you should log the exception and stack trace to a file
} catch (ModelLookupException mle) {
// Perform exception handling here
} catch(CheckedToUncheckedException ctue) {
// Perform exception handling here
} catch (ClassNotFoundException cnfe) {
// Perform exception handling here
} catch (oracle.apps.cz.utilities.EffectivityUsageException eue) {
// Perform exception handling here
} catch (BomExplosionException bee) {
// Perform exception handling here
}
}
public static void printList(List list) {
Iterator iter = list.iterator();
while (iter.hasNext()) {
System.out.println("Node: " + iter.next());
}
System.out.println("***************\n");
}
}
This example must use a child window of the kind described in Sharing a Configuration Session, which describes the background and purpose of the example. The child window must be created with the HTML-based version of Oracle Configurator Developer and run with a generated Configurator UI for the runtime Oracle Configurator.
This JSP generates the contents of a child window and performs the following tasks:
Imports the necessary user classes by importing the CIO. Session-related classes, such as PageContext, are supplied by your servlet/JSP container.
Gets the session’s Configuration object (cfg) through the session key configurationObject. This allows the child window to modify the same configuration as the parent window.
Gets the URL of the runtime Configurator in the parent window (retUrl) through the session key czReturnToConfiguratorUrl, so that control can return to it when the child window is closed.
Modifies the state of the current configuration.
Example code for modifying the runtime configuration from the child window is shown after the comment // Start configuration changes here. For simplicity, this code illustrates only basic interaction with the configuration model. For true interaction with the configuration model, you must tailor the code to your own circumstances.
The example here locates a node named Boolean Feature-1, checks whether it exists and is a Boolean Feature, and, if so, toggles its state. This action is performed when the end user clicks a button like that described in UI Specifications for Invoking Child Window.
For background on modifying the runtime configuration model, see Working with Model Entities. For details on toggling state, see Setting the State of a Node in Getting and Setting Logic States.
Provides a button (labeled Close), which refreshes the parent window with the results of the child window’s actions then closes the child window. This button calls a function, refreshMainWdw(), that uses the URL of the parent window (retUrl) to return control to it.
Sharing a Configuration Session in a Child Window (TestChildWin.jsp)
<%@ page contentType="text/html;charset=windows-1252"
import="oracle.apps.cz.cio.*"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>
Test Child Window
</title>
</head>
<body>
<%
// Get the session’s configuration object, through javax.servlet.jsp.PageContext
Configuration cfg = (Configuration)pageContext.getAttribute("configurationObject", PageContext.SESSION_SCOPE);
// Get URL of the runtime Configurator, so we can return to it.
String retUrl = (String)pageContext.getAttribute("czReturnToConfiguratorUrl", PageContext.SESSION_SCOPE);
if (cfg != null) {
out.println("<p>Got Configuration object from HTTP session. Can now modify the configuration.</p>");
// Start configuration changes here.
IRuntimeNode node = cfg.getRootComponent().getChildByName("Boolean Feature-1");
if (node != null && node instanceof BooleanFeature) {
((BooleanFeature)node).setState(IState.TOGGLE);
}
// End configuration changes here.
}
%>
<script>
function refreshMainWdw() {
opener.location="<%= retUrl %>";
window.close();
}
</script>
<form>
<input type="button" name="b1" value="Close" onclick="javascript:refreshMainWdw();">
</form>
</body>
</html>
The code in Tracking Session Changes (DeltaExample.java) assembles together the fragmentary examples shown in Configuration Session Change Tracking.
Tracking Session Changes (DeltaExample.java)
import com.sun.java.util.collections.*;
import oracle.apps.cz.cio.*;
import oracle.apps.cz.common.CZWebAppsContext;
import oracle.apps.fnd.common.Context;
public class DeltaExample
{
public static void main(String [] args) {
// Define some constants
int modelId = 1234;
String dbcFilename = "/jdevhome/users/dbc_files/secure/server01_sid02.dbc";
String user = "scott";
String pwd = "tiger";
try {
// Load the JDBC Driver and create Context, CIO
Class.forName("oracle.jdbc.driver.OracleDriver");
Context context = new CZWebAppsContext(dbcFilename);
context.getSessionManager().validateLogin( user, pwd);
CIO cio = new CIO();
cio.initializeAppsSession(context);
// Create a new Configuration and DeltaManager
ConfigParameters params = new ConfigParameters(modelId);
Configuration config = cio.startConfiguration(params, context);
DeltaManager deltaMgr = config.createDeltaManager("MyDeltaMgr");
// Create a Navigation (Tree) region. This is interested in watching
// all runtime nodes for instance name, instantiation, and unsatisfaction
// changes.
List dvList = new ArrayList();
dvList.add(deltaMgr.getDeltaValidator(DeltaValidator.INSTANCE_NAME_DV));
dvList.add(deltaMgr.getDeltaValidator(DeltaValidator.INSTANTIATION_DV));
dvList.add(deltaMgr.getDeltaValidator(DeltaValidator.UNSATISFACTION_DV));
List watchedNodes = config.getRuntimeNodes();
DeltaRegion treeRegion = deltaMgr.registerRegion(watchedNodes, dvList, "MyTreeRegion");
// Create a component region. This region displays a Component screen and is
// interested in watching all nodes in that component for availability, count,
// price, state and unsatisfaction changes
dvList.clear();
dvList.add(deltaMgr.getDeltaValidator(DeltaValidator.AVAILABILITY_DV));
dvList.add(deltaMgr.getDeltaValidator(DeltaValidator.COUNT_DV));
dvList.add(deltaMgr.getDeltaValidator(DeltaValidator.PRICE_DV));
dvList.add(deltaMgr.getDeltaValidator(DeltaValidator.STATE_DV));
dvList.add(deltaMgr.getDeltaValidator(DeltaValidator.UNSATISFACTION_DV));
watchedNodes = getRuntimeNodesInSelectedComponent(); // a custom method, not defined here
DeltaRegion compRegion = deltaMgr.registerRegion(watchedNodes, dvList, "MyCompRegion");
// Make an assertion to change the current configuration
Option option1 = (Option)config.getRootComponent().getChildByName("Feature").getChildByName("Option1");
option1.select();
// Get the deltas due to this assertion and update the tree and component regions
Map treeChanges = deltaMgr.getUpdateMapForRegion("MyTreeRegion");
// Now update the tree region cache and UI with treeChanges
updateTreeRegion(treeChanges);
Map compChanges = compRegion.getUpdateMap();
updateCompRegion(compChanges); // a custom method, not defined here
} catch (MyCustomException mce) {
mce.printStackTrace();
// here, you should log the exception and stack trace to a file
}
}
public static void updateTreeRegion(Map changes) {
for (Iterator iter = changes.keySet().iterator(); iter.hasNext();) {
RuntimeNode changedNode = (RuntimeNode)iter.next();
uiNode = getUiNode(changedNode); // custom method
Collection nodeChanges = (Collection)changes.get(changedNode);
for (Iterator iter2 = nodeChanges.iterator(); iter2.hasNext();) {
IValidatorChange change = (IValidatorChange)iter2.next();
switch (change.getType()) {
case DeltaValidator.INSTANCE_NAME_DV:
InstanceNameDeltaValidator.InstanceNameChange nameChange = (InstanceNameDeltaValidator.InstanceNameChange)change;
String newName = nameChange.getInstanceName();
uiNode.setName(newName); // custom method on uiNode
break;
case DeltaValidator.INSTANTIATION_DV:
InstantiationDeltaValidator.InstantiationChange iChange = (InstantiationDeltaValidator.InstantiationChange) change;
Collection added = iChange.getNewlyAddedInstances();
Collection deleted = iChange.getNewlyDeletedInstances();
uiNode.updateInstances(added, deleted); // custom method on uiNode
break;
case DeltaValidator.UNSATISFACTION_DV:
UnsatisfactionDeltaValidator.UnsatisfactionChange uChange = (UnsatisfactionDeltaValidator.UnsatisfactionChange) change;
boolean unsatisfied = uChange.isUnsatisfied();
uiNode.setUnsatisfied(unsatisfied); // custom method on uiNode
break;
}
}
}
}
}
Copyright © 1999, 2010, Oracle and/or its affiliates. All rights reserved.