Following recent discussions on the mailing list I have been updating the SDO Java sample code and I'd like to solicit some input.
My aims have been -- to make it an informative exercise to run binary samples without necessarily directly referencing the source code -- categorize the samples into novice, intermediate and advanced -- allow customization of output to match the skill level of the user to novice, intermediate or advanced -- to make the sample code clearer for inspection while executing the code -- to make the main aspect of the sample stand out from the standard prerequisite initialisation code -- to bring the samples up to date with current best practice, given the revisions between the 2.01. and .1 specifications and updates to our own Tuscany APIs -- to make the samples more aligned with common usage I would welcome your comments on these updates. To that end, rather than get you to build and run them I will point out the relevant new code and paste output from running selected samples. I have created 2 base classes for the samples, one that provides uninteresting infrastructure [1], and a derived one that provides SDO utility methods common to samples that are of interest to the SDO user [2]. For example, take a look at the createScopeForTypes() and loadTypesFromXMLSchemaFile() methods in [2]. I have increased the level of commentary output from each sample. This commentary includes a verbose description of the steps being taken. It also includes and echo of the relevant lines of SDO code, thus making the execution of samples which are pre-compiled binaries a useful exercise in the absence of the original source code. Each sample is assigned an experience level, NOVICE, INTERMEDIATE or ADVANCED. Each element of commentary is assigned a user level, for example the commentary output from all the utility methods in SampleBase is NOVICE commentary. If you run the sample with COMMENTARY_FOR_INTERMEDIATE, you won't see any of the commentary for novices, (extrapolate for ADVANCED). (The default experience level for each comment is that of the sample itself.) Some elements of commentary for which the code may be executed more than once in a sample run are given alternative briefer forms of commentary so that the verbose form only appears once per sample run, and the terse form will be output each subsequent time that the code block is executed. The terse form usually ends with some thing like "... as we saw before" The samples are designed to be run either on their own or from a program which executes a sequence of samples [3] (still under development) . In this way the above feature allowing terse forms of commentary reduces the overall length of output significantly. The top level program [3] may currently be edited to run samples up to a given user experience level. This may be better as a command line argument. The set of sample program classes which I have moved to the new format may be seen in the "sampleClasses" instance member of [3]. For example see the runSample() method of [4]. Attached below is the execution of this sample with commentary level for a novice user and then repeated for an intermediate user. Your comments are very welcome. Kelvin. [1] https://svn.apache.org/repos/asf/incubator/tuscany/java/sdo/sample/src/main/java/org/apache/tuscany/samples/sdo/SampleInfrastructure.java [2] https://svn.apache.org/repos/asf/incubator/tuscany/java/sdo/sample/src/main/java/org/apache/tuscany/samples/sdo/SampleBase.java [3] https://svn.apache.org/repos/asf/incubator/tuscany/java/sdo/sample/src/main/java/org/apache/tuscany/samples/sdo/ExecuteSamples2.java [4] https://svn.apache.org/repos/asf/incubator/tuscany/java/sdo/sample/src/main/java/org/apache/tuscany/samples/sdo/specCodeSnippets/DynamicCustomerTypeSample.java -------------------------------------------------------------- - Running with commentary level for a novice user - - Edit the sample program's constructor argument to one from - - COMMENTARY_FOR_NOVICE - - COMMENTARY_FOR_INTERMEDIATE or - - COMMENTARY_FOR_ADVANCED - - in order to alter the level of commentary you are seeing - -------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- - Tuscany SDO Java Sample org.apache.tuscany.samples.sdo.specCodeSnippets.DynamicCustomerTypeSample - - This sample is aimed at a intermediate user - ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------ - Demonstrates the use of the SDO API to build types dynamically - - by building a data graph representing the type system and - - submitting that graph to TypeHelper.define() - ------------------------------------------------------------------ ----------------------------------------------------------------------------------------------- - All MetaData for SDO types can be viewed as being held in an instance of HelperContext - - The Helper Context instance provides access to a collection of other helpers - - that you will see exercised in the SDO samples - - All the Helpers related to a given helper context instance know about the same set of types - - - - The SDO specification doesn't state how an SDO implementation should create a HelperContext - - So we use a Tuscany specific API to do this ... - - - - HelperContext scope = SDOUtil.createHelperContext(); - ----------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------- - A TypeHelper is used for both looking up types, and later creating them - - - - TypeHelper typeHelper = scope.getTypeHelper(); - ---------------------------------------------------------------------------- ---------------------------------------------------------------------- - We can look up existing types to use in the creation of Properties - - - - Type intType = types.getType("commonj.sdo", "Int"); - - Type stringType = types.getType("commonj.sdo", "String"); - ---------------------------------------------------------------------- ----------------------------------------------------------------------------------- - To begin modelling the type system we create a DataObject with - - Type "commonj.sdo#Type" and set the URI and name for that type - - - - DataObject customerType = scope.getDataFactory().create("commonj.sdo", "Type"); - - customerType.set("uri", "http://example.com/customer"); - - customerType.set("name", "Customer"); - ----------------------------------------------------------------------------------- --------------------------------------------------------------------------- - Now we can create a model for the Properties for the Type - - and set the name and Types of those Properties - - - - DataObject custNumProperty = customerType.createDataObject("property"); - - custNumProperty.set("name", "custNum"); - - custNumProperty.set("type", intType); - --------------------------------------------------------------------------- ------------------------------------------------------------------------------------ - We continue in this manner until all the Types and their Properties are modelled - ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ - Now that our type is fully modelled we submit the model to the TypeHelper - - The new Type instance is retuend to us, but is also available for lookup within - - the scope associated with the TypeHelper - - - - Type t = typeHelper.define(customerType); - ------------------------------------------------------------------------------------ --------------------------------------------------------------------------------------------- - Here we see the newly created Type being accessed via the TypeHelper - - along with a printout of the Type's Properties - - - - Type testType = scope.getTypeHelper().getType("http://example.com/customer", "Customer"); - --------------------------------------------------------------------------------------------- [EMAIL PROTECTED] (name: custNum) (ordered: true, unique: true, lowerBound: 0, upperBound: 1) (changeable: true, volatile: false, transient: false, defaultValueLiteral: null, unsettable: false, derived: false) (iD: false) [EMAIL PROTECTED] (name: lastName) (ordered: true, unique: true, lowerBound: 0, upperBound: 1) (changeable: true, volatile: false, transient: false, defaultValueLiteral: null, unsettable: false, derived: false) (iD: false) [EMAIL PROTECTED] (name: firstName) (ordered: true, unique: true, lowerBound: 0, upperBound: 1) (changeable: true, volatile: false, transient: false, defaultValueLiteral: null, unsettable: false, derived: false) (iD: false) -------------------------------------------------------------------------------------------------- - Now we can create an instance of the type using the DataFactory associated with the type scope - - - - DataFactory factory = scope.getDataFactory(); - - DataObject customer1 = factory.create("http://example.com/customer", "Customer"); - -------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------ - Here's an XML String representing a DataObject we have created with the new type - ------------------------------------------------------------------------------------ <?xml version="1.0" encoding="ASCII"?> <customer:customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:customer="http://www.example.com/customer" xmlns:customer_1="http://example.com/customer" xsi:type="customer_1:Customer" custNum="1" lastName="Adams" firstName="John"/> --------------------------------------------------------------------------------------------------- - End of sample org.apache.tuscany.samples.sdo.specCodeSnippets.DynamicCustomerTypeSample - --------------------------------------------------------------------------------------------------- -------------------------------------------------------------- - Running with commentary level for a intermediate user - - Edit the sample program's constructor argument to one from - - COMMENTARY_FOR_NOVICE - - COMMENTARY_FOR_INTERMEDIATE or - - COMMENTARY_FOR_ADVANCED - - in order to alter the level of commentary you are seeing - -------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- - Tuscany SDO Java Sample org.apache.tuscany.samples.sdo.specCodeSnippets.DynamicCustomerTypeSample - - This sample is aimed at a intermediate user - ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------ - Demonstrates the use of the SDO API to build types dynamically - - by building a data graph representing the type system and - - submitting that graph to TypeHelper.define() - ------------------------------------------------------------------ ---------------------------------------------------------------------------- - A TypeHelper is used for both looking up types, and later creating them - - - - TypeHelper typeHelper = scope.getTypeHelper(); - ---------------------------------------------------------------------------- ---------------------------------------------------------------------- - We can look up existing types to use in the creation of Properties - - - - Type intType = types.getType("commonj.sdo", "Int"); - - Type stringType = types.getType("commonj.sdo", "String"); - ---------------------------------------------------------------------- ----------------------------------------------------------------------------------- - To begin modelling the type system we create a DataObject with - - Type "commonj.sdo#Type" and set the URI and name for that type - - - - DataObject customerType = scope.getDataFactory().create("commonj.sdo", "Type"); - - customerType.set("uri", "http://example.com/customer"); - - customerType.set("name", "Customer"); - ----------------------------------------------------------------------------------- --------------------------------------------------------------------------- - Now we can create a model for the Properties for the Type - - and set the name and Types of those Properties - - - - DataObject custNumProperty = customerType.createDataObject("property"); - - custNumProperty.set("name", "custNum"); - - custNumProperty.set("type", intType); - --------------------------------------------------------------------------- ------------------------------------------------------------------------------------ - We continue in this manner until all the Types and their Properties are modelled - ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ - Now that our type is fully modelled we submit the model to the TypeHelper - - The new Type instance is retuend to us, but is also available for lookup within - - the scope associated with the TypeHelper - - - - Type t = typeHelper.define(customerType); - ------------------------------------------------------------------------------------ --------------------------------------------------------------------------------------------- - Here we see the newly created Type being accessed via the TypeHelper - - along with a printout of the Type's Properties - - - - Type testType = scope.getTypeHelper().getType("http://example.com/customer", "Customer"); - --------------------------------------------------------------------------------------------- [EMAIL PROTECTED] (name: custNum) (ordered: true, unique: true, lowerBound: 0, upperBound: 1) (changeable: true, volatile: false, transient: false, defaultValueLiteral: null, unsettable: false, derived: false) (iD: false) [EMAIL PROTECTED] (name: lastName) (ordered: true, unique: true, lowerBound: 0, upperBound: 1) (changeable: true, volatile: false, transient: false, defaultValueLiteral: null, unsettable: false, derived: false) (iD: false) [EMAIL PROTECTED] (name: firstName) (ordered: true, unique: true, lowerBound: 0, upperBound: 1) (changeable: true, volatile: false, transient: false, defaultValueLiteral: null, unsettable: false, derived: false) (iD: false) -------------------------------------------------------------------------------------------------- - Now we can create an instance of the type using the DataFactory associated with the type scope - - - - DataFactory factory = scope.getDataFactory(); - - DataObject customer1 = factory.create("http://example.com/customer", "Customer"); - -------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------ - Here's an XML String representing a DataObject we have created with the new type - ------------------------------------------------------------------------------------ <?xml version="1.0" encoding="ASCII"?> <customer:customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:customer="http://www.example.com/customer" xmlns:customer_1="http://example.com/customer" xsi:type="customer_1:Customer" custNum="1" lastName="Adams" firstName="John"/> --------------------------------------------------------------------------------------------------- - End of sample org.apache.tuscany.samples.sdo.specCodeSnippets.DynamicCustomerTypeSample - ---------------------------------------------------------------------------------------------------
