無為

          無為則可為,無為則至深!

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks

          引言:什么是 SDO?

          Service Data Object (SDO) 2.0 是一個開放標準數據模型編程 API,允許開發人員在較高的級別方便地操作數據。盡管 SDO 1.0 以相同的數據抽象為目標,但有幾個大的缺點,其中主要的一點是缺少 Helper 類,如 XSDHelper, XMLHelper 等。而最終結果是,開發人員被迫使用 SDO 1.0 實現 API(來自 Eclipse Modeling Framework (EMF) SDK)。

          當前的實現 (SDO 2.0) 使用 EMF 2.2 SDK,但這個 SDO 2.0 實現細節并不會影響開發人員根據新 API 編寫程序。將來,開放源代碼社區(通過 Apache Software Foundation)可能會決定提供不同的 SDO 2.0 實現,但這不應影響基于 SDO 2.0 API 構建的應用程序。

          了解這個新 API 的優勢的最基本方法是使用 SDO 2.0 來創建符合 XML 模式 (XSD) 的 XML 文檔并對其進行讀取操作。要在不使用 SDO 2.0 的情況下完成相同的工作,開發人員需要理解 XML 解析器如何工作,并將數據解析邏輯與應用程序緊密集成。如果以后 XSD 需要更改,將需要對應用程序的各處進行調整,從而可能對代碼的質量帶來災難性的影響。

          SDO 2.0 API 的新用戶很難直接通過學習規范來理解相關概念。為了提供一定的幫助,我們從 XML Schema Primer(請參閱參考資料)創建了一個示例,以說明如何使用 SDO 2.0 API 進行以下任務:

          • 將 XML 文檔寫入到磁盤
          • 從磁盤讀取該文檔。

          場景:購買訂單信息收集和配送

          以下是我們將嘗試通過我們的示例實現的使用場景。首先,公司確定購買訂單(purchase order,PO)信息的要求。完成此任務后,我們就開始創建靜態表單,以設計信息的結構。在數據庫中,此靜態表單即表模式。在 XML,此靜態表單即 XML 模式 (XSD)。如果以后需要收集更多的客戶信息,我們將需要重新設計表單/表模式/XSD。

          下訂單時,客戶需要填寫 PO 表單,或向操作員提供相同的信息,以便填寫此表單。表單中的信息將隨后由公司用于對訂單進行配送。

          公司接收到 PO 信息后,很有可能會將其進行保存,并在以后對其進行讀取以用于各種目的(如提供客戶支持)。在此示例中,我們可以將信息以 XML 格式保存,然后使用 SDO API 進行讀取。

          圖 1 顯示了從客戶 Robert Smith 收集的 PO 信息示例。將創建 XSD 文件,以采用結構化的方式存儲此示例購買訂單。將用一個名為 CreatePurchaseOrder.java 的示例程序來采用 XML 格式創建示例 PO(名為 po.xml)。最后,將使用 ReadPurchaseOrder.java 來演示如何從 po.xml 讀取訂單信息。


          圖 1. 來自 Rober Smith 的示例購買訂單信息
          Order date: 1999-10-20

          Shipping information:
          Name:Alice Smith
          Street:123 Maple Street
          City:Mill Valley
          State:CA
          Zip code: 90952
          Country:US

          Billing information:
          Name:Robert Smith
          Street:8 Oak Avenue
          City:Mill Valley
          State:PA
          Zip code: 95819
          Country:US

          Order Items:
          1. Part number:872-AA
          Product name:Lawnmower
          Quantity: 1
          Price: 148.95
          Comment:Confirm this is electric

          2. Part number:926-AA
          Product name:Baby Monitor
          Quantity: 1
          Price: 39.98
          Ship date: 1999-05-21

          Comment: Hurry, my lawn is going wild!





          回頁首


          購買訂單的 XML 模式

          基于圖 1 所示的示例購買訂單,可以使用一個 PO 類型來表示訂單。我們將其命名為 PurchaseOrderTypePurchaseOrderType 的實例可以包含四個主要數據,如下所示:

          1. shipping information
          2. billing information
          3. order items information
          4. comment

          shipping information 和 billing information 可包含更多的數據,如 namestreetcitystatezipcountry。Order items information 可以包含客戶所購買的物品的很多信息。每個物品可能包含 part numberproduct namequantity, priceship datecomment。PO 的 comment 區域包含一個字符串值,并不要求采用更結構化的信息。

          清單 1 顯示了結構化為 XSD 格式的文件中包含的所有購買訂單信息。


          清單 1. PO.xsd
          <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
              xmlns:po="http://www.example.com/PO" targetNamespace="http://www.example.com/PO">
          
              <xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
              <xsd:element name="comment" type="xsd:string"/>
          
              <xsd:complexType name="PurchaseOrderType">
                  <xsd:sequence>
                      <xsd:element name="shipTo" type="USAddress"/>
                      <xsd:element name="billTo" type="USAddress"/>
                      <xsd:element ref="comment" minOccurs="0"/>
                      <xsd:element name="items"  type="Items"/>
                  </xsd:sequence>
                  <xsd:attribute name="orderDate" type="xsd:date"/>
              </xsd:complexType>
          
              <xsd:complexType name="USAddress">
                  <xsd:sequence>
                      <xsd:element name="name"   type="xsd:string"/>
                      <xsd:element name="street" type="xsd:string"/>
                      <xsd:element name="city"   type="xsd:string"/>
                      <xsd:element name="state"  type="xsd:string"/>
                      <xsd:element name="zip"    type="xsd:decimal"/>
                  </xsd:sequence>
                  <xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
              </xsd:complexType>
          
              <xsd:complexType name="Items">
                  <xsd:sequence>
                      <xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
                          <xsd:complexType>
                              <xsd:sequence>
                                  <xsd:element name="productName" type="xsd:string"/>
                                  <xsd:element name="quantity">
                                      <xsd:simpleType>
                                          <xsd:restriction base="xsd:positiveInteger">
                                              <xsd:maxExclusive value="100"/>
                                          </xsd:restriction>
                                      </xsd:simpleType>
                                  </xsd:element>
                                  <xsd:element name="USPrice"  type="xsd:decimal"/>
                                  <xsd:element ref="comment"   minOccurs="0"/>
                                  <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
                              </xsd:sequence>
                              <xsd:attribute name="partNum" type="po:SKU" use="required"/>
                          </xsd:complexType>
                      </xsd:element>
                  </xsd:sequence>
              </xsd:complexType>
              <xsd:simpleType name="SKU">
                  <xsd:restriction base="xsd:string">
                      <xsd:pattern value="\d{3}-[A-Z]{2}"/>
                  </xsd:restriction>
              </xsd:simpleType>
          
          

          還可以使用統一建模語言(Unified Modeling Language,UML)類關系圖來對購買訂單信息進行結構化,如圖 2 中所示。


          圖 2. 購買訂單的 UML 類關系圖
          購買訂單的 UML 類關系圖

          XSD po.xsd 文件和該 UML 類關系圖具有以下區別:

          1. 類關系圖定義了 ItemType,而并未在 po.xsd.diagram 中定義此項。盡管 po.xsd 并不具體定義 ItemType,XSD 規范仍可將 ItemType 作為匿名類型處理。
          2. XSD 中所有 xsd:<type> 在類關系圖中都縮寫為了 <type>。在 XSD 中,xsd:<type> 模式中的 xsd 用于指示類型所屬的命名空間。在類關系圖中,為了簡單起見而將其省略了。
          3. SKU type 未在類關系圖中定義。SKU type 事實上是在 po 命名空間中定義的規范化字符串類型。在類關系圖中,它由 string type 加以表示。




          回頁首


          創建 XML 格式的示例 PO

          清單 2 中所示的示例 CreatePurchaseOrder.java 程序用于創建一個 PO,該 PO 采用名為 po.xml 的 XML 格式(如清單 3 所示)。


          清單 2. CreatePurchaseOrder.java
          /**
           * Author:	Fuhwei Lwo
           */
          import java.io.FileOutputStream;
          import java.io.FileInputStream;
          import java.io.OutputStream;
          
          import commonj.sdo.DataObject;
          import commonj.sdo.helper.DataFactory;
          import commonj.sdo.helper.XMLHelper;
          import commonj.sdo.helper.XSDHelper;
          
          public class CreatePurchaseOrder {
            private static final String PO_MODEL = "po.xsd";
            private static final String PO_NAMESPACE = "http://www.example.com/PO";
            private static final String PO_XML = "po.xml";
          
          	private static void definePOTypes() throws Exception {
          	 FileInputStream fis = new FileInputStream(PO_MODEL);
          	 XSDHelper.INSTANCE.define(fis, null);
          	 fis.close();
          	}
          
          	public static void main(String[] args) throws Exception {
          	 definePOTypes();
                
          	 DataObject purchaseOrder = 
          	   DataFactory.INSTANCE.create(PO_NAMESPACE, "PurchaseOrderType");
          		
          	 purchaseOrder.setString("orderDate", "1999-10-20");
          		
          	 DataObject shipTo = purchaseOrder.createDataObject("shipTo");
          	 shipTo.set("country", "US");
          	 shipTo.set("name", "Alice Smith");
          	 shipTo.set("street", "123 Maple Street");
          	 shipTo.set("city", "Mill Valley");
          	 shipTo.set("state", "CA");
          	 shipTo.setString("zip", "90952");
          	 DataObject billTo = purchaseOrder.createDataObject("billTo");
          	 billTo.set("country", "US");
          	 billTo.set("name", "Robert Smith");
          	 billTo.set("street", "8 Oak Avenue");
          	 billTo.set("city", "Mill Valley");
          	 billTo.set("state", "PA");
          	 billTo.setString("zip", "95819");
          	 purchaseOrder.set("comment", "Hurry, my lawn is going wild!");
          		
          	 DataObject items = purchaseOrder.createDataObject("items");
          		
          	 DataObject item1 = items.createDataObject("item");
          	 item1.set("partNum", "872-AA");
          	 item1.set("productName", "Lawnmower");
          	 item1.setInt("quantity", 1);
          	 item1.setString("USPrice", "148.95");
          	 item1.set("comment", "Confirm this is electric");
          		
          	 DataObject item2 = items.createDataObject("item");
          	 item2.set("partNum", "926-AA");
          	 item2.set("productName", "Baby Monitor");
          	 iteim2.setInt("quantity", 1);
          	 item2.setString("USPrice", "39.98");
          	 item2.setString("shipDate", "1999-05-21");
          		
          	 OutputStream stream = new FileOutputStream(PO_XML);
          	 XMLHelper.INSTANCE.save(purchaseOrder, PO_NAMESPACE, "purchaseOrder", stream);
          	}
          }
          


          清單 3. Po.xml
          <?xml version="1.0" encoding="ASCII"?>
          <po:purchaseOrder xmlns:po="http://www.example.com/PO" orderDate="1999-10-20">
            <shipTo country="US">
              <name>Alice Smith</name>
              <street>123 Maple Street</street>
              <city>Mill Valley</city>
              <state>CA</state>
              <zip>90952</zip>
            </shipTo>
            <billTo country="US">
              <name>Robert Smith</name>
              <street>8 Oak Avenue</street>
              <city>Mill Valley</city>
              <state>PA</state>
              <zip>95819</zip>
            </billTo>
            <comment>Hurry, my lawn is going wild!</comment>
            <items>
              <item partNum="872-AA">
                <productName>Lawnmower</productName>
                <quantity>1</quantity>
                <USPrice>148.95</USPrice>
                <comment>Confirm this is electric</comment>
              </item>
              <item partNum="926-AA">
                <productName>Baby Monitor</productName>
                <quantity>1</quantity>
                <USPrice>39.98</USPrice>
                <shipDate>1999-05-21</shipDate>
              </item>
            </items>
          </po:purchaseOrder>
          

          該示例 Java 程序首先通過調用 XSDHelper.INSTANCE.define() 方法向 SDO 運行時注冊 po.xsd 中描述的所有類型。然后,它從 PurchaseOrderType 創建一個根 DataObject。該程序將從該處使用 DataObject API 來構建 DataObject 樹,以表示購買訂單信息,如圖 3 中所示。


          圖 3. DataObject 樹
          DataObject 樹

          在圖 3 中,每個矩形都劃分為兩個隔間。頂部間隔(灰色)指示 DataObject 實例名稱及其實際類型;底部間隔指示所包含的屬性。例如,樹的根元素為 purchaseOrder DataObject 實例;其實際類型為 PurchaseOrderType,在清單 1 中的 PO.xsd 中定義。在此 DataObject 實例中,包含兩個屬性值——orderDatecomment

          創建 DataObject 樹后,該程序調用 XMLHelper.INSTANCE.save() 方法來將從 purchaseOrder DataObject 實例開始的樹內容保存到 XML 文檔中(此例中為 po.xml)。事實上,可以將樹中任何 DataObject 實例指定為 XMLHelper.INSTANCE.save() 方法的第一個參數,save() 方法將保存從所指定的實例開始的所有 DataObject 實例。





          回頁首


          讀取示例 PO

          CreatePurchaseOrder.java 創建了 po.xml 后,我們可以編譯并運行清單 4 中所示的 ReadPurchaseOrder.java,以演示如何使用 SDO API 來遍歷 po.xml 的內容。該應用程序將執行以下操作:

          1. 進行檢查,以確保已向 SDO 運行時注冊了 po.xsd 中定義的類型
          2. 調用 XMLHelper.load() 方法來將 po.xml 加載到內存中(使用 XMLDocument 實例 xmlDoc 加以表示)
          3. 調用 xmlDoc.getRootObject() 方法來檢索名為 purchaseOrderDataObject 樹的根對象,該對象與圖 3 中所示的 DataObject 樹關系圖中的 purchaseOrder DataObject 對應
          4. purchaseOrder DataObject 返回后,遍歷 DataObject 樹,以檢索關于此 PO 的所有信息

          清單 4. ReadPurchaseOrder.java
          /**
          /**
           * Author:	Fuhwei Lwo
           */
          import java.io.FileInputStream;
          import java.util.List;
          
          import commonj.sdo.DataObject;
          import commonj.sdo.helper.XMLDocument;
          import commonj.sdo.helper.XMLHelper;
          import commonj.sdo.helper.XSDHelper;
          
          
          public class ReadPurchaseOrder {
           private static final String PO_MODEL = "po.xsd";
           private static final String PO_XML = "po.xml";
          
          	private static void definePOTypes() throws Exception {
          	  FileInputStream fis = new FileInputStream(PO_MODEL);
          	  XSDHelper.INSTANCE.define(fis, null);
          	  fis.close();
                  }
          
          	public static void main(String[] args) throws Exception {
           	  definePOTypes();
          
           	  FileInputStream fis = new FileInputStream(PO_XML);
          
           	  XMLDocument xmlDoc = XMLHelper.INSTANCE.load(fis);
          
           	  DataObject purchaseOrder = xmlDoc.getRootObject();
           	  
                     System.out.println("Order date: " + purchaseOrder.get("orderDate"));
                    System.out.println("Comment: " + purchaseOrder.get("comment"));
          
           	  DataObject shipTo = purchaseOrder.getDataObject("shipTo");
           	  System.out.println("Ship to name: " + shipTo.get("name"));
          
          	  DataObject billTo = purchaseOrder.getDataObject("billTo");
                     System.out.println("Bill to name: " + billTo.get("name"));
                    System.out.println();
          
                      DataObject items = purchaseOrder.getDataObject("items");
                      List itemList = items.getList("item");
                      for (int i=0; i<itemList.size(); i++) {
                  
          		       DataObject item = (DataObject)itemList.get(i);
          			
          		       System.out.println("Part num: " + item.get("partNum"));S
          		      System.out.println("Product name: " + item.get("productName"));
              } // for
            }
          }
          

          清單 4 中以黑體顯示的 System.out.println() 顯示各種數據對象的屬性值,包括:

          • purchaseOrder DataObjectorderDatecomment 屬性
          • shipTo DataObjectname 屬性
          • billTo DataObjectname 屬性
          • 各種數據對象的 partNumproductName 屬性

          圖 4. 運行 ReadPurchaseOrder 的控制臺輸出
          Order date: 1999-10-20

          Comment:Hurry, my lawn is going wild!
          Ship to name:Alice Smith
          Bill to name:Robert Smith

          Part num:872-AA
          Product name:Lawnmower

          Part num:926-AA
          Product name:Baby monitor

          在圖 4 中,我們可以看到運行 ReadPurchaseOrder Java 代碼的輸出。





          回頁首


          結束語:SDO 將成為事實上的數據模型編程 API

          SDO 2.0 API 提供了創建和訪問數據的一致方式,使開發人員不必了解分析和維護數據完整性的底層實現細節。SDO 2.0 目前是 Apache Software Foundation 下的一個試驗性子項目(稱為 Tuscany),預期將成為 SOA 開發的數據模型編程 API 的事實標準。請參閱參考資料部分,以獲得一個相關鏈接。

          可以從上面的示例中看出,SDO 2.0 API 使您完全不必知道和使用 XML 解析器 API 來讀取、寫入和操作數據。如果使用 Java 創建了 DataObject 來表示符合您所定義的 XML 模式的 XML 數據,SDO 2.0 將提供足夠的方便性和靈活性,讓您將精力放在如何使用數據上。因此,它可為您帶來極大的好處,從而提高開發工作效率和產品質量。

          總之,通過使用 SDO 2.0 提供的數據抽象技術,您可以根據所定義的業務邏輯來處理數據,以滿足您的業務需求。這可以幫助您簡化業務應用程序開發,也能提高團隊的工作效率和工作質量。





          回頁首


          參考資料

          學習

          討論




          回頁首


          關于作者

          Fuhwei Lwo 的照片

          Fuhwei Lwo 目前是 WebSphere Service Data Objects (SDO) 的團隊負責人。他主要的工作重點是推動在面向服務的體系結構(Service Oriented Architecture,SOA)中將 SDO 作為數據數據模型編程 API 成功采用。





          凡是有該標志的文章,都是該blog博主Caoer(草兒)原創,凡是索引、收藏
          、轉載請注明來處和原文作者。非常感謝。

          posted on 2007-01-12 09:42 草兒 閱讀(850) 評論(0)  編輯  收藏 所屬分類: javaWeb Data Mining
          主站蜘蛛池模板: 于都县| 商都县| 开平市| 栾川县| 桦甸市| 永济市| 张家界市| 玉环县| 镇雄县| 遂川县| 沈丘县| 自贡市| 彝良县| 龙门县| 会东县| 汕尾市| 九龙坡区| 西和县| 巴青县| 鹤山市| 虞城县| 永春县| 山阳县| 康定县| 凤台县| 弥勒县| 兴安县| 甘孜| 长葛市| 锡林浩特市| 峨山| 舞阳县| 象州县| 库车县| 兖州市| 富宁县| 崇信县| 宁晋县| 漠河县| 四平市| 论坛|