001//@formatter:off
002/*
003 * Database - static placeholder for any kind of persistence in this example
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.transferobjectassembler;
021
022import java.text.ParseException;
023import java.text.SimpleDateFormat;
024import java.util.Date;
025import java.util.HashMap;
026import java.util.Map;
027
028/**
029 * Database - static placeholder for any kind of persistence in this example
030 * 
031 * @author <a href="mailto:Karl.Eilebrecht(a/t)calamanari.de">Karl Eilebrecht</a>
032 */
033public final class Database {
034
035    /**
036     * The "database table" for customers
037     */
038    static final Map<String, CustomerEntity> CUSTOMERS = new HashMap<>();
039
040    /**
041     * The "database table" for customer addresses
042     */
043    static final Map<String, AddressEntity> ADDRESSES = new HashMap<>();
044
045    /**
046     * The "database table" for dwh data
047     */
048    static final Map<String, CustomerDwhInfoEntity> CUSTOMER_DWH_INFOS = new HashMap<>();
049
050    /**
051     * Utility class
052     */
053    private Database() {
054        // no instances
055    }
056
057    /**
058     * @param customerId mandatory
059     * @return BUILDER instance with customerId set
060     */
061    public static Builder prepareCustomer(String customerId) {
062        return new Builder(customerId);
063    }
064
065    /**
066     * Builder to avoid huge constructor for setting up our "database"
067     */
068    public static class Builder {
069
070        private final CustomerEntity customerEntity;
071        private final AddressEntity addressEntity;
072        private final CustomerDwhInfoEntity.Builder customerBuilder;
073
074        /**
075         * initializes the builder (customer/address) for the given id
076         * @param customerId mandatory
077         */
078        Builder(String customerId) {
079            this.customerEntity = new CustomerEntity();
080            customerEntity.setCustomerId(customerId);
081            this.addressEntity = new AddressEntity();
082            addressEntity.setCustomerId(customerId);
083            this.customerBuilder = CustomerDwhInfoEntity.forCustomerId(customerId);
084        }
085
086        /**
087         * @param title customer property
088         * @return builder
089         */
090        public Builder withTitle(String title) {
091            customerEntity.setTitle(title);
092            return this;
093        }
094
095        /**
096         * @param lastName customer property
097         * @return builder
098         */
099        public Builder withLastName(String lastName) {
100            customerEntity.setLastName(lastName);
101            return this;
102        }
103
104        /**
105         * @param firstName customer property
106         * @return builder
107         */
108        public Builder withFirstName(String firstName) {
109            customerEntity.setFirstName(firstName);
110            return this;
111        }
112
113        /**
114         * @param phone customer property
115         * @return builder
116         */
117        public Builder withPhone(String phone) {
118            customerEntity.setPhone(phone);
119            return this;
120        }
121
122        /**
123         * @param email customer property
124         * @return builder
125         */
126        public Builder withEmail(String email) {
127            customerEntity.setEmail(email);
128            return this;
129        }
130
131        /**
132         * @param promotionOptIn customer property
133         * @return builder
134         */
135        public Builder withPromotionOptIn(boolean promotionOptIn) {
136            customerEntity.setPromotionOptIn(promotionOptIn);
137            return this;
138        }
139
140        /**
141         * @param addressId address property
142         * @return builder
143         */
144        public Builder withAddressId(String addressId) {
145            addressEntity.setAddressId(addressId);
146            return this;
147        }
148
149        /**
150         * @param street address property
151         * @return builder
152         */
153        public Builder withStreet(String street) {
154            addressEntity.setStreet(street);
155            return this;
156        }
157
158        /**
159         * @param zipCode address property
160         * @return builder
161         */
162        public Builder withZipCode(String zipCode) {
163            addressEntity.setZipCode(zipCode);
164            return this;
165        }
166
167        /**
168         * @param city address property
169         * @return builder
170         */
171        public Builder withCity(String city) {
172            addressEntity.setCity(city);
173            return this;
174        }
175
176        /**
177         * @param country address property
178         * @return builder
179         */
180        public Builder withCountry(String country) {
181            addressEntity.setCountry(country);
182            return this;
183        }
184
185        /**
186         * @param salutation address property
187         * @return builder
188         */
189        public Builder withSalutation(String salutation) {
190            addressEntity.setSalutation(salutation);
191            return this;
192        }
193
194        /**
195         * @param customerType customer identifier
196         * @return builder
197         */
198        public Builder withCustomerType(String customerType) {
199            customerBuilder.withCustomerType(customerType);
200            return this;
201        }
202
203        /**
204         * @param scorePoints customer property
205         * @return builder
206         */
207        public Builder withScorePoints(int scorePoints) {
208            customerBuilder.withScorePoints(scorePoints);
209            return this;
210        }
211
212        /**
213         * @param firstOrderDateISO as 'yyyy-MM-dd' or null
214         * @return builder
215         */
216        public Builder withFirstOrderDate(String firstOrderDateISO) {
217            Date firstOrderDate = parseOrderDate(firstOrderDateISO);
218            customerBuilder.withFirstOrderDate(firstOrderDate);
219            return this;
220        }
221
222        /**
223         * @param lastOrderDateISO as 'yyyy-MM-dd' or null
224         * @return builder
225         */
226        public Builder withLastOrderDate(String lastOrderDateISO) {
227            Date lastOrderDate = parseOrderDate(lastOrderDateISO);
228            customerBuilder.withLastOrderDate(lastOrderDate);
229            return this;
230        }
231
232        /**
233         * @param dueInvoice customer property
234         * @return builder
235         */
236        public Builder withDueInvoice(boolean dueInvoice) {
237            customerBuilder.withDueInvoice(dueInvoice);
238            return this;
239        }
240
241        /**
242         * @param fraudSuspicion customer property
243         * @return builder
244         */
245        public Builder withFraudSuspicion(boolean fraudSuspicion) {
246            customerBuilder.withFraudSuspicion(fraudSuspicion);
247            return this;
248        }
249
250        /**
251         * @param badPayer customer property
252         * @return builder
253         */
254        public Builder withBadPayer(boolean badPayer) {
255            customerBuilder.withBadPayer(badPayer);
256            return this;
257        }
258
259        /**
260         * Adds the customer with all information to the database
261         */
262        public void commit() {
263            CUSTOMERS.put(customerEntity.getCustomerId(), customerEntity);
264            ADDRESSES.put(customerEntity.getCustomerId(), addressEntity);
265            CUSTOMER_DWH_INFOS.put(customerEntity.getCustomerId(), customerBuilder.build());
266        }
267
268        /**
269         * Parses the order date from String to Date
270         * 
271         * @param orderDateISO 'yyyy-MM-dd' or null
272         * @return parsed date, can be null
273         * @throws RuntimeException if the date was in wrong format
274         */
275        private Date parseOrderDate(String orderDateISO) {
276            Date orderDate = null;
277            try {
278                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
279                orderDate = (orderDateISO == null ? null : sdf.parse(orderDateISO));
280            }
281            catch (ParseException ex) {
282                throw new DatabaseException("Error parsing orderDateISO=" + orderDateISO, ex);
283            }
284            return orderDate;
285        }
286
287    }
288}