From c993ba575bdd1530b7bbc0c6a19c32e66fce4b89 Mon Sep 17 00:00:00 2001 From: lresende Date: Tue, 10 Nov 2009 19:19:15 +0000 Subject: moving SDO branches git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@834612 13f79535-47bb-0310-9956-ffa450edef68 --- .../samples/sdo/advanced/MedicalScenario.java | 424 +++++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 sdo-java/branches/sdo-1.0-incubating/sample/src/main/java/org/apache/tuscany/samples/sdo/advanced/MedicalScenario.java (limited to 'sdo-java/branches/sdo-1.0-incubating/sample/src/main/java/org/apache/tuscany/samples/sdo/advanced/MedicalScenario.java') diff --git a/sdo-java/branches/sdo-1.0-incubating/sample/src/main/java/org/apache/tuscany/samples/sdo/advanced/MedicalScenario.java b/sdo-java/branches/sdo-1.0-incubating/sample/src/main/java/org/apache/tuscany/samples/sdo/advanced/MedicalScenario.java new file mode 100644 index 0000000000..1e288ccc48 --- /dev/null +++ b/sdo-java/branches/sdo-1.0-incubating/sample/src/main/java/org/apache/tuscany/samples/sdo/advanced/MedicalScenario.java @@ -0,0 +1,424 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.samples.sdo.advanced; + +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.samples.sdo.SampleBase; +import org.apache.tuscany.sdo.api.SDOUtil; + +import commonj.sdo.DataObject; +import commonj.sdo.Property; +import commonj.sdo.Type; +import commonj.sdo.helper.DataFactory; +import commonj.sdo.helper.HelperContext; +import commonj.sdo.helper.TypeHelper; + +/** + * This sample is based on a 2 part article by Kelvin Goodson and Geoffrey Winn. + * See Part1 and Part 2 of the article. + *

+ *

Running this Sample

See the main overview for instructions on how to run this + * sample. + */ +public class MedicalScenario extends SampleBase { + + private static final String sdoApiUri = "commonj.sdo"; + + private static final String peopleURI = "www.example.org/people"; + + private static final String medicalURI = "www.example.org/MedicalTest"; + + boolean typesViaAPI = false; + + private static final String usage = " [-api |-xsd]\n" + + " -api : define the types using the SDO API\n" + + " -xsd : define the types using an XML schema file"; + + public MedicalScenario(String[] args, Integer userLevel) { + + super(userLevel, SAMPLE_LEVEL_ADVANCED); + + if (args.length > 1) { + printUsage(args); + System.exit(-1); + } + if (args.length == 1) { + if (args[0].equals("-xsd")) { + typesViaAPI = false; + } else if (args[0].equals("-api")) { + typesViaAPI = true; + } else { + printUsage(args); + System.exit(-1); + } + } + } + + public MedicalScenario(Integer userLevel) { + super(userLevel, SAMPLE_LEVEL_ADVANCED); + } + + + private void printUsage(String[] args) { + System.out.println("Usage: " + this.getClass().getName() + usage); + } + + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + + MedicalScenario s = new MedicalScenario(args, COMMENTARY_FOR_NOVICE); + s.run(); + + } + + /* + * metadata for the sample documenting the areas of SDO that are explored + */ + public static int [] CORE_FUNCTION = { + SDOFacets.CONTAINMENT, + SDOFacets.CREATE_TYPES_USING_THE_SDO_API, + SDOFacets.CREATE_TYPES_USING_XML_SCHEMA, + SDOFacets.OPEN_CONTENT, + SDOFacets.NON_CONTAINMENT + }; + + public static int [] SIGNIFICANT_FUNCTION = { + SDOFacets.CREATE_DATAOBJECTS_BY_NAME, + SDOFacets.ISMANY_PROPERTIES, + SDOFacets.GENERIC_DATA_GRAPH_TRAVERSAL, + SDOFacets.SAVING_DATA_TO_XML + }; + + public void runSample() throws Exception { + + HelperContext scope = SDOUtil.createHelperContext(); + + if (typesViaAPI) { + + commentary("In this execution of the sample we use Types created\n" + + "using the SDO API"); + + createTypesViaAPI(scope); + + } else { + + commentary("In this execution of the sample we use Types created\n" + + "by loading an XMLSchema"); + + loadTypesFromXMLSchemaFile(scope, "MedicalTest.xsd"); + + } + + commentary( + COMMENTARY_FOR_NOVICE, + "The DataFactory associated with the scope that the types were created within\n" + + "can be used to create an instance of the Person Type\n\n" + + "DataFactory dataFactory = scope.getDataFactory();\n" + + "DataObject person1 = dataFactory.create(\"www.example.org/people\", \"Person\");"); + + DataFactory dataFactory = scope.getDataFactory(); + DataObject person1 = dataFactory.create("www.example.org/people", "Person"); + + commentary("The setString() of dataObject method is used to set the properties of the\n" + + "new Person DataObject, including a unique identifier reference value\n" + + "for the Person instance.\n\n" + + "person1.setString(\"id\", \"1\");\n" + + "person1.setString(\"name\", \"Joe Johnson Snr.\");\n" + + "person1.setString(\"gender\", \"male\"););"); + + person1.setString("id", "1"); + person1.setString("name", "Joe Johnson Snr."); + person1.setString("gender", "male"); + + commentary("An alternative approach to using the DataFactory directly to create\n" + + "all DataObjects is to use a top-down approach, where we create the\n" + + "root object for a data graph, and then use the createDataObject(String propertyName)\n" + + "method to create the contained DataObjects. Here we create the overall\n" + + "medical test DataObject, and then create the contained \"referrals\" DataObject\n\n" + + "DataObject test = dataFactory.create(\"www.example.org/MedicalTest\", \"Test\");\n" + + "DataObject referrals = test.createDataObject(\"referrals\");"); + + DataObject test = dataFactory.create("www.example.org/MedicalTest", "Test"); + DataObject referrals = test.createDataObject("referrals"); + + commentary("Now we can add the person we created earlier into the set of people who have\n" + + "been referred for this medical test.\n\n" + + "test.set(\"referrals\", referrals);\n" + + "referrals.getList(\"person\").add(person1);"); + + test.set("referrals", referrals); + referrals.getList("person").add(person1); + + commentary("Let's take a look at how the current state of the data" + + "graph is rendered in XML ..."); + + System.out.println(scope.getXMLHelper().save(test, + "www.example.org/MedicalTest", "test")); + + commentary("The scenario unfolds and the Joe Johnson Snr. becomes a patient\n\n" + + "DataObject patients = test.createDataObject(\"patients\");\n" + + "patients.getList(\"person\").add(person1);"); + + DataObject patients = test.createDataObject("patients"); + + patients.getList("person").add(person1); + + commentary("Having added Joe Johnson Snr. to the set of patients we can see\n" + + "the way that SDO preserves a single containment hierarchy within a\n" + + "datagraph. If we look at the XML rendering of the graph again, we will\n" + + "see that by adding him to the set of patients he has been removed from the\n" + + "containment property associated with the referrals set ..."); + + System.out.println(scope.getXMLHelper().save(test, + "www.example.org/MedicalTest", "test")); + + commentary("The 'Person' Type we are making use of here has been designed to be\n" + + "multi-purpose, in that the type has been declared to be 'Open'.\n" + + "That means that we can make use of 'Open Content' Properties\n" + + "(If the type system has been defined using an XML schema\n" + + "then these properties will derive from global elements)\n" + + "We can look up open content Properties using the TypeHelper\n\n" + + "Property conditionProperty = scope.getTypeHelper().getOpenContentProperty(\n" + + " \"www.example.org/MedicalTest\", \"condition\");"); + + Property conditionProperty = scope.getTypeHelper().getOpenContentProperty( + "www.example.org/MedicalTest", "condition"); + + commentary("We can create a value of the appropriate Type for this open\n" + + "content Property\n\n" + + "DataObject condition = dataFactory.create(conditionProperty.getType());\n" + + "condition.setString(\"name\", \"Panar Syndrome\");"); + + DataObject condition = dataFactory.create(conditionProperty.getType()); + condition.setString("name", "Panar Syndrome"); + + commentary("If you ask a DataObject that has an 'Open' Type for its list of\n" + + "values associated with an open content Property, and the DataObject\n" + + "doesn't currently have any values for the Property, it will return\n" + + "an empty list. We can use the list to add values for the Property\n\n" + + "List conditions = person1.getList(conditionProperty);\n" + + "conditions.add(condition);"); + + List conditions = person1.getList(conditionProperty); + conditions.add(condition); + + commentary("A further look at the data graph in XML form shows\n" + + "the presence of the new condition Property's value ..."); + + System.out.println(scope.getXMLHelper().save(test, + "www.example.org/MedicalTest", "test")); + + commentary("Having looked at the way SDO handles Open content\n" + + "We now turn our attention to 'non-containment' relationships.\n" + + "To do this we first create the set of people in the test that\n" + + "constitute the blood relatives of patients -- 'relatives'\n" + + "and define a new person to be Joe Johnson Snr's child.\n\n" + + "DataObject relatives = test.createDataObject(\"relatives\");\n" + + "DataObject person2 = relatives.createDataObject(\"person\");\n" + + "person2.setString(\"id\", \"2\");\n" + + "person2.setString(\"name\", \"Joe Johnson Jnr.\");\n" + + "person2.setString(\"gender\", \"male\");"); + + DataObject relatives = test.createDataObject("relatives"); + DataObject person2 = relatives.createDataObject("person"); + + person2.setString("id", "2"); + person2.setString("name", "Joe Johnson Jnr."); + person2.setString("gender", "male"); + + commentary("Another quick look at the XML rendering of the graph confirms that\n" + + "the set of relatives now includes Joe Johnson Jnr, but we haven't yet\n" + + "defined who he is related to, or how."); + + System.out.println(scope.getXMLHelper().save(test, + "www.example.org/MedicalTest", "test")); + + commentary("The Person type has a Property 'relative'\n" + + "so we create a relative for Joe Johnson Snr.\n\n" + + "DataObject relation = person1.createDataObject(\"relative\");\n" + + "relation.set(\"target\", person2);\n" + + "relation.set(\"relationship\", \"child\");"); + + DataObject relation = person1.createDataObject("relative"); + relation.set("target", person2); + relation.set("relationship", "child"); + + commentary("Now when we look at the XML rendering of the data graph\n" + + "we can see that the action of setting the 'target' of the\n" + + "relationship to Joe Johnson Jnr didn't displace him from the\n" + + "set of 'relatives', because the 'target' Property is a\n" + + "non-containment Property. This non-containment relationship\n" + + "is reflected in the XML by a reference to the Person DataObject\n" + + "describing Joe Johnson Jnr, \"2\" ...\n" + + "If the Type system has been created from an XML schema then the\n" + + "unique ID of the target can be used in the serialization.\n" + + "If however the type system was defined dynamically, then the reference\n" + + "will be represented as an XPath from the root of the data graph."); + + System.out.println(scope.getXMLHelper().save(test, + "www.example.org/MedicalTest", "test")); + + commentary("Now that the graph is complete we can use the PrintDataGraph sample utility\n" + + "to reveal the full SDO nature of the final data graph\n\n" + + ""); + + PrintDataGraph printer = new PrintDataGraph(COMMENTARY_FOR_ADVANCED); + printer.printDataObject(test); + System.out.println(printer.getBuf()); + } + + /** + * @throws Exception + * @throws FileNotFoundException + */ + private void createTypesViaAPI(HelperContext scope) throws Exception { + + List typeDeclarations = new ArrayList(); + + TypeHelper typeHelper = scope.getTypeHelper(); + + Type stringType = typeHelper.getType(sdoApiUri, "String"); + Type dateType = typeHelper.getType(sdoApiUri, "Date"); + Type booleanType = typeHelper.getType(sdoApiUri, "Boolean"); + + // + // + // + // + // + // + // + // + // + // + + DataObject personTypeDesc = createTypeDescription(scope, peopleURI, + "Person"); + typeDeclarations.add(personTypeDesc); + + addPropertyDescription(personTypeDesc, stringType, "name"); + addPropertyDescription(personTypeDesc, dateType, "dob"); + addPropertyDescription(personTypeDesc, stringType, "id"); // set to unique + // identifier? + addPropertyDescription(personTypeDesc, stringType, "gender"); // restrict? + + DataObject relativeType = createTypeDescription(scope, peopleURI, + "Relative"); // forward declare the Relative type + typeDeclarations.add(relativeType); + + DataObject rp = addPropertyDescription(personTypeDesc, relativeType, + "relative"); + rp.setBoolean("many", true); + personTypeDesc.set("open", Boolean.TRUE); + + // + // + // + // + // + + addPropertyDescription(relativeType, stringType, "relationship"); + addPropertyDescription(relativeType, booleanType, "genetic"); + DataObject targetPersonProp = addPropertyDescription(relativeType, + personTypeDesc, "target"); + targetPersonProp.setBoolean("containment", false); + + // + // + // + // + // + + DataObject pSet = createTypeDescription(scope, peopleURI, "PersonSet"); + typeDeclarations.add(pSet); + DataObject pSetProperty = addPropertyDescription(pSet, personTypeDesc, + "person"); + pSetProperty.setBoolean("many", true); + + // + // + // + // + // + // + + DataObject condition = createTypeDescription(scope, medicalURI, "Condition"); + typeDeclarations.add(condition); + addPropertyDescription(condition, booleanType, "diagnosed"); + addPropertyDescription(condition, stringType, "name"); // constrain? + + // + // + // + // + // + // + // + + DataObject testType = createTypeDescription(scope, medicalURI, "Test"); + typeDeclarations.add(testType); + addPropertyDescription(testType, pSet, "referrals"); + addPropertyDescription(testType, pSet, "patients"); + addPropertyDescription(testType, pSet, "relatives"); + + List types = typeHelper.define(typeDeclarations); + + DataObject p = scope.getDataFactory().create("commonj.sdo", "Property"); + p.set("type", typeHelper.getType(medicalURI, "Condition")); + p.set("name", "condition"); + p.setBoolean("many", true); + p.setBoolean("containment", true); // why is this not the default? + + typeHelper.defineOpenContentProperty(medicalURI, p); + + } + + /** + * @param uri + * @param name + * @return + */ + private DataObject createTypeDescription(HelperContext scope, String uri, + String name) { + DataObject typeDesc = scope.getDataFactory().create(sdoApiUri, "Type"); + typeDesc.set("name", name); + typeDesc.set("uri", uri); + return typeDesc; + } + + private DataObject addPropertyDescription( + DataObject containerTypeDescription, Object propertyType, + String propertyName) { + DataObject property = containerTypeDescription.createDataObject("property"); + property.set("type", propertyType); + property.setString("name", propertyName); + property.setBoolean("containment", true); + return property; + } + +} -- cgit v1.2.3