summaryrefslogtreecommitdiffstats
path: root/sdo-java/tags/1.0-incubator-M3/sdo/sample/src/main/java/org/apache/tuscany/samples/sdo/otherSources/PurchaseOrderControl.java
blob: d58a9307f4069ac30c685254ad9c9027cd39ea41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
/**
 *
 *  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

    }
}