001/*
002 * Copyright 2006-2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.batch.sample.domain.order.internal;
018
019import java.util.ArrayList;
020
021import org.apache.commons.logging.Log;
022import org.apache.commons.logging.LogFactory;
023import org.springframework.batch.item.ItemReader;
024import org.springframework.batch.item.file.mapping.FieldSetMapper;
025import org.springframework.batch.item.file.transform.FieldSet;
026import org.springframework.batch.sample.domain.order.Address;
027import org.springframework.batch.sample.domain.order.BillingInfo;
028import org.springframework.batch.sample.domain.order.Customer;
029import org.springframework.batch.sample.domain.order.LineItem;
030import org.springframework.batch.sample.domain.order.Order;
031import org.springframework.batch.sample.domain.order.ShippingInfo;
032
033/**
034 * @author peter.zozom
035 * 
036 */
037public class OrderItemReader implements ItemReader<Order> {
038        private static Log log = LogFactory.getLog(OrderItemReader.class);
039
040        private Order order;
041
042        private boolean recordFinished;
043
044        private FieldSetMapper<Order> headerMapper;
045
046        private FieldSetMapper<Customer> customerMapper;
047
048        private FieldSetMapper<Address> addressMapper;
049
050        private FieldSetMapper<BillingInfo> billingMapper;
051
052        private FieldSetMapper<LineItem> itemMapper;
053
054        private FieldSetMapper<ShippingInfo> shippingMapper;
055
056        private ItemReader<FieldSet> fieldSetReader;
057
058        /**
059         * @see org.springframework.batch.item.ItemReader#read()
060         */
061        @Override
062        public Order read() throws Exception {
063                recordFinished = false;
064
065                while (!recordFinished) {
066                        process(fieldSetReader.read());
067                }
068
069                log.info("Mapped: " + order);
070
071                Order result = order;
072                order = null;
073
074                return result;
075        }
076
077        private void process(FieldSet fieldSet) throws Exception {
078                // finish processing if we hit the end of file
079                if (fieldSet == null) {
080                        log.debug("FINISHED");
081                        recordFinished = true;
082                        order = null;
083                        return;
084                }
085
086                String lineId = fieldSet.readString(0);
087
088                if (Order.LINE_ID_HEADER.equals(lineId)) {
089                        log.debug("STARTING NEW RECORD");
090                        order = headerMapper.mapFieldSet(fieldSet);
091                }
092                else if (Order.LINE_ID_FOOTER.equals(lineId)) {
093                        log.debug("END OF RECORD");
094
095                        // Do mapping for footer here, because mapper does not allow to pass
096                        // an Order object as input.
097                        // Mapper always creates new object
098                        order.setTotalPrice(fieldSet.readBigDecimal("TOTAL_PRICE"));
099                        order.setTotalLines(fieldSet.readInt("TOTAL_LINE_ITEMS"));
100                        order.setTotalItems(fieldSet.readInt("TOTAL_ITEMS"));
101
102                        // mark we are finished with current Order
103                        recordFinished = true;
104                }
105                else if (Customer.LINE_ID_BUSINESS_CUST.equals(lineId)) {
106                        log.debug("MAPPING CUSTOMER");
107                        if (order.getCustomer() == null) {
108                                Customer customer = customerMapper.mapFieldSet(fieldSet);
109                                customer.setBusinessCustomer(true);
110                                order.setCustomer(customer);
111                        }
112                }
113                else if (Customer.LINE_ID_NON_BUSINESS_CUST.equals(lineId)) {
114                        log.debug("MAPPING CUSTOMER");
115                        if (order.getCustomer() == null) {
116                                Customer customer = customerMapper.mapFieldSet(fieldSet);
117                                customer.setBusinessCustomer(false);
118                                order.setCustomer(customer);
119                        }
120                }
121                else if (Address.LINE_ID_BILLING_ADDR.equals(lineId)) {
122                        log.debug("MAPPING BILLING ADDRESS");
123                        order.setBillingAddress(addressMapper.mapFieldSet(fieldSet));
124                }
125                else if (Address.LINE_ID_SHIPPING_ADDR.equals(lineId)) {
126                        log.debug("MAPPING SHIPPING ADDRESS");
127                        order.setShippingAddress(addressMapper.mapFieldSet(fieldSet));
128                }
129                else if (BillingInfo.LINE_ID_BILLING_INFO.equals(lineId)) {
130                        log.debug("MAPPING BILLING INFO");
131                        order.setBilling(billingMapper.mapFieldSet(fieldSet));
132                }
133                else if (ShippingInfo.LINE_ID_SHIPPING_INFO.equals(lineId)) {
134                        log.debug("MAPPING SHIPPING INFO");
135                        order.setShipping(shippingMapper.mapFieldSet(fieldSet));
136                }
137                else if (LineItem.LINE_ID_ITEM.equals(lineId)) {
138                        log.debug("MAPPING LINE ITEM");
139                        if (order.getLineItems() == null) {
140                                order.setLineItems(new ArrayList<LineItem>());
141                        }
142                        order.getLineItems().add(itemMapper.mapFieldSet(fieldSet));
143                }
144                else {
145                        log.debug("Could not map LINE_ID=" + lineId);
146                }
147        }
148
149        /**
150         * @param fieldSetReader reads lines from the file converting them to
151         *        {@link FieldSet}.
152         */
153        public void setFieldSetReader(ItemReader<FieldSet> fieldSetReader) {
154                this.fieldSetReader = fieldSetReader;
155        }
156
157        public void setAddressMapper(FieldSetMapper<Address> addressMapper) {
158                this.addressMapper = addressMapper;
159        }
160
161        public void setBillingMapper(FieldSetMapper<BillingInfo> billingMapper) {
162                this.billingMapper = billingMapper;
163        }
164
165        public void setCustomerMapper(FieldSetMapper<Customer> customerMapper) {
166                this.customerMapper = customerMapper;
167        }
168
169        public void setHeaderMapper(FieldSetMapper<Order> headerMapper) {
170                this.headerMapper = headerMapper;
171        }
172
173        public void setItemMapper(FieldSetMapper<LineItem> itemMapper) {
174                this.itemMapper = itemMapper;
175        }
176
177        public void setShippingMapper(FieldSetMapper<ShippingInfo> shippingMapper) {
178                this.shippingMapper = shippingMapper;
179        }
180
181}