001//@formatter:off
002/*
003 * Customer Mapper - demonstrates MAPPER pattern
004 * Code-Beispiel zum Buch Patterns Kompakt, Verlag Springer Vieweg
005 * Copyright 2014 Karl Eilebrecht
006 * 
007 * Licensed under the Apache License, Version 2.0 (the "License"):
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019//@formatter:on
020package de.calamanari.pk.mapper;
021
022import java.util.Date;
023
024import org.slf4j.Logger;
025import org.slf4j.LoggerFactory;
026
027import de.calamanari.pk.mapper.firstsys.Address;
028import de.calamanari.pk.mapper.firstsys.Person;
029import de.calamanari.pk.mapper.secondsys.Customer;
030import de.calamanari.pk.util.TimeUtils;
031
032/**
033 * Customer Mapper - demonstrates MAPPER pattern<br>
034 * In the first subsystem there exists a Person entity and an address entity.<br>
035 * For some reason in a second subsystem a Customer entity exists including address information.<br>
036 * This mapper is responsible for transparently mapping data between the two without giving one subsystem any knowledge of the other one.<br>
037 * Neither of the subsystems is aware of the mapper.
038 * 
039 * @author <a href="mailto:Karl.Eilebrecht(a/t)calamanari.de">Karl Eilebrecht</a>
040 */
041public class CustomerMapper extends AbstractMapper {
042
043    private static final Logger LOGGER = LoggerFactory.getLogger(CustomerMapper.class);
044
045    /**
046     * customer reference
047     */
048    private final Customer customer;
049
050    /**
051     * address reference
052     */
053    private final Address address;
054
055    /**
056     * person reference
057     */
058    private final Person person;
059
060    /**
061     * Creates new customer mapper for the two entities from the first subsystem and the customer entity from the second subsystem
062     * 
063     * @param person the person to be mapped
064     * @param address the address to be mapped
065     * @param customer the customer to be mapped
066     */
067    public CustomerMapper(Person person, Address address, Customer customer) {
068        LOGGER.debug("{} created", this.getClass().getSimpleName());
069        this.person = person;
070        this.address = address;
071        this.customer = customer;
072    }
073
074    @Override
075    public void map() {
076        LOGGER.debug("{}.map() called", this.getClass().getSimpleName());
077
078        LOGGER.debug("Mapping data from subsystem1 (Person+Address) to subsystem2 structure (Customer[customerId='{}'])", customer.getCustomerId());
079        customer.setFirstName(person.getFirstName());
080        customer.setLastName(person.getLastName());
081
082        // a common task of a (data) mapper is to handle structural differences
083        int customerLifeTimeDays = 0;
084        Date firstOrderDate = person.getFirstOrderDate();
085        if (firstOrderDate != null) {
086            customerLifeTimeDays = TimeUtils.dayDiff(firstOrderDate, new Date(System.currentTimeMillis()));
087        }
088        customer.setCustomerLifeTimeDays(customerLifeTimeDays);
089
090        customer.setStreet(address.getStreet());
091        customer.setZipCode(address.getZipCode());
092        customer.setCity(address.getCity());
093    }
094
095    @Override
096    public void mapBack() {
097        LOGGER.debug("{}.mapBack() called", this.getClass().getSimpleName());
098
099        LOGGER.debug("Mapping data from subsystem2 (Customer[customerId='{}']) back to subsystem1 structures (Person+Address)", customer.getCustomerId());
100
101        // here a merge strategy could be placed as there might
102        // be scenarios allowing concurrent changes in both subsystems
103
104        person.setFirstName(customer.getFirstName());
105        person.setLastName(customer.getLastName());
106
107        // in some cases not all information can/should be mapped back
108        // here the customer lifetime cannot be changed
109
110        address.setStreet(customer.getStreet());
111        address.setZipCode(customer.getZipCode());
112        address.setCity(customer.getCity());
113
114    }
115
116}