001//@formatter:off
002/*
003 * Persistence Session - supplementary class for LAZY LOAD demonstration
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.lazyload;
021
022import java.util.ArrayList;
023import java.util.Collections;
024import java.util.HashMap;
025import java.util.List;
026import java.util.Map;
027
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030
031import de.calamanari.pk.util.TimeUtils;
032
033/**
034 * Persistence Session - supplementary class for LAZY LOAD demonstration<br>
035 * Placeholder for some kind of persistence management.
036 * 
037 * @author <a href="mailto:Karl.Eilebrecht(a/t)calamanari.de">Karl Eilebrecht</a>
038 */
039public class PersistenceSession {
040
041    private static final Logger LOGGER = LoggerFactory.getLogger(PersistenceSession.class);
042
043    /**
044     * our "database"
045     */
046    private static Map<String, String[]> database = new HashMap<>();
047
048    /**
049     * simulated time for accessing database
050     */
051    private static final long SIMULATED_DATABASE_DELAY_MILLIS = 100;
052
053    /**
054     * flag to indicate closed session
055     */
056    private boolean closed = false;
057
058    /**
059     * Method to fill-in test data
060     * 
061     * @param invoiceId identifier
062     * @param amountClaimed monetary value to be payed by the debtor
063     * @param debtorName name of the person who has to pay
064     * @param street address field
065     * @param zipCode address field
066     * @param city address field
067     */
068    public static void addInvoice(String invoiceId, String amountClaimed, String debtorName, String street, String zipCode, String city) {
069        database.put(invoiceId, new String[] { invoiceId, amountClaimed, debtorName, street, zipCode, city });
070    }
071
072    /**
073     * finds the invoice in the database by id
074     * 
075     * @param invoiceId identifier
076     * @return invoice or null if not found
077     */
078    public Invoice findInvoice(String invoiceId) {
079        LOGGER.debug("{}.findInvoice('{}') called", this.getClass().getSimpleName(), invoiceId);
080        ensureValidSession();
081        simulateDatabaseDelay();
082        Invoice res = null;
083        String[] invoiceData = database.get(invoiceId);
084        if (invoiceData != null) {
085            LOGGER.debug("Creating lazy-load invoice instance ...");
086            res = new Invoice(this, invoiceData[0], invoiceData[1]);
087        }
088        return res;
089    }
090
091    /**
092     * Returns a list of all invoices
093     * 
094     * @param lazy if true enable lazy load, otherwise load all
095     * @return list of invoice instances
096     */
097    public List<Invoice> findAllInvoices(boolean lazy) {
098        LOGGER.debug("{}.findAllInvoices({}) called ...", this.getClass().getSimpleName(), lazy);
099        ensureValidSession();
100        simulateDatabaseDelay();
101        List<Invoice> res = new ArrayList<>(database.size());
102        for (String[] invoiceData : database.values()) {
103            if (lazy) {
104                LOGGER.debug("Creating lazy-load invoice instance ...");
105                res.add(new Invoice(this, invoiceData[0], invoiceData[1]));
106            }
107            else {
108                LOGGER.debug("Creating complete invoice instance ...");
109                res.add(new Invoice(this, invoiceData[0], invoiceData[1], invoiceData[2], invoiceData[3], invoiceData[4], invoiceData[5]));
110            }
111        }
112        Collections.sort(res, Invoice.BY_ID_COMPARATOR);
113        return res;
114    }
115
116    /**
117     * Returns a list of all invoices, using lazy load
118     * 
119     * @return list of invoice instances
120     */
121    public List<Invoice> findAllInvoices() {
122        return findAllInvoices(true);
123    }
124
125    /**
126     * Loads the data for the lazy load fields from the database and sets the fields
127     * 
128     * @param invoice instance of the invoice to be loaded
129     */
130    public void loadLazyFields(Invoice invoice) {
131        LOGGER.debug("{}.loadLazyFields({}) called ...", this.getClass().getSimpleName(), invoice);
132        ensureValidSession();
133        simulateDatabaseDelay();
134        String[] invoiceData = database.get(invoice.getInvoiceId());
135        if (invoiceData != null) {
136            invoice.setLazyFields(invoiceData[2], invoiceData[3], invoiceData[4], invoiceData[5]);
137        }
138    }
139
140    /**
141     * Simulate delay for accessing the underlying database
142     */
143    private static void simulateDatabaseDelay() {
144        TimeUtils.sleepIgnoreException(SIMULATED_DATABASE_DELAY_MILLIS);
145    }
146
147    /**
148     * Checks whether the session is valid or not
149     */
150    private void ensureValidSession() {
151        LOGGER.debug("{}.ensureValidSession() called ...", this.getClass().getSimpleName());
152        if (closed) {
153            LOGGER.debug("Found closed session, cannot load, throwing exception");
154            throw new IllegalStateException("Session closed!");
155        }
156    }
157
158    /**
159     * closes the persistence session
160     */
161    public void close() {
162        LOGGER.debug("{}.close() called ...", this.getClass().getSimpleName());
163        this.closed = true;
164    }
165
166}