| Oracle Internet File System Developer Reference Release 9.0.1.1.0 Part Number A90093-02 |
|
This chapter covers the following topics:
Oracle 9iFS provides three mechanisms for attribute validation:
Once validation has been set for an attribute, if an end user attempts to set the attribute to an invalid value, an exception is thrown. It is up to the developer to determine what should happen as a result of an exception, and handle it appropriately through the user interface.
A ValueDefault is used to set the initial value of an attribute to a specific value when a ClassObject is created. A ValueDefault can be explicitly overridden by an end user. If no value is supplied by the user, the ValueDefault will be used.
A ValueDefault is stored as a PropertyBundle with only a single value (if the ValueDefault is an array value, there is only one array identified as the default value). The PropertyBundle is identified by a unique integer value. Figure 7-1 shows the complex relationships used to relate the ValueDefault object with its value, stored in the table ODM_PROPERTY.
The ValueDomain table is linked to ODM_ValueDefaultPB table by its VALUEDEFAULTPB attribute. ODM_VALUEDEFAULTPB is linked to the ODM_PROPERTYBUNDLE table by the same ID value. Finally, the ODM_PROPERTYBUNDLE table is linked to the BUNDLE column in the ODM_PROPERTY table using the same ID. This completes the association between the STRINGVALUE and the ValueDefault object.
If you create a ValueDomain using an XML configuration file, much of this complexity is handled for you.
The XML configuration file in Example 7-1, "ValueDefault XML Configuration File, ApproverVDefault.xml" creates the ValueDefault ApproverVDefault for the custom class ExpenseReport. The root element of this XML configuration file identifies the object to be created as a ValueDefault. The VDValue tag uses the Datatype parameter to identify the default with the data type String, and identifies the string value to be used.
<?xml version='1.0' standalone= 'yes'?> <ValueDefault> <Name> ApproverVDefault </Name> <VDValue Datatype="String">Chris Stevens</VDValue> </ValueDefault>
Once the ValueDefault object is created, a ClassObject can be created that uses the ValueDefault created in Example 7-1. Example 7-2, "ClassObject XML Configuration File, ExpenseReport.xml" shows an XML configuration file that creates the ExpenseReport custom class. The ExpenseReport class uses the ApproverVDefault to populate the Approver attribute when a new ExpenseReport instance is created.
<?xml version = '1.0' standalone = 'yes'?> <ClassObject> <Name>ExpenseReport</Name> <Superclass RefType= 'name'>Document</Superclass> <Attributes> <Attribute> <Name>Approver</Name> <DataType>String</DataType> <DataLength>20</DataLength> <ValueDefault RefType='name'>ApproverVDefault </ValueDefault> </Attribute> </Attributes> </ClassObject>
You can test the ValueDefault example using the following examples. Example 7-3, "ExpenseReport101.xml" creates an instance of the ExpenseReport class that uses the default value defined in Example 7-1. Example 7-4, "ExpenseReport102.xml" creates an instance of the ExpenseReport class that overrides the default value, providing its own entry, Joyce Doe, for the Approver attribute.
<EXPENSEREPORT> <Name>ExpenseReport101</Name> </EXPENSEREPORT>
<EXPENSEREPORT> <Name>ExpenseReport102</Name> <Approver>Joyce Doe</Approver> </EXPENSEREPORT>
To test the ExpenseReport example files:
ApproverVDefault.xml through any protocol. This file defines the ValueDefault. If you are using the web user interface, ensure that the Parse File on Upload box is checked as this and the remaining files are uploaded to Oracle 9iFS.
ExpenseReport.xml to Oracle 9iFS. This will define the custom subclass ExpenseReport.
ExpenseReport101.xml. This XML file does not include a definition for the Approver attribute, so the default is used.
ExpenseReport102.xml. This XML file includes a definition for the Approver attribute. The explicit value provided in the file is used rather than the ValueDefault.
A ClassDomain limits the values for an attribute to a specific Oracle 9iFS class or set of classes.
Continuing the ExpenseReport example, a separate class might use the ExpenseReport object as a detail line in a larger report. To facilitate this, an attribute of the type PublicObject could be added to the summary report, but it needs to be limited to PublicObjects of the ExpenseReport class. Example 7-5, "XML Configuration File for ExpenseReportClassDomain.xml" shows an XML configuration file that will create a ClassDomain limited to the ExpenseReport class
Table 7-1, "Attributes of the ClassDomain Class" describes the attributes that need to be set in the XML configuration file.
The values that must be set to create the ExpenseReportClassDomain are:
The resulting XML file is shown in Example 7-5, "XML Configuration File for ExpenseReportClassDomain.xml"
<?xml version = '1.0' standalone = 'yes'?> <ClassDomain> <Name>ExpenseReportClassDomain</Name> <DomainType>1</DomainType> <Classes> <ArrayElement RefType='name'>ExpenseReport</ArrayElement> </Classes> </ClassDomain>
Once the ExpenseReportClassDomain is created, the ExpenseDetailLine class can be created, using the ExpenseReportClassDomain object to validate entries to its single attribute, RelatedExpenseReport.
<?xml version = '1.0' standalone = 'yes'?> <ClassObject> <Name>ExpenseDetailLine</Name> <Superclass Reftype='name'>Document</Superclass> <Attributes> <Attribute> <Name>RelatedExpenseReport</Name> <DataType>PublicObject</DataType> <ClassDomain RefType='name'>ExpenseReportClassDomain</ClassDomain> </Attribute> </Attributes> </ClassObject>
Now that the ClassDomain has been created, you can test the results using the example files.
Example 7-7, "GoodExpenseDetailLine.xml" creates a valid instance of the ExpenseDetailLine class, using the ExpenseReport101 ExpenseReport instance created in Example 7-3, "ExpenseReport101.xml" as the value for the attribute RelatedExpenseReport.
<EXPENSEDETAILLINE> <Name>GoodExpenseDetailLine</Name> <RelatedExpenseReport RefType='name'>ExpenseReport101 </RelatedExpenseReport> </EXPENSEDETAILLINE>
Example 7-8, "ExpenseDetailLine101.xml" creates an instance of the ExpenseDetailLine class with the name ExpenseDetailLine101. This is a dummy object, to give us a known object that is not of the ExpenseReport class.
<EXPENSEDETAILLINE> <Name>ExpenseDetailLine101</Name> </EXPENSEDETAILLINE>
Example 7-9, "BadExpenseDetailLine.xml" attempts, but fails, to create an instance of ExpenseDetailLine, because the RelatedExpenseReport attribute identifies an instance of the ExpenseDetailLine class created in Example 7-8, "ExpenseDetailLine101.xml" rather than an instance of the ExpenseReport class as required by the ClassDomain.
<EXPENSEDETAILLINE> <Name>BadExpenseDetailLine</Name> <RelatedExpenseReport RefType='name'>ExpenseDetailLine101 </RelatedExpenseReport> </EXPENSEDETAILLINE>
To test the ClassDomain example files:
A ValueDomain can be applied to an attribute to ensure that the values for that attribute lie within a set of acceptable values. In the context of the ongoing Expense Report scenario, Example 7-10 illustrates using a ValueDomain to restrict the value of the Approver attribute.
ValueDomains can be created in XML using the VDomainValue tag for the value of a ValueDomain, as shown in Example 7-10. The tag has the following required parameters:
Enumerated, exclusive_maximum, exclusive_minimum, exclusive_range, maximum, minimum and range.
To illustrate the way ValueDomain works, this section uses XML to create several objects, then shows Java classes used to verify the assignments made by the XML files.
Specifically, the files listed in table Table 7-2 are used in this section.
TestVDomain.java class.
<ORACLE_HOME>/9ifs/custom_classes/oracle/ifs/examples/ directory.
<ORACLE_HOME>/9ifs/custom_classes/oracle/ifs/examples/ directory.
ValueDomains can be created by inserting into the repository an XML file such as the one in Example 7-10:
<?xml version = '1.0' standalone = 'yes'?> <VALUEDOMAIN> <Name>ApproverValueDomain</Name> <Active>true</Active> <Description> my value_domain to set the Approver attribute </Description> <VDomainValue Domaintype="enumerated" Datatype="string_array"> <ArrayElement>Bob Alva</ArrayElement> <ArrayElement>John Smith</ArrayElement> <ArrayElement>Chris Stevens</ArrayElement> </VDomainValue> <UniqueName>ApproverValueDomain</UniqueName> </VALUEDOMAIN>
In Example 7-10, the DomainType is set to "enumerated," meaning only those values listed explicitly are valid. The Datatype is set to "string_array," meaning that the ValueDomain consists of an array of String objects.
Because they apply to the same object, the DomainType and DataType must correspond. For example, to assign a ValueDomain to equal a range of integers, the DataType must be integer_array and DomainType must be range, as shown in Example 7-11.
<?xml version = '1.0' standalone = 'yes'?> <VALUEDOMAIN> <Name>codes_range</Name> <Active>true</Active> <Description> my value_domain to set value ranges </Description> <VDomainValue datatype="integer_array" domaintype="range"> <MinValue>10</MinValue> <MaxValue>20</MaxValue> </VDomainValue> <UniqueName>codes_range</UniqueName> </VALUEDOMAIN>
Value domains can be updated using XML, as shown in Example 7-12. In this case, an existing ValueDomain called codes_max has its DomainType set to maximum, and its DataType assigned to integer.
<?xml version="1.0" standalone="yes"?> <ValueDomain> <update reftype="name"> codes_max</update> <VDomainValue domaintype="maximum" datatype="integer"> 100 </VDomainValue> </ValueDomain>
Creating ValueDomains Using Java
The ApproverVDomain.java class shown in Example 7-13 illustrates how to use the Oracle 9iFS Java API to make use of these validation objects. This class creates a ValueDomain for the Approver attribute of the ExpenseReport, limiting its value to Bob Alva, John Smith, or Chris Stevens. This program creates the same ValueDomain created with an XML configuration file in Example 7-10.
package oracle.ifs.examples.documentation.validate; import oracle.ifs.beans.Attribute; import oracle.ifs.beans.ClassObject; import oracle.ifs.beans.LibraryService; import oracle.ifs.beans.LibrarySession; import oracle.ifs.beans.PublicObject; import oracle.ifs.beans.SchemaObject; import oracle.ifs.beans.ValueDomain; import oracle.ifs.beans.ValueDomainDefinition; import oracle.ifs.beans.ValueDomainPropertyBundle; import oracle.ifs.beans.ValueDomainPropertyBundleDefinition; import oracle.ifs.common.AttributeValue; import oracle.ifs.common.CleartextCredential; import oracle.ifs.common.Collection; import oracle.ifs.common.IfsException; /** * ApproverVDomain class * This class creates a valuedomain for the APPROVER attribute of * class EXPENSEREPORT. The valuedomain limits the value of the APPROVER * attribute to Bob Alva, John Smith, or Chris Stevens. **/ public class ApproverVDomain { /** * Creates the valuedoamin and applies it to the APPROVER attribute * of class EXPENSEREPORT. * * @param args the command-line arguments for connecting to iFS: * userName, passWord, serviceName */ public static void main(String[] args) { ApproverVDomain vDomain = new ApproverVDomain(); vDomain.CreateVDomain(args[0], args[1], args[2], args[3]); } /** * Creates the valuedomain and applies it to the APPROVER attribute * of class EXPENSEREPORT. * * @param usedfor connecting to iFS: * userName, passWord, serviceName, schemaPassWord */ public void CreateVDomain(String userName, String passWord, String serviceName, String schemaPassWord) { try { //Connects to the IFS. LibraryService service=LibraryService.startService(userName, passWord); CleartextCredential cred=new CleartextCredential(serviceName, schemaPassWord); LibrarySession session=service.connect(cred, null); session.setAdministrationMode(true); System.out.println("Successfully connected."); String s = "STRING_ENUMERATED"; //Creates the ValueDomainPropertyBundle ValueDomainPropertyBundleDefinition vdpbd = new ValueDomainPropertyBundleDefinition(session); vdpbd.setEnumeratedValues(new String[] { "Bob Alva", "John Smith", "Chris Stevens" }); ValueDomainPropertyBundle vdpb = (ValueDomainPropertyBundle)session.createPublicObject(vdpbd); //Creates the ValueDomain ValueDomainDefinition vdd = new ValueDomainDefinition(); vdd.setName("ApproverValueDomain"); vdd.setAttribute("VALUEDOMAINPROPERTYBUNDLE", AttributeValue.newAttributeValue(vdpb)); ValueDomain vd = (ValueDomain) session.createSchemaObject(vdd); //Gets class object collection, then gets the specific EXPENSEREPORT class object. Collection classObjectCollection = session.getClassObjectCollection(); ClassObject expenseReportClassObject = (ClassObject) classObjectCollection.getItems("EXPENSEREPORT"); //Gets the APPROVER attribute for the class object. Attribute attribute = expenseReportClassObject.getEffectiveClassAttributes("APPROVER"); //Modifies the attribute for the class object. //Applies the value doamin to this class object. attribute.setValueDomain(vd); attribute.setValueDomainValidated(true); System.out.println("ValueDomain applied."); } catch ( IfsException ifex ) { System.err.println( "ERROR OCCURRED: " + ifex.toString() ); ifex.printStackTrace( System.err ); } } }
Using the TestVDomain class in Example 7-14, you can verify whether the ValueDomain you created in either Example 7-10 or Example 7-13 is functioning as expected.
package oracle.ifs.examples.documentation.validate; import oracle.ifs.beans.ClassObject; import oracle.ifs.beans.Document; import oracle.ifs.beans.DocumentDefinition; import oracle.ifs.beans.LibraryService; import oracle.ifs.beans.LibrarySession; import oracle.ifs.common.AttributeValue; import oracle.ifs.common.CleartextCredential; import oracle.ifs.common.Collection; import oracle.ifs.common.IfsException; /** * TestVDomain class. * This class creates two instances of the EXPENSEREPORT class. * One instance has a value in the APPROVER attribute that complies * with the value domain, the other instance has one that violates * the value domain. * * An exception is generated when you try to create an instance * that violates the value domain. **/ public class TestVDomain { public static void main(String[] args) { try { //Shows detailed error message while the exception is thrown IfsException.setVerboseMessage(true); //Connects to iFS LibraryService service=LibraryService.startService(args[0], args[1]); CleartextCredential cred=new CleartextCredential(args[2], args[3]); LibrarySession session=service.connect(cred, null); System.out.println("Successfully connected"); //Gets class object collection, then gets the specific EXPENSEREPORT class //object. Collection classObjectCollection = session.getClassObjectCollection(); ClassObject expenseReportClassObject = (ClassObject) classObjectCollection.getItems("EXPENSEREPORT"); //Creates an EXPENSEREPORT instance that complies with the value domain System.out.println("Attempting to create an EXPENSEREPORT instance that" + " complies with the value domain"); DocumentDefinition docdef = new DocumentDefinition(session); docdef.setName("GoodVDomainExpenseReport"); docdef.setClassObject(expenseReportClassObject); docdef.setAttribute("APPROVER", AttributeValue.newAttributeValue("John Smith")); Document doc = (Document)session.createPublicObject(docdef); AttributeValue av = doc.getAttribute("APPROVER"); System.out.println("Created an expense report with Approver as " + av.getString(session)); //Creates an EXPENSEREPORT instance that violates the value domain System.out.println("Attempting to create an EXPENSEREPORT instance that " + "violates the value domain"); docdef = new DocumentDefinition(session); docdef.setName("BadVDomainExpenseReport"); docdef.setClassObject(expenseReportClassObject); docdef.setAttribute("APPROVER", AttributeValue.newAttributeValue("foo")); doc = (Document)session.createPublicObject(docdef); av = doc.getAttribute("APPROVER"); System.out.println("Created an expense report with Approver as " + av.getString(session)); } catch (Exception e) { e.printStackTrace(); } } }
|
|
![]() Copyright © 2001 Oracle Corporation. All Rights Reserved. |
|