1 /*
   2  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  *
   8  *   - Redistributions of source code must retain the above copyright
   9  *     notice, this list of conditions and the following disclaimer.
  10  *
  11  *   - Redistributions in binary form must reproduce the above copyright
  12  *     notice, this list of conditions and the following disclaimer in the
  13  *     documentation and/or other materials provided with the distribution.
  14  *
  15  *   - Neither the name of Oracle nor the names of its
  16  *     contributors may be used to endorse or promote products derived
  17  *     from this software without specific prior written permission.
  18  *
  19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30  */
  31 
  32 /*
  33  * This source code is provided to illustrate the usage of a given feature
  34  * or technique and has been deliberately simplified. Additional steps
  35  * required for a production-quality application, such as security checks,
  36  * input validation and proper error handling, might not be present in
  37  * this sample code.
  38  */
  39 package stream.data;
  40 
  41 import java.io.File;
  42 import java.util.ArrayList;
  43 import java.util.List;
  44 import javax.xml.bind.JAXBContext;
  45 import javax.xml.bind.JAXBException;
  46 import javax.xml.bind.Unmarshaller;
  47 import javax.xml.bind.annotation.XmlElement;
  48 import javax.xml.bind.annotation.XmlRootElement;
  49 
  50 /**
  51  * DataUtilities is a singleton helper class that creates test data. This class
  52  * uses jaxws API to read xml into java object, which includes 3 list of data 1.
  53  * Customers 2. Products 3. Vendors Note in this demo here we don't use stream
  54  * API to change data, if we use stream API to populate source data, we should
  55  * be aware this is not free and not thread-safe.
  56  */
  57 interface XMLList<E> {
  58 
  59     public List<E> getList();
  60 }
  61 
  62 /**
  63  * class for PRODUCTS_XML's root
  64  */
  65 @XmlRootElement(name = "products")
  66 class Products implements XMLList<Product> {
  67 
  68     /**
  69      * node products only contains product list
  70      */
  71     @XmlElement(name = "product")
  72     private ArrayList<Product> products;
  73 
  74     /**
  75      * product list
  76      */
  77     @Override
  78     public List<Product> getList() {
  79         return products;
  80     }
  81 }
  82 
  83 /**
  84  * class for VENDORS_XML's root
  85  */
  86 @XmlRootElement(name = "vendors")
  87 class Vendors implements XMLList<Vendor> {
  88 
  89     /**
  90      * node Vendors only contains vendor list
  91      */
  92 
  93     @Override
  94     public List<Vendor> getList() {
  95         return vendors;
  96     }
  97 
  98     /**
  99      * vendor list
 100      */
 101     @XmlElement(name = "vendor")
 102     private ArrayList<Vendor> vendors;
 103 }
 104 
 105 /**
 106  * class for CUSTOMERS_XML's root
 107  */
 108 @XmlRootElement(name = "customers")
 109 class Customers implements XMLList<Customer> {
 110 
 111     /**
 112      * node customers only contains customer list
 113      */
 114     @Override
 115     public List<Customer> getList() {
 116         return customers;
 117     }
 118 
 119     /**
 120      * customer list
 121      */
 122     @XmlElement(name = "customer")
 123     private ArrayList<Customer> customers;
 124 }
 125 
 126 public class DataUtilities {
 127 
 128     /**
 129      * xml file name for Customers object
 130      */
 131 
 132     private final static String CUSTOMERS_XML = "Customers.xml";
 133 
 134     /**
 135      * xml file name for Products object
 136      */
 137     private final static String PRODUCTS_XML = "Products.xml";
 138 
 139     /**
 140      * xml file name for Products object
 141      */
 142     private final static String VENDORS_XML = "Vendors.xml";
 143 
 144     /**
 145      * Lazy initiate static inner class for
 146      */
 147     private static class UtilitiesHolder {
 148 
 149         static DataUtilities instance = new DataUtilities();
 150     }
 151 
 152     /**
 153      * private constructor is needed for singleton
 154      */
 155     private DataUtilities() {
 156     }
 157 
 158     //products
 159     private List<Product> productList;
 160 
 161     //customer
 162     private List<Customer> customerList;
 163 
 164     //vendors
 165     private List<Vendor> vendorList;
 166 
 167     /**
 168      * Lazy initial to get product list
 169      *
 170      * @return initiated product list
 171      */
 172     public List<Product> getProductList() {
 173         if (productList == null) {
 174             createLists();
 175         }
 176         return productList;
 177     }
 178 
 179     /**
 180      * Lazy initial to get customer list
 181      *
 182      * @return initiated customer list
 183      */
 184     public List<Customer> getCustomerList() {
 185         if (customerList == null) {
 186             createLists();
 187         }
 188         return customerList;
 189     }
 190 
 191     /**
 192      * Lazy initial to get vendor list
 193      *
 194      * @return initiated vendor list
 195      */
 196     public List<Vendor> getVendorList() {
 197         if (vendorList == null) {
 198             createLists();
 199         }
 200         return vendorList;
 201     }
 202 
 203     /**
 204      * convert xml files to java objects
 205      */
 206     private void createLists() {
 207         customerList = xmlToObject(Customers.class, CUSTOMERS_XML);
 208         productList = xmlToObject(Products.class, PRODUCTS_XML);
 209         vendorList = xmlToObject(Vendors.class, VENDORS_XML);
 210     }
 211 
 212     /**
 213      * Convert a xml file to instance of class by given file name
 214      *
 215      * @param clazz to be converted java object's class
 216      * @param file xml file name
 217      * @return a list of object that xml's root contains
 218      */
 219     private <U, V extends XMLList<U>> List<U> xmlToObject(Class<V> clazz,
 220             String file) {
 221         try {
 222             JAXBContext context = JAXBContext.newInstance(clazz);
 223             Unmarshaller um = context.createUnmarshaller();
 224             @SuppressWarnings("unchecked")
 225             V cs = (V) um.unmarshal(new File(file));
 226             return cs.getList();
 227         } catch (JAXBException ex) {
 228             throw new RuntimeException(ex);
 229         }
 230     }
 231 
 232     /**
 233      * static factory method for singleton
 234      *
 235      * @return a DataUtitlities signgleton instance
 236      */
 237     public static DataUtilities getUtilities() {
 238         return UtilitiesHolder.instance;
 239     }
 240 }