/** * * 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.otherSources; import java.io.*; import java.util.List; import java.math.BigDecimal; import commonj.sdo.DataObject; import commonj.sdo.ChangeSummary; import commonj.sdo.helper.XMLDocument; import commonj.sdo.helper.XMLHelper; import commonj.sdo.helper.XSDHelper; import commonj.sdo.helper.CopyHelper; import org.apache.tuscany.samples.sdo.SdoSampleConstants; import org.apache.tuscany.samples.sdo.specCodeSnippets.*; /** * Provides operational API for purchase order sample for SDO. It is used by * {@link PurchaseOrderCmdLine} for an interactive sample. Often relies upon * methods that are located within the {@link org.apache.tuscany.samples.sdo.otherSources} package. * @see org.apache.tuscany.samples.sdo.otherSources.PurchaseOrderCmdLine * */ public class PurchaseOrderControl { // there are a number of ways to set properties // these constants define which mechanism the user // would like to use. public static final int SET_DECIMAL_PROPERTY_VIA_SET = 1; public static final int SET_DECIMAL_PROPERTY_VIA_SET_STRING = 2; public static final int SET_DECIMAL_PROPERTY_VIA_SET_DOUBLE = 3; // local variable to determine which of the above mechanisms to use private int decimalPropertyMethod = SET_DECIMAL_PROPERTY_VIA_SET_STRING; // these files can be optionally used to specify where to locate xsd and xml // to define types and populate DataObject // if these are null will use the resources above private String xmlFileName; private String xsdFileName; // root DataObject private DataObject purchaseOrder; /** * Uses resources files included in jar file to define types (using xsd), and * populate DataObjects (xml) * * @throws Exception */ public PurchaseOrderControl() throws Exception { this(null, null); } /** * Uses files on the file system to define types (using xsd), and populate * DataObjects (xml) * * @param xsdFileName * location of po.xsd * @param xmlFileName * location of xml to populate DataObject (for example po.xml) * @throws Exception */ public PurchaseOrderControl(String xsdFileName, String xmlFileName) throws Exception { this.xsdFileName = xsdFileName; this.xmlFileName = xmlFileName; // define purchase order types for SDO definePurchaseOrderTypes(); // read in existing xml and populate DataObjects readPurchaseOrderXml(); } /** * Method to take XSD (w3c) to define SDO types. This is static so that it can be * used as a helper method for some simpler examples Uses either fileName used to * construct this class or will use resource ( po.xsd ) included within jar file */ private void definePurchaseOrderTypes() throws Exception { if ((xsdFileName == null) || (xsdFileName.equals("")) || (xsdFileName.equalsIgnoreCase("null"))) { // use simple example to define type from resource CreateDataObjectFromXsdAndXmlFiles.definePurchaseOrderTypeUsingXsdResource(); } else { System.out.println("Using file to access xsd in order to define types"); try { FileInputStream fis = new FileInputStream(xsdFileName); XSDHelper.INSTANCE.define(fis, null); fis.close(); System.out.println("Sucessfully used " + xsdFileName + " to define types"); } catch (Exception e) { System.out.println("Could not access file " + xsdFileName); e.printStackTrace(); throw e; } } } /** * Reads in xml and populates DataGraph. * * Will set the purchaseOrder to the root object Uses either fileName used to * construct this class or will use resource ( po.xml ) included within jar file */ public void readPurchaseOrderXml() throws Exception, FileNotFoundException { if ((xmlFileName == null) || (xmlFileName.equals("")) || (xmlFileName.equalsIgnoreCase("null"))) { purchaseOrder = CreateDataObjectFromXsdAndXmlFiles.createPurchaseOrderDataObjectUsingXmlResource(); } else { try { System.out.println("Using file to access xml to populate DataObjects"); FileInputStream fis = new FileInputStream(xmlFileName); XMLDocument xmlDoc = XMLHelper.INSTANCE.load(fis); purchaseOrder = xmlDoc.getRootObject(); System.out.println("Sucessfully used file to populate DataObjects"); fis.close(); } catch (Exception e) { System.out.println("Could not open and use file " + xmlFileName); e.printStackTrace(); throw e; } } } /** * Appends new comment to comment property of purchase order Accesses comment * property by name * * @param newComment */ public void appendComment(String newComment) { String oldComment = (String) purchaseOrder.get("comment"); setComment(oldComment + "-" + newComment); } /** * Sets comment property on purchase order by accessing property by name * * @param comment */ public void setComment(String comment) { // set using path info purchaseOrder.set("comment", comment); } /** * Modifies complex address type for billTo. If any parameter is null it will not * be modified * * @param name * @param street * @param city * @param state * @param zip */ public void modifyBillTo(String name, String street, String city, String state, String zip) { DataObject billTo = purchaseOrder.getDataObject("billTo"); modifyAddress(billTo, name, street, city, state, zip); } /** * Modifies complex address type for shipTo. If any parameter is null it will not * be modified * * @param name * @param street * @param city * @param state * @param zip */ public void modifyShipTo(String name, String street, String city, String state, String zip) { DataObject shipTo = purchaseOrder.getDataObject("shipTo"); modifyAddress(shipTo, name, street, city, state, zip); } /** * Modifies complex address type ( used for either billTo or shipTo ) If any * parameter is null it will not be modified * * @param name * @param street * @param city * @param state * @param zip */ private void modifyAddress(DataObject dataObject, String name, String street, String city, String state, String zip) { if ((name != null) && (!name.equals(""))) { dataObject.set("name", name); } if ((street != null) && (!street.equals(""))) { dataObject.set("street", street); } if ((city != null) && (!city.equals(""))) { dataObject.set("city", city); } if ((state != null) && (!state.equals(""))) { dataObject.set("state", state); } if ((zip != null) && (!zip.equals(""))) { // there are a number of ways to set a decimal property // so in order to demonstrate the various output results // the user can determine which manner to do so setDecimalPropertyOnDataObject(dataObject, "zip", zip); } } /** * Adds an additional item to the items list of the item property on purchase * order DataObject * * @param partNumber * @param productName * @param price * @param quantity * @param comment */ public void addItem(String partNumber, String productName, double price, int quantity, String comment) { // get items dataObject DataObject items = purchaseOrder.getDataObject("items"); // create a new child data object DataObject newItem = items.createDataObject("item"); newItem.setString("partNum", partNumber); newItem.setString("productName", productName); newItem.setInt("quantity", quantity); newItem.setDouble("price", price); newItem.setString("comment", comment); } /** * Removes a particular item from the items list. Obtains the List associated * with the item property and removes by index * * @param index */ public void removeItem(int index) { // TODO: this is not working due to java.lang.ClassCastException: // org.eclipse.emf.ecore.util.EcoreEList$Dynamic incompatible with // commonj.sdo.DataObject // access a DataObject by the index and then remove it DataObject items = purchaseOrder.getDataObject("items"); List itemList = items.getList("item"); itemList.remove(index); } /** * Saves modified purchase order DataObject to original xml used to populate it * If resource packaged within jar is used will create a new file on file system * * @throws IOException */ public void save() throws IOException { if (this.xmlFileName != null) { saveAs(xmlFileName); } else { System.out.println("Sorry, can not save to resource within jar, will create file called " + SdoSampleConstants.PO_XML_RESOURCE + " and save"); saveAs(SdoSampleConstants.PO_XML_RESOURCE); } } /** * Saves modified purchaseOrder DataObject to file * * @param fileName. * Location to save file to save DataObject to * @throws IOException */ public void saveAs(String fileName) throws IOException { OutputStream stream = new FileOutputStream(fileName); XMLHelper.INSTANCE.save(purchaseOrder, SdoSampleConstants.PO_NAMESPACE, "purchaseOrder", stream); System.out.println("Saved to " + fileName); } // PRINTING METHODS TO SYSTEM.OUT /** * Prints purchase order summary to System.out */ public void printChangeSummary() { // TODO: change summary is not currently working ChangeSummary changeSummary = getChangeSummary(); boolean logging = changeSummary.isLogging(); if (!logging) { System.out.println("Change logging is disabled"); } else { System.out.println("Change logging is enabled"); } // TODO: complete this method } /** * Uses simple sample PrintPropertiesOfDataObject */ public void printPurchaseOrderProperties() throws Exception { // use previously created method from simple sample PrintPropertiesOfDataObject.printDataObjectProperties(purchaseOrder); } /** * Accesses key properties via name and prints to System.out * */ public void printPurchaseOrderSummary() { // use previously created method from simple sample // for an example of accessing properties by name see // AccessDataObjectPropertiesByName or // the method below printAddressInfo AccessDataObjectPropertiesByName.printPurchaseOrderSummary(purchaseOrder); } /** * Accesses properties of USAddress Type by name and prints to System.out * * @param dataObject. * Either shipTo and billTo property of purchase order */ private void printAddressInfo(DataObject dataObject) { System.out.println(" name: " + dataObject.get("name")); System.out.println(" street: " + dataObject.get("street")); System.out.println(" city: " + dataObject.get("city")); System.out.println(" state: " + dataObject.get("state")); System.out.println(" zip: " + dataObject.get("zip")); } /** * Prints properties of shipTo * */ public void printBillTo() { DataObject billTo = purchaseOrder.getDataObject("billTo"); printAddressInfo(billTo); } /** * Prints properties of billTo * */ public void printShipTo() { DataObject shipTo = purchaseOrder.getDataObject("shipTo"); printAddressInfo(shipTo); } // GETTERS AND SETTERS /** * Sets the mechanism to set decimal property for zip code Decimals can be set in * a number of ways. This scenario controls how this class will set the zip code * when modifying address */ public void setDecimalPropertyMethod(int i) { decimalPropertyMethod = i; } /** * Gets the mechanism used to zip decimal property for the zip code of an address * * @return */ public int getDecimalPropertyMethod() { return decimalPropertyMethod; } // METHODS TO GET AND COPY DATAOBJECTS /** * @return purchaseOrder DataObject */ public DataObject getPurchaseOrder() { return purchaseOrder; } /** * * @return deep copy of the purchase order DataObject */ public DataObject getDeepCopyPurchaseOrder() { return CopyHelper.INSTANCE.copy(purchaseOrder); } /** * * @return shallow copy of the purchase order DataObject */ public DataObject getShallowCopyPurchaseOrder() { return CopyHelper.INSTANCE.copyShallow(purchaseOrder); } /** * Currently this does not work * * @return Change summary for purchaseOrder * */ public ChangeSummary getChangeSummary() { // TODO: why is the data graph null return purchaseOrder.getDataGraph().getChangeSummary(); } /** * * @return XMLDocument that represents current purchase order DataObject */ public XMLDocument getXMLDocuement() { return XMLHelper.INSTANCE.createDocument(purchaseOrder, SdoSampleConstants.PO_NAMESPACE, "purchaseOrder"); } /** * * @return String xml representation of current purcahse order DataObject */ public String getXMLString() { // alternativly could use the following // return XMLHelper.INSTANCE.createDocument(purchaseOrder, PO_NAMESPACE, // "purchaseOrder").toString(); return XMLHelper.INSTANCE.save(purchaseOrder, SdoSampleConstants.PO_NAMESPACE, "purchaseOrder"); } // PRIVATE HELPER METHODS /** * Uses a variety of ways to set a decimal property on a DataObject * * @param dataObject * @param propertyName * @param propertyValue */ private void setDecimalPropertyOnDataObject(DataObject dataObject, String propertyName, String propertyValue) { // since the type specified in the xsd is of type decimal when we // wish to just use the set method one must construct a BigDecimal or // else a ClassCastException will occur // alternativly one could call dataObject.setString(zip) or // dataObject.setDouble( Double.valueOf(zip)) switch (decimalPropertyMethod) { case (SET_DECIMAL_PROPERTY_VIA_SET): { dataObject.set(propertyName, new BigDecimal(propertyValue)); break; } case (SET_DECIMAL_PROPERTY_VIA_SET_DOUBLE): { dataObject.setDouble(propertyName, Double.valueOf(propertyValue).doubleValue()); break; } case (SET_DECIMAL_PROPERTY_VIA_SET_STRING): { dataObject.setString(propertyName, propertyValue); break; } default: { dataObject.setString(propertyName, propertyValue); } }// end of switch } }