From 24f258848c67500d347f9cce051f27aecda48f97 Mon Sep 17 00:00:00 2001 From: shaiktaj Date: Thu, 25 May 2017 11:04:30 -0500 Subject: [PATCH 01/45] Updated ThreadSafeLazyLoadedivoryTower Added null check in private constructor to prevent instantiating by Reflection call --- .../iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java index 0b1b51b23..68f190d46 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java @@ -33,7 +33,12 @@ public final class ThreadSafeLazyLoadedIvoryTower { private static ThreadSafeLazyLoadedIvoryTower instance; - private ThreadSafeLazyLoadedIvoryTower() {} + private ThreadSafeLazyLoadedIvoryTower() { + // to prevent instantiating by Reflection call + if (instance != null) { + throw new IllegalStateException("Already initialized."); + } + } /** * The instance gets created only when it is called for first time. Lazy-loading From 0271e55983a27fd73ebe00a7ab87dac3b00ed611 Mon Sep 17 00:00:00 2001 From: "mahendran.mookkiah" Date: Sat, 5 Aug 2017 10:07:28 -0400 Subject: [PATCH 02/45] #587 SonarQube reports bugs --- .../model/view/presenter/FileLoader.java | 18 +++++++++++++++--- .../view/presenter/FileSelectorPresenter.java | 9 ++++++++- .../model/view/presenter/FileSelectorView.java | 4 +++- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java index 01af677ae..f5606e638 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java @@ -25,6 +25,10 @@ package com.iluwatar.model.view.presenter; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; +import java.io.Serializable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Every instance of this class represents the Model component in the Model-View-Presenter @@ -32,7 +36,14 @@ import java.io.FileReader; *

* It is responsible for reading and loading the contents of a given file. */ -public class FileLoader { +public class FileLoader implements Serializable{ + + /** + * Generated serial version UID + */ + private static final long serialVersionUID = -4745803872902019069L; + + private static final Logger LOGGER = LoggerFactory.getLogger(FileLoader.class); /** * Indicates if the file is loaded or not. @@ -48,7 +59,8 @@ public class FileLoader { * Loads the data of the file specified. */ public String loadData() { - try (BufferedReader br = new BufferedReader(new FileReader(new File(this.fileName)))) { + String dataFileName = this.fileName; + try (BufferedReader br = new BufferedReader(new FileReader(new File(dataFileName)))) { StringBuilder sb = new StringBuilder(); String line; @@ -60,7 +72,7 @@ public class FileLoader { return sb.toString(); } catch (Exception e) { - e.printStackTrace(); + LOGGER.error("File {} does not exist", dataFileName); } return null; diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java index f2fefe8eb..560a8d274 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java @@ -22,13 +22,20 @@ */ package com.iluwatar.model.view.presenter; +import java.io.Serializable; + /** * Every instance of this class represents the Presenter component in the Model-View-Presenter * architectural pattern. *

* It is responsible for reacting to the user's actions and update the View component. */ -public class FileSelectorPresenter { +public class FileSelectorPresenter implements Serializable{ + + /** + * Generated serial version UID + */ + private static final long serialVersionUID = 1210314339075855074L; /** * The View component that the presenter interacts with. diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorView.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorView.java index cfafadbab..5272ea0b7 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorView.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorView.java @@ -22,11 +22,13 @@ */ package com.iluwatar.model.view.presenter; +import java.io.Serializable; + /** * This interface represents the View component in the Model-View-Presenter pattern. It can be * implemented by either the GUI components, or by the Stub. */ -public interface FileSelectorView { +public interface FileSelectorView extends Serializable{ /** * Opens the view. From 9f612ecfdac6c14e3580f477458f9c3f1c7498bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serdar=20Hamzao=C4=9Fullar=C4=B1?= Date: Sat, 5 Aug 2017 23:33:08 +0300 Subject: [PATCH 03/45] first commit --- event-sourcing/README.md | 21 ++++++++++++++++++ event-sourcing/etc/.gitkeep | 0 event-sourcing/pom.xml | 43 +++++++++++++++++++++++++++++++++++++ event-sourcing/src/.gitkeep | 0 4 files changed, 64 insertions(+) create mode 100644 event-sourcing/README.md create mode 100644 event-sourcing/etc/.gitkeep create mode 100644 event-sourcing/pom.xml create mode 100644 event-sourcing/src/.gitkeep diff --git a/event-sourcing/README.md b/event-sourcing/README.md new file mode 100644 index 000000000..c513d2da9 --- /dev/null +++ b/event-sourcing/README.md @@ -0,0 +1,21 @@ +--- +layout: pattern +title: Event Sourcing +folder: event-sourcing +permalink: /patterns/event-sourcing/ +categories: Concurrency +tags: + - Java + - Difficulty Intermediate + - Performance +--- + +## Intent + +## Applicability +Use the Event Sourcing pattern when + +* You have a limited accesibility resource and the asynchronous process is acceptable to reach that + +## Credits + diff --git a/event-sourcing/etc/.gitkeep b/event-sourcing/etc/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/event-sourcing/pom.xml b/event-sourcing/pom.xml new file mode 100644 index 000000000..6dc90063e --- /dev/null +++ b/event-sourcing/pom.xml @@ -0,0 +1,43 @@ + + + + 4.0.0 + + java-design-patterns + com.iluwatar + 1.17.0-SNAPSHOT + + event-sourcing + + + junit + junit + test + + + \ No newline at end of file diff --git a/event-sourcing/src/.gitkeep b/event-sourcing/src/.gitkeep new file mode 100644 index 000000000..e69de29bb From 1474a50e5e612af12372979af2c62f1da5db9bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serdar=20Hamzao=C4=9Fullar=C4=B1?= Date: Sun, 6 Aug 2017 22:51:43 +0300 Subject: [PATCH 04/45] Example done with app class --- event-sourcing/pom.xml | 7 ++ .../event/sourcing/api/DomainEvent.java | 41 ++++++++ .../event/sourcing/api/EventProcessor.java | 11 +++ .../sourcing/api/ExternalEventListener.java | 8 ++ .../event/sourcing/api/ProcessorJournal.java | 10 ++ .../com/iluwatar/event/sourcing/app/App.java | 58 +++++++++++ .../event/sourcing/domain/Account.java | 63 ++++++++++++ .../event/sourcing/domain/Transaction.java | 46 +++++++++ .../sourcing/event/AccountCreateEvent.java | 43 ++++++++ .../sourcing/event/MoneyDepositEvent.java | 38 +++++++ .../sourcing/event/MoneyTransferEvent.java | 56 +++++++++++ .../sourcing/event/MoneyWithdrawalEvent.java | 38 +++++++ .../gateway/AccountCreateContractSender.java | 12 +++ .../event/sourcing/gateway/Gateways.java | 17 ++++ .../sourcing/gateway/TransactionLogger.java | 12 +++ .../sourcing/journal/JsonFileJournal.java | 99 +++++++++++++++++++ .../processor/DomainEventProcessor.java | 48 +++++++++ .../sourcing/service/AccountService.java | 22 +++++ .../service/MoneyTransactionService.java | 35 +++++++ .../sourcing/service/SequenceIdGenerator.java | 14 +++ .../sourcing/state/AccountAggregate.java | 29 ++++++ pom.xml | 1 + 22 files changed, 708 insertions(+) create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ExternalEventListener.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java create mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java diff --git a/event-sourcing/pom.xml b/event-sourcing/pom.xml index 6dc90063e..35d462cb1 100644 --- a/event-sourcing/pom.xml +++ b/event-sourcing/pom.xml @@ -39,5 +39,12 @@ junit test + + + com.google.code.gson + gson + 2.8.1 + + \ No newline at end of file diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java new file mode 100644 index 000000000..d77654869 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java @@ -0,0 +1,41 @@ +package com.iluwatar.event.sourcing.api; + +import java.io.Serializable; + +/** + * Created by serdarh on 06.08.2017. + */ +public abstract class DomainEvent implements Serializable { + private final long sequenceId; + private final long createdTime; + private boolean replica = false; + private final String eventClassName; + + public DomainEvent(long sequenceId, long createdTime, String eventClassName) { + this.sequenceId = sequenceId; + this.createdTime = createdTime; + this.eventClassName = eventClassName; + } + + public long getSequenceId() { + return sequenceId; + } + + public long getCreatedTime() { + return createdTime; + } + + public boolean isReplica() { + return replica; + } + + public void setReplica(boolean replica) { + this.replica = replica; + } + + public abstract void process(); + + public String getEventClassName() { + return eventClassName; + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java new file mode 100644 index 000000000..729efc83c --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java @@ -0,0 +1,11 @@ +package com.iluwatar.event.sourcing.api; + +/** + * Created by serdarh on 06.08.2017. + */ +public interface EventProcessor { + void process(DomainEvent domainEvent); + void setPrecessorJournal(ProcessorJournal precessorJournal); + void addExternalEventListener(ExternalEventListener externalEventListener); + void recover(); +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ExternalEventListener.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ExternalEventListener.java new file mode 100644 index 000000000..a1cb78108 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ExternalEventListener.java @@ -0,0 +1,8 @@ +package com.iluwatar.event.sourcing.api; + +/** + * Created by serdarh on 06.08.2017. + */ +public interface ExternalEventListener { + void notify(DomainEvent domainEvent); +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java new file mode 100644 index 000000000..906c66247 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java @@ -0,0 +1,10 @@ +package com.iluwatar.event.sourcing.api; + +/** + * Created by serdarh on 06.08.2017. + */ +public interface ProcessorJournal { + void write(DomainEvent domainEvent); + void reset(); + DomainEvent readNext(); +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java new file mode 100644 index 000000000..8627736f1 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java @@ -0,0 +1,58 @@ +package com.iluwatar.event.sourcing.app; + +import com.iluwatar.event.sourcing.journal.JsonFileJournal; +import com.iluwatar.event.sourcing.processor.DomainEventProcessor; +import com.iluwatar.event.sourcing.service.AccountService; +import com.iluwatar.event.sourcing.service.MoneyTransactionService; +import com.iluwatar.event.sourcing.state.AccountAggregate; + +import java.math.BigDecimal; + +/** + * Created by serdarh on 06.08.2017. + */ +public class App { + + public static void main(String[] args) { + System.out.println("Running the system first time............"); + + DomainEventProcessor domainEventProcessor = new DomainEventProcessor(); + JsonFileJournal jsonFileJournal = new JsonFileJournal(); + jsonFileJournal.reset(); + domainEventProcessor.setPrecessorJournal(jsonFileJournal); + + System.out.println("Creating th accounts............"); + + AccountService accountService = new AccountService(domainEventProcessor); + MoneyTransactionService moneyTransactionService = new MoneyTransactionService(domainEventProcessor); + accountService.createAccount(1,"Daenerys Targaryen"); + accountService.createAccount(2,"Jon Snow"); + + System.out.println("Do some money operations............"); + + moneyTransactionService.depositMoney(1,new BigDecimal("100000")); + moneyTransactionService.depositMoney(2,new BigDecimal("10")); + + moneyTransactionService.transferMoney(1,2,new BigDecimal("10000")); + moneyTransactionService.withdrawalMoney(2, new BigDecimal("1000")); + + System.out.println("...............State:............"); + System.out.println(AccountAggregate.getAccount(1)); + System.out.println(AccountAggregate.getAccount(2)); + + System.out.println("At that point system goes down state in memory cleared............"); + + AccountAggregate.resetState(); + + System.out.println("Recover the syste by the events in journal file............"); + + domainEventProcessor = new DomainEventProcessor(); + jsonFileJournal = new JsonFileJournal(); + domainEventProcessor.setPrecessorJournal(jsonFileJournal); + domainEventProcessor.recover(); + + System.out.println("...............State Recovered:............"); + System.out.println(AccountAggregate.getAccount(1)); + System.out.println(AccountAggregate.getAccount(2)); + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java new file mode 100644 index 000000000..5a7a77fcf --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java @@ -0,0 +1,63 @@ +package com.iluwatar.event.sourcing.domain; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by serdarh on 06.08.2017. + */ +public class Account { + private final int accountNo; + private final String owner; + private BigDecimal money; + private List transactions; + + public Account(int accountNo, String owner) { + this.accountNo = accountNo; + this.owner = owner; + money = BigDecimal.ZERO; + transactions = new ArrayList<>(); + } + + public int getAccountNo() { + return accountNo; + } + + public String getOwner() { + return owner; + } + + public BigDecimal getMoney() { + return money; + } + + public List getTransactions() { + return transactions; + } + + public void setMoney(BigDecimal money) { + this.money = money; + } + + public void setTransactions(List transactions) { + this.transactions = transactions; + } + + public Account copy() { + Account account = new Account(accountNo, owner); + account.setMoney(money); + account.setTransactions(transactions); + return account; + } + + @Override + public String toString() { + return "Account{" + + "accountNo=" + accountNo + + ", owner='" + owner + '\'' + + ", money=" + money + + ", transactions=" + transactions + + '}'; + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java new file mode 100644 index 000000000..557efbedc --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java @@ -0,0 +1,46 @@ +package com.iluwatar.event.sourcing.domain; + +import java.math.BigDecimal; + +/** + * Created by serdarh on 06.08.2017. + */ +public class Transaction { + private final int accountNo; + private final BigDecimal moneyIn; + private final BigDecimal moneyOut; + private final BigDecimal lastBalance; + + public Transaction(int accountNo, BigDecimal moneyIn, BigDecimal moneyOut, BigDecimal lastBalance) { + this.accountNo = accountNo; + this.moneyIn = moneyIn; + this.moneyOut = moneyOut; + this.lastBalance = lastBalance; + } + + public int getAccountNo() { + return accountNo; + } + + public BigDecimal getMoneyIn() { + return moneyIn; + } + + public BigDecimal getMoneyOut() { + return moneyOut; + } + + public BigDecimal getLastBalance() { + return lastBalance; + } + + @Override + public String toString() { + return "Transaction{" + + "accountNo=" + accountNo + + ", moneyIn=" + moneyIn + + ", moneyOut=" + moneyOut + + ", lastBalance=" + lastBalance + + '}'; + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java new file mode 100644 index 000000000..3957a4fe7 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java @@ -0,0 +1,43 @@ +package com.iluwatar.event.sourcing.event; + +import com.iluwatar.event.sourcing.api.DomainEvent; +import com.iluwatar.event.sourcing.domain.Account; +import com.iluwatar.event.sourcing.gateway.Gateways; +import com.iluwatar.event.sourcing.state.AccountAggregate; + +/** + * Created by serdarh on 06.08.2017. + */ +public class AccountCreateEvent extends DomainEvent { + private final int accountNo; + private final String owner; + + public AccountCreateEvent(long sequenceId, long createdTime, int accountNo, String owner) { + super(sequenceId, createdTime, "AccountCreateEvent"); + this.accountNo = accountNo; + this.owner = owner; + } + + public int getAccountNo() { + return accountNo; + } + + public String getOwner() { + return owner; + } + + @Override + public void process() { + Account account = AccountAggregate.getAccount(accountNo); + if(account!=null){ + throw new RuntimeException("Account already exists"); + } + account = new Account(accountNo,owner); + AccountAggregate.putAccount(account); + + // check if this event is replicated from journal before calling an external gateway function + if(!isReplica()) { + Gateways.getAccountCreateContractSender().sendContractInfo(account); + } + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java new file mode 100644 index 000000000..ffa9d0763 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java @@ -0,0 +1,38 @@ +package com.iluwatar.event.sourcing.event; + +import com.iluwatar.event.sourcing.api.DomainEvent; +import com.iluwatar.event.sourcing.domain.Account; +import com.iluwatar.event.sourcing.domain.Transaction; +import com.iluwatar.event.sourcing.gateway.Gateways; +import com.iluwatar.event.sourcing.state.AccountAggregate; + +import java.math.BigDecimal; + +/** + * Created by serdarh on 06.08.2017. + */ +public class MoneyDepositEvent extends DomainEvent { + private BigDecimal money; + private int accountNo; + + public MoneyDepositEvent(long sequenceId, long createdTime, int accountNo,BigDecimal money) { + super(sequenceId, createdTime, "MoneyDepositEvent"); + this.money = money; + this.accountNo = accountNo; + } + + @Override + public void process() { + Account account = AccountAggregate.getAccount(accountNo); + if(account==null){ + throw new RuntimeException("Account not found"); + } + account.setMoney(account.getMoney().add(money)); + Transaction transaction = new Transaction(accountNo,money,BigDecimal.ZERO,account.getMoney()); + account.getTransactions().add(transaction); + AccountAggregate.putAccount(account); + if(!isReplica()) { + Gateways.getTransactionLogger().log(transaction); + } + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java new file mode 100644 index 000000000..4e0fb9829 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java @@ -0,0 +1,56 @@ +package com.iluwatar.event.sourcing.event; + +import com.iluwatar.event.sourcing.api.DomainEvent; +import com.iluwatar.event.sourcing.domain.Account; +import com.iluwatar.event.sourcing.domain.Transaction; +import com.iluwatar.event.sourcing.gateway.Gateways; +import com.iluwatar.event.sourcing.state.AccountAggregate; + +import java.math.BigDecimal; + +/** + * Created by serdarh on 06.08.2017. + */ +public class MoneyTransferEvent extends DomainEvent { + private BigDecimal money; + private int accountNoFrom; + private int accountNoTo; + + public MoneyTransferEvent(long sequenceId, long createdTime, BigDecimal money, int accountNoFrom, int accountNoTo) { + super(sequenceId, createdTime, "MoneyTransferEvent"); + this.money = money; + this.accountNoFrom = accountNoFrom; + this.accountNoTo = accountNoTo; + } + + @Override + public void process() { + Account accountFrom = AccountAggregate.getAccount(accountNoFrom); + if(accountFrom==null){ + throw new RuntimeException("Account not found "+accountNoFrom); + } + Account accountTo = AccountAggregate.getAccount(accountNoTo); + if(accountTo==null){ + throw new RuntimeException("Account not found"+ accountTo); + } + if(accountFrom.getMoney().compareTo(money)==-1){ + throw new RuntimeException("Insufficient Account Balance"); + } + accountFrom.setMoney(accountFrom.getMoney().subtract(money)); + accountTo.setMoney(accountTo.getMoney().add(money)); + + Transaction transactionFrom = new Transaction(accountNoFrom,BigDecimal.ZERO,money,accountFrom.getMoney()); + accountFrom.getTransactions().add(transactionFrom); + + Transaction transactionTo = new Transaction(accountNoTo,money,BigDecimal.ZERO,accountTo.getMoney()); + accountTo.getTransactions().add(transactionTo); + + AccountAggregate.putAccount(accountFrom); + AccountAggregate.putAccount(accountTo); + + if(!isReplica()) { + Gateways.getTransactionLogger().log(transactionFrom); + Gateways.getTransactionLogger().log(transactionTo); + } + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java new file mode 100644 index 000000000..27a63d13d --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java @@ -0,0 +1,38 @@ +package com.iluwatar.event.sourcing.event; + +import com.iluwatar.event.sourcing.api.DomainEvent; +import com.iluwatar.event.sourcing.domain.Account; +import com.iluwatar.event.sourcing.domain.Transaction; +import com.iluwatar.event.sourcing.gateway.Gateways; +import com.iluwatar.event.sourcing.state.AccountAggregate; + +import java.math.BigDecimal; + +/** + * Created by serdarh on 06.08.2017. + */ +public class MoneyWithdrawalEvent extends DomainEvent { + private BigDecimal money; + private int accountNo; + + public MoneyWithdrawalEvent(long sequenceId, long createdTime, int accountNo,BigDecimal money) { + super(sequenceId, createdTime, "MoneyWithdrawalEvent"); + this.money = money; + this.accountNo = accountNo; + } + + @Override + public void process() { + Account account = AccountAggregate.getAccount(accountNo); + if(account==null){ + throw new RuntimeException("Account not found"); + } + account.setMoney(account.getMoney().subtract(money)); + Transaction transaction = new Transaction(accountNo,BigDecimal.ZERO,money,account.getMoney()); + account.getTransactions().add(transaction); + AccountAggregate.putAccount(account); + if(!isReplica()) { + Gateways.getTransactionLogger().log(transaction); + } + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java new file mode 100644 index 000000000..42dfccf7b --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java @@ -0,0 +1,12 @@ +package com.iluwatar.event.sourcing.gateway; + +import com.iluwatar.event.sourcing.domain.Account; + +/** + * Created by serdarh on 06.08.2017. + */ +public class AccountCreateContractSender { + public void sendContractInfo(Account account){ + // an example imaginary funciton which sends account info to some external end point + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java new file mode 100644 index 000000000..d167393bf --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java @@ -0,0 +1,17 @@ +package com.iluwatar.event.sourcing.gateway; + +/** + * Created by serdarh on 06.08.2017. + */ +public class Gateways { + private static AccountCreateContractSender accountCreateContractSender = new AccountCreateContractSender(); + private static TransactionLogger transactionLogger = new TransactionLogger(); + + public static AccountCreateContractSender getAccountCreateContractSender() { + return accountCreateContractSender; + } + + public static TransactionLogger getTransactionLogger() { + return transactionLogger; + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java new file mode 100644 index 000000000..6d961d96e --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java @@ -0,0 +1,12 @@ +package com.iluwatar.event.sourcing.gateway; + +import com.iluwatar.event.sourcing.domain.Transaction; + +/** + * Created by serdarh on 06.08.2017. + */ +public class TransactionLogger { + public void log(Transaction transaction) { + // example imaginary function that logs the transaction to somewhere + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java new file mode 100644 index 000000000..45a982c19 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java @@ -0,0 +1,99 @@ +package com.iluwatar.event.sourcing.journal; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.iluwatar.event.sourcing.api.DomainEvent; +import com.iluwatar.event.sourcing.api.ProcessorJournal; +import com.iluwatar.event.sourcing.event.AccountCreateEvent; +import com.iluwatar.event.sourcing.event.MoneyDepositEvent; +import com.iluwatar.event.sourcing.event.MoneyTransferEvent; +import com.iluwatar.event.sourcing.event.MoneyWithdrawalEvent; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by serdarh on 06.08.2017. + */ +public class JsonFileJournal implements ProcessorJournal{ + + private File aFile; + private List events = new ArrayList<>(); + private int index = 0; + public JsonFileJournal() { + aFile = new File("Journal.json"); + if(aFile.exists()) { + try (BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(aFile), "UTF-8"))) { + String line; + while ((line = input.readLine()) != null) { + events.add(line); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + }else{ + reset(); + } + } + + @Override + public void write(DomainEvent domainEvent) { + Gson gson = new Gson(); + JsonElement jsonElement; + if(domainEvent instanceof AccountCreateEvent) { + jsonElement = gson.toJsonTree(domainEvent, AccountCreateEvent.class); + }else if(domainEvent instanceof MoneyDepositEvent) { + jsonElement = gson.toJsonTree(domainEvent, MoneyDepositEvent.class); + }else if(domainEvent instanceof MoneyWithdrawalEvent) { + jsonElement = gson.toJsonTree(domainEvent, MoneyWithdrawalEvent.class); + }else if(domainEvent instanceof MoneyTransferEvent) { + jsonElement = gson.toJsonTree(domainEvent, MoneyTransferEvent.class); + }else{ + throw new RuntimeException("Journal Event not recegnized"); + } + + try (Writer output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(aFile, true), "UTF-8"))) { + String eventString = jsonElement.toString(); + output.write(eventString +"\r\n"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void reset() { + aFile.delete(); + } + + + @Override + public DomainEvent readNext() { + if(index>=events.size()){ + return null; + } + String event = events.get(index); + index++; + + JsonParser parser = new JsonParser(); + JsonElement jsonElement = parser.parse(event); + String eventClassName = jsonElement.getAsJsonObject().get("eventClassName").getAsString(); + Gson gson = new Gson(); + DomainEvent domainEvent; + if(eventClassName.equals("AccountCreateEvent")) { + domainEvent = gson.fromJson(jsonElement, AccountCreateEvent.class); + }else if(eventClassName.equals("MoneyDepositEvent")) { + domainEvent = gson.fromJson(jsonElement, MoneyDepositEvent.class); + }else if(eventClassName.equals("MoneyTransferEvent")) { + domainEvent = gson.fromJson(jsonElement, MoneyTransferEvent.class); + }else if(eventClassName.equals("MoneyWithdrawalEvent")) { + domainEvent = gson.fromJson(jsonElement, MoneyWithdrawalEvent.class); + }else{ + throw new RuntimeException("Journal Event not recegnized"); + } + + domainEvent.setReplica(true); + return domainEvent; + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java new file mode 100644 index 000000000..a23c41905 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java @@ -0,0 +1,48 @@ +package com.iluwatar.event.sourcing.processor; + +import com.iluwatar.event.sourcing.api.DomainEvent; +import com.iluwatar.event.sourcing.api.EventProcessor; +import com.iluwatar.event.sourcing.api.ExternalEventListener; +import com.iluwatar.event.sourcing.api.ProcessorJournal; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by serdarh on 06.08.2017. + */ +public class DomainEventProcessor implements EventProcessor { + + private ProcessorJournal precessorJournal; + private List externalEventListeners = new ArrayList<>(); + + @Override + public void process(DomainEvent domainEvent) { + externalEventListeners.forEach(externalEventListener -> externalEventListener.notify(domainEvent)); + domainEvent.process(); + precessorJournal.write(domainEvent); + } + + @Override + public void setPrecessorJournal(ProcessorJournal precessorJournal) { + this.precessorJournal = precessorJournal; + } + + @Override + public void addExternalEventListener(ExternalEventListener externalEventListener) { + externalEventListeners.add(externalEventListener); + } + + @Override + public void recover() { + DomainEvent domainEvent; + while(true) { + domainEvent = precessorJournal.readNext(); + if(domainEvent==null){ + break; + }else{ + domainEvent.process(); + } + } + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java new file mode 100644 index 000000000..b0a707788 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java @@ -0,0 +1,22 @@ +package com.iluwatar.event.sourcing.service; + +import com.iluwatar.event.sourcing.api.EventProcessor; +import com.iluwatar.event.sourcing.event.AccountCreateEvent; + +import java.util.Date; + +/** + * Created by serdarh on 06.08.2017. + */ +public class AccountService { + private EventProcessor eventProcessor; + + public AccountService(EventProcessor eventProcessor) { + this.eventProcessor = eventProcessor; + } + + public void createAccount(int accountNo, String owner){ + AccountCreateEvent accountCreateEvent = new AccountCreateEvent(SequenceIdGenerator.nextSequenceId(), new Date().getTime(),accountNo,owner); + eventProcessor.process(accountCreateEvent); + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java new file mode 100644 index 000000000..80c2a5a4f --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java @@ -0,0 +1,35 @@ +package com.iluwatar.event.sourcing.service; + +import com.iluwatar.event.sourcing.api.EventProcessor; +import com.iluwatar.event.sourcing.event.MoneyDepositEvent; +import com.iluwatar.event.sourcing.event.MoneyTransferEvent; +import com.iluwatar.event.sourcing.event.MoneyWithdrawalEvent; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * Created by serdarh on 06.08.2017. + */ +public class MoneyTransactionService { + private EventProcessor eventProcessor; + + public MoneyTransactionService(EventProcessor eventProcessor) { + this.eventProcessor = eventProcessor; + } + + public void depositMoney(int accountNo, BigDecimal money){ + MoneyDepositEvent moneyDepositEvent = new MoneyDepositEvent(SequenceIdGenerator.nextSequenceId(), new Date().getTime(), accountNo, money); + eventProcessor.process(moneyDepositEvent); + } + + public void withdrawalMoney(int accountNo, BigDecimal money){ + MoneyWithdrawalEvent moneyWithdrawalEvent = new MoneyWithdrawalEvent(SequenceIdGenerator.nextSequenceId(), new Date().getTime(), accountNo, money); + eventProcessor.process(moneyWithdrawalEvent); + } + + public void transferMoney(int accountNoFrom, int accountNoTo, BigDecimal money){ + MoneyTransferEvent moneyTransferEvent = new MoneyTransferEvent(SequenceIdGenerator.nextSequenceId(), new Date().getTime(), money, accountNoFrom, accountNoTo); + eventProcessor.process(moneyTransferEvent); + } +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java new file mode 100644 index 000000000..2eec6a70d --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java @@ -0,0 +1,14 @@ +package com.iluwatar.event.sourcing.service; + +/** + * Created by serdarh on 06.08.2017. + */ +public class SequenceIdGenerator { + private static long sequenceId = 0L; + + public static long nextSequenceId(){ + sequenceId++; + return sequenceId; + } + +} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java new file mode 100644 index 000000000..b927af0e1 --- /dev/null +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java @@ -0,0 +1,29 @@ +package com.iluwatar.event.sourcing.state; + +import com.iluwatar.event.sourcing.domain.Account; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by serdarh on 06.08.2017. + */ +public class AccountAggregate { + private static Map accounts = new HashMap<>(); + + public static void putAccount(Account account){ + accounts.put(account.getAccountNo(), account); + } + + public static Account getAccount(int accountNo){ + Account account = accounts.get(accountNo); + if(account == null){ + return null; + } + return account.copy(); + } + + public static void resetState(){ + accounts = new HashMap<>(); + } +} diff --git a/pom.xml b/pom.xml index 4f4b5dee6..5f46c9401 100644 --- a/pom.xml +++ b/pom.xml @@ -143,6 +143,7 @@ extension-objects marker cqrs + event-sourcing From db10b937f2b07e8357ebb0b4eb02ca0972d83b25 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Wed, 9 Aug 2017 15:27:36 +0530 Subject: [PATCH 05/45] #348 - Data Tranfer Object : Added module to project. --- data-bus/pom.xml | 4 ++++ data-transfer-object/pom.xml | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 data-transfer-object/pom.xml diff --git a/data-bus/pom.xml b/data-bus/pom.xml index a77b59106..22b3f0229 100644 --- a/data-bus/pom.xml +++ b/data-bus/pom.xml @@ -27,6 +27,10 @@ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 + pom + + ../data-transfer-object + 1.16.14 diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml new file mode 100644 index 000000000..c5bfc7fa8 --- /dev/null +++ b/data-transfer-object/pom.xml @@ -0,0 +1,16 @@ + + + + data-bus + com.iluwatar + 1.17.0-SNAPSHOT + ../data-bus/pom.xml + + 4.0.0 + + data-transfer-object + + + \ No newline at end of file From 67d4477d25698e08e8fd6fcf0ccf82de484a7304 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Thu, 10 Aug 2017 13:45:46 +0530 Subject: [PATCH 06/45] #348 - Data Tranfer Object : Add puml file to etc. --- data-transfer-object/etc/data-transfer-object.urm.puml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data-transfer-object/etc/data-transfer-object.urm.puml diff --git a/data-transfer-object/etc/data-transfer-object.urm.puml b/data-transfer-object/etc/data-transfer-object.urm.puml new file mode 100644 index 000000000..02af47ddf --- /dev/null +++ b/data-transfer-object/etc/data-transfer-object.urm.puml @@ -0,0 +1,2 @@ +@startuml +@enduml \ No newline at end of file From 148de06bb1f07efc91f745198762444ef7cf55ba Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Fri, 11 Aug 2017 15:42:21 +0530 Subject: [PATCH 07/45] #348 - Data Tranfer Object : Implement Data Transfer Object pattern simple version. --- .../iluwatar/datatransfer/CustomerDto.java | 60 ++++++++++++++ .../datatransfer/CustomerResource.java | 63 +++++++++++++++ .../datatransfer/CustomerResourceTest.java | 81 +++++++++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java create mode 100644 data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java create mode 100644 data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java new file mode 100644 index 000000000..ce9ffdb78 --- /dev/null +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java @@ -0,0 +1,60 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2017 Gopinath Langote + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.iluwatar.datatransfer; + +/** + * {@link CustomerDto} is a data transfer object POJO. Instead of sending individual information to client + * We can send related information together in POJO. + *

+ * Dto will not have any business logic in it. + */ +public class CustomerDto { + private String id; + private String firstName; + private String lastName; + + /** + * @param id customer id + * @param firstName customer first name + * @param lastName customer last name + */ + public CustomerDto(String id, String firstName, String lastName) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + } + + public String getId() { + return id; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } +} diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java new file mode 100644 index 000000000..a4926d08c --- /dev/null +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java @@ -0,0 +1,63 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2017 Gopinath Langote + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.iluwatar.datatransfer; + +import java.util.List; + +/** + * The resource class which serves customer information. + * This class act as server in the demo. Which has all customer details. + */ +public class CustomerResource { + private List customers; + + /** + * @param customers initialize resource with existing customers. Act as database. + */ + public CustomerResource(List customers) { + this.customers = customers; + } + + /** + * @return : all customers in list. + */ + public List getAllCustomers() { + return customers; + } + + /** + * @param customer save new customer to list. + */ + public void save(CustomerDto customer) { + customers.add(customer); + } + + /** + * @param customerId delete customer with id {@code customerId} + */ + public void delete(String customerId) { + customers.removeIf(customer -> customer.getId().equals(customerId)); + } +} \ No newline at end of file diff --git a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java new file mode 100644 index 000000000..8d5c7b50f --- /dev/null +++ b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java @@ -0,0 +1,81 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2017 Gopinath Langote + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.iluwatar.datatransfer; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +/** + * tests {@link CustomerResource}. + */ +public class CustomerResourceTest { + @Test + public void shouldGetAllCustomers() { + CustomerDto customer = new CustomerDto("1", "David", "Roy"); + List customers = new ArrayList<>(); + customers.add(customer); + + CustomerResource customerResource = new CustomerResource(customers); + + List allCustomers = customerResource.getAllCustomers(); + + assertEquals(allCustomers.size(), 1); + assertEquals(allCustomers.get(0).getId(), "1"); + assertEquals(allCustomers.get(0).getFirstName(), "David"); + assertEquals(allCustomers.get(0).getLastName(), "Roy"); + } + + @Test + public void shouldSaveCustomer() { + CustomerDto customer = new CustomerDto("1", "David", "Roy"); + CustomerResource customerResource = new CustomerResource(new ArrayList<>()); + + customerResource.save(customer); + + List allCustomers = customerResource.getAllCustomers(); + assertEquals(allCustomers.get(0).getId(), "1"); + assertEquals(allCustomers.get(0).getFirstName(), "David"); + assertEquals(allCustomers.get(0).getLastName(), "Roy"); + } + + @Test + public void shouldDeleteCustomer() { + CustomerDto customer = new CustomerDto("1", "David", "Roy"); + List customers = new ArrayList<>(); + customers.add(customer); + + CustomerResource customerResource = new CustomerResource(customers); + + customerResource.delete(customer.getId()); + + List allCustomers = customerResource.getAllCustomers(); + assertEquals(allCustomers.size(), 0); + } + +} \ No newline at end of file From 229fda9f3c0530e5a26380b77a12b86b702dd11b Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Fri, 11 Aug 2017 15:55:12 +0530 Subject: [PATCH 08/45] #348 - Data Tranfer Object : Add puml diagram. --- .../etc/data-transfer-object.urm.png | Bin 0 -> 14193 bytes .../etc/data-transfer-object.urm.puml | 19 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 data-transfer-object/etc/data-transfer-object.urm.png diff --git a/data-transfer-object/etc/data-transfer-object.urm.png b/data-transfer-object/etc/data-transfer-object.urm.png new file mode 100644 index 0000000000000000000000000000000000000000..3c4377ee978dc37ff69d045d771583790062b8ea GIT binary patch literal 14193 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 + + CustomerResource(customers : List) + + delete(customerId : String) + + getAllCustomers() : List + + save(customer : CustomerDto) + } +} +CustomerResource --> "-customers" CustomerDto @enduml \ No newline at end of file From df9be7850490558e7e506961a24c4816765c37d4 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Fri, 11 Aug 2017 16:17:51 +0530 Subject: [PATCH 09/45] #348 - Data Tranfer Object : customer client request customer details to server at one shot. --- .../etc/data-transfer-object.urm.png | Bin 14193 -> 19132 bytes .../etc/data-transfer-object.urm.puml | 5 ++ .../datatransfer/CustomerClientApp.java | 78 ++++++++++++++++++ .../datatransfer/CustomerResourceTest.java | 14 ++-- 4 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java diff --git a/data-transfer-object/etc/data-transfer-object.urm.png b/data-transfer-object/etc/data-transfer-object.urm.png index 3c4377ee978dc37ff69d045d771583790062b8ea..46facff8dee4c45b2c6bbafb7ea6c3b6be80dfc3 100644 GIT binary patch literal 19132 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 R(&9dol~j_*6aUNm{{y~+`I`U$ literal 14193 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 {static} + } class CustomerDto { - firstName : String - id : String diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java new file mode 100644 index 000000000..3a9e8b88f --- /dev/null +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java @@ -0,0 +1,78 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2017 Gopinath Langote + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.iluwatar.datatransfer; + +import java.util.ArrayList; +import java.util.List; + +/** + * The Data Transfer Object pattern is a design pattern in which an data transfer object is used to serve related + * information together to avoid multiple call for each piece of information. + *

+ * In this example, ({@link CustomerClientApp}) as as customer details consumer i.e. client to request for + * customer details to server. + *

+ * CustomerResource ({@link CustomerResource}) act as server to serve customer information. + * And The CustomerDto ({@link CustomerDto} is data transfer object to share customer information. + */ +public class CustomerClientApp { + /** + * Method as act client and request to server for details. + * + * @param args program argument. + */ + public static void main(String[] args) { + List customers = new ArrayList<>(); + CustomerDto customerOne = new CustomerDto("1", "Kelly", "Brown"); + CustomerDto customerTwo = new CustomerDto("2", "Alfonso", "Bass"); + customers.add(customerOne); + customers.add(customerTwo); + + CustomerResource customerResource = new CustomerResource(customers); + + System.out.println("All customers:-"); + List allCustomers = customerResource.getAllCustomers(); + printCustomerDetails(allCustomers); + + System.out.println("----------------------------------------------------------"); + + System.out.println("Deleting customer with id {1}"); + customerResource.delete(customerOne.getId()); + allCustomers = customerResource.getAllCustomers(); + printCustomerDetails(allCustomers); + + System.out.println("----------------------------------------------------------"); + + System.out.println("Adding customer three}"); + CustomerDto customerThree = new CustomerDto("3", "Lynda", "Blair"); + customerResource.save(customerThree); + allCustomers = customerResource.getAllCustomers(); + printCustomerDetails(allCustomers); + } + + private static void printCustomerDetails(List allCustomers) { + allCustomers.forEach(customer -> System.out.println(customer.getFirstName())); + } +} diff --git a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java index 8d5c7b50f..adfe66b7d 100644 --- a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java +++ b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java @@ -37,7 +37,7 @@ import static org.junit.Assert.assertEquals; public class CustomerResourceTest { @Test public void shouldGetAllCustomers() { - CustomerDto customer = new CustomerDto("1", "David", "Roy"); + CustomerDto customer = new CustomerDto("1", "Melody", "Yates"); List customers = new ArrayList<>(); customers.add(customer); @@ -47,26 +47,26 @@ public class CustomerResourceTest { assertEquals(allCustomers.size(), 1); assertEquals(allCustomers.get(0).getId(), "1"); - assertEquals(allCustomers.get(0).getFirstName(), "David"); - assertEquals(allCustomers.get(0).getLastName(), "Roy"); + assertEquals(allCustomers.get(0).getFirstName(), "Melody"); + assertEquals(allCustomers.get(0).getLastName(), "Yates"); } @Test public void shouldSaveCustomer() { - CustomerDto customer = new CustomerDto("1", "David", "Roy"); + CustomerDto customer = new CustomerDto("1", "Rita", "Reynolds"); CustomerResource customerResource = new CustomerResource(new ArrayList<>()); customerResource.save(customer); List allCustomers = customerResource.getAllCustomers(); assertEquals(allCustomers.get(0).getId(), "1"); - assertEquals(allCustomers.get(0).getFirstName(), "David"); - assertEquals(allCustomers.get(0).getLastName(), "Roy"); + assertEquals(allCustomers.get(0).getFirstName(), "Rita"); + assertEquals(allCustomers.get(0).getLastName(), "Reynolds"); } @Test public void shouldDeleteCustomer() { - CustomerDto customer = new CustomerDto("1", "David", "Roy"); + CustomerDto customer = new CustomerDto("1", "Terry", "Nguyen"); List customers = new ArrayList<>(); customers.add(customer); From bfbc8fd740f74739017cd95008a16146e5484217 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Fri, 11 Aug 2017 16:51:46 +0530 Subject: [PATCH 10/45] #348 - Data Tranfer Object : Add readme.md --- data-transfer-object/README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 data-transfer-object/README.md diff --git a/data-transfer-object/README.md b/data-transfer-object/README.md new file mode 100644 index 000000000..ad9b9f4e2 --- /dev/null +++ b/data-transfer-object/README.md @@ -0,0 +1,30 @@ +--- +layout: pattern +title: Data Transfer Object +folder: data-transfer-object +permalink: /patterns/data-transfer-object/ +categories: Architectural +tags: + - Java + - KISS + - YAGNI + - Difficulty-Beginner +--- + +## Intent +Pass data with multiple attributes in one shot from client to server, +to avoid multiple calls to remote server. + +![alt text](./etc/data-transfer-object.urm.png "data-transfer-object") + +## Applicability +Use the Data Transfer Object pattern when + +* The client is asking for multiple information. And the information is related. +* When you want to boost the performance to get resources. +* You want reduced number of remote calls. + +## Credits + +* [Design Pattern - Transfer Object Pattern](https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm) +* [Data Transfer Object](https://msdn.microsoft.com/en-us/library/ff649585.aspx) From 64824d65aa9df0928d67e31bc7e2e0290c989ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serdar=20Hamzao=C4=9Fullar=C4=B1?= Date: Sat, 12 Aug 2017 16:21:35 +0300 Subject: [PATCH 11/45] Some Object Orianted refactor --- .../event/sourcing/api/DomainEvent.java | 10 +-- .../event/sourcing/api/EventProcessor.java | 1 - .../sourcing/api/ExternalEventListener.java | 8 --- .../event/sourcing/domain/Account.java | 67 +++++++++++++++++++ .../sourcing/event/AccountCreateEvent.java | 8 +-- .../sourcing/event/MoneyDepositEvent.java | 18 ++--- .../sourcing/event/MoneyTransferEvent.java | 34 ++++------ .../sourcing/event/MoneyWithdrawalEvent.java | 18 ++--- .../sourcing/journal/JsonFileJournal.java | 2 +- .../processor/DomainEventProcessor.java | 11 --- 10 files changed, 106 insertions(+), 71 deletions(-) delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ExternalEventListener.java diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java index d77654869..e20d03232 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java @@ -8,7 +8,7 @@ import java.io.Serializable; public abstract class DomainEvent implements Serializable { private final long sequenceId; private final long createdTime; - private boolean replica = false; + private boolean realTime = true; private final String eventClassName; public DomainEvent(long sequenceId, long createdTime, String eventClassName) { @@ -25,12 +25,12 @@ public abstract class DomainEvent implements Serializable { return createdTime; } - public boolean isReplica() { - return replica; + public boolean isRealTime() { + return realTime; } - public void setReplica(boolean replica) { - this.replica = replica; + public void setRealTime(boolean realTime) { + this.realTime = realTime; } public abstract void process(); diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java index 729efc83c..0fc673bf4 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java @@ -6,6 +6,5 @@ package com.iluwatar.event.sourcing.api; public interface EventProcessor { void process(DomainEvent domainEvent); void setPrecessorJournal(ProcessorJournal precessorJournal); - void addExternalEventListener(ExternalEventListener externalEventListener); void recover(); } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ExternalEventListener.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ExternalEventListener.java deleted file mode 100644 index a1cb78108..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ExternalEventListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.iluwatar.event.sourcing.api; - -/** - * Created by serdarh on 06.08.2017. - */ -public interface ExternalEventListener { - void notify(DomainEvent domainEvent); -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java index 5a7a77fcf..48cda1eca 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java @@ -1,5 +1,12 @@ package com.iluwatar.event.sourcing.domain; +import com.iluwatar.event.sourcing.event.AccountCreateEvent; +import com.iluwatar.event.sourcing.event.MoneyDepositEvent; +import com.iluwatar.event.sourcing.event.MoneyTransferEvent; +import com.iluwatar.event.sourcing.event.MoneyWithdrawalEvent; +import com.iluwatar.event.sourcing.gateway.Gateways; +import com.iluwatar.event.sourcing.state.AccountAggregate; + import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; @@ -60,4 +67,64 @@ public class Account { ", transactions=" + transactions + '}'; } + + private Transaction depositMoney(BigDecimal money) { + this.money = this.money.add(money); + Transaction transaction = new Transaction(accountNo,money,BigDecimal.ZERO,this.money); + transactions.add(transaction); + return transaction; + } + + private Transaction withdrawMoney(BigDecimal money) { + this.money = this.money.subtract(money); + Transaction transaction = new Transaction(accountNo,BigDecimal.ZERO,money,this.money); + transactions.add(transaction); + return transaction; + } + + private void handleDeposit(BigDecimal money,boolean realTime) { + Transaction transaction = depositMoney(money); + AccountAggregate.putAccount(this); + if(realTime) { + Gateways.getTransactionLogger().log(transaction); + } + } + + private void handleWithdrawal(BigDecimal money, boolean realTime) { + if(this.money.compareTo(money)==-1){ + throw new RuntimeException("Insufficient Account Balance"); + } + + Transaction transaction = withdrawMoney(money); + AccountAggregate.putAccount(this); + if(realTime) { + Gateways.getTransactionLogger().log(transaction); + } + } + + public void handleEvent(MoneyDepositEvent moneyDepositEvent) { + handleDeposit(moneyDepositEvent.getMoney(),moneyDepositEvent.isRealTime()); + } + + + public void handleEvent(MoneyWithdrawalEvent moneyWithdrawalEvent) { + handleWithdrawal(moneyWithdrawalEvent.getMoney(),moneyWithdrawalEvent.isRealTime()); + } + + + public void handleTransferFromEvent(MoneyTransferEvent moneyTransferEvent) { + handleWithdrawal(moneyTransferEvent.getMoney(),moneyTransferEvent.isRealTime()); + } + + public void handleTransferToEvent(MoneyTransferEvent moneyTransferEvent) { + handleDeposit(moneyTransferEvent.getMoney(),moneyTransferEvent.isRealTime()); + } + + public void handleEvent(AccountCreateEvent accountCreateEvent) { + AccountAggregate.putAccount(this); + // check if this event is replicated from journal before calling an external gateway function + if(accountCreateEvent.isRealTime()) { + Gateways.getAccountCreateContractSender().sendContractInfo(this); + } + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java index 3957a4fe7..1ea089e2f 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java @@ -2,7 +2,6 @@ package com.iluwatar.event.sourcing.event; import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; -import com.iluwatar.event.sourcing.gateway.Gateways; import com.iluwatar.event.sourcing.state.AccountAggregate; /** @@ -33,11 +32,6 @@ public class AccountCreateEvent extends DomainEvent { throw new RuntimeException("Account already exists"); } account = new Account(accountNo,owner); - AccountAggregate.putAccount(account); - - // check if this event is replicated from journal before calling an external gateway function - if(!isReplica()) { - Gateways.getAccountCreateContractSender().sendContractInfo(account); - } + account.handleEvent(this); } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java index ffa9d0763..384a9e198 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java @@ -2,8 +2,6 @@ package com.iluwatar.event.sourcing.event; import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; -import com.iluwatar.event.sourcing.domain.Transaction; -import com.iluwatar.event.sourcing.gateway.Gateways; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; @@ -21,18 +19,20 @@ public class MoneyDepositEvent extends DomainEvent { this.accountNo = accountNo; } + public BigDecimal getMoney() { + return money; + } + + public int getAccountNo() { + return accountNo; + } + @Override public void process() { Account account = AccountAggregate.getAccount(accountNo); if(account==null){ throw new RuntimeException("Account not found"); } - account.setMoney(account.getMoney().add(money)); - Transaction transaction = new Transaction(accountNo,money,BigDecimal.ZERO,account.getMoney()); - account.getTransactions().add(transaction); - AccountAggregate.putAccount(account); - if(!isReplica()) { - Gateways.getTransactionLogger().log(transaction); - } + account.handleEvent(this); } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java index 4e0fb9829..6c873d4db 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java @@ -2,8 +2,6 @@ package com.iluwatar.event.sourcing.event; import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; -import com.iluwatar.event.sourcing.domain.Transaction; -import com.iluwatar.event.sourcing.gateway.Gateways; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; @@ -23,6 +21,18 @@ public class MoneyTransferEvent extends DomainEvent { this.accountNoTo = accountNoTo; } + public BigDecimal getMoney() { + return money; + } + + public int getAccountNoFrom() { + return accountNoFrom; + } + + public int getAccountNoTo() { + return accountNoTo; + } + @Override public void process() { Account accountFrom = AccountAggregate.getAccount(accountNoFrom); @@ -33,24 +43,8 @@ public class MoneyTransferEvent extends DomainEvent { if(accountTo==null){ throw new RuntimeException("Account not found"+ accountTo); } - if(accountFrom.getMoney().compareTo(money)==-1){ - throw new RuntimeException("Insufficient Account Balance"); - } - accountFrom.setMoney(accountFrom.getMoney().subtract(money)); - accountTo.setMoney(accountTo.getMoney().add(money)); - Transaction transactionFrom = new Transaction(accountNoFrom,BigDecimal.ZERO,money,accountFrom.getMoney()); - accountFrom.getTransactions().add(transactionFrom); - - Transaction transactionTo = new Transaction(accountNoTo,money,BigDecimal.ZERO,accountTo.getMoney()); - accountTo.getTransactions().add(transactionTo); - - AccountAggregate.putAccount(accountFrom); - AccountAggregate.putAccount(accountTo); - - if(!isReplica()) { - Gateways.getTransactionLogger().log(transactionFrom); - Gateways.getTransactionLogger().log(transactionTo); - } + accountFrom.handleTransferFromEvent(this); + accountTo.handleTransferToEvent(this); } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java index 27a63d13d..8ed617008 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java @@ -2,8 +2,6 @@ package com.iluwatar.event.sourcing.event; import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; -import com.iluwatar.event.sourcing.domain.Transaction; -import com.iluwatar.event.sourcing.gateway.Gateways; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; @@ -21,18 +19,20 @@ public class MoneyWithdrawalEvent extends DomainEvent { this.accountNo = accountNo; } + public BigDecimal getMoney() { + return money; + } + + public int getAccountNo() { + return accountNo; + } + @Override public void process() { Account account = AccountAggregate.getAccount(accountNo); if(account==null){ throw new RuntimeException("Account not found"); } - account.setMoney(account.getMoney().subtract(money)); - Transaction transaction = new Transaction(accountNo,BigDecimal.ZERO,money,account.getMoney()); - account.getTransactions().add(transaction); - AccountAggregate.putAccount(account); - if(!isReplica()) { - Gateways.getTransactionLogger().log(transaction); - } + account.handleEvent(this); } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java index 45a982c19..2d50db55f 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java @@ -93,7 +93,7 @@ public class JsonFileJournal implements ProcessorJournal{ throw new RuntimeException("Journal Event not recegnized"); } - domainEvent.setReplica(true); + domainEvent.setRealTime(false); return domainEvent; } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java index a23c41905..55453b1c6 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java @@ -2,23 +2,17 @@ package com.iluwatar.event.sourcing.processor; import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.api.EventProcessor; -import com.iluwatar.event.sourcing.api.ExternalEventListener; import com.iluwatar.event.sourcing.api.ProcessorJournal; -import java.util.ArrayList; -import java.util.List; - /** * Created by serdarh on 06.08.2017. */ public class DomainEventProcessor implements EventProcessor { private ProcessorJournal precessorJournal; - private List externalEventListeners = new ArrayList<>(); @Override public void process(DomainEvent domainEvent) { - externalEventListeners.forEach(externalEventListener -> externalEventListener.notify(domainEvent)); domainEvent.process(); precessorJournal.write(domainEvent); } @@ -28,11 +22,6 @@ public class DomainEventProcessor implements EventProcessor { this.precessorJournal = precessorJournal; } - @Override - public void addExternalEventListener(ExternalEventListener externalEventListener) { - externalEventListeners.add(externalEventListener); - } - @Override public void recover() { DomainEvent domainEvent; From 746e452c2bfbb623df0285a53793cf791f3539f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 12 Aug 2017 18:20:45 +0300 Subject: [PATCH 12/45] #590 Add new presentation for Singleton --- singleton/README.md | 29 ++++++++- singleton/etc/singleton.png | Bin 22292 -> 0 bytes singleton/etc/singleton.ucls | 104 ------------------------------- singleton/etc/singleton.urm.puml | 43 ------------- singleton/etc/singleton_1.png | Bin 16417 -> 0 bytes 5 files changed, 27 insertions(+), 149 deletions(-) delete mode 100644 singleton/etc/singleton.png delete mode 100644 singleton/etc/singleton.ucls delete mode 100644 singleton/etc/singleton.urm.puml delete mode 100644 singleton/etc/singleton_1.png diff --git a/singleton/README.md b/singleton/README.md index 4032ffaed..0a81ba0fc 100644 --- a/singleton/README.md +++ b/singleton/README.md @@ -15,7 +15,32 @@ tags: Ensure a class only has one instance, and provide a global point of access to it. -![alt text](./etc/singleton_1.png "Singleton") + +## Explanation +Real world example +> There can only be one ivory tower where the wizards study their magic. The same enchanted ivory tower is always used by the wizards. Ivory tower here is singleton. + +In plain words +> Ensures that only one object of a particular class is ever created. + +Wikipedia says +> In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. + +**Programmatic Example** + +Joshua Bloch, Effective Java 2nd Edition p.18 +> A single-element enum type is the best way to implement a singleton +``` +public enum EnumIvoryTower { + INSTANCE; +} +``` +Then in order to use +``` +EnumIvoryTower enumIvoryTower1 = EnumIvoryTower.INSTANCE; +EnumIvoryTower enumIvoryTower2 = EnumIvoryTower.INSTANCE; +assertEquals(enumIvoryTower1, enumIvoryTower2); // true +``` ## Applicability Use the Singleton pattern when @@ -40,7 +65,7 @@ Use the Singleton pattern when * Violates Single Responsibility Principle (SRP) by controlling their own creation and lifecycle. * Encourages using a global shared instance which prevents an object and resources used by this object from being deallocated. -* Creates tightly coupled code that is difficult to test. +* Creates tightly coupled code. The clients of the Singleton become difficult to test. * Makes it almost impossible to subclass a Singleton. ## Credits diff --git a/singleton/etc/singleton.png b/singleton/etc/singleton.png deleted file mode 100644 index 0bf0c9b283b751a3b32179e3e7bd3e2927ff49db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22292 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

WR8<5D*{^GczS48yE-=>C)RQClp=7 zov}X|P|9jI6}phh2Re|g=evBWTF@Euv~$EX&J?BFe(?q3$U=p~ALVSi?b@>bDH8EA z4r|y@{YFwbsQTq~HwJF@UE3wo!!ItRPS5b$ng&?KlIKLvvTJ#T$tE{IGbq#hOOb{C zc4X)>YsevJ$kYB(t>?N8_I8(-)XD=VK3$s#9erCH+VGYfg)gYSdNYJSCJsZJkhC~X zw>X?8nqZTTOK%uxaxsdIyNEBQZ$s3|i8a99qh~vWLa@Fb)%INA)fu3^{O@%Jj;5fo z&*@5KQ6};o-MIF9S|@2C#vvP=$35Psm}lJ55^IQKq5~QV^2&6^U!kS9wHj6 zA_DsYzrSGNcTe3VN{+`$|C3ryFQpq}FqbyL$rZ@B?DKxgHr!8GZ-hRZm@Ny=^R1Me z8N;4|R(N(DrAC-vR|agMuWB%?mDk>y?VRbV+_L^>qcVYu9a|XK5z_d*s@^If!Lr7iLl&NFc0n+DUcLE}c9v8;gH9yqyIJQ__ zKW};zu~^pAEqx6kHhxLv%qhe@;V(&JTpL{oUkSVMO{NLY)kee1MxN)%b6tYva7Yc3 zLj`%t7}i=LWUk+lXb9dyo$t*W;852Sq(Z-R3|}>JI~V4678$0y&ib8zQY8OMS*KoZ(ZC&OUh7U_U>uI ztf#5;(H(_dj){b*kDHpuJjXEF7(qYj2?U;eS*NoZj<)jnnAkjCU1z9{z_?yF;btKP!#o!n%OvR6rEud_>1CWuBM#G8y;=0+ zW4gR^sEy)?`n^+lhD+KGJnTV5AOX<|U7dGR^RyemHh7*zi5Pn9WQ5t$!`*L`#;*o+ z-B@_+*0?p#)vlHNTK+a$9q!Bq>g@K4iG?_cb}&leqLZOD9-En}y2V!hl1BV;m7;o- zNKmRO>ds}GWY<}mk^o6Tf0BB2khZHa%G4}7w3)Y!#}}3iwRDUib+0Z&;zR(9aBiT~ zhU7nLjn({k7Us^=g8vMle~)soZcLv2M%bqhaGNCqM;IT%z8S!MMYCT;ffZtvE8v%F z?u8(jef|oo9i#I>117xh|5@;8C`!U}F1>5zyrAvNU8oz)nD6Rt@o;-;@r4ajndDOo z^}4b|{Kp!_aEU^a6bqIw*Xotr7=nmL-K{Puuq0PQ(@Jyg#&M(a;)7y-*2N{|q~9+V zypx&%70=FSF#%VK6xW(;DuUlQEd)hdDIS4t<>)PAdL~ZD;Y~*HFw`QTxX;{7u$W0s zG0%=#+4cxJ`h;&kB7)oDHM|5NgP}eWVN;;!RMHHS@aDM0n(% z(+SxwO4-{-$&$}KK_%zoC4SJ{=W~Op#@iAD`|*(U+6bxcp)8Q6Ca=Fb} zj3K3pm=K^8k4_jnFl${qL7(J7uhcEm=BiGUS? zhH#kIj=a`Amt`!ou$q(d4*Um#o2w&g?XLTN(~^CMjC!x(Yr=0k7(0xw-CB=%=3t^0 zy^~Ts9<@(ura34RmQ}~9BfW|C4w*_tbosK`v7K{7IURlue=bq&C_ze;gx1QpylCLu zh|zTJtM2z>&^1pP(^At4B*E6pDryexhP;6z$OZV=&`lXiH*fnA7O<5OqAtx)L2n_$1WC)P2igZTeO-r;JL4qErWf5AP&NO#tl$@>Y z;05h0NO|Fn - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/singleton/etc/singleton.urm.puml b/singleton/etc/singleton.urm.puml deleted file mode 100644 index f61377e17..000000000 --- a/singleton/etc/singleton.urm.puml +++ /dev/null @@ -1,43 +0,0 @@ -@startuml -package com.iluwatar.singleton { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } - enum EnumIvoryTower { - + INSTANCE {static} - + toString() : String - + valueOf(name : String) : EnumIvoryTower {static} - + values() : EnumIvoryTower[] {static} - } - class InitializingOnDemandHolderIdiom { - - InitializingOnDemandHolderIdiom() - + getInstance() : InitializingOnDemandHolderIdiom {static} - } - -class HelperHolder { - - INSTANCE : InitializingOnDemandHolderIdiom {static} - - HelperHolder() - } - class IvoryTower { - - INSTANCE : IvoryTower {static} - - IvoryTower() - + getInstance() : IvoryTower {static} - } - class ThreadSafeDoubleCheckLocking { - - instance : ThreadSafeDoubleCheckLocking {static} - - ThreadSafeDoubleCheckLocking() - + getInstance() : ThreadSafeDoubleCheckLocking {static} - } - class ThreadSafeLazyLoadedIvoryTower { - - instance : ThreadSafeLazyLoadedIvoryTower {static} - - ThreadSafeLazyLoadedIvoryTower() - + getInstance() : ThreadSafeLazyLoadedIvoryTower {static} - } -} -IvoryTower --> "-INSTANCE" IvoryTower -ThreadSafeDoubleCheckLocking --> "-instance" ThreadSafeDoubleCheckLocking -ThreadSafeLazyLoadedIvoryTower --> "-instance" ThreadSafeLazyLoadedIvoryTower -HelperHolder ..+ InitializingOnDemandHolderIdiom -HelperHolder --> "-INSTANCE" InitializingOnDemandHolderIdiom -@enduml \ No newline at end of file diff --git a/singleton/etc/singleton_1.png b/singleton/etc/singleton_1.png deleted file mode 100644 index 58dc440a9ca9167260bc6b81f7b710213d046e1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16417 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 From 2150a2bb55f9116bcb16c391d0018d269a741abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 12 Aug 2017 18:42:14 +0300 Subject: [PATCH 13/45] #590 Skip puml processing for singleton module --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 4f4b5dee6..0ea198c3f 100644 --- a/pom.xml +++ b/pom.xml @@ -460,6 +460,7 @@ java-design-patterns + singleton From 002774b5aa8db75f53fc5205d8bd14977d077f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 12 Aug 2017 19:24:55 +0300 Subject: [PATCH 14/45] Fix Travis out of memory error --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 817b6635f..a2aaf764b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,4 +36,4 @@ notifications: on_failure: always # options: [always|never|change] default: always on_start: never # options: [always|never|change] default: always -sudo: false # route the build to the container-based infrastructure for a faster build +sudo: required \ No newline at end of file From 2d750dc0fdfc848e67d5f9a8524b5a19817401e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 12 Aug 2017 20:02:14 +0300 Subject: [PATCH 15/45] #590 Alter Factory Method presentation --- factory-method/README.md | 41 +++++++- factory-method/etc/factory-method.png | Bin 22316 -> 0 bytes factory-method/etc/factory-method.ucls | 117 --------------------- factory-method/etc/factory-method.urm.puml | 54 ---------- factory-method/etc/factory-method_1.png | Bin 47622 -> 0 bytes pom.xml | 1 + 6 files changed, 41 insertions(+), 172 deletions(-) delete mode 100644 factory-method/etc/factory-method.png delete mode 100644 factory-method/etc/factory-method.ucls delete mode 100644 factory-method/etc/factory-method.urm.puml delete mode 100644 factory-method/etc/factory-method_1.png diff --git a/factory-method/README.md b/factory-method/README.md index 17e0818e9..de3a9dd8c 100644 --- a/factory-method/README.md +++ b/factory-method/README.md @@ -19,7 +19,46 @@ Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. -![alt text](./etc/factory-method_1.png "Factory Method") +## Explanation + +Real world example +> Blacksmith manufactures weapons. Elves require Elvish weapons and orcs require Orcish weapons. Depending on the customer at hand the right type of blacksmith is summoned. + +In plain words +> It provides a way to delegate the instantiation logic to child classes. + +Wikipedia says +> In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor. + + **Programmatic Example** + +Taking our blacksmith example above. First of all we have a blacksmith interface and some implementations for it + +``` +public interface Blacksmith { + Weapon manufactureWeapon(WeaponType weaponType); +} + +public class ElfBlacksmith implements Blacksmith { + public Weapon manufactureWeapon(WeaponType weaponType) { + return new ElfWeapon(weaponType); + } +} + +public class OrcBlacksmith implements Blacksmith { + public Weapon manufactureWeapon(WeaponType weaponType) { + return new OrcWeapon(weaponType); + } +} +``` + +Now as the customers come the correct type of blacksmith is summoned and requested weapons are manufactured +``` +Blacksmith blacksmith = new ElfBlacksmith(); +blacksmith.manufactureWeapon(WeaponType.SPEAR); +blacksmith.manufactureWeapon(WeaponType.AXE); +// Elvish weapons are created +``` ## Applicability Use the Factory Method pattern when diff --git a/factory-method/etc/factory-method.png b/factory-method/etc/factory-method.png deleted file mode 100644 index c2edfd6484ea802895f57e08797c0172bedb0f1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22316 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 JtBW^6{|~uX4SWCq diff --git a/factory-method/etc/factory-method.ucls b/factory-method/etc/factory-method.ucls deleted file mode 100644 index 562437995..000000000 --- a/factory-method/etc/factory-method.ucls +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/factory-method/etc/factory-method.urm.puml b/factory-method/etc/factory-method.urm.puml deleted file mode 100644 index 73a05e178..000000000 --- a/factory-method/etc/factory-method.urm.puml +++ /dev/null @@ -1,54 +0,0 @@ -@startuml -package com.iluwatar.factory.method { - class App { - - LOGGER : Logger {static} - - blacksmith : Blacksmith - + App(blacksmith : Blacksmith) - + main(args : String[]) {static} - - manufactureWeapons() - } - interface Blacksmith { - + manufactureWeapon(WeaponType) : Weapon {abstract} - } - class ElfBlacksmith { - + ElfBlacksmith() - + manufactureWeapon(weaponType : WeaponType) : Weapon - } - class ElfWeapon { - - weaponType : WeaponType - + ElfWeapon(weaponType : WeaponType) - + getWeaponType() : WeaponType - + toString() : String - } - class OrcBlacksmith { - + OrcBlacksmith() - + manufactureWeapon(weaponType : WeaponType) : Weapon - } - class OrcWeapon { - - weaponType : WeaponType - + OrcWeapon(weaponType : WeaponType) - + getWeaponType() : WeaponType - + toString() : String - } - interface Weapon { - + getWeaponType() : WeaponType {abstract} - } - enum WeaponType { - + AXE {static} - + SHORT_SWORD {static} - + SPEAR {static} - + UNDEFINED {static} - - title : String - + toString() : String - + valueOf(name : String) : WeaponType {static} - + values() : WeaponType[] {static} - } -} -ElfWeapon --> "-weaponType" WeaponType -OrcWeapon --> "-weaponType" WeaponType -App --> "-blacksmith" Blacksmith -ElfBlacksmith ..|> Blacksmith -ElfWeapon ..|> Weapon -OrcBlacksmith ..|> Blacksmith -OrcWeapon ..|> Weapon -@enduml \ No newline at end of file diff --git a/factory-method/etc/factory-method_1.png b/factory-method/etc/factory-method_1.png deleted file mode 100644 index 6b9276781be2e1f498f590a7877a6434204caa41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47622 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 E0=f?*lK=n! diff --git a/pom.xml b/pom.xml index 0ea198c3f..7f96043f5 100644 --- a/pom.xml +++ b/pom.xml @@ -461,6 +461,7 @@ java-design-patterns singleton + factory-method From fba30e59ee8f0a82c577493ed0b2089ae4afae6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 12 Aug 2017 21:44:21 +0300 Subject: [PATCH 16/45] #590 Kramdown fixes --- factory-method/README.md | 5 ++++- singleton/README.md | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/factory-method/README.md b/factory-method/README.md index de3a9dd8c..07c92d0e5 100644 --- a/factory-method/README.md +++ b/factory-method/README.md @@ -20,14 +20,16 @@ decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. ## Explanation - Real world example + > Blacksmith manufactures weapons. Elves require Elvish weapons and orcs require Orcish weapons. Depending on the customer at hand the right type of blacksmith is summoned. In plain words + > It provides a way to delegate the instantiation logic to child classes. Wikipedia says + > In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor. **Programmatic Example** @@ -53,6 +55,7 @@ public class OrcBlacksmith implements Blacksmith { ``` Now as the customers come the correct type of blacksmith is summoned and requested weapons are manufactured + ``` Blacksmith blacksmith = new ElfBlacksmith(); blacksmith.manufactureWeapon(WeaponType.SPEAR); diff --git a/singleton/README.md b/singleton/README.md index 0a81ba0fc..1be304d8e 100644 --- a/singleton/README.md +++ b/singleton/README.md @@ -18,24 +18,31 @@ access to it. ## Explanation Real world example + > There can only be one ivory tower where the wizards study their magic. The same enchanted ivory tower is always used by the wizards. Ivory tower here is singleton. In plain words + > Ensures that only one object of a particular class is ever created. Wikipedia says + > In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. **Programmatic Example** Joshua Bloch, Effective Java 2nd Edition p.18 + > A single-element enum type is the best way to implement a singleton + ``` public enum EnumIvoryTower { INSTANCE; } ``` + Then in order to use + ``` EnumIvoryTower enumIvoryTower1 = EnumIvoryTower.INSTANCE; EnumIvoryTower enumIvoryTower2 = EnumIvoryTower.INSTANCE; From 4b3435c550def35d2b55cdb72ffa44410efca7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serdar=20Hamzao=C4=9Fullar=C4=B1?= Date: Sun, 13 Aug 2017 00:08:35 +0300 Subject: [PATCH 17/45] Code formating --- event-sourcing/etc/.gitkeep | 0 event-sourcing/etc/event-sourcing.urm.puml | 184 +++++++++++ event-sourcing/src/.gitkeep | 0 .../event/sourcing/api/DomainEvent.java | 108 +++++-- .../event/sourcing/api/EventProcessor.java | 44 ++- .../event/sourcing/api/ProcessorJournal.java | 44 ++- .../com/iluwatar/event/sourcing/app/App.java | 89 ++++-- .../event/sourcing/domain/Account.java | 295 ++++++++++++------ .../event/sourcing/domain/Transaction.java | 114 +++++-- .../sourcing/event/AccountCreateEvent.java | 83 +++-- .../sourcing/event/MoneyDepositEvent.java | 82 +++-- .../sourcing/event/MoneyTransferEvent.java | 117 ++++--- .../sourcing/event/MoneyWithdrawalEvent.java | 82 +++-- .../gateway/AccountCreateContractSender.java | 34 +- .../event/sourcing/gateway/Gateways.java | 49 ++- .../sourcing/gateway/TransactionLogger.java | 34 +- .../sourcing/journal/JsonFileJournal.java | 183 ++++++----- .../processor/DomainEventProcessor.java | 64 ++-- .../sourcing/service/AccountService.java | 52 ++- .../service/MoneyTransactionService.java | 84 ++++- .../sourcing/service/SequenceIdGenerator.java | 38 ++- .../sourcing/state/AccountAggregate.java | 64 +++- 22 files changed, 1396 insertions(+), 448 deletions(-) delete mode 100644 event-sourcing/etc/.gitkeep create mode 100644 event-sourcing/etc/event-sourcing.urm.puml delete mode 100644 event-sourcing/src/.gitkeep diff --git a/event-sourcing/etc/.gitkeep b/event-sourcing/etc/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/event-sourcing/etc/event-sourcing.urm.puml b/event-sourcing/etc/event-sourcing.urm.puml new file mode 100644 index 000000000..207d238e6 --- /dev/null +++ b/event-sourcing/etc/event-sourcing.urm.puml @@ -0,0 +1,184 @@ +@startuml +package com.iluwatar.event.sourcing.journal { + class JsonFileJournal { + - aFile : File + - events : List + - index : int + + JsonFileJournal() + + readNext() : DomainEvent + + reset() + + write(domainEvent : DomainEvent) + } +} +package com.iluwatar.event.sourcing.processor { + class DomainEventProcessor { + - precessorJournal : ProcessorJournal + + DomainEventProcessor() + + process(domainEvent : DomainEvent) + + recover() + + setPrecessorJournal(precessorJournal : ProcessorJournal) + } +} +package com.iluwatar.event.sourcing.service { + class AccountService { + - eventProcessor : EventProcessor + + AccountService(eventProcessor : EventProcessor) + + createAccount(accountNo : int, owner : String) + } + class MoneyTransactionService { + - eventProcessor : EventProcessor + + MoneyTransactionService(eventProcessor : EventProcessor) + + depositMoney(accountNo : int, money : BigDecimal) + + transferMoney(accountNoFrom : int, accountNoTo : int, money : BigDecimal) + + withdrawalMoney(accountNo : int, money : BigDecimal) + } + class SequenceIdGenerator { + - sequenceId : long {static} + + SequenceIdGenerator() + + nextSequenceId() : long {static} + } +} +package com.iluwatar.event.sourcing.event { + class AccountCreateEvent { + - accountNo : int + - owner : String + + AccountCreateEvent(sequenceId : long, createdTime : long, accountNo : int, owner : String) + + getAccountNo() : int + + getOwner() : String + + process() + } + class MoneyDepositEvent { + - accountNo : int + - money : BigDecimal + + MoneyDepositEvent(sequenceId : long, createdTime : long, accountNo : int, money : BigDecimal) + + getAccountNo() : int + + getMoney() : BigDecimal + + process() + } + class MoneyTransferEvent { + - accountNoFrom : int + - accountNoTo : int + - money : BigDecimal + + MoneyTransferEvent(sequenceId : long, createdTime : long, money : BigDecimal, accountNoFrom : int, accountNoTo : int) + + getAccountNoFrom() : int + + getAccountNoTo() : int + + getMoney() : BigDecimal + + process() + } + class MoneyWithdrawalEvent { + - accountNo : int + - money : BigDecimal + + MoneyWithdrawalEvent(sequenceId : long, createdTime : long, accountNo : int, money : BigDecimal) + + getAccountNo() : int + + getMoney() : BigDecimal + + process() + } +} +package com.iluwatar.event.sourcing.gateway { + class AccountCreateContractSender { + + AccountCreateContractSender() + + sendContractInfo(account : Account) + } + class Gateways { + - accountCreateContractSender : AccountCreateContractSender {static} + - transactionLogger : TransactionLogger {static} + + Gateways() + + getAccountCreateContractSender() : AccountCreateContractSender {static} + + getTransactionLogger() : TransactionLogger {static} + } + class TransactionLogger { + + TransactionLogger() + + log(transaction : Transaction) + } +} +package com.iluwatar.event.sourcing.app { + class App { + + App() + + main(args : String[]) {static} + } +} +package com.iluwatar.event.sourcing.state { + class AccountAggregate { + - accounts : Map {static} + + AccountAggregate() + + getAccount(accountNo : int) : Account {static} + + putAccount(account : Account) {static} + + resetState() {static} + } +} +package com.iluwatar.event.sourcing.domain { + class Account { + - accountNo : int + - money : BigDecimal + - owner : String + - transactions : List + + Account(accountNo : int, owner : String) + + copy() : Account + - depositMoney(money : BigDecimal) : Transaction + + getAccountNo() : int + + getMoney() : BigDecimal + + getOwner() : String + + getTransactions() : List + - handleDeposit(money : BigDecimal, realTime : boolean) + + handleEvent(accountCreateEvent : AccountCreateEvent) + + handleEvent(moneyDepositEvent : MoneyDepositEvent) + + handleEvent(moneyWithdrawalEvent : MoneyWithdrawalEvent) + + handleTransferFromEvent(moneyTransferEvent : MoneyTransferEvent) + + handleTransferToEvent(moneyTransferEvent : MoneyTransferEvent) + - handleWithdrawal(money : BigDecimal, realTime : boolean) + + setMoney(money : BigDecimal) + + setTransactions(transactions : List) + + toString() : String + - withdrawMoney(money : BigDecimal) : Transaction + } + class Transaction { + - accountNo : int + - lastBalance : BigDecimal + - moneyIn : BigDecimal + - moneyOut : BigDecimal + + Transaction(accountNo : int, moneyIn : BigDecimal, moneyOut : BigDecimal, lastBalance : BigDecimal) + + getAccountNo() : int + + getLastBalance() : BigDecimal + + getMoneyIn() : BigDecimal + + getMoneyOut() : BigDecimal + + toString() : String + } +} +package com.iluwatar.event.sourcing.api { + abstract class DomainEvent { + - createdTime : long + - eventClassName : String + - realTime : boolean + - sequenceId : long + + DomainEvent(sequenceId : long, createdTime : long, eventClassName : String) + + getCreatedTime() : long + + getEventClassName() : String + + getSequenceId() : long + + isRealTime() : boolean + + process() {abstract} + + setRealTime(realTime : boolean) + } + interface EventProcessor { + + process(DomainEvent) {abstract} + + recover() {abstract} + + setPrecessorJournal(ProcessorJournal) {abstract} + } + interface ProcessorJournal { + + readNext() : DomainEvent {abstract} + + reset() {abstract} + + write(DomainEvent) {abstract} + } +} +Gateways --> "-accountCreateContractSender" AccountCreateContractSender +DomainEventProcessor --> "-precessorJournal" ProcessorJournal +Account --> "-transactions" Transaction +Gateways --> "-transactionLogger" TransactionLogger +AccountService --> "-eventProcessor" EventProcessor +MoneyTransactionService --> "-eventProcessor" EventProcessor +AccountCreateEvent --|> DomainEvent +MoneyDepositEvent --|> DomainEvent +MoneyTransferEvent --|> DomainEvent +MoneyWithdrawalEvent --|> DomainEvent +JsonFileJournal ..|> ProcessorJournal +DomainEventProcessor ..|> EventProcessor +@enduml \ No newline at end of file diff --git a/event-sourcing/src/.gitkeep b/event-sourcing/src/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java index e20d03232..693ea1755 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.api; import java.io.Serializable; @@ -6,36 +28,72 @@ import java.io.Serializable; * Created by serdarh on 06.08.2017. */ public abstract class DomainEvent implements Serializable { - private final long sequenceId; - private final long createdTime; - private boolean realTime = true; - private final String eventClassName; - public DomainEvent(long sequenceId, long createdTime, String eventClassName) { - this.sequenceId = sequenceId; - this.createdTime = createdTime; - this.eventClassName = eventClassName; - } + private final long sequenceId; + private final long createdTime; + private final String eventClassName; + private boolean realTime = true; - public long getSequenceId() { - return sequenceId; - } + /** + * Instantiates a new Domain event. + * + * @param sequenceId the sequence id + * @param createdTime the created time + * @param eventClassName the event class name + */ + public DomainEvent(long sequenceId, long createdTime, String eventClassName) { + this.sequenceId = sequenceId; + this.createdTime = createdTime; + this.eventClassName = eventClassName; + } - public long getCreatedTime() { - return createdTime; - } + /** + * Gets sequence id. + * + * @return the sequence id + */ + public long getSequenceId() { + return sequenceId; + } - public boolean isRealTime() { - return realTime; - } + /** + * Gets created time. + * + * @return the created time + */ + public long getCreatedTime() { + return createdTime; + } - public void setRealTime(boolean realTime) { - this.realTime = realTime; - } + /** + * Is real time boolean. + * + * @return the boolean + */ + public boolean isRealTime() { + return realTime; + } - public abstract void process(); + /** + * Sets real time. + * + * @param realTime the real time + */ + public void setRealTime(boolean realTime) { + this.realTime = realTime; + } - public String getEventClassName() { - return eventClassName; - } + /** + * Process. + */ + public abstract void process(); + + /** + * Gets event class name. + * + * @return the event class name + */ + public String getEventClassName() { + return eventClassName; + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java index 0fc673bf4..afa218939 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java @@ -1,10 +1,48 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.api; /** * Created by serdarh on 06.08.2017. */ public interface EventProcessor { - void process(DomainEvent domainEvent); - void setPrecessorJournal(ProcessorJournal precessorJournal); - void recover(); + + /** + * Process. + * + * @param domainEvent the domain event + */ + void process(DomainEvent domainEvent); + + /** + * Sets precessor journal. + * + * @param precessorJournal the precessor journal + */ + void setPrecessorJournal(ProcessorJournal precessorJournal); + + /** + * Recover. + */ + void recover(); } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java index 906c66247..8814b82d9 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java @@ -1,10 +1,48 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.api; /** * Created by serdarh on 06.08.2017. */ public interface ProcessorJournal { - void write(DomainEvent domainEvent); - void reset(); - DomainEvent readNext(); + + /** + * Write. + * + * @param domainEvent the domain event + */ + void write(DomainEvent domainEvent); + + /** + * Reset. + */ + void reset(); + + /** + * Read next domain event. + * + * @return the domain event + */ + DomainEvent readNext(); } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java index 8627736f1..f62cebb62 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.app; import com.iluwatar.event.sourcing.journal.JsonFileJournal; @@ -5,7 +27,6 @@ import com.iluwatar.event.sourcing.processor.DomainEventProcessor; import com.iluwatar.event.sourcing.service.AccountService; import com.iluwatar.event.sourcing.service.MoneyTransactionService; import com.iluwatar.event.sourcing.state.AccountAggregate; - import java.math.BigDecimal; /** @@ -13,46 +34,52 @@ import java.math.BigDecimal; */ public class App { - public static void main(String[] args) { - System.out.println("Running the system first time............"); + /** + * The entry point of application. + * + * @param args the input arguments + */ + public static void main(String[] args) { + System.out.println("Running the system first time............"); - DomainEventProcessor domainEventProcessor = new DomainEventProcessor(); - JsonFileJournal jsonFileJournal = new JsonFileJournal(); - jsonFileJournal.reset(); - domainEventProcessor.setPrecessorJournal(jsonFileJournal); + DomainEventProcessor domainEventProcessor = new DomainEventProcessor(); + JsonFileJournal jsonFileJournal = new JsonFileJournal(); + jsonFileJournal.reset(); + domainEventProcessor.setPrecessorJournal(jsonFileJournal); - System.out.println("Creating th accounts............"); + System.out.println("Creating th accounts............"); - AccountService accountService = new AccountService(domainEventProcessor); - MoneyTransactionService moneyTransactionService = new MoneyTransactionService(domainEventProcessor); - accountService.createAccount(1,"Daenerys Targaryen"); - accountService.createAccount(2,"Jon Snow"); + AccountService accountService = new AccountService(domainEventProcessor); + MoneyTransactionService moneyTransactionService = new MoneyTransactionService( + domainEventProcessor); + accountService.createAccount(1, "Daenerys Targaryen"); + accountService.createAccount(2, "Jon Snow"); - System.out.println("Do some money operations............"); + System.out.println("Do some money operations............"); - moneyTransactionService.depositMoney(1,new BigDecimal("100000")); - moneyTransactionService.depositMoney(2,new BigDecimal("10")); + moneyTransactionService.depositMoney(1, new BigDecimal("100000")); + moneyTransactionService.depositMoney(2, new BigDecimal("100")); - moneyTransactionService.transferMoney(1,2,new BigDecimal("10000")); - moneyTransactionService.withdrawalMoney(2, new BigDecimal("1000")); + moneyTransactionService.transferMoney(1, 2, new BigDecimal("10000")); + moneyTransactionService.withdrawalMoney(2, new BigDecimal("1000")); - System.out.println("...............State:............"); - System.out.println(AccountAggregate.getAccount(1)); - System.out.println(AccountAggregate.getAccount(2)); + System.out.println("...............State:............"); + System.out.println(AccountAggregate.getAccount(1)); + System.out.println(AccountAggregate.getAccount(2)); - System.out.println("At that point system goes down state in memory cleared............"); + System.out.println("At that point system goes down state in memory cleared............"); - AccountAggregate.resetState(); + AccountAggregate.resetState(); - System.out.println("Recover the syste by the events in journal file............"); + System.out.println("Recover the syste by the events in journal file............"); - domainEventProcessor = new DomainEventProcessor(); - jsonFileJournal = new JsonFileJournal(); - domainEventProcessor.setPrecessorJournal(jsonFileJournal); - domainEventProcessor.recover(); + domainEventProcessor = new DomainEventProcessor(); + jsonFileJournal = new JsonFileJournal(); + domainEventProcessor.setPrecessorJournal(jsonFileJournal); + domainEventProcessor.recover(); - System.out.println("...............State Recovered:............"); - System.out.println(AccountAggregate.getAccount(1)); - System.out.println(AccountAggregate.getAccount(2)); - } + System.out.println("...............State Recovered:............"); + System.out.println(AccountAggregate.getAccount(1)); + System.out.println(AccountAggregate.getAccount(2)); + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java index 48cda1eca..9e1bc560e 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.domain; import com.iluwatar.event.sourcing.event.AccountCreateEvent; @@ -6,7 +28,6 @@ import com.iluwatar.event.sourcing.event.MoneyTransferEvent; import com.iluwatar.event.sourcing.event.MoneyWithdrawalEvent; import com.iluwatar.event.sourcing.gateway.Gateways; import com.iluwatar.event.sourcing.state.AccountAggregate; - import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; @@ -15,116 +36,184 @@ import java.util.List; * Created by serdarh on 06.08.2017. */ public class Account { - private final int accountNo; - private final String owner; - private BigDecimal money; - private List transactions; - public Account(int accountNo, String owner) { - this.accountNo = accountNo; - this.owner = owner; - money = BigDecimal.ZERO; - transactions = new ArrayList<>(); + private final int accountNo; + private final String owner; + private BigDecimal money; + private List transactions; + + /** + * Instantiates a new Account. + * + * @param accountNo the account no + * @param owner the owner + */ + public Account(int accountNo, String owner) { + this.accountNo = accountNo; + this.owner = owner; + money = BigDecimal.ZERO; + transactions = new ArrayList<>(); + } + + /** + * Gets account no. + * + * @return the account no + */ + public int getAccountNo() { + return accountNo; + } + + /** + * Gets owner. + * + * @return the owner + */ + public String getOwner() { + return owner; + } + + /** + * Gets money. + * + * @return the money + */ + public BigDecimal getMoney() { + return money; + } + + /** + * Sets money. + * + * @param money the money + */ + public void setMoney(BigDecimal money) { + this.money = money; + } + + /** + * Gets transactions. + * + * @return the transactions + */ + public List getTransactions() { + return transactions; + } + + /** + * Sets transactions. + * + * @param transactions the transactions + */ + public void setTransactions(List transactions) { + this.transactions = transactions; + } + + /** + * Copy account. + * + * @return the account + */ + public Account copy() { + Account account = new Account(accountNo, owner); + account.setMoney(money); + account.setTransactions(transactions); + return account; + } + + @Override + public String toString() { + return "Account{" + + "accountNo=" + accountNo + + ", owner='" + owner + '\'' + + ", money=" + money + + ", transactions=" + transactions + + '}'; + } + + private Transaction depositMoney(BigDecimal money) { + this.money = this.money.add(money); + Transaction transaction = new Transaction(accountNo, money, BigDecimal.ZERO, this.money); + transactions.add(transaction); + return transaction; + } + + private Transaction withdrawMoney(BigDecimal money) { + this.money = this.money.subtract(money); + Transaction transaction = new Transaction(accountNo, BigDecimal.ZERO, money, this.money); + transactions.add(transaction); + return transaction; + } + + private void handleDeposit(BigDecimal money, boolean realTime) { + Transaction transaction = depositMoney(money); + AccountAggregate.putAccount(this); + if (realTime) { + Gateways.getTransactionLogger().log(transaction); + } + } + + private void handleWithdrawal(BigDecimal money, boolean realTime) { + if (this.money.compareTo(money) == -1) { + throw new RuntimeException("Insufficient Account Balance"); } - public int getAccountNo() { - return accountNo; + Transaction transaction = withdrawMoney(money); + AccountAggregate.putAccount(this); + if (realTime) { + Gateways.getTransactionLogger().log(transaction); } + } - public String getOwner() { - return owner; + /** + * Handle event. + * + * @param moneyDepositEvent the money deposit event + */ + public void handleEvent(MoneyDepositEvent moneyDepositEvent) { + handleDeposit(moneyDepositEvent.getMoney(), moneyDepositEvent.isRealTime()); + } + + + /** + * Handle event. + * + * @param moneyWithdrawalEvent the money withdrawal event + */ + public void handleEvent(MoneyWithdrawalEvent moneyWithdrawalEvent) { + handleWithdrawal(moneyWithdrawalEvent.getMoney(), moneyWithdrawalEvent.isRealTime()); + } + + /** + * Handle event. + * + * @param accountCreateEvent the account create event + */ + public void handleEvent(AccountCreateEvent accountCreateEvent) { + AccountAggregate.putAccount(this); + // check if this event is replicated from journal before calling an external gateway function + if (accountCreateEvent.isRealTime()) { + Gateways.getAccountCreateContractSender().sendContractInfo(this); } + } - public BigDecimal getMoney() { - return money; - } + /** + * Handle transfer from event. + * + * @param moneyTransferEvent the money transfer event + */ + public void handleTransferFromEvent(MoneyTransferEvent moneyTransferEvent) { + handleWithdrawal(moneyTransferEvent.getMoney(), moneyTransferEvent.isRealTime()); + } - public List getTransactions() { - return transactions; - } - - public void setMoney(BigDecimal money) { - this.money = money; - } - - public void setTransactions(List transactions) { - this.transactions = transactions; - } - - public Account copy() { - Account account = new Account(accountNo, owner); - account.setMoney(money); - account.setTransactions(transactions); - return account; - } - - @Override - public String toString() { - return "Account{" + - "accountNo=" + accountNo + - ", owner='" + owner + '\'' + - ", money=" + money + - ", transactions=" + transactions + - '}'; - } - - private Transaction depositMoney(BigDecimal money) { - this.money = this.money.add(money); - Transaction transaction = new Transaction(accountNo,money,BigDecimal.ZERO,this.money); - transactions.add(transaction); - return transaction; - } - - private Transaction withdrawMoney(BigDecimal money) { - this.money = this.money.subtract(money); - Transaction transaction = new Transaction(accountNo,BigDecimal.ZERO,money,this.money); - transactions.add(transaction); - return transaction; - } - - private void handleDeposit(BigDecimal money,boolean realTime) { - Transaction transaction = depositMoney(money); - AccountAggregate.putAccount(this); - if(realTime) { - Gateways.getTransactionLogger().log(transaction); - } - } - - private void handleWithdrawal(BigDecimal money, boolean realTime) { - if(this.money.compareTo(money)==-1){ - throw new RuntimeException("Insufficient Account Balance"); - } - - Transaction transaction = withdrawMoney(money); - AccountAggregate.putAccount(this); - if(realTime) { - Gateways.getTransactionLogger().log(transaction); - } - } - - public void handleEvent(MoneyDepositEvent moneyDepositEvent) { - handleDeposit(moneyDepositEvent.getMoney(),moneyDepositEvent.isRealTime()); - } + /** + * Handle transfer to event. + * + * @param moneyTransferEvent the money transfer event + */ + public void handleTransferToEvent(MoneyTransferEvent moneyTransferEvent) { + handleDeposit(moneyTransferEvent.getMoney(), moneyTransferEvent.isRealTime()); + } - public void handleEvent(MoneyWithdrawalEvent moneyWithdrawalEvent) { - handleWithdrawal(moneyWithdrawalEvent.getMoney(),moneyWithdrawalEvent.isRealTime()); - } - - - public void handleTransferFromEvent(MoneyTransferEvent moneyTransferEvent) { - handleWithdrawal(moneyTransferEvent.getMoney(),moneyTransferEvent.isRealTime()); - } - - public void handleTransferToEvent(MoneyTransferEvent moneyTransferEvent) { - handleDeposit(moneyTransferEvent.getMoney(),moneyTransferEvent.isRealTime()); - } - - public void handleEvent(AccountCreateEvent accountCreateEvent) { - AccountAggregate.putAccount(this); - // check if this event is replicated from journal before calling an external gateway function - if(accountCreateEvent.isRealTime()) { - Gateways.getAccountCreateContractSender().sendContractInfo(this); - } - } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java index 557efbedc..29cdc4d15 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.domain; import java.math.BigDecimal; @@ -6,41 +28,71 @@ import java.math.BigDecimal; * Created by serdarh on 06.08.2017. */ public class Transaction { - private final int accountNo; - private final BigDecimal moneyIn; - private final BigDecimal moneyOut; - private final BigDecimal lastBalance; - public Transaction(int accountNo, BigDecimal moneyIn, BigDecimal moneyOut, BigDecimal lastBalance) { - this.accountNo = accountNo; - this.moneyIn = moneyIn; - this.moneyOut = moneyOut; - this.lastBalance = lastBalance; - } + private final int accountNo; + private final BigDecimal moneyIn; + private final BigDecimal moneyOut; + private final BigDecimal lastBalance; - public int getAccountNo() { - return accountNo; - } + /** + * Instantiates a new Transaction. + * + * @param accountNo the account no + * @param moneyIn the money in + * @param moneyOut the money out + * @param lastBalance the last balance + */ + public Transaction(int accountNo, BigDecimal moneyIn, BigDecimal moneyOut, + BigDecimal lastBalance) { + this.accountNo = accountNo; + this.moneyIn = moneyIn; + this.moneyOut = moneyOut; + this.lastBalance = lastBalance; + } - public BigDecimal getMoneyIn() { - return moneyIn; - } + /** + * Gets account no. + * + * @return the account no + */ + public int getAccountNo() { + return accountNo; + } - public BigDecimal getMoneyOut() { - return moneyOut; - } + /** + * Gets money in. + * + * @return the money in + */ + public BigDecimal getMoneyIn() { + return moneyIn; + } - public BigDecimal getLastBalance() { - return lastBalance; - } + /** + * Gets money out. + * + * @return the money out + */ + public BigDecimal getMoneyOut() { + return moneyOut; + } - @Override - public String toString() { - return "Transaction{" + - "accountNo=" + accountNo + - ", moneyIn=" + moneyIn + - ", moneyOut=" + moneyOut + - ", lastBalance=" + lastBalance + - '}'; - } + /** + * Gets last balance. + * + * @return the last balance + */ + public BigDecimal getLastBalance() { + return lastBalance; + } + + @Override + public String toString() { + return "Transaction{" + + "accountNo=" + accountNo + + ", moneyIn=" + moneyIn + + ", moneyOut=" + moneyOut + + ", lastBalance=" + lastBalance + + '}'; + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java index 1ea089e2f..8356cd3e8 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.event; import com.iluwatar.event.sourcing.api.DomainEvent; @@ -8,30 +30,49 @@ import com.iluwatar.event.sourcing.state.AccountAggregate; * Created by serdarh on 06.08.2017. */ public class AccountCreateEvent extends DomainEvent { - private final int accountNo; - private final String owner; - public AccountCreateEvent(long sequenceId, long createdTime, int accountNo, String owner) { - super(sequenceId, createdTime, "AccountCreateEvent"); - this.accountNo = accountNo; - this.owner = owner; - } + private final int accountNo; + private final String owner; - public int getAccountNo() { - return accountNo; - } + /** + * Instantiates a new Account create event. + * + * @param sequenceId the sequence id + * @param createdTime the created time + * @param accountNo the account no + * @param owner the owner + */ + public AccountCreateEvent(long sequenceId, long createdTime, int accountNo, String owner) { + super(sequenceId, createdTime, "AccountCreateEvent"); + this.accountNo = accountNo; + this.owner = owner; + } - public String getOwner() { - return owner; - } + /** + * Gets account no. + * + * @return the account no + */ + public int getAccountNo() { + return accountNo; + } - @Override - public void process() { - Account account = AccountAggregate.getAccount(accountNo); - if(account!=null){ - throw new RuntimeException("Account already exists"); - } - account = new Account(accountNo,owner); - account.handleEvent(this); + /** + * Gets owner. + * + * @return the owner + */ + public String getOwner() { + return owner; + } + + @Override + public void process() { + Account account = AccountAggregate.getAccount(accountNo); + if (account != null) { + throw new RuntimeException("Account already exists"); } + account = new Account(accountNo, owner); + account.handleEvent(this); + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java index 384a9e198..9d73639eb 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java @@ -1,38 +1,78 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.event; import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; - import java.math.BigDecimal; /** * Created by serdarh on 06.08.2017. */ public class MoneyDepositEvent extends DomainEvent { - private BigDecimal money; - private int accountNo; - public MoneyDepositEvent(long sequenceId, long createdTime, int accountNo,BigDecimal money) { - super(sequenceId, createdTime, "MoneyDepositEvent"); - this.money = money; - this.accountNo = accountNo; - } + private BigDecimal money; + private int accountNo; - public BigDecimal getMoney() { - return money; - } + /** + * Instantiates a new Money deposit event. + * + * @param sequenceId the sequence id + * @param createdTime the created time + * @param accountNo the account no + * @param money the money + */ + public MoneyDepositEvent(long sequenceId, long createdTime, int accountNo, BigDecimal money) { + super(sequenceId, createdTime, "MoneyDepositEvent"); + this.money = money; + this.accountNo = accountNo; + } - public int getAccountNo() { - return accountNo; - } + /** + * Gets money. + * + * @return the money + */ + public BigDecimal getMoney() { + return money; + } - @Override - public void process() { - Account account = AccountAggregate.getAccount(accountNo); - if(account==null){ - throw new RuntimeException("Account not found"); - } - account.handleEvent(this); + /** + * Gets account no. + * + * @return the account no + */ + public int getAccountNo() { + return accountNo; + } + + @Override + public void process() { + Account account = AccountAggregate.getAccount(accountNo); + if (account == null) { + throw new RuntimeException("Account not found"); } + account.handleEvent(this); + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java index 6c873d4db..995fb9326 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java @@ -1,50 +1,97 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.event; import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; - import java.math.BigDecimal; /** * Created by serdarh on 06.08.2017. */ public class MoneyTransferEvent extends DomainEvent { - private BigDecimal money; - private int accountNoFrom; - private int accountNoTo; - public MoneyTransferEvent(long sequenceId, long createdTime, BigDecimal money, int accountNoFrom, int accountNoTo) { - super(sequenceId, createdTime, "MoneyTransferEvent"); - this.money = money; - this.accountNoFrom = accountNoFrom; - this.accountNoTo = accountNoTo; + private BigDecimal money; + private int accountNoFrom; + private int accountNoTo; + + /** + * Instantiates a new Money transfer event. + * + * @param sequenceId the sequence id + * @param createdTime the created time + * @param money the money + * @param accountNoFrom the account no from + * @param accountNoTo the account no to + */ + public MoneyTransferEvent(long sequenceId, long createdTime, BigDecimal money, int accountNoFrom, + int accountNoTo) { + super(sequenceId, createdTime, "MoneyTransferEvent"); + this.money = money; + this.accountNoFrom = accountNoFrom; + this.accountNoTo = accountNoTo; + } + + /** + * Gets money. + * + * @return the money + */ + public BigDecimal getMoney() { + return money; + } + + /** + * Gets account no from. + * + * @return the account no from + */ + public int getAccountNoFrom() { + return accountNoFrom; + } + + /** + * Gets account no to. + * + * @return the account no to + */ + public int getAccountNoTo() { + return accountNoTo; + } + + @Override + public void process() { + Account accountFrom = AccountAggregate.getAccount(accountNoFrom); + if (accountFrom == null) { + throw new RuntimeException("Account not found " + accountNoFrom); + } + Account accountTo = AccountAggregate.getAccount(accountNoTo); + if (accountTo == null) { + throw new RuntimeException("Account not found" + accountTo); } - public BigDecimal getMoney() { - return money; - } - - public int getAccountNoFrom() { - return accountNoFrom; - } - - public int getAccountNoTo() { - return accountNoTo; - } - - @Override - public void process() { - Account accountFrom = AccountAggregate.getAccount(accountNoFrom); - if(accountFrom==null){ - throw new RuntimeException("Account not found "+accountNoFrom); - } - Account accountTo = AccountAggregate.getAccount(accountNoTo); - if(accountTo==null){ - throw new RuntimeException("Account not found"+ accountTo); - } - - accountFrom.handleTransferFromEvent(this); - accountTo.handleTransferToEvent(this); - } + accountFrom.handleTransferFromEvent(this); + accountTo.handleTransferToEvent(this); + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java index 8ed617008..64fddc16e 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java @@ -1,38 +1,78 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.event; import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; - import java.math.BigDecimal; /** * Created by serdarh on 06.08.2017. */ public class MoneyWithdrawalEvent extends DomainEvent { - private BigDecimal money; - private int accountNo; - public MoneyWithdrawalEvent(long sequenceId, long createdTime, int accountNo,BigDecimal money) { - super(sequenceId, createdTime, "MoneyWithdrawalEvent"); - this.money = money; - this.accountNo = accountNo; - } + private BigDecimal money; + private int accountNo; - public BigDecimal getMoney() { - return money; - } + /** + * Instantiates a new Money withdrawal event. + * + * @param sequenceId the sequence id + * @param createdTime the created time + * @param accountNo the account no + * @param money the money + */ + public MoneyWithdrawalEvent(long sequenceId, long createdTime, int accountNo, BigDecimal money) { + super(sequenceId, createdTime, "MoneyWithdrawalEvent"); + this.money = money; + this.accountNo = accountNo; + } - public int getAccountNo() { - return accountNo; - } + /** + * Gets money. + * + * @return the money + */ + public BigDecimal getMoney() { + return money; + } - @Override - public void process() { - Account account = AccountAggregate.getAccount(accountNo); - if(account==null){ - throw new RuntimeException("Account not found"); - } - account.handleEvent(this); + /** + * Gets account no. + * + * @return the account no + */ + public int getAccountNo() { + return accountNo; + } + + @Override + public void process() { + Account account = AccountAggregate.getAccount(accountNo); + if (account == null) { + throw new RuntimeException("Account not found"); } + account.handleEvent(this); + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java index 42dfccf7b..aa15f746f 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.gateway; import com.iluwatar.event.sourcing.domain.Account; @@ -6,7 +28,13 @@ import com.iluwatar.event.sourcing.domain.Account; * Created by serdarh on 06.08.2017. */ public class AccountCreateContractSender { - public void sendContractInfo(Account account){ - // an example imaginary funciton which sends account info to some external end point - } + + /** + * Send contract info. + * + * @param account the account + */ + public void sendContractInfo(Account account) { + // an example imaginary funciton which sends account info to some external end point + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java index d167393bf..932338c32 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java @@ -1,17 +1,50 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.gateway; /** * Created by serdarh on 06.08.2017. */ public class Gateways { - private static AccountCreateContractSender accountCreateContractSender = new AccountCreateContractSender(); - private static TransactionLogger transactionLogger = new TransactionLogger(); - public static AccountCreateContractSender getAccountCreateContractSender() { - return accountCreateContractSender; - } + private static AccountCreateContractSender accountCreateContractSender = new AccountCreateContractSender(); + private static TransactionLogger transactionLogger = new TransactionLogger(); - public static TransactionLogger getTransactionLogger() { - return transactionLogger; - } + /** + * Gets account create contract sender. + * + * @return the account create contract sender + */ + public static AccountCreateContractSender getAccountCreateContractSender() { + return accountCreateContractSender; + } + + /** + * Gets transaction logger. + * + * @return the transaction logger + */ + public static TransactionLogger getTransactionLogger() { + return transactionLogger; + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java index 6d961d96e..3cfea0751 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.gateway; import com.iluwatar.event.sourcing.domain.Transaction; @@ -6,7 +28,13 @@ import com.iluwatar.event.sourcing.domain.Transaction; * Created by serdarh on 06.08.2017. */ public class TransactionLogger { - public void log(Transaction transaction) { - // example imaginary function that logs the transaction to somewhere - } + + /** + * Log. + * + * @param transaction the transaction + */ + public void log(Transaction transaction) { + // example imaginary function that logs the transaction to somewhere + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java index 2d50db55f..a5d82e5be 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.journal; import com.google.gson.Gson; @@ -9,91 +31,104 @@ import com.iluwatar.event.sourcing.event.AccountCreateEvent; import com.iluwatar.event.sourcing.event.MoneyDepositEvent; import com.iluwatar.event.sourcing.event.MoneyTransferEvent; import com.iluwatar.event.sourcing.event.MoneyWithdrawalEvent; - -import java.io.*; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.util.ArrayList; import java.util.List; /** * Created by serdarh on 06.08.2017. */ -public class JsonFileJournal implements ProcessorJournal{ +public class JsonFileJournal implements ProcessorJournal { - private File aFile; - private List events = new ArrayList<>(); - private int index = 0; - public JsonFileJournal() { - aFile = new File("Journal.json"); - if(aFile.exists()) { - try (BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(aFile), "UTF-8"))) { - String line; - while ((line = input.readLine()) != null) { - events.add(line); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - }else{ - reset(); + private File aFile; + private List events = new ArrayList<>(); + private int index = 0; + + /** + * Instantiates a new Json file journal. + */ + public JsonFileJournal() { + aFile = new File("Journal.json"); + if (aFile.exists()) { + try (BufferedReader input = new BufferedReader( + new InputStreamReader(new FileInputStream(aFile), "UTF-8"))) { + String line; + while ((line = input.readLine()) != null) { + events.add(line); } + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + reset(); + } + } + + @Override + public void write(DomainEvent domainEvent) { + Gson gson = new Gson(); + JsonElement jsonElement; + if (domainEvent instanceof AccountCreateEvent) { + jsonElement = gson.toJsonTree(domainEvent, AccountCreateEvent.class); + } else if (domainEvent instanceof MoneyDepositEvent) { + jsonElement = gson.toJsonTree(domainEvent, MoneyDepositEvent.class); + } else if (domainEvent instanceof MoneyWithdrawalEvent) { + jsonElement = gson.toJsonTree(domainEvent, MoneyWithdrawalEvent.class); + } else if (domainEvent instanceof MoneyTransferEvent) { + jsonElement = gson.toJsonTree(domainEvent, MoneyTransferEvent.class); + } else { + throw new RuntimeException("Journal Event not recegnized"); } - @Override - public void write(DomainEvent domainEvent) { - Gson gson = new Gson(); - JsonElement jsonElement; - if(domainEvent instanceof AccountCreateEvent) { - jsonElement = gson.toJsonTree(domainEvent, AccountCreateEvent.class); - }else if(domainEvent instanceof MoneyDepositEvent) { - jsonElement = gson.toJsonTree(domainEvent, MoneyDepositEvent.class); - }else if(domainEvent instanceof MoneyWithdrawalEvent) { - jsonElement = gson.toJsonTree(domainEvent, MoneyWithdrawalEvent.class); - }else if(domainEvent instanceof MoneyTransferEvent) { - jsonElement = gson.toJsonTree(domainEvent, MoneyTransferEvent.class); - }else{ - throw new RuntimeException("Journal Event not recegnized"); - } + try (Writer output = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(aFile, true), "UTF-8"))) { + String eventString = jsonElement.toString(); + output.write(eventString + "\r\n"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } - try (Writer output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(aFile, true), "UTF-8"))) { - String eventString = jsonElement.toString(); - output.write(eventString +"\r\n"); - } catch (IOException e) { - throw new RuntimeException(e); - } + @Override + public void reset() { + aFile.delete(); + } + + + @Override + public DomainEvent readNext() { + if (index >= events.size()) { + return null; + } + String event = events.get(index); + index++; + + JsonParser parser = new JsonParser(); + JsonElement jsonElement = parser.parse(event); + String eventClassName = jsonElement.getAsJsonObject().get("eventClassName").getAsString(); + Gson gson = new Gson(); + DomainEvent domainEvent; + if (eventClassName.equals("AccountCreateEvent")) { + domainEvent = gson.fromJson(jsonElement, AccountCreateEvent.class); + } else if (eventClassName.equals("MoneyDepositEvent")) { + domainEvent = gson.fromJson(jsonElement, MoneyDepositEvent.class); + } else if (eventClassName.equals("MoneyTransferEvent")) { + domainEvent = gson.fromJson(jsonElement, MoneyTransferEvent.class); + } else if (eventClassName.equals("MoneyWithdrawalEvent")) { + domainEvent = gson.fromJson(jsonElement, MoneyWithdrawalEvent.class); + } else { + throw new RuntimeException("Journal Event not recegnized"); } - @Override - public void reset() { - aFile.delete(); - } - - - @Override - public DomainEvent readNext() { - if(index>=events.size()){ - return null; - } - String event = events.get(index); - index++; - - JsonParser parser = new JsonParser(); - JsonElement jsonElement = parser.parse(event); - String eventClassName = jsonElement.getAsJsonObject().get("eventClassName").getAsString(); - Gson gson = new Gson(); - DomainEvent domainEvent; - if(eventClassName.equals("AccountCreateEvent")) { - domainEvent = gson.fromJson(jsonElement, AccountCreateEvent.class); - }else if(eventClassName.equals("MoneyDepositEvent")) { - domainEvent = gson.fromJson(jsonElement, MoneyDepositEvent.class); - }else if(eventClassName.equals("MoneyTransferEvent")) { - domainEvent = gson.fromJson(jsonElement, MoneyTransferEvent.class); - }else if(eventClassName.equals("MoneyWithdrawalEvent")) { - domainEvent = gson.fromJson(jsonElement, MoneyWithdrawalEvent.class); - }else{ - throw new RuntimeException("Journal Event not recegnized"); - } - - domainEvent.setRealTime(false); - return domainEvent; - } + domainEvent.setRealTime(false); + return domainEvent; + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java index 55453b1c6..81ec2e761 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.processor; import com.iluwatar.event.sourcing.api.DomainEvent; @@ -9,29 +31,29 @@ import com.iluwatar.event.sourcing.api.ProcessorJournal; */ public class DomainEventProcessor implements EventProcessor { - private ProcessorJournal precessorJournal; + private ProcessorJournal precessorJournal; - @Override - public void process(DomainEvent domainEvent) { - domainEvent.process(); - precessorJournal.write(domainEvent); - } + @Override + public void process(DomainEvent domainEvent) { + domainEvent.process(); + precessorJournal.write(domainEvent); + } - @Override - public void setPrecessorJournal(ProcessorJournal precessorJournal) { - this.precessorJournal = precessorJournal; - } + @Override + public void setPrecessorJournal(ProcessorJournal precessorJournal) { + this.precessorJournal = precessorJournal; + } - @Override - public void recover() { - DomainEvent domainEvent; - while(true) { - domainEvent = precessorJournal.readNext(); - if(domainEvent==null){ - break; - }else{ - domainEvent.process(); - } - } + @Override + public void recover() { + DomainEvent domainEvent; + while (true) { + domainEvent = precessorJournal.readNext(); + if (domainEvent == null) { + break; + } else { + domainEvent.process(); + } } + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java index b0a707788..59cefaaee 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java @@ -1,22 +1,56 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.service; import com.iluwatar.event.sourcing.api.EventProcessor; import com.iluwatar.event.sourcing.event.AccountCreateEvent; - import java.util.Date; /** * Created by serdarh on 06.08.2017. */ public class AccountService { - private EventProcessor eventProcessor; - public AccountService(EventProcessor eventProcessor) { - this.eventProcessor = eventProcessor; - } + private EventProcessor eventProcessor; - public void createAccount(int accountNo, String owner){ - AccountCreateEvent accountCreateEvent = new AccountCreateEvent(SequenceIdGenerator.nextSequenceId(), new Date().getTime(),accountNo,owner); - eventProcessor.process(accountCreateEvent); - } + /** + * Instantiates a new Account service. + * + * @param eventProcessor the event processor + */ + public AccountService(EventProcessor eventProcessor) { + this.eventProcessor = eventProcessor; + } + + /** + * Create account. + * + * @param accountNo the account no + * @param owner the owner + */ + public void createAccount(int accountNo, String owner) { + AccountCreateEvent accountCreateEvent = new AccountCreateEvent( + SequenceIdGenerator.nextSequenceId(), new Date().getTime(), accountNo, owner); + eventProcessor.process(accountCreateEvent); + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java index 80c2a5a4f..5f7c0e9c7 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java @@ -1,10 +1,31 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.service; import com.iluwatar.event.sourcing.api.EventProcessor; import com.iluwatar.event.sourcing.event.MoneyDepositEvent; import com.iluwatar.event.sourcing.event.MoneyTransferEvent; import com.iluwatar.event.sourcing.event.MoneyWithdrawalEvent; - import java.math.BigDecimal; import java.util.Date; @@ -12,24 +33,53 @@ import java.util.Date; * Created by serdarh on 06.08.2017. */ public class MoneyTransactionService { - private EventProcessor eventProcessor; - public MoneyTransactionService(EventProcessor eventProcessor) { - this.eventProcessor = eventProcessor; - } + private EventProcessor eventProcessor; - public void depositMoney(int accountNo, BigDecimal money){ - MoneyDepositEvent moneyDepositEvent = new MoneyDepositEvent(SequenceIdGenerator.nextSequenceId(), new Date().getTime(), accountNo, money); - eventProcessor.process(moneyDepositEvent); - } + /** + * Instantiates a new Money transaction service. + * + * @param eventProcessor the event processor + */ + public MoneyTransactionService(EventProcessor eventProcessor) { + this.eventProcessor = eventProcessor; + } - public void withdrawalMoney(int accountNo, BigDecimal money){ - MoneyWithdrawalEvent moneyWithdrawalEvent = new MoneyWithdrawalEvent(SequenceIdGenerator.nextSequenceId(), new Date().getTime(), accountNo, money); - eventProcessor.process(moneyWithdrawalEvent); - } + /** + * Deposit money. + * + * @param accountNo the account no + * @param money the money + */ + public void depositMoney(int accountNo, BigDecimal money) { + MoneyDepositEvent moneyDepositEvent = new MoneyDepositEvent( + SequenceIdGenerator.nextSequenceId(), new Date().getTime(), accountNo, money); + eventProcessor.process(moneyDepositEvent); + } - public void transferMoney(int accountNoFrom, int accountNoTo, BigDecimal money){ - MoneyTransferEvent moneyTransferEvent = new MoneyTransferEvent(SequenceIdGenerator.nextSequenceId(), new Date().getTime(), money, accountNoFrom, accountNoTo); - eventProcessor.process(moneyTransferEvent); - } + /** + * Withdrawal money. + * + * @param accountNo the account no + * @param money the money + */ + public void withdrawalMoney(int accountNo, BigDecimal money) { + MoneyWithdrawalEvent moneyWithdrawalEvent = new MoneyWithdrawalEvent( + SequenceIdGenerator.nextSequenceId(), new Date().getTime(), accountNo, money); + eventProcessor.process(moneyWithdrawalEvent); + } + + /** + * Transfer money. + * + * @param accountNoFrom the account no from + * @param accountNoTo the account no to + * @param money the money + */ + public void transferMoney(int accountNoFrom, int accountNoTo, BigDecimal money) { + MoneyTransferEvent moneyTransferEvent = new MoneyTransferEvent( + SequenceIdGenerator.nextSequenceId(), new Date().getTime(), money, accountNoFrom, + accountNoTo); + eventProcessor.process(moneyTransferEvent); + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java index 2eec6a70d..6e1730679 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java @@ -1,14 +1,42 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.service; /** * Created by serdarh on 06.08.2017. */ public class SequenceIdGenerator { - private static long sequenceId = 0L; - public static long nextSequenceId(){ - sequenceId++; - return sequenceId; - } + private static long sequenceId = 0L; + + /** + * Next sequence id long. + * + * @return the long + */ + public static long nextSequenceId() { + sequenceId++; + return sequenceId; + } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java index b927af0e1..a42826160 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java @@ -1,7 +1,28 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.event.sourcing.state; import com.iluwatar.event.sourcing.domain.Account; - import java.util.HashMap; import java.util.Map; @@ -9,21 +30,36 @@ import java.util.Map; * Created by serdarh on 06.08.2017. */ public class AccountAggregate { - private static Map accounts = new HashMap<>(); - public static void putAccount(Account account){ - accounts.put(account.getAccountNo(), account); - } + private static Map accounts = new HashMap<>(); - public static Account getAccount(int accountNo){ - Account account = accounts.get(accountNo); - if(account == null){ - return null; - } - return account.copy(); - } + /** + * Put account. + * + * @param account the account + */ + public static void putAccount(Account account) { + accounts.put(account.getAccountNo(), account); + } - public static void resetState(){ - accounts = new HashMap<>(); + /** + * Gets account. + * + * @param accountNo the account no + * @return the account + */ + public static Account getAccount(int accountNo) { + Account account = accounts.get(accountNo); + if (account == null) { + return null; } + return account.copy(); + } + + /** + * Reset state. + */ + public static void resetState() { + accounts = new HashMap<>(); + } } From eb2a232382f2de3eee5d9a288e67b2ab1c90af44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serdar=20Hamzao=C4=9Fullar=C4=B1?= Date: Sun, 13 Aug 2017 01:36:52 +0300 Subject: [PATCH 18/45] README edited --- event-sourcing/README.md | 16 +- event-sourcing/etc/event-sourcing.png | Bin 0 -> 105812 bytes event-sourcing/etc/event-sourcing.ucls | 263 +++++++++++++++++++++++++ 3 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 event-sourcing/etc/event-sourcing.png create mode 100644 event-sourcing/etc/event-sourcing.ucls diff --git a/event-sourcing/README.md b/event-sourcing/README.md index c513d2da9..1079405fa 100644 --- a/event-sourcing/README.md +++ b/event-sourcing/README.md @@ -3,7 +3,7 @@ layout: pattern title: Event Sourcing folder: event-sourcing permalink: /patterns/event-sourcing/ -categories: Concurrency +categories: Architectural tags: - Java - Difficulty Intermediate @@ -11,11 +11,23 @@ tags: --- ## Intent +Instead of storing just the current state of the data in a domain, use an append-only store to record the full series of actions taken on that data. The store acts as the system of record and can be used to materialize the domain objects. This can simplify tasks in complex domains, by avoiding the need to synchronize the data model and the business domain, while improving performance, scalability, and responsiveness. It can also provide consistency for transactional data, and maintain full audit trails and history that can enable compensating actions. + +![alt text](./etc/event-sourcing.png "Event Sourcing") ## Applicability Use the Event Sourcing pattern when -* You have a limited accesibility resource and the asynchronous process is acceptable to reach that +* You need very high performance on persisting your application state even your application state have a complex relational data structure +* You need log of changes of your application state and ability to restore a state of any moment in time. +* You need to debug production problems by replaying the past events. + +## Real world examples + +* [The Lmax Architecture] (https://martinfowler.com/articles/lmax.html) ## Credits +* [Martin Fowler - Event Sourcing] (https://martinfowler.com/eaaDev/EventSourcing.html) +* [Event Sourcing | Microsoft Docs] (https://docs.microsoft.com/en-us/azure/architecture/patterns/event-sourcing) +* [Reference 3: Introducing Event Sourcing] (https://msdn.microsoft.com/en-us/library/jj591559.aspx) diff --git a/event-sourcing/etc/event-sourcing.png b/event-sourcing/etc/event-sourcing.png new file mode 100644 index 0000000000000000000000000000000000000000..ac7192b195fb67b1d67c1b5c0e5fcc3a5cfd6fb0 GIT binary patch literal 105812 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 M|6O9HyGJ!3|Bxmyy?LP zdd*-~!N2`v4K#81!%=lBjSg(59Qpz{{nDPg>>&nlnm=VE2yJFf8nelT9MqtM{Dpey z8M~QxGjEW`)A-S;SaM*)EfVa7gJy7AkYakJya-8hJj5pY*%E~Emk9L9Cm;DZh2v)nH``U=?&oS zK_@xj(75?Ys6W&iGhWi$e90DCD|FDz1sOj_GhA|A`m^SBF!O%^;w!S$F?jRdm4rzh#L3tDpY=i5{LHK$)qcid+iLL8+6yF`?E@4(97m zvlK44(v}rnr}_&%AILvtH0^d9`xZS-z9{v7sGbaz1n~A>2OAz|^uD;8?g81OZ9ox9 zrqWwQcUDce!`dB`+y>UqJyyeB4=W*oPp2+bc>x(My zDrb4Nn_PA~dkVBD6QFa^X2kGWP=u9S&4#gzYrn2`znomr0q%}3xhey<08*sSi$2HF zud3&|bl}3ZJ8|)QVSc0+oG23sctyABF`bygMY(!F?8##kQZczNZi!tWm5TU3@h|?X zTK`Ysr_~(DOzMO8JM-9eAO;=v%cQ1R?KXyWs>jh;GYTP;FKFga516nPD4TYZo&=@Z z+WvUKwK`SseHQ?)|2Uli3>s}1b2_gUb&yKPSWUm;NH8XIo02MNQ$(bF_WY!V*2~aN ziX>|{`Ca)`!Hwsn5|ea}0p z=KKLt0s1!lVXE52;0GmD!G6Y520)i&U82FjflL!tb{o%uUHTwaKBc)U0bFiCDB1np zR-%k4-*VSjEpvo;1YM{)$&p9ivJclb90w>B3V5Fl1{Oi9%ZO-B#RZh|2XBDZ4fNK=89y2q zA;x%v9V&3xorFP#i4Jpb<&=R>r)IL}#xe}AancBI>Mm5%j161R8O(s<1y=0|-DDHG zAr(zv-~lY{;&;W6%wkwi$U+J+_)U_L&$%G|vn{}wIBFtJOFMg^Lu-a;? z4kBD*JZ!qM-CBI=?jk3V>*9zLFp~%RI931=xs~qMbJ8`1ybRR%f`iJWW!6CR1*5Jr zt!*o*R#ErUqeERb-J_DEK}Ll1CBv-jav@ub%?A!rshvaUm-_poXufC)H3jUtaz+#-fx{p=)}POnhm5^@!#FWl7El? z26W%xk^@$uD*%)LPkw@F`9#5KZUQ`?c>3)k_ZsB3^UnU3!pp ziQ5#jix2tvTE4-*ef>KCBE~1K%g-pPrz{I0v%p$xwgZv%m z*}>hVoFRH}EeWSp6C=Jpmr_i@518EDckK~?LnrTMx*k)Naf65GV`Wyput{2|9jmuB zt9cxi`lH=-28h;Pb2H`4y?^<0cYh@Aj_DIOCE7BDVyzwq`?P*~o|qu+M2BIWDbQ-_ zjMPzSLECsnD4!R!<_5{bG>p zq@UhK&LM-nn-lJI7^E}eAcLI4A_ed$oxcm|UG+4G^GOk9Y(5P~_`}nY1Ht}eI$NO5(#XE?hVm`~3F%AbS2hWrWd6+gpsY4E_~rWhq{s+X zH9=*%Fa?p|hv^%yNV98n$1FM%+haUAn3j1hbslxyN~^h%|L_mh^3fCmVkAHl?q7W{ zgZGDUiaT@1kA>WZPse*jj!)Q5diPF&CT48D_plVINrwRbM2ONK${@R=S;Lfg_Iinv z>U441Fm=z6IQe^H?n}TG$2@rY#|)X5L6PD|Y<~B!WdHtvb36BsKi~ogD-9BrEukEP zlh(y*^55&|Z8O}lq`-ty6S(#r6SxR~)~s~}a4dv>Y1M3@E5HX_TCEy>zFX#PXtV~U zktQx#Sa`}hH6?vvr+wTyZE?w_eMYi^9fddYdn=&fSoJyYal+A8V=z4Jfn8jIAgiVwRPq4e_qGAy)VS(M09RT8US@thE7v+l)*c z)g<5kCER`eouI$dF(U2A)7Mlu?F`LKuNlda9C2AG^>%(fYh45da5bxM3fVV-UGa$8 ziKsL?ljUi31?0N51zWZBh{w2)=1fiJ%O`wO?x5C)3gNLEFyT2JvwmiN*j{(?p3-x7n4EPC{@%i z9TgZS59^ogUI90()myIIV|(ag_0lP+AAGn=tY=vgB{MMzYYyFxbL`O;EIbuT$|nF+ z6SzA2A2=4z?gbocG#!NL9Q}T1ll^v9@x=+G-=Qp@U2Kr*9*bO1+$h|qcLJ(CSFm=} z$4o7(%s3&OQG9KHUz$&QZYCX;@Pa8%2c{EG=5h^`>eAP1cIqeUj(?Qcc?=_tp$c7lrlTzp_iQ~= zI(wVSR*xe4m(_4Dbp6mhUbWuYMQ4B#a`D_d-KsJ)nppHU%sjA59eg<-CBMi+mg%<| zQ`RyXt^oqEIzYPFioGi)F`As0iT6T;XXB3N8)p3qoLW-Nmv92 zukMH3uFp;BL@V;oa|JUU9n%6rE`Ps1!}Lax!DX=OA9z_J~fON?Sh%l5|H(&)u5ZmRToGzBom!f&wY?n+}zHCe%Kq8;Zt{_wb^|Y=bS(mE$`+nKKh`J>-q0iwOeo?Pmg_Y$b7QKIl%5)(|>{%KaaqO0*7B(tF?Jsy; z?|;GTSRu%Wd#W2Dt^w&C>kI+7NWy272}3BBRglSLlMH+2RtSH_g`ZE*DkNm@jC%7thcVJm zW@d)Sns3+~&Fihw*CC&sB=mmLp4v-Gbf8j1njZa9n%9HkSqx}{Cl;bsShKMN?7gYf zOpzVHkrFwc4W1p|*_t?>_hvh32n;626=8`FA98}W-)#?rbXl^Xq~$Blf4qm42dGW6LGTueK{s&6n$m zY-giTDoa$VqEeb=gHyyRI2Ef;ZzB^j=Zl;x6YhaC(XI{z@6WL!HZ^Mm40v~T$E;Y7 z5TZpYCDmNyvHQdn@wWuDbrkeV#4Z3^({F`jzXR6p?>rK5DP8QVL$s%3;e=;3^Ncw;y{ zcZ?5`tA}JF!Sd;zou*(=A5xl4$1b_nKtZ_!XgeOkDq-5$#1U2>gHoN*AO(e*^Cx$pDkIV;TUcE38D#?oSC?}q~6xn?Rwx3;+DVZQ#<-aq~ZN(0cBfP=-E7?NVS~D< zCVr;uuI5p~s!g+P6ZbE#YRYY}YWv$2xS+>=Yeg0A7{e*SIZLr0+-@6eN_x=#uq(?H zpqoV6Sa|+UT_@uPz?=M!fG?02j*RFEli3d0c!0bs5Y8L2*ZU=Qt{S3tEPxwo%ugbr zLjE$PJOQGl(MLlUYM-!plpi9XcAYydy7fBdjCWtx)dP}F>`}V7^)6GQ)l3k|)Jf#f zdA3@^b8bXF#~`9Qh1^AD(G6BhGTfgZ^J~ulr}%%$-qYFdq^Vn;aATX*60~iEOVo`X zbJwHkExH3{n!r8v%N;M2%jm$p7*H&@pDfy^7-|KR2Bj0v#gpiI&*l!+JY6|Zn$31M z$P2aZ-CH>{b>AzY{bdbg^>+$lQBJF=iF_WDGaKvU)aM+iYHGDdfiWOC<g^$t`++}2=1>2K=IfLU57G| z{LwvkFtmGp^rQ>$`@gHyW#n^1)F?5<~X^b6s4&ZvwnHz!X{AVU6v4&B-<3tfYTV;!SGDpC_X-a~Te zA!|^ymdXI){pi<$dLf`-iDLI)<@lFx?!R~cCHFs%r~gwc{Hl#+{XzuZI+bz=v{d%4 zEfL}J-dA_}Nq24b7CKL#b_rtdf+_l2h~eFI;2&mT^pqIq5(hpI6n@sYBKG@4FyIvu z4?p=nIU=znC$P$1Rq%D`cjAJqr?Q;MC$M(v1oYpdDSUi0<$2Br?|FdPwJGv4m>c){iW zX-;_+cacO=#XWidJ;1SkT;DfaSLQlKrfYNofwo+zHr$R>f1o3V zKo=`}$ZbxgC@WKvdW$)VNMpq8rW$~*q28Pfc$m@PfBa~{owW=)I&-8RfT7>^OE=In zzWa64PuPl{6Q0{4@aA8mlgIx~=&P+e=-g)ze>mM--==>J9&@Ke-nAx!CH&y4Tq-pr ztab*sAWk)|eSkMCLCq1`oV`N!C9!fn@BL-;nsK}K(TX`Yb3|SXd&z74BbC&L)cY$atM2-7xfsm}|L;aV7wkAtJo(I&2--n$x zYAvV+lvVu>V^D55K_ZNIDeD(tQyt3xDGo^J91M55f7C+iVI>Fn&=VuR4b?I1q!PFH zvOWu~)371{2uqxpC$RnM5J^tCf@|NyV6?<%K}Y*1mM5$E_vQlQNFL~+Lv+kOaE3(3 z69$zPA^UmkT%o>B2qn8g5QPGd{ZSK-$OT%+``-MtN8) zKcjBv+j82Rj1pod>EYYdaS+?sb&Z?6U*5fex76|pede1SeZ=7#uRC9g?Y!4$)E;wm zdPOqX5A8L6t5BGw8L6TR-$;m!1Z(p})LhE7;?%O>h%8q)qCe;r&bM;$v*3E{N`P>~ zOx2Ze@vZ!wxs|#NAANewOO4UsQo4-K_5eKwdeQ!ZiC>ng$zO2|!5^}v|FUbY=0&no zXGw+Cb8PHmLGIQERLj{+u_HjCQs=Vk1~==#z$FVgnGyVcAL1-mMH0f=w11`vcu28W zSEhmS1oNVjn?pyXiQjLYF0lmqVr^%utUt^ce36WdV4#55ujRbuwyUX;%I@RN>~`7~ zDc+qSlc6a#60C6Mb@oaAfq5PliiSWq!vRa}oc>{ioDrL|ae06C#1duU-=9Nq?5{1K zm%3Sr-2eI;?4v-RTzAXodj??Sy#2w@I$oFdNzf|k$azScStG3GfDiXWockPNPEgO; z)Yb?;eZjm;#Aznt{1 zU`Qxt>Vqe~Vp$Bpaz4TQ-A(`9hTRtjkVZiJf8kfJpt_Ih%`rog0cXFl6hH^>Zl0?Z zP**fO{(2{Tf_HPWkn;FzbYb1@fC3PIEDFV1=K~{rKg}KI4ePj0&-sLQi)RTB1bSeL zFz!t{PRa3iVTg30_OQA$(?Lq}dWiFtYKo=ok3I@Bf~H6#RF3k5H0zCNO|< zLh{;Qh~5UJFzK=G$GUc)ghMZ0YXrDCAb(yCp(r(~Q??u5xLN2IO{Jd~q??yE{O%Q$ z?9qQcQNBkZ@uN09T7*lFR*33OnmH%VdbcCJj^6I?ZD>*n?XDC7ybzy;R~cRRJ!-Dy zuyxf;$RE_?-v?wBVVw1EaRvfI3Mhje(xKPAHeH7|$=I*HQmj5l8@}E1np{GPPTYRA zs*|eO%P2LA*Utm-+P1o0ey$sU9IxB4iFnm6#RHbr2N8Hf1-N&YZ@8afRE>33lR2Bm z-*-_wkgj2Bai+o43|QR|VD+@x!B~meRAXms6v?}2V9Q$rHHW5vyk#>uJ1B9kJ8oDf zF>_lqFgS+VO97;*i3L@%x_h^sedTtNtmNCodfK6oLY|Tz=4YwfuE#laoV@VcJ6vWRKu|~g0i2UFte+#(HB(o zZcb;3)8dWVqL77SiJ8#HHBiaz%3Ux$IL%g=;Da<=TQHzl%iZ>R<_*bZ7GO=5D!Wd- z#xToR&{0e26i8%aVNyxxbkwHyaA*70gxj)Do!0@-Ht`rXa=KV(x))!kdA!}Pgvuw! zt*bL-!F3`_MPQb^HiO&?rw!%$#-$o7+SqN*#eBO5`Od#tey?kWcl(~}@C`&Iel zm)06v(4uwlx6$LhIevnd4mH3r{!hMdr;`EVRmJ!f|}+2ew$2IKNgFGt=e8Z&L{C($fgmmO2K$AQ?RwfmbYgmYB}>X5p6 zHXNvoJU{E0AX`fxY${*6_w(owT5Rt8(2$UHgUbfA8&ONgxzOQdVXv8Xa4A7GwV>9{=Qa?#=JYLVUT`^ijosy zlpP;D+rX;Vo7t1!D7XjQZ2Q%+wFwOI|4qG|#$eh)ZX7pBEJe|_-Mk45FyQ{zSz)z` z@e(DE!~LHNpy4NGZ5d>S#RwOCv6^HDck{`-;_ztc+z_e-af8qz0=L&B&BNgKO9u*I zW&Ts`6}sRTy1G#&w5E{aP>@su^d|5{mMTFrH8V&#-1-Q;S>|0#2N0mapuBV;i&+YO zhsHMuR1Hr8P^}085`#E$_ALJuK4|o>1B*>hcb&-!`9X?{jDO zT#@M*VR%R~=nsSNH$2VO_rG%FcrtK9RcfPQ3O!w1{jkN#$t5%U1pmjCP7!8V$R44P zf;SI=UKvn-mKDVz3A1#jqyYgsu}BF(=YJ(ACmLTZ-IUFkwlrR2Zy6O_4Ure~)wzq# zk|1KkcjKM)HhTLL506L3s7^OqHlK-{b$JQz_lcnPTOVww@zLe?KF@Y{xUKE5DlbRT z5XM4mp*^+moTp@^T%jiAS@zYPap=Jh4P?gAv-iD@sgk~`5%2+)iQ<}^K1mF#$7bWN zV&N?B&+eO_Z$vRTgIeX7sY~>Z?J>EOTen%{ z9eg%RRBJyqzI6v6>hHEt@@=2i)hHfwDP?yLg-aI&>CC35rUuxXscSqHE zOBsn_Ahb=OlitjJy>y6K#hl{Exi0+R z^rWQi-soGWt~8u`z0DtE1*{SSA6HWR00ERf;MC8Tn6ctTqS6t|1~wI zF)9#%7`gIrd3(t{{{EOTtqyO z+GNz$!%x#gwS_i&<_7q|7U9M2(~(<%EZcJ;_qqr}Y(i|?XLU!mRC7!HrWGP?};#a7R~D4{a& zko!R{Qu5xKk49ZO4I~l>k7-CO&j1JZ*kKz54UTu2jR0ym^SO#9+2?fzqCR!t%~&-m z&@Lvn@cIWS+QAt#n>!S7q0K7K;u?iln=H}{*pb>Tz5djme*93Q66oaGq;+a5fCE&xu>HaqQ zGbEXr*Rh1X;W%dY>PDi*!L-t;M&!=WPC{wrXt+ZBwDl#2F)*QrZ6FgPIBoQBy$?(X zkGC;rsuxIj*a6*ymPQ9Vd$Nqq&g}UjZ^;1~Ki~*GIjg*9sf#|{w8p{hrfoBkDqzCa zya;O?X?^;xXu(1x{#kQj)6^`l{}fL(z2~K|{t0{&s9&vtm&+h)tieO8_iX~FF*i3k zKNA%z@lHUySP@EKpkmZ>d%fKy|G3kXPH5VH+^lC087xnXgZD2PJ~cU7h4`_{3}mwo zK$TX|W@n^k8T~;MS5}|vXlA5WO7p>N;OK7zjP6B{9OY9F_nr6MIAxSThj+=^$A<6L ztzsB&5O#f`zxCUS%DeqFs{c}ok>@U*)+?)7|$OQQipLh_bj_v&WaKWxt*%HFme`oO01X6A5oy+1s8ai ze@PbN&L^~M4;s2W9{u11;2UQIiv;qX@a#mVP^80JX^-{_P--<&SV>B^_0?pk{*mUu z;l>nbSOHj$s}nHo2;16X=1?zuneX9Ij=S6`{Alm#8x|OPnESc69Ug&X=I_RFP8q=q z>RXgg!&Ade>z17W$f+F_=`BGIO;EAZ{~)LOTym;wHC+_yfxyAIk`2uO9>1_sbJUG; z-)tHSpLbptsbd1|#tYLsk$R2fP`A^0vmBOIAt?7~Rroc(>uW3NNWoQ4N?lw{avs#s z?>Ti4FXE(0+%^fr=Pe{f@in5=5aZacO_I=4hd2B~m`c^q8VruHqa zdj;*IY4;U1s7R-Kybh`hnVQ|40h(3*&Ww#?sho>ec9l399n>wOjCo9YpQg}NQvp)7 z+uIXY`)YIFdHo&$kHu%0H%76s&du<*8N8cn-)s*Ra*Mj3J0#)^4eFn}Vc8WXOYJ3N zBqsb`AdCbx`uR&EvnY^2bs>~C6)Z+r@4U?p`uyWWXY-`qVj9$dw(&F%q!;q<=+kj4 z0T|Ma*_(`=y=8qUqYRpomKT}q?Vn4Yz&|D{>G;+YppSknn-Vh?2v8>h93u2R%6~w) z+ovrSG8-w`Gf6G3ADlBxHJ*rmLkH=9<%LFc_71k9j7)=F)8Rg2XDK>L2n;$F@o(q( zvhuF+ve&Gm89-$H*0D?3LZNP!g<|@Fhu7q(#$FV`k9U$;B)=WJ?GX^T_IR*IQ$JdYdppa(7^O=H-ckj_+kcv{(t}bIh%Sco)U_=N2%_Jk2G%H?K z=h|5--fg8AMe1!NMBDhCrP4FrZV&$Gr4-AzXtQ8@D znNCnVq#rJ&Z+kP7L>!H1IQGK$J&GSo&yvdb7#hsmF`MEH*Po*CbH@k0H}F0cEe@HEadA5~2ZmWHXX#T!L7wGdr`BU9OP0wL z%3w@>Wfs+KYz7t)M10FwWcV1&iY(oYD5Y#2x>bi{4jN*GeHLBJ9gk;=b3Iz)j`mnh z8p+buU%H;51*+lXo=s|Wnc05OA9{d4SXfLyOX?+|TPT`Z=&M5!)enwRw_d!hn*Tv3 zhd-|pS<3b-aPw}O)jvIr?9q_R7!0N8W#RcWXXDpaPHQFK4|Hdn3DBuc)5Sk&oV+c)6pZ_HW(?McZc66m59CH3c77uiQPm64hz0!3g3@HNL7-tsnQCs!&TrNSm}^ zB$e5nPRWpxnX1o%#@=dAZShxds7IkXzwJl_Fm2%7)z zu7NAZWSM_tS0F({W~dR4ZNF?=cZvi@Qyq?j6dk$ZT(osCo#wM>ctl|zB+srO9wehZ zD>mf6%DGrD-+Z#{*1o1)DV*Q3;_5EZ)ODwH{bkjlseH$BWNF6JT*HpR8S_DL_3Yc6 zY-U3~>XphgzmN+3@LxdO8#eKp)sdh3KGSsi!l4$fV&^6BFn9z|AZ(I{0_WV$H-FVZ zp}5=cK4u^DMDK2oTZChH#!1P^mou>;i>}jx+T}wf0s$e-tslTN+9zei3FWRequodb zc+75^LS^sn*|KC780|eLX~X%vddAD@oVV|IoymD^*PI_kTtF`H zY;uIxk0&`GhEMt~vyt8*clV4?li$2=)E#u$Ae@DNnq}qE!u5_8%oGiHU5=~vKH_Zj zhB5=i&S7hEP?`lp%cmy*`FUM;QH9zH)4Vq!s8S2C@gT*(#IVN~pP>HDTH?KQFw7Y&v>WgfM|dn}fDf zQ^=tjwMS%jg>1%Hv4Cin^I8o~ZVwuw!(wPr7j%AD6_-U;o7n*NeS}8i90mXyp#@84 zB+4yTrJ*Fry`b1+Sr_kRshf3=wvc$mS%I-Qg0Q?$zxbvOH86CR=42$uBIEVg9EzJD zYHUGs9Kf+-G=T9wy?LP&WhxT81(L^GpuCfKEk#1Dm_V~A(PN`O`Tlv(t3H-dOI%|X zl~f)$Wj=ndz+_ZS*2!rx4EeRP`*`%r(gF*o7$BybVXK*aTdq`{O^XZ?|qt0s)h>nqPW=dtK( z8Oj+Iy43BX?jM2jwBJ2!;cu2*{rMYw6eUQ3C3Xd{VLC~*$h=bG8sP~ecK304`5PLOtchlcULxws8 zSwD5sR%1PIBF|BnoiWq&rUiwt!d z`Vh^kt3*78Sx~(x+hCS)o^5}a5h?CNBqnzrWixf*mYTD>4j=RMeP#ie3S35`ts$?m z62lIz^j$rbBctY85t7_W^@>W$BKFU|)2vJsamOMm>Go+_68SmHsj(C{>!+Bx_PMSM z5-2mWNm3=P+#~G>8qE@D_9jq<5&!|{8fHWp0K3uQNB&n($r z%+=6lom~P;Ob!!a^tjyozT32}^(;p-0m9xvtM2PU77Z%hosb-R@=|}GPPp+rl@!R- zf6wyV(vFD1D{3BoVihkok9!=eG9|+57|hjw^D?|bBhLyD&vFjV9R>`cx98dO==-p+MY-oiv-0YP zv({^(z_C}3mc2_ET z!#)_(WjiGszAk}-`+3{lom@;83x}qWt+a|IUONax{ZdIQxTS3{fVL+9`5X_C^Rx22 zlokz zZ|<{INN4=KU?nSHPF-Hf{OIMG&#j4t>i1_^Ba0P>g#|6}Wbyw$V$*NZwFC1eJl z11BHynO@sXcm=z|p9AAmDNJ(qr)~zG8r=v3w5?%ERBh+K;O`3Ij@|OG5{<$X0dwIe zMU_bAs6@vjrk2^2)QH;D(Kii@9#Ta5Sz=0v>@DPDC|5@d*mocNx*5zLIK`_vOsGE+ z4vJACgI7=jlbG%MCtLoU`~c!h!`PP6g>Yt`jl506Ozn87h{-@ktYK+E-=_R8p{=P7 zb6qN|BU?x?oWQjjC|M#4XPXI^SDCglE@3sJ;O3cYQh|JpCCZep+ZQ`z7QJ%K#Xf)4m(7@wT-#$FN^Qv({Bm`Dhw>7dynhx*J&*$u1m5Rq14OM@ zUP;G(($3NFQ&hShf|wAf)+(*?6?n;Ym6%IiPl!2~Bx_01SAhtKu7M!#oGJ7z2cl;1 zsdlJb!OgUFVZm6-fxt?oIqqTev+x>}B-E-LPf{G+nh~A-P4ZOINmX*|;{m$zRcX%> zum%;4nzUQyRZD5_@E&sNjEy;3sJ&y`QfEHEKfPI6(dNptm|sVY##aCmg4QSfN2dqk z!I?r9O_J_EjSS*)kE;h%T2L*#Nb#bbhSJ~#KEYCJ7+6Ha<)Jl}l z8OuXRNuS}i37#qAnjE&w5aa6ZyTxvr0iy2htn>|*?(uc7ai*mOjx&&O{R5_cRwznH z6*=v1JY=nF5pSm<#81DZx{4SKkhr$|L|0Bjz!EYr!{}HHd@T`~>+--OqiB1iI7gqx zWVhE+xhwXEWO(W4A)=(dp@)oapdu%g}}S_B`dYm1JEo zJFc}ZEM$pY)^%?oU)@AXkE<{Y!mL?j<#xw;(n=_3(5>~ch+=RWj_7vY73;X~6)KxP zuh1iwi1VT$1;9694CrMlOORDUq_nH`9J`jQXe5>p$~&_rujMY5vdz!~*J6AZwh_Ns zi-3=HlCE7$M`T~;3mpbG@4o2O!gYCO$(K2co{ez~mWi zRG0#~%owF>zXNUpqcXGhh`L`P=2~61Aj_^i77_7@TVi!!YSAUFg98|I*T3w?)+Ne< zf@6wt$=tu_{fl(cnWrW|e6jblyvu#ao7V%@`Pn0)gjUn>UM-{Mtk_yYsT>@fGsY%& zS3wtHxWXf{39N`H zB+VSmcK2-CBM@b*#^VyI{SKqjSRG#R#A*iQttDGKcCJ2ORDCUH@6@govRb)oor!ps zhNAbg;8m6^QGGTRH9x_?oWjcFJ*+ill(CWFHT*ZXEk?m9A-@@-bT+5qxe4z>$~h~Q z;C^yP4Gg%Q2++bc4M^gSJ&c8{jDl+~cF3}vCUw(&ka#h_Z%PyqXkv zPlzTP8eocHqCKrQur3x{zy!LJ^P6JoU;XkDWv_+V^VdCqN-R3r<{iS^A%8lEjI}z zv~q?e5(ZQY_J#rC{Z)}=J_7J4VkjeRwy6X{@PC^M!qB;3u$d6Jy}*l~dG3hatuK}- zIHtog7yJ4GkMd5`_D(-=VHuj=_N(ZybQWZP`1|NI=Pz^0;1bbYfM6E2kC8vn;+G4t zdcd(L5)Cw&;~%m1sri4{d&{t>x3+KCty@J9QA8RHx}^qb0Ric*Ax1i9=q{C#R62%k z7&@duL_oT82wfS1eUA4zj`zdkr}3C!#ktn{oqe81Es{}s#!-*T z;(>z#9C|+}x-3zH4!(5uHG5Ue>qwDOo~IG{K>jYKCO~%p1AheO0Gzvxjo-A(=luy- zUVx-}aifpsel(NF^hnozu@RqP$bS4ax_t-P4IGbSLCPP&e*feta|@M)*B6E|6Mg*M zp+fGHe7bh--%z;+fKfo`^fB#g;(5KJ6H)P=JKBc(ut4*qKCvI7c9o1it4rw75)Oaj zLHYxdwm#>Y_E#LCSSN5nkKsd)qN}@H^f60kG1=zqE_RlE6OWDMfrKwprfjo9j+O z&S_Fm9o5LZ-dFi@qthsIVWLVypv=zs*+R@(v!mfU0zSjbt5(eq%#r{<=?`9j8ixQj zKuDg$`E=FpW3t;dSZM>CCaB;6Kv%TaQ&Yt&oQu9TC|bu%yA?x~ZL#mHZ`YcrkLi5}MHR81RIw1nF4+vY*+O&%+z%In ziNz@NnE?o==*)U@UFpMN;aKVed1aNPDrQO`lI^GX@QT6gLvSDKYO?%p{E*QtaMeeG zd>?cmYA#SAI+a4^=%6$4sP$BSO{3+mn8>T4+bTO1S+|qhr!%6!LIr#fC+5j+(R;a1 z05RZW#*L~}qjJEUPeP9l@Yw(7;UE_vSjuGlo1ftn-D5y## zo(}-ar}%!9_|0xEAC`j8umr*YYc^M(^tk{xHWnA?duh_>p8BH5-!>i94AxT_hT{DapFW3zm4a=Z2jE446dRT zRsjMS-mv`n*c%2RgJJ}Y~fwnWm^_+hfx^%`&<593ikz!iz?vt0-)Rm--&{QaXEfHLhp=z zFP#%xmjR$v?(b+ZZUg5&Z@oh)3W%g(w^ekDYxF|7TxXtD8Ouu(tZ2A*L(fPVR+xb6 zk`VYrS>g9-_tGcP(bRk*Dmv>0Ds-wvHO+t@>sVkg<@Xtg9pGV$F8%aUuT-?erv!R4 zRH8@O{K^(4F-}7wz571hI#TJW3)ATc?1O&WanEK4An~phhH$nq`U0y|0=GTzaO3j@-5|5_X0{cVng8 zs+(ShCyyQDR*Ox0d-}afTeu3L)CJLS^cnFSN%(GgZ-!H8EmnEwWM<#fN@^!;tw0pzD2!8@SM)kxOdr9Zh(xNl3`z zgPMYIqzT?ieQ zCm^iK<*S7PMUH=3lNRvPl1L^MZj4pC)%T0a=(j*dcy??#d)E>y7~%(XM4vJs49>Ib zYISYGa%^55A+7`A4!_=g2C;!_TWT23Y+eLuh7<>tj+AOQxV++8;bTTwct#(AX36_} z#gx2yd=sM{m*peku%cxkAh*w8yKq1HVG<^!FmNz@AS|%jzGv zC%A{U2Ra$cfp;w&Xc!liRm@s~@AGiQ|9!%71c-sXyxbJ|q}POHpWIl?s$eRm;@4@Qi7ww;D}k zdf)_-TWu?mplpcg0i^rrB!D~)soq&YDOg^K$rm5S29v=8A14g+JwM>tu_5y@I1_`> znRnwVPr!B3xIaLP+S3+J9eq1-|9tQ(U?=Cs7*NMrO*|gD{ws(rqzX64Y?kp{KL0vU z^2X;uyAd*TJhZ%wCLg5ar5y;wKE4x~4+cWHArH7$(OKl`_SYkx;-^7$7VZy2vw=9- z-xQFY+L#wKJKfRYYWsj1MN?`r?i~O z?7By1cymw7xA+QkLvotO@u>$;Ze@f|vNh{j#$3Z?S!NseNV1eYL&T};b3F9I{*?ey zcaXwhL1bD&ZqjxYwh6On-+}FPb!tt@7WiisIMTddeU-vjjsR*yd1;<@^A~8^!kbO! z{tQuyg@o>(BgJFizhc&ZhB&GjH39JId2Gm!+(wfTDBwOgy@B+0nwrw5(&ezaK?U2* zy*&49IC-F=_dZGtp7yz6G=bmLkCjGzW^9j$Z7)=mi8&&Rr$S@dd^$F8KPQ@*yb;v1 z`iS+MVaNS)m3*2ayCKh~ArP(BQ$5B=VM149F!?K&r4y>N-QeAHCI~qa&K*VlXYfyU zSND;A!|8yGnf3h}%H~{$(k6We!p^H1rN+0dH+YS+G!Rgws`x|YRX6y_A;jg{qDl}q zlavR6dn>6P`1LR0{Fi*69k_MgbZI+MJiUHddO3AzJPRpiI>^2?0UKyohmSzpBXSmE zPde2*uog79EE0i8jdi1qnuQ6Yu^gbjn8&3G{&W)*49Lu{*~ot6YZg6&Xxp^$My*I= z&OGsmBs-H3;`YL=I2OEE@;u*|zL@>i2q8U-_%K?3Bshi0=&P2D+JkHNhO26eJ|aN0aj zYT?LVUTmbTi(8#L;9oL>z~}_<-wQItBF{W8AevIq(GEDBj|`5JVoM(B1UK<2bv2*J z6QFAy{AH0rSFr$l4q^2|UGUoxMFxgj=F?0y>JL|y|32!kG}&Gc3`Ny06_+gz3#kzY8m6Kmjwlb_SXk z0lA~Jw}eiUYUdWS(w3&&);lk!r%s!}HWP;lHy`iOzAp55^o{ZDb%W8{P-okF`HhdG zYWg30y}_o4c~%u*^yLHmOUG;WS2*Rdks?!wj-xQ@3=N`c_S-nn{3>;3-z%2Xvq_Kh zX8yosnS+9pvL1S!8UDmiS`uX_+ZsfBM^7Y{QAm$ z0TzPOW47AZlpU6Ij@@bj=dsxsn-mJ$6m7$M)UF!T+{dNE*Q#>)Y?*;>tgwT(SZpfS z?8pLX+64Ob%wSdTLhH>Us=A8?uBF`pw4CLui43oGfZDitQXJTt->`%Z>z)eMx;pLk zDWoif0u!70jj2kyI$CFr<=e1oT94B2#~X^L>h()|fsaK_OIELbR*{>lh7FWJ7qtw# zL(4L6DQ`|Xz~5YDRorI&njWWPdkh)O`A=JXqsGi@lpSzd-eX8rQWCk>br< z#bs>iEdUDqL_aM}=zlo;K7D8-buOX^IasRZxV3*>4;8mHSO|7+sO-`KTzCK2gIxXY zY!#f~y&&JSdfV^)3D=6PH(RKRl>|FE!#sn%P>cB~_nH_WXl^AoZ=tJshqo@MOB{!tMN0hI%FB6a>jyt^1e z@0k-l&i1ol6Z`^hTh6H9>N^a^?Gm-&vj!dW^swA@LB4Y1TP0D1bd#BLB@6zG%VV+b zqijjmvJjT8`S#hKnN?~hu$ZOl$X#L}87`)kIPUZ^V5gPs^x zQ8UNJ8*TRWF^O#3V#&8mvbRLP=c$|q`HKyAwTPMRY;1*?5Py6``ZlrZ+@}6&z$gZO zy&l%7QqYSghUC2{Yz|4_MOMFF!c11<*+T9$q@>e^A=e#P`7^Yi?TCKogR1UE7Ljvc zhijm&B?wE%umWi@d^qiJ!4PIC+GVdS5Hq~>BCXDGF#6XCzsa0>->_4}v_a?|7Z5wU z*Y4;VFobN^wOD8^@mIb5s^cK~TG@`iq7=URd{?+ubl^&k{!~jnMj|J9A>&PFrE*ay zekkb^b?q;F9kthObDC6|w)D(J2a2vITz>QE9Y%#(UFTD~Qip2;e}B;q@i;{0ejz`P zG5a&xO3QWA(W8ue58)WK*T$VIRJ235^n!T5&Au`wadkqh0VA=>EGe$6_PVD6Qj~J* zGxtEI&gT}UY|q=})6JkjV2=RKp~~L;xKg*Oy8Id_Nf+e+-@R52((Op9g>@(lHrwDl zl2k?hTAvcCORTc1&%|d{SSdWSlZ$u4z6&`I+=V>2M8#Y?tM{d; z-zMsE!P_S<9fl3)%;!tkoHJ%-A#?9BzpY3_-qx1ndXrJdNb@OA(+8*Gmib9K$d1In0Ht?1wmNH>$R;>K)lpB=< zjqGY09e6hIDXF%k8_H?wc0F;B4@>xig1){V9e7a(0^k+OHDLEg&x7ZM-V=-01TV+7 zE<)&wTLl>RANN1)WE9kAcE~yju<0h$U0n|?8-8LLjGh3<)7~$anJZ~xc{^ei^$4I( zfC-)Pr#zjJvie7J_*znA!=4113~|0pKdn(%P6bz7sOCYQi%S;RI;RJ;9hZ3#k=x+- zDLA-b+z<3XrV0Pwwk@pG!_=eaf*qAd>UOWzUTs69?**`CRNUCFHTMpR&_)3-B>D8N zLH;}BiJj|NZGKdaxAMi;g_Fm0e7VyfER{X;hwF0gVCu&G`ZHjj04iW@7=Fo!hgz2t zjruqqTVbOn$92yLSjYG5422n|w~N#7e5<(G#?`6fT&>?y!t9L2;sFU)=TFTW zAG?wzKcCK=P>SPPX=UWidaqG#5$REDd)XO72X+v}AAs=Uv-W33cE2CIvF&T~Kr1+h zIC)KWFtXTelG?t>5okhA_z#+W_enn0iFr81&v&w%-MjM=6|U4|k(FK-_iSJyV&JMo zh3YXaBASISY`FgIitKsE8S(KggZc<=g;;hqfVp6{I>51U^EHF%tV&HNe!&;;Zkus| zD{v&-d#zB*X?A#lp(3fnPUTDuJ;CbjNQWTgWb9;6GhNk!mW!NPXTFEe+0*F@JGoxy z2^)kS$X?i-sQ#S8!ivg1@`d3;|8ZJZAs8+@2?RZpwN7UT+c8#A2olCStcyer;%G_-pM)?}T^|Mepmt$TsZg zBBT|!AIOI3aD=)q7t3%2^_XVv?saZN@1k6fMc*G_Rp?_DzV3fnqxr0c`R7${ADuKB zK{Vw^sO4AZtAB=FsTiv+UOS%RrO%#04MF0QoU4|v6`)U}Qje(G?BNfmjh{p*Yd;=* z@8IdS8u`ZzvNXm9Rqg_6MCXH6gC#S-`q?{VWncLU)NT}29F*vx8dXhN{PBU*C}*{~ z`TN3b5@s9|?0Kan#+;At{&CZ%y-eJ3zWT4&EBt$zQ6l_LWc(Kg*&yVu^RDZR^Ni$% zIs|YU$?p~1S&Aq45<}5f5tNuP!#;#RZe+kdfGp84q_`d zSoxBdD7I8f&~jiBU8E$o;j%TZai=>K_PyDZD|_N)AB|S9$N^<_S;Jw9rVR&n>y`fz z^Kb})z9i0LBLL97#B#0h&eFd2P$=*OK#p*I?awfg3R436jh)wK;Ng*U?8hxoVg0|e zK$f%FB=9m~gJ{UM&W zYOuxoPXc(#_+BZvL@Dq|^sBKBS$}N|EmP^ko(xMfeRkvTv)uH!D4jkh15{gwpr#KT zV8eoVQ6ozoUa1dX8hEs<>f_soVmg*34wvJoUb;hVbEelnNsZ=gR$LTx@lR>Ijbp+w zVL4Qb%om6sjm?DoCZl6alg8@IG^NkXn&O_Yf( z8`J7^2)EQAv$Vuv+@e+BQ27Va0f=zSl~m`%;Cwj11@myz1`y%okCmYIp<2k$gtE=K z`oJ7rYlpZ71GN~pdzn1@#tpO0tu+`u) zliy+KxdYCDqxwOSWp>Y7B@6Bk^tM&>?*sPqTtz{5v z{ep$+wJ-cG5MtMU$$CJq4>Y6xMDUi}Y2ovIAmFj;Tq_eX+kjpiP?;u^-a^+C#;%hp za;cK`$1hR&H_hh1(h7JPpN4_lPm77WH3L9U72kttA{ipq0eZ1V)Jn+8Z zVlcR-)o+WR1t?Lo7Gv=#S3pXBp*NSmeYJ97J2)sQzKDiS+pvpKXp%C3n&B53iot9L zV$buZFYI&9Z>&s^Z2E$$qO@t*4TY`YS0w{%zD`IhrZ0EIlrT?QWP)_{32Lm}YAm5? zTRfGtv&8-myZkNp0XF9?(#u`}=~jDwkEF@HG~mH)0CyEqO>%#oWzZOue(ObsgJI~` zscU0jZ9^1ysqiZ3lBpB8o|p4|tzw;2oZ=XWS_v$enKa6C;D*`WB-;KS5dLL7Lt3RJ z>0?7mndEP`HS)RARx8ALG|C}JOF)(xpXO$m%8gF2e8DqnUNu{|ienOA#pp}?EC&5H zUQT-`Q;n7If{SB!9{sLu1VJeO?fSWeZ#+#nM;3)$SJLWRF9)7Jp>Tj>V53r2&~H=n zD^%cw!Si_15`pVlra!-9eK5P&o)}wxrFuesB2%ADY(?6}Rn?9zCbL7mgE^+R)4_L$ zSFQa8*)D%+$Dp(MvHVo7rs6{h1f1V|2L~`G52%^>B#&xa2WaIK+D)<>f}|`3hAf#H zO8P4-I*Vo}=FURm+~yXrQL$SjSu6^3KNt4jVLss!9znk~(ft#G*6ajuoPOVwKBG%T z2}~qIlkt!|H_*1SvD$m^455+F2r)9>C6}@tEO0kJ=zQ3`zvdP<03G*vg`>MaS!q<8 z01>h$IEgWE-N$f!f61GB-cnAY40~~)uw?3tt35tF*DLcp&i5X0@6k@&pIo%&u$Sd> zuZqCK<^thqeE~cipmaiCNU^(*)|Kan;C9x>6*-lKS{i=p`yR?hya=uY^ zx*A2fJ^v@>)u*>1SybR9RMlK_UzirL@U)tIV!c0-qh#b8iJ;N|TepmC+2b#jT`Pcl z6v9EMo>j!$Jc&P8QrbO+fp)GZ@ z+>GV^s)+76Yyb|lS?5J8RP8!*!`R2gCRT@S-pkZ@BvS@5%w7JK~(388@8r0=nY{p=PrPHKSIAZA!-jxvz(}6n~4RHDAE4w1|Lpe9ur-uyerq* zi$nYAj<5=LFGJ~Tidv+k>OsHf0?s80vUO$HI)cedi~Xeyvnsb z$xqPKMVs0P6SMDzd$I(9i&4)Cc)+n%cIZ0vL8Q56e;ISoHI+j}P{X5;7+q)osZDn7 zA1-LAA6;Eq?2ZcO^FlQ0qslvf`kIn^V;Rkt(1pJVxs`{m)S;0VUDun!FPAu34J~M+ z7c`Gr5L%P@ZSt|N(1L=lr4iK)&84isV@8dW!qSN(i35DZ@T~;O_I6wv!^f!>pgLpTMVo8O9WHaJRHa1`OM z<-S2m%RU*svVWq-+h9~}TR19fTf&tDs0J#FO2#Dnvn}rS3i2K2gW;AgGN`>>3Bo{; z=2m6buBCwMw(8DimgU6RQ8ke1s=a6+7;DULmVs>JxfRKuQ-hQUz6W0h45f#-y;d`v?=EKXZ8Oo{{s%{m#H^ zm;;7O!w}yE&JIoaQso4yO@!Cmc7es~Hem*;W6m<-8irYL$ab$l(Zk>N33OVEJcQJJ zA6}>sbj}}?LG@|BBUQ6*v#Uyon_(+G#y%h&IH445*wv%RGmL4OdFO7|r388Sfmo&l z(wJL`!$xIOi}_$6F#X(##;2-ZmL>eVPOog)de;D1GHLzVGgcOnjI5EbuWKU`|3GGl zGh{#MiBquC8DK{6>9?rymEn9r^>FzFT(@Lnpta)P**1{KagfGAxN}{2jj%jWdOWe# zOZG8;3+MB)<@mfCU&f8E2Su@_gQS!VUPZcemoUglD0d{f2=OYoDi;kveQgk=`o^D@ zHOeQACf+LU-mlL@a7*-8{1N#_@xe>wLVq^#{(>*8 z5&~+yrY4m6bNG8NI_4IXMY=WKPRtpZi}h!2J*Ur<1)`HWamyrxj)PL&yS}{~Uu7U4 zzX?Q_UAgk@cEzn;c7Y1Iz2(`JR*2_n%j8_sVIs=X>>Q*|xgo*5)>*$uS+1X(W9ZF= z0IDCSurYNQWX3YI*76o;RRMtzZRE8|u2IQPM3-LcQuM99a3xMLlP~6~00iJNO=jOu zxd~+p?)LKX2SCcC`AK{GS%BZcn{#v}{2z~>>Kn-Cr!A1MmhPeW5U<~MhErepPH7)K zTLN7-ChY*aB>pS(>y{jaZl;qKQossokwrf5$#Rf<5-l-^VstB|A0ryR1#B51|NDS} z7SR5;(F&!qu8zBTK!@t>J*s1R!ZI#-I?iJaEQ`$&dL>e|Jj+MnEV2VHj5Ssly2mU$ ziF%wE?>k!;^CQ?kOj}rY7`6ygX+$a3*0x!EVbRUc9_f}Fahxpv4eve!)lzPb2s(Zr z^_s4s1Q9>;wjcTgrKY)O@!G|`I03>wS*2!?#XSb^(Xa0MJdlaZ`9qVkxjFJ&vgL*y zyidxhip8?14n5%AhyNu8k?R8(M5do%`VS1UF9$G4=Vdui#P?Z;H0wT-hK(t1NBVkW z2d*|_J9*XoxE?dMu7|@f3@TH1{`f!>&M4c=X}hIt@SLeS6)~U`2BuqRO+U7auw6Oq zFHmk4T{>J7sQ1F{7FeWm4vWwzFI=IWU$@&W@B@87pN95Z6xsvtHoR%^|>@j4!!yP2XGdKqFN<73Pivcas16)@bKOM*#29mu+5T(c-&}}~M z6HoBYdPIceC7MSu3!zw=K!x)()^1acpZG(v2Vio4pr*_U2%A9R@( z>o}Gs{#e4W|Kj4$Z>Kt`(N@lLiwO7y0A2uYBy*wIHqgN{$!)3GmWzel)5*$h>01Wx zO})8^U@1N0I%EWy9;_nged?fiKR!@bkH)S?m*NcR!KQZO3$d|J?Fa5K2dWT>ovOF8 zA{3@%70EPU@uI5gXRzGxG1q;))p@O4{t|Y>oc+b#E9_LbxrcN#9}e^v}%pFcxBf`mERlm z=+1RUnnxu^uD|02d?56Sc6SItxcRb!op4yJ!OgV(QXYiSEi)}i;{uxkwnv3&(pvMU zIy|(xKyvsJr@N2E)P66}cO7VXQ6%-3B!tOtd%EBTRE=hJQW6NsRl7MSwVkS@3h414 z6@Nn%-HNJkn_891s-3BZ0=ISi6-ou)L0OsKesSLpj$x1P#`FJ)4D|mJ(k$jdY9oug z=7@v*-2p(CW;`F!*zBQn4OCh4mc?B-K{QXfS%c5l*kW@Y)@-TCG zf^}o3Eslc^6~?dqj`HiELJzBR+newCkLslK(%wX?t6@(V+2A(b$Q~g;u5u2%AHm-} zH^hOxFcRU^rjg(kA*4NHZiiMqYzm)4-MLpUQFjjD7CjBe>&=>NHA(f>yK`%(KE_p{ z=agG%3>#f$#cBs*33#oPr){0~(hdcSAcSny*~<>joXIdWSQW2}c7~}_$CYbRo8I`6 z!GT3tAg@(ymol8V3JT;ik!6#5@&S92wm_8z5ebgbz-^IqXR%mD%6z?i)J!&w$bK(b}&ZQWt-`0&<{*9 zcxWZJVIj@0xLT9P55^S(MFbs}%&fac_^edX)x7FrTPc_baOL86UXF@XUbl2J(R_z$ zs~1E4*QNivdo=Dw+jo+Tv=5fI!L8ZudT~H+2T&(Zt5!kYPoXG2(lDtrUcI&Qkd~-) zA{n}r$1hNkb6bb(^`h)WZ^gso^xBJk*wCin7tEAPM zQ4M?hPlMV$uKe&q0KaD86gsm^fOPZd- zEn7Bp=e5{ecgF$nppPz*Hj0Cn7}r=YN&@MzgRD4E!~S6)aJgfMF$tq}4issT&5s!7 z6Dfd~V5!!D4;PGjaOZ0?H5h?L!9!dEWlU()lD_|g_sXOg!y4iXf!a|wEZbW{i?3pu zWj|v`Ua$N&mTyb5;B-2b; zdg_k(5|N~549ls@QKzh%*U=yy`4>nhdhU(|R)jeUy3Z}Pjx_roEt`GWqH(@dTfr>Z zVm4eYXr3R=7j)Kjxu&X{Yh^`cU$=E>sp-NmkM?D8}ImX2-H+1 z_3NK$bar@_FowH`+aSCB9at8E4K%>ihT@Q@Hb5(@L~CU$UlaF50iEoA29{de!7GT+ zP0?ug&cK%jX_ePc;|f@~_$SW>no;_W#e=_|w%U~E{%6hT>5KVtMK089vx7GuwWQ7z z*gXM21w5y-nIraQ(U@*ic9h)SF5Af7D6TJ8LTWtH=Dka5LaOz-hJ=0XL7@tGta}wQ zgl(P5LpmtUwGkX49>-nW-c>nmvt(18q(iw;&P$gU!RuO&HSTZb?&#%yeLJwAlB|oC zr_eN7=Yq!UYz58tKVts%RR8WTlc_M}7~l*yig`0jI8^=8^;IR?0>1=8UuMNJPfChB z*&%dHJ4Yp;#Y9DXI+OH+hPF}-7E-dx*9$)(eCYM4yey-pp|MRB3tN#Szwwwg!B-u7 zA@MggtstC(2QOH7P95Av>>{W7FaAa!oLZY1f6eH^2@mE0m2C*1p5|G@O$Vlj=mvYC z)jIvV;Dj5dL?PKlH*<$r71ukUi&;{wxa|_xeraj!XQRML?4|Bjc75VR<3Y`zC=&#r z`G#-RI&CgC&*9*NY?0R5Ej_o0ud$X`&vS&Aw9@sCsc7K2Q$kt2*`5Ure0*|I)?cxX zhkRA*OIsrYop$W2sugqtkwrLS*takZBW7i+&{42y`TXgh#BDtkBC&#GT-G=2~ zu#^>u!uC=6zvL?)a&5lzqcyq7N>{g|sa=5CalE&-Gl;zZ$zY(Y5`JNWi9cfo?!;9d z^A$5?>L4;Tk|kM*NzIH!DpQBCo~~I`gFzi} zxi>c#7gzQfmXnu(0(i?{X=f4qe3@IwAszFH*&2r0xB<96ZgO#d~QEv88 z&Aimgw;b9+adzK^&6FUU;_XO@)QJnTVlGJhB2l&ttwXobX@`2f$!N(&`f?eYRv~TK z{f>q<)njzC^dGjZTQyz(=5g;;w49T!g_SDL)PqW%Zt0X1MVM+a2>qA zfj6{9l4DNL6Qbbf6-OZLN->~6A)$UlOy#_*yk^Y6qG*8RB>iD6@(nAphy<)f4EIBOQ6Xim z2?^MzZ$rZDaKPkw7HI?t?!5Kp)smK`m#EadD_0!u{RM_Mb*jF9$?s5u2}ZBv9-(>y z4OeyzKCV0oA+DAgsd3X0AAH2r^y~q%u>A|M0Fs(6w=6rx6iVVs8E#((nTnORn3>ia z49I2CC2RPb9|{&V#(xh&`t-dts@y~<5b9@pHa_6M2!K%ZHlCwyZ7u*pgjR4M_U(?V zTUh$m1s#P{oy2HV8+n*Z^~;}17nMb{flDpxQ12^4lHVYR%O4FvKrRJZ#ruyCwC5PP z`^BKNs*>z&e2!>L5`O8QDx0Ya;0~MFxY#kM`Zzgf^J@TuVnWFbF(XAKl$7%$xNg<; zYL)((Z*W6)L*s4d=8N)?KBcfXRn9I<$U6buiBw+!*?J|`GyI3Lj~2_W!jzU{kt|CL z$?t+4HZ02$bGdHMNj?0d#xRfy9dI2M^jnj|4bn0obN|O6 zsQvuV)8ob!*1K{8y*M0z9O?ZD#kzri&)v|18}RAwL$sk6`1Iu_x+yR4X&Vh4|MzGA zmmt6$_`f&gw8p+z2!3)83Br|GY;CK z%5}WJAVR(VPcRYwo4xk|hth|~sK>Sr`X7Bg0n10bgscl3s$&S0!l*lz3B-|Td&|!e zCSaoM-Z?{z(u-pfY)H*Kpl2<*sjCCYD);NePtXv}+*@`V3b$tfql1G?;{3y`er-jmMQ`ac3+M5Svb9Z>Ey0aSH1^h#n``y&hcOz7r$)8I$;;wEC@k6yIorxDmSZ zB!^@duqI!ZKbnC;ePZv<(kSO;#Q#ha`gV^brN90~9ZBz$(#wr-#yYKqm(dcYYz#D} zWJl_7GNf*QNzr+3E&B4!y|>8tR17h%PZS`S z^E8r?FMSoX>(M+&s+#znGIk4#Y1ekL^=n7edGKcyBV;6Uut$;?+#%3e8x6FcbcJg& z{imTm=1bNkjmyP=zpU?iq}q`)-?z6zoD%Lr5V0PZK=(;=Ivgfc_ep5syO#TYe^CMh zW*hK?5c}$TLgBA>`{_g=*tkMJ>t4Sdr?^y~@Y24}7 z#o5XB!}Dd!i(SZR)|T5`n&+Wk%gABVI%`&Lyt-Do4^PoY2k1FOQ{ z?p`p>o&Bo;Kx|6T-HAm!(Wk_Jk{55UZPj@kuT5Y2HC(27hI$%$9$5+=K?GeEZYEtw z6`w!67+9^?s-?Zye|Xl&6);EUwTsoZA08ldUy>l(7MHE7a`76&j^iKm9*3NfN}bn} zjPzrpZeRb8x4xy2#dFEL!DFX<`t->2{`5%0<$F)JmBWixt;_k#$}^nHZ(KeXo8}OL z*7=*p39%=sl2wW{8Zx2$N{b{6ryzDjtY+it>rSfN0Z7Njth>!x+!)=0nRMw+g2P7p zn|f6a%>QDKfqqL5PmCcK-QuRxiw(zf4+W1jFPm80b{hzANg#Yq>z1Va7vHxFJ+{AD zF5HC6_B+{^y0z7ox%ERO^_`7~o9!qPz!rkB(a2nVjslIuCs5-VWo>f8U`61jiPXKG zMP1Q9E4W2}p3aVA{lWCbL7~T7!Zbcm>FPA;qQREs{G_Sj++5i6`<&y{#r(~N;v*W! zakr(@Dad|0<}$p$(WFu)*v!C!bFBQxvN%7uma`xhJF^SlEzHteQaoT|;_82~Kh)Wf z3tW^JGI{LMTpqK0Q9EezJT1J;swi+jg^dp#FI^tfczSNb8$4`QRxWpwpVgN{pNN;Q z^>c@*t|65p$ny@&jF1O(xgA}HJxd{K9JX@2iH07bO2Gc+5CrNw1m!@F60w&wuy9&# z8(^1zRB(IvzuX^5bUm`1J~|O}U-~wE-YQs7Un6+lc6r&3<9W!XY5)wb1l`z)6DiOxUg!Lt1>+#kBhAmeTl@<@PL=|Z0&l~nP@%=@NlQ0xKyny zZ~GnrMVf?fUap>aO`q*VH=H{%yI(%^+=YbUM$x~-`-H>|druR)`l zG#0ukL!%0{64kob^y^o1y2KDL*Fp`_%z{IN7SL?Gl?8a=#cMvC(PvDavBYM5mhMEl zRT$0@N!7%83bm#I3Q7rdf_!Wv z3NZ{4>5^@I?Pls^b3byuXJO@p?eo;4mcWHxkNT*DRB;z^bK{M4cPr>czFYMOGpM6C zL9VqjOiV*DP)|@{GBd3=?=4mOCw2c7(8&8Ru_BZ2*&}@M`@H5)eBzQaQyS+$BHJ7Z zLn28_O%r2$CB5}y_#n?OcZGSW0Xnm;`jkhV$r!SDMM#=PeN~m|k{#m$nl#0xDAug6 z(g?CcFs<@IwJXHU-FU%TLkrW9J+GqTuQL>;k;raoYifjv(;r(W!s?+yFW+qA4nPaY zsCu+u>}RMYw2xoecq01j&k=FN$*U!tCrlJr8*u0!75;bGQ1}Cod^oJZ*mx0KBWm70 zwz4#yL-a9s=H4>W4kT5Q8R9vbH7sUR2+Et6KMt)k3f6-JY{GLp8fut~4caE*W(l;e zSY>TZ3FeG98OxAruG-9xueV4^S5(0w%JgKs#QDFUeqis+C!y0aC(OH_FWguFdRG?6 z$n*jLRv_3D%^o}R>bn-DE>>BX;}}k=gA9R09yOB%5PXj#amB0KCbwm%+8pmx(QbMW zNU4gX>M2p&{HVcc(M6bJJYoL{swzn36lKx^{XBfP%F;H0HkR%iD50;Fj71A8t|Aam zwxUX`4D&j#=iM>dlCryiXaPj)JQn$N4G^_N>E)ij%Rr`&=*kw-&QKqlVNHTnaypY& z3i}k4Pg=b@U0_+ttc~JxF)-UY+7%3ZY;yY~llgblb1Cg5b53++aQ3O|%<@F=4nqJCQu#8_te@%m5ljqVH2QF-QH z2Sxb$4R4s$!>PQ~w0+p#&hmat@0}&9EY!WMchO}4V2%P0 z1*mQn&SDXJ60RwbH5N`s2S)T?ttkhK%TKk%MhZ4!kZ3U4YX%8Dg&x5bRWxcP}mC2yJ=MrBD!yXl|PY>LuZ)H>7eU48eO27Dr&4;%~YUd$ASi~ZIxiwK- zsf*$)h@ArC@r;0Ij4%T^PYvzqEe6aDF|&@R=f%<_?D+b4EqK4PZ60g5$-Eg!P*j^+ zaln4o2w&BZ-qh2{Me#d-yjKs-g|&4eB3d%-o&hbZKlO($Es*rZ`R`QAY)_vL-eEcj zr`&%j!Nb*J%31tk+re>jGw3|ZJj_2zf-!t2--1Fd^4j15oZqiqJH9~maJ>fTZ@KSV z1y=1YYiG#1p~ysQ+mJ;YL}IG!+yC@%uW9U#iGd7|;$1k8r0wV`G#c1E$wxe1c(G7d zty=N1Juv|kTZ9soIZHlV{eY5{!8g(p>$C#rt>8$;CVqV8%{&g9fQJ6tK=OJ6vQr?D z5uc`ma)ThhR&{KmHp@|g{xsjZYIP4McN@W`PyT9gm^=%-4_)N<-mFoDrEgAkc;+)N zFsKhXjEl}xhguP3X5l4d*ja#vE8~3GymNi&*D7H5)J6WN+Su2;dA$09bHT2rdBF;9 zQcJA%@{g~dpt1`2ZxxPt%d+DJ%y=aho3}nM;tbB(hEa}hwd{Pz)pI<{%imxNlafPR zXoLKMytT0J?dFxP`fV6IW-hwDrBKLdSw+UD$C;a#P{gonE+xk@4ThC|7tHY*mnyka zear{(Qe);#*JN}D8eDe0=-IJ746lmc>j*`BKn{lN?L*^^`#Q`PHv1+Aq?7Hjjy)g> z>W*MdU!R@`Um{NVa1$*8rb$=QKL$qGM6xMX@kex+)EF3U6ASfszO~_Wd{JHic{op^ zCSnAut)MQpHBmKKP${v~AHqZFHgVo~uM-=AJu-QP9w4nWv^#(XAGV1(f~Qfg?U&}Q zgvNA&mIMUy;T>>{mQV*_2lmebQpoI`tSyBCC9UcOxo^aLdgb(*u*5^qB&>ALGH#BZ z=k}8Aq;+JIHA0OvoKmn}tD?g1gWJ`vOZcf}N_A!pZ60qvLld8x>#nzi@36c(2Mm`fVSC_C%tz#&k33P?e*Cj1 z4Y-sW)t_8QQjfT{_DOCYTXEuL%cqMd+k6W-R_(W;0Lusg@*QTyEwp?mY6UlQH`~*y zMsgS}YzlUS$M^FT6LU!lw}=WGA0L`{VU(UV6Q*@g_?{>?)puq4$8Eh!1#$1zM!2@TU?bH-=~gM zYcAR$mclZMT-md6pm+Fid%jfn1#|<1d=OgA8_|@EoT$tstVAhStV>0aR`937)z?KfZR4;!$`}KW0D)%|}}BhdEG-n-hhUaiRJ2Pgq@+mLPT{1I4AS3(G6;Evb<&T2@~Xbn)) zhRJRCFczayCtEWhHwwZkB+kY+0KJvi`*iE_?3elFb{nJWG<64FsWdA#A0dOiJ20Ad z5TIcSjh3mrxjW7c$obui`@+Yr9OxeboFc$6>e1}TomLje)06Y*%X6t{<{VdY=lM_~ z+ILq?FNnstZFpbDzXGgYc@!;0yAU4N*@L@c;qx< zB#n{${H4zZcMgHP7D})G2Fl9jBb;G(^#v--eR{3&mipZ)w=qYZyfR=yc`5)HJ(P#P zRC$hqhB=7N5aJlYlBMfp4S*5qcH1{kZ?7ooiGkzO{O?s&F9gPkCcp_YsFAuh+&leDHCe{HZ)scDR5|P zO!8U6bN;xImddWXrOC+Jlg9lXGQNXvhs^%L?5&JKIYXVK+74$no**QIho!t4v^BQl zj~5`wsgL*?KF;yvN_)CH&o` zpB*1fMzNl;`8ZmluMUt%9yB~jk1AZh?8K3kG2NGoyCTXZcufaxpNkDEnhFFDbuVO1?riCYZzHP6WOvG=OzKj*N5dwp~LvgxYp z;dJu6854z=9=d>H- zhA3|^^4s2?*eBNa{s1Hc>l?p-h1%MgN@aFd=k!&*lh$QneBj*hJ?WSn!0uSZR`qAneqKW?D&&Rn%)5^u zn1)f0yuksPGx)uRR4)gx&?eTu42!}?_gohbI*u`E_4L0t+!eKH0T-$R&9*jqe9i`;=s&B0>Skn${pg}{)WDpOi6k`C9hTO^Q5OhsB{avU@o-B&-D zab>6?!c|z!KY6gRgcs>7m{jnT)z-83q>#3E5+Wotug}(T(((F%`y~%b>;em$tRZY_ z+O>YdfTg7WD-?9wc~KGb&Cii*+%K@m}UkpO}SkrqUh-pfm9 z2|^4?z#v6I2p}L&LKRdL2sPBuMg<*Of)FAQn$o2A7DV3(PH`OP$IGvLU-IRgdvoqy zYp=8RK5|-I_fKqQIQup4f!p)eOiJD&bgkJk+(Pn|M;RKg7M=nua~~CN`+b)1=*mCu zCa|SGirkT&^4?B@`sVCPg)Qrn9wJb6+efW8 zcEe`gSW7^L_$IWeC+C`K5n)0H^uLS9QTetm#T;mbm~xMZTksIv&ml&aa4Iu5d{pg3NX7iKIIyGK5Wn^$4by_~S~UM76*| z`worV#6HUS@Dti11cz2S>~HIdaiK0H;lE(WFtmcJS>SI`bT2h>^tbdGXhY#sa2<7H_S_xZd2LN2hyd z$SRrVSh-gX-6VZ_xl&o(?|B0JRq11QzZY|bKZn_D3}Dau1AkJ9pJ#h2JEVf%&V{-? z9#-@+x5}k=-mSFTR{cf`T&$6&Dsng~F{hBvRaQ1==B8h*oi<>N7k`Lv1N&8e=m6n0 zn^wcz@E6VP{EhNoPY$W<5~~uW&?Z6Q+w;!o^!J#|sDhI?BU>D$FVjafSBYuHiWD7n zIN3D9o=5Tb^b8y9`*migK7C|TR71T_$vqK6@`SC>pHA|-=}L4pwJp^yokb7(PFN-R z;Www1A#<%6kd+tTk(Hl;F6f>kQ529OIA+kC(n#}lRq5<*zwS6nm=4(1l$kQ7rk(C# zW#(Qq-%4<|9Mjp2PefgcczvDtI z1_hAv$Eu?#X+)*Yf~dl0=R&up+bFWWH`qcCVcx@0A_CZGc` z(yF)W!K$YYTCq#6O?{o7JUG>XUBi{FuAkry-uBPIeg?}hY+!LJzX0N5PlXt*$PRr0 zi8$?3I&9ocU%I%`DNV)bZLE@%3DG&?zcK4W7GltfCM}YJS0%_}aBnCuSKrm8& z?%IEjOK=xO7Cui-s$+ziJ*t)rUAXVm7M!aVcqPIlT%p>b+kg@kr6R&GL0$E~#1#SJK)D6H58q0NiM=sx+SN6b#dA+3u^mI?sdr$RtrLbPT+BEzW~6Ftm; zu&kn?rs%owms}H^W!1MA@)&1QS;ehT9nrF*;XJ8FVkRHOJHIkt7vlES zAzwwc(~$I#s*>YTf+CY+hy5ZCwkXsjv{?eYuwUKsO~u_Y&gLWlpL+*^`smzygL|LH zm7^5C(|nX3(=fivbSkJ3Z=HBT5Wex@qcl=iv;<~_TsQVQ)1j{uX!A6NLFDv(6F122 z@2!g!fx4jN_zU>wegh{z0s}aYaZbVcyaY|@Zb{aTs!JkkyU(t=)kOfV?2zEJwNJq` zOyGJ7qY=q#rYME7ew(0&e7qD&4c8|eR=UA<;?R18(9>U|jAs=2?y6p@l0Lab^~y-7 zG>_!_9=MQw7uEk1t#l7MbwIXpa|}hVq-fQ7eYq{2-gUtS@;l?Z?oCLK2ADUx_l@^6 zcqQsMN+`$`F!vLJR|PVH=Y3nL!4%)V%)2ly_pM388~`HBz(v|jg z_L4eNqE<*$v52(mOVR~)jPN&bh0z@(cZFp#>hVPHJDm`49pw}xciB-vU6mo`YwZTB zNOGK(O*qkqmh|~JyLdqoxB{p?^%B1>AG>*8+NWkChGeq>sl+Kl9BlGB{t272{d+ZE z>|sIEV_TOZjs@9wDvOlvJT4U)qzu-R=@&oHc#X62OM&u}(5kTW0+}RH8@nCCY(5VF z7IuWHE;L*b8m2!rUMem&YVc9n*IA zcyrFNj;SR3`!Y6fLYflgVingV;?>p;MLrsjT1q%KntVNbEru^=uL_-Ha6kP6>tQK} zeM@g`Dq-?ami+y9@FV$TRONNNVqY3bp$Q*K_4?)Ek#W2KAK~&fq_Qz~C0#;ox@_@0 z2~$cLD{;Pau3;IXr#j&&y)@@nmt(YmVtaU!-7~_7M79;g=W9 zuxF8=!No<2cs{>V^0Ve;>t>E#=Td}-@aQ(}$jnld5wEuf(do2@Uy-DqM_)geP`7eZmHpAYDu3?zb@AxpU4iu&uKdX;@Ha zWXB>#n@W?A;72L9PwH-4xGkvr=QFnh@&p$wTl?3H(ON_p(J@a4`yttV;$=s(1iby8 zJ0>H1s-(rnFq5Q*Ug=|on7h-zmbY5Y(6H7nFXWqJikrOG>`WdWL6HK0mH-O1+Ks57 z9X}QMiyHYBbMAc_*=uEWwtAFR1aOX+JbWT6Iaa1gzh>Y8(6TzP!-y%X{Mm+7@-yqI z7uYo;^@-+$1!%(^h0#dWKBX-t6+i)RtzOr^xMG+K-<^2lemag-c6z7x9+u;=*!Si| z`-N-A$jWECR{F~2O_xA*M~31l8Ct~VoEWS*X>}s$V_M6}uzGQ}>1vqkLz_op4bv+F z_2M$L;J?0B2M38;aqz!ep9=3Y{D)%f61Oe}tvd1b1j8=LZTh0*S-vQlC!XBGPdAO* zmHU?XH7L|5BTD^Jrt=zkY|L~j59 literal 0 HcmV?d00001 diff --git a/event-sourcing/etc/event-sourcing.ucls b/event-sourcing/etc/event-sourcing.ucls new file mode 100644 index 000000000..d187b1bb0 --- /dev/null +++ b/event-sourcing/etc/event-sourcing.ucls @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 37b9d45a7404c76e8977757f57455092a35885c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 13 Aug 2017 10:09:26 +0300 Subject: [PATCH 19/45] #590 Add explanation for Abstract Factory --- abstract-factory/README.md | 105 +++++++++++- abstract-factory/etc/abstract-factory.png | Bin 21644 -> 0 bytes abstract-factory/etc/abstract-factory.ucls | 159 ------------------ .../etc/abstract-factory.urm.puml | 89 ---------- abstract-factory/etc/abstract-factory_1.png | Bin 58331 -> 0 bytes pom.xml | 1 + 6 files changed, 102 insertions(+), 252 deletions(-) delete mode 100644 abstract-factory/etc/abstract-factory.png delete mode 100644 abstract-factory/etc/abstract-factory.ucls delete mode 100644 abstract-factory/etc/abstract-factory.urm.puml delete mode 100644 abstract-factory/etc/abstract-factory_1.png diff --git a/abstract-factory/README.md b/abstract-factory/README.md index f153c1202..c049401fc 100644 --- a/abstract-factory/README.md +++ b/abstract-factory/README.md @@ -18,7 +18,107 @@ Kit Provide an interface for creating families of related or dependent objects without specifying their concrete classes. -![alt text](./etc/abstract-factory_1.png "Abstract Factory") +## Explanation +Real world example + +> To create a kingdom we need objects with common theme. Elven kingdom needs an Elven king, Elven castle and Elven army whereas Orcish kingdom needs an Orcish king, Orcish castle and Orcish army. There is a dependency between the objects in the kingdom. + +In plain words + +> A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes. + +Wikipedia says + +> The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes + +**Programmatic Example** + +Translating the kingdom example above. First of all we have some interfaces and implementation for the objects in the kingdom + +``` +public interface Castle { + String getDescription(); +} +public interface King { + String getDescription(); +} +public interface Army { + String getDescription(); +} + +// Elven implementations -> +public class ElfCastle implements Castle { + static final String DESCRIPTION = "This is the Elven castle!"; + @Override + public String getDescription() { + return DESCRIPTION; + } +} +public class ElfKing implements King { + static final String DESCRIPTION = "This is the Elven king!"; + @Override + public String getDescription() { + return DESCRIPTION; + } +} +public class ElfArmy implements Army { + static final String DESCRIPTION = "This is the Elven Army!"; + @Override + public String getDescription() { + return DESCRIPTION; + } +} + +// Orcish implementations similarly... + +``` + +Then we have the abstraction and implementations for the kingdom factory + +``` +public interface KingdomFactory { + Castle createCastle(); + King createKing(); + Army createArmy(); +} + +public class ElfKingdomFactory implements KingdomFactory { + public Castle createCastle() { + return new ElfCastle(); + } + public King createKing() { + return new ElfKing(); + } + public Army createArmy() { + return new ElfArmy(); + } +} + +public class OrcKingdomFactory implements KingdomFactory { + public Castle createCastle() { + return new OrcCastle(); + } + public King createKing() { + return new OrcKing(); + } + public Army createArmy() { + return new OrcArmy(); + } +} +``` + +Now we have our abstract factory that lets us make family of related objects i.e. Elven kingdom factory creates Elven castle, king and army etc. + +``` +KingdomFactory factory = new ElfKingdomFactory(); +Castle castle = factory.createCastle(); +King king = factory.createKing(); +Army army = factory.createArmy(); + +castle.getDescription(); // Output: This is the Elven castle! +king.getDescription(); // Output: This is the Elven king! +army.getDescription(); // Output: This is the Elven Army! +``` ## Applicability Use the Abstract Factory pattern when @@ -41,9 +141,6 @@ Use the Abstract Factory pattern when * Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time. - - - ## Real world examples * [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html) diff --git a/abstract-factory/etc/abstract-factory.png b/abstract-factory/etc/abstract-factory.png deleted file mode 100644 index c709276b662b0006412938e5b675628d48e92840..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21644 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 diff --git a/abstract-factory/etc/abstract-factory.ucls b/abstract-factory/etc/abstract-factory.ucls deleted file mode 100644 index bdf1e1510..000000000 --- a/abstract-factory/etc/abstract-factory.ucls +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/abstract-factory/etc/abstract-factory.urm.puml b/abstract-factory/etc/abstract-factory.urm.puml deleted file mode 100644 index 7b5e1b701..000000000 --- a/abstract-factory/etc/abstract-factory.urm.puml +++ /dev/null @@ -1,89 +0,0 @@ -@startuml -package com.iluwatar.abstractfactory { - class App { - - LOGGER : Logger {static} - - army : Army - - castle : Castle - - king : King - + App() - + createKingdom(factory : KingdomFactory) - + getArmy() : Army - ~ getArmy(factory : KingdomFactory) : Army - + getCastle() : Castle - ~ getCastle(factory : KingdomFactory) : Castle - + getKing() : King - ~ getKing(factory : KingdomFactory) : King - + main(args : String[]) {static} - - setArmy(army : Army) - - setCastle(castle : Castle) - - setKing(king : King) - } - interface Army { - + getDescription() : String {abstract} - } - interface Castle { - + getDescription() : String {abstract} - } - class ElfArmy { - ~ DESCRIPTION : String {static} - + ElfArmy() - + getDescription() : String - } - class ElfCastle { - ~ DESCRIPTION : String {static} - + ElfCastle() - + getDescription() : String - } - class ElfKing { - ~ DESCRIPTION : String {static} - + ElfKing() - + getDescription() : String - } - class ElfKingdomFactory { - + ElfKingdomFactory() - + createArmy() : Army - + createCastle() : Castle - + createKing() : King - } - interface King { - + getDescription() : String {abstract} - } - interface KingdomFactory { - + createArmy() : Army {abstract} - + createCastle() : Castle {abstract} - + createKing() : King {abstract} - } - class OrcArmy { - ~ DESCRIPTION : String {static} - + OrcArmy() - + getDescription() : String - } - class OrcCastle { - ~ DESCRIPTION : String {static} - + OrcCastle() - + getDescription() : String - } - class OrcKing { - ~ DESCRIPTION : String {static} - + OrcKing() - + getDescription() : String - } - class OrcKingdomFactory { - + OrcKingdomFactory() - + createArmy() : Army - + createCastle() : Castle - + createKing() : King - } -} -App --> "-castle" Castle -App --> "-king" King -App --> "-army" Army -ElfArmy ..|> Army -ElfCastle ..|> Castle -ElfKing ..|> King -ElfKingdomFactory ..|> KingdomFactory -OrcArmy ..|> Army -OrcCastle ..|> Castle -OrcKing ..|> King -OrcKingdomFactory ..|> KingdomFactory -@enduml \ No newline at end of file diff --git a/abstract-factory/etc/abstract-factory_1.png b/abstract-factory/etc/abstract-factory_1.png deleted file mode 100644 index 5990edd831264f2084ee888ddba7447707622726..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58331 zcmc$`byU>d_cn|HDu^g4Ev+EkEg(pvbfbdwFi1BF0@4lA-JJtcB1$)s0}M!a$B@rK z{N8$hfA90W>s{+v>*Wt+%?#&rVxPUQeeG+H?{oQQnCL|4C@3hHQj$*|9k~$(q-kPsWO-}*{JH8?z(CCF2pEoH)V005|4*D&YFzHbW#mSc$ueZ2J;^3Axbz+)ooXXj^?}W3Pz5* zyJ|i8va4A^Pr#(Txzhvr1S1xzg%1_zns@j1R$Exedz6`2@afgpDkPCjnUM*N*SI$@ zALt=6YrJP?N8Vo}^~Yn-&Qa8WZrtdMKIn?l5WoSRJca`^;%BSbkXiN@r=N*C#bN zGfUC&&tBs$!7HIj3CwzvG&0TZCl1=~G|ZE*Iww5arG7)EHOH%9KRWg69NxB$kFV~n zWPkg%`189zHTBb*-Oc`;s;5Uozn^Tk9xvw2{MdZ5#-5eBkw|w}WDz`WtP&D+Chc{r z9up9n3m>(`#^J!ARL!sEk}-l8|diV4zC16^+R}pKWd_ zVSKzM+70J0e=AGl<_tl*2Ry_B-~Hn{J7rDC>b=|53eBfET)?Uo6@O;RlfHcQqE@}+ zYnp_sjD#G_+c2$p;8`-3C`P}}>$to5%IUy(LwHBTuiVARIO59GZ#m(!JIS?KdfgIS zgrBcnVJiJ{sz=#zLs$Lm1Q`~tf9-1KaG{P@073M=Qe}@&-q$F~f%(<(LIv^~OkzVz z6Ja@=_`szmpAk_nS^d{1hp`a2p-T31K33M)1Bi!NG9flLWj3KfZLad8jfI6mEgS-v zH<1Fli1n#Qq%__it2IY7+w8BR83x-hv;|g}3~YAAQJD?P7rbclTP9#48OV^4VOn!i zhglS8(D=^hsP}o)4zCQqa59{!a6x`+kL*a`C-{~TlM76=NMna8>usH!CFa@Lz*vRZ z?$*rP+|}NcTh$yBM5bJvx@Ok@el{8+^VzLi_elBORI)=%N?v=7?j#12twBbL4Z+D) zn5o5ZnmL40dL8oTGBK^y*h8Dz!E@)6%j3gO$M$3%u#k6@v#f++>!yXqu;>7sJ zO8#Gb#)CARfA;SR0*x@?&(R)owJu)&=T?1zy^)~n{(i7SK5XKStd zO75Q%xPpjE5on4I(IKvX8{piEOH1!QJsPt-pf%g%qaHTPsFwTp@TZj4Lzad&f;X3H zdLY5oZq)1ZtWKC8_1M{6GWTXxJ%$(sT0=c=TowQ_#Sd_ItML;VyE>)Tsa zA!keXPfDt(sK|&^i9zl>d&6@J``@#(t3RzNTHGKfkR-J|ZNpSMPmxXI3MQ?5bv@@G z_dQ4OJmushRkjSc7srPI=~p+toShxB)G=!QcnrLsT-;FG&XQAnn>Qx=u7bz)KL`H> zw$w+Em_U4DzTkW~uve+iE&n5FvVKwl5t6;>^{k~?_fA1=LjC4qdbMOAk!ofps&0Ki zt*bLPFAFg-gKAGFVTn=CRVSI|pmt2+p&!Ek57Un8d259gBSvbw@cnd1XhN%NNqWqZ z(%^X1GP)v-@9?v+F4R9rSL75q7hM6as-(f#VHVCOUIy)|spEr|s`7?#I<;rez5g-o zDa`eP+M0bm{+}xSX3Kf4!mlOJ6m;(IEp5X)($!9ff)?w)?)fm1ot(HHkHsxc{oGz! zx;`0Sa`M2}w-33qz|P4S5=&HM6gDgPK%o(K<$?9DAh`)~viYf93#>&@?am47x0xO~ z?n8O!&E>w6)(oaR?_T9I$9@9lJ9zX4(nMVO3IvBXEEs63|Q19mN1=DABY-(kO zH1ab-IqTGt&;JUpac+(u7<13V6DGdu7G6P|2R0+u&&735e zu(UcZZ@tB&qp3Jo>zL+Xty*c`CKX;^R$iXGy*i4pCaRaS$EJSxPjI|i&nOnkTb5uk z?E3w|!k}2Z8fJ1!^Q4HFG7uW9P3)ER>H|7E z|Ghx1b;*JFH*WtmH~WZB_a{m-3WkahZ1LA`q5t1-B$e@I@JfwvT2}&G4*fBXVe_Kd zxsFy4C1uVu0!07XbFJ>Zv(pj~7)g#QF$lQqmiiU9dtT%Iy-*=H0U;L$nB5vtD1^_N zc5|ZU(~GovTTA1iG9&onA|8jB`be#i>#DKo#OFcP!g$$m&GKSFyUt)eF^5AJ=Au`f zu(fgCmKGyw64 zE^X?Wks%Jk8nZ4*e{8w)fwpNtVBlbim<;s>6YtHxc4_AziOV>I3a?OiVt!#k$o(uk zl*+jmPN%TXZLS`Uu2p#=S{Q`h*qE5)s_KOfoEte$Z>XNzW@hUn8D{%0-6DN8r%oyD6i6Hj(Asjmp zqweebYi7c4q|ZtD4eb|uzrmfaBa3~o4)!+?eSIZJdxULqW#ue@3G39cNkhzz&)S~- zb$0Nx(|Y~p-PErIS~aw?i(>1h+q3oBV+e)Fhc7sId81s2^C%F_Ol3=35IC%dOsJMv zB~ggE_nVR;Juah;Bm=B~_Kf77tU`V2OLxXB!iCM^5@hc}j#trNVYl zSn%Hw#L5t$#)%r(Qg4cs%gI=JdYUI1Zx~})MFnk3bH)T6-Yz7Vd?Qc0ngqbe{Z);p zAQXcWUPUxe)pWII==87jr7_~Qy7BV5e$K|nnHkR45L6qM_q<_GYrPLFQLQL7duonT z)*jm>F6!?GXMX!;TmZ|-*&5Y_1JF&_9Ug{#aAX^y+U0{);t~Ep?r#?r()S0n{eK9@ zp>)BwP?}Lu3w|79qC6r01-EdtK?)#8TQ!OHuJ#w${Q?t_p!@6aG1>V3caQ#Jee262 z_~&=};B~7ICelm`M!fc9@^=RDzefZ9`G;KHcF|&kIf1#SCvzzuX2Qs8DF*+zht^uC zSy>UcwRt`4TJ{5EBe7z^KO5$sf5a6ij%jz_?SN?>+_Y5{D+QD`y?=~HyxUbvS~@;b zh45L+{HW0FU~o!r(_(KJnc$dej^f#5U9mZdC$r9& zfMqfj19WnAX@y_aN(-e;`=8;x+z?zQ=c!l8NLQHcGpZP?G{sxe{a`3?SiA%YJ?|*CE-KaE03F&rF|4s}(qR7PA0gXNC-c^C{o*cy+SrAbomfv(g;20Xbkwr?4Iua+lS{ zSk200NhQn=pHoJfuf3=k0{3QRbqnLaCfWVR+4b*0X7(8^?~v7;uI9SWJ%i>bnpJ-J zlJpBaa+<071!%WtXq2BIcS2**wkyowJ98b!>pB51=T48OGo)k83X7q7$DC$v5#xkU zto~$op^4BA?tw}6_JNh+VPU?X;=cw49yRi@i3J2AMX#71;xFUO)CC(I)7;s?Wi++h zTjpwP9~n`pFjX1So<7{F%aSL3P|f~s_VGWqM=6Lf-SOJ+*I=c1%=1s*y`%hmf$3}Yxc+c>n_M`T3QJV)qWyBJcj)0 z?#ViMktV0Ol@Ust#y`g>?obboNV1tMx)NEaoWmOoJGcozUo0np zHQMFIkB=Y0K>$@!nh_Kj2fpRY>G3gFfwZD8ws?}jXirhfi!{xKv(Kvk9^Wf*0eh_A zwDDCSy!|1xr;a`Q3ADoSaJ7t{n7jK&evGiYG6*THsgaCYr66ODio)OB?@o9QwrNQ< zOcQn{z~_X@Ku6bt&#XHOEa1Nmb9dniAr4>k+?5p3d8|BxKGUK6r(PhPK8;M5ixW87 zuP~bHiW5Y#UC;P)ohcd48Im-%@EMz=6-`ZD@>DTL=3w}Y<{Oh;^4q$SDt}Dn+a?4g z%_AlHc82sZ-APz}fjZ*s=5Q_sI=GiI!?3G{yO*)x6Y0#t$L zWP@`M88tbeh1QJF2k_ z5g4skkak;X^b~Y5tgLEp-jc5YT4VW2|NM-!;k@3t zEo`2YkE8mnzR}81l9s0CV{IO9MzXssb*csJUKj+_$J=n|nRYB=8gI^*C{n?(n5c@1 z3V;)m%uMdw>Du2o$hgYOt~7A9B?wt^1c;B;){Nb;G9xY1G5|P2sTk01TP}`lxuFB z?7O6OsQ^Bm1l90O_9nqe|oVh9)?Q}J?i*QK@oQt|f!V48c zV!#8W>m;OcWl{*YQY(>B~Zj8-|-6?f*H9O>D z{gdRTFTk7Ew5CV|?2boO&f9}06*J}q48j0QqT%@UgHQrL?ByFP7LKLCylk0hE^8Ak z{KKQ50<|JO054Q)9qw_t+wA%Qxt2uoB!{*=NB+)I3Dea0QB7g zo~25q6d6mT5IJku9?3A8>cv?0JQmIWoZ`GKd}UOxyQR4>S0#@vkJ^3z0O5m#czJb! z%*ztEe>p_+`HQ-nAPKTJ)<6sC-=1_%nJAb7-RG)ptKU!^qiiBF@~5YF;Oqb-4jp ziLGIkrj^b~aF2(F;ogF0H({V zC$WvGUTPrFPyk#o;7{-VLot95NsP^wSAjs;xQVrKjZElA(sS35@oMsk7It-dhYp=20pwJws8@fH-m?-p zTtJuhXLLP!^p=dwV)qp%vE`Y|U5%bRHCSkwjg{%GzjqZwu!p8x>)5l22p0KbGSS)S z`TI%Ju4Du(w8HdnDvGDN5C%9oC0`|^ks$5z8ushM5rn;(pW3mqOywTM~A~q&Q zQzJ4(!D(&GZoL5sk77!Ao*TidQKws1{~n4X_D>A(Ium%HFS<}F@IbkBl45_f>|;bk zRcDWaMLtx|xhoc6Y`X~=rB2N^iri4|rxHwW=71Y(C9+ytfDVi~IZ^twFrD362Go+> z+dJ5Qh80)cUZ3|?RGQJMFtuEe&%QE@+=rBBWT3{d11C8<__b-l+N8b!oK|9@MMspJ zF}#vu2g0a1GFeAV>qz(H=nvyE`wbR~!*+#Gq>j3}@5LwC3+v^+MB*_zP|xJse?Izu zMB*A-knxUIhyC+(Wl1f~BQc(I(SL=g*^v>&bNqDS4`TFxn50la#6ELB`B$1BfC%nM zB9Evg+3bWzX2M8}W8X8ht8}r0?lDNP(s5K0A^6&mB zD}XrfaN9X4;yllxF(m-v?F4FaW@+V7q>oJ;HaK(Y?JAr{Hv!=Cw)vvhC5 zlbY7&aoo;FM?qc99v%}HdldSsfYG}Fr(M(gcDCS$9uIyGBGVbo*Qnc`lW{$FwdWg2 z;wRvE`A)1QNN+G-V+mlWzCMQKVHlHYz9rynk>|PSH$Um-sm^`%!sw?!!Vo7pnMOU8 zKW+nZEB2ZFy~+Eb45^r;!u7HC@*o1IfR7O$A8hbAm0N?DTv<7^&~u}N@Pb{3GN_hs zZV|TWS*Essw#@_fZZXb7Fp1MEVPZ`qjcaRVirk#mbxYVyF-|CtB<8lOv^cHK$oT%% zOMiqC1nH56==NgAB_!8G;_xY2MLkBrnyFiZ@JX+AS1kFcbP$QgWKoh}^nRAXe*$s2 zCYx@Pk3IbJpnn%W5#MlEm((WC)=5bXEU-=rU#Fdj{ z$RFQ)c_5YZ1iJK5>$453`?*O^qBsv9*TEhsF?jn=iBr}gO-O1bTEm2fP_lEa&>hSb2fak&Oe1PJ7G070@$Dn zJf0U(q$}v<8xZlbXT{C)#9kz@Z=!Jipyo{nb64E35qXqqm2sbN^e8BNNZJLWW8ep5 z21_wyasGu zdbV-*zD?-7lDD;E4IL}*&Qp7lZZ=#woU0N;pW^~bH1r|i52BwJ>DtQAOvX=v?ddCV z`Sy_voZ!4Wvd|>JkAV5BUTm&X7Cm08XayAUNu^MWJCKk{(;WbFbs9*5qlXtp3x}C% zuu8v#iIxGmNrItaX1>*bfWsK2+-G;;_^~EagAswDBu1^Ve%eoq@O!I{6VQ-zrt7dg zhw82?zx=v=U0f7X_ojm<^`Ji%a^Y>dQsR z3*eURuJVI`?Ondrz2G2+UrTQp7=ZLXc-BS4R|t3w-$?f(lLw?T9gz%eD+b!>0&-noAMyh)Yb=lSL_N1WrQTF)z%9nH+&42Tq)~o zuJd03#M;c&i;^UW$Yrq`0>w<+NR9KO0sj35}7nU6j_lOIjsPXXS}M*AEjYx%T~ z&B@%Qd~MF%cr<+8y;}mcmuiQ%IMMrNbX@Eg%j`RuJ|}lK=j3F3f?-NXH7UE<{4wC_ zxpPi(GGXU^Mh&*aqVe)JPe%_uH$qc@7gU5Cis=-{!lRj~IEQo00@f!n8C3I&Goj%s zJJ(&~ew!~vl}^`2^aV2r%8OLb_SNfMDD_5b?2lFQGL0=_h4Ra+YXC3FW&SC2lI~}X zOfe1!CM-<9XzV3qB?U#9<}v1G(B`Jl)U@>%PxJz{&ll*k;hao6J7j6DqfwcRa~V#^ zj%G$SjDwTb)zt;6nFd4YAQhdxh5w)G*0uuhlx9B;7esMK6P^X{qcf#O8aH*Ase?)& z4mRa3F;(n)RXn_k00GrFF3cEKK6jyyCqsjI@YZM^-U@@nclgYJ%FmFAQ&RjXATU1S zDt6lZ5gqtM*KGsgtnkdIce-$PAs&K7$C%p)uPM6<7dQw`Z#ts#b?bi4v>YF{15a^! zw35Zd=iieA#^+vP(VO<`~ISa*}J1HT2mp+lmAwWaBi*I z9u04?U|pcTUVrJnIRs(?MeL52-7J_nDt&`vLQfhDffS5-Mj6}$RK7+-z3tkVieVR# zZn|U&z%n_B_&rI&c0gt zfbhV@!4=|3oWsKa4tDm6QhG76pPyX1yo8kPJ2D!_#rTlfaM?3EVZY6YVzYCD6 zIiP#Ur(9Nxc z_q#wqYb;lu7(DF!W3RO6b(3h1)c*l;|3ixKe;^VC9I21%cu__@Jye%Z(NL1HfR+J8 z|Mh%lj3W0H6cp-f;L5+`pr)aTiH((>0OF01+aMi%*Y~8ptEJ`HvMLJ7I|C3iFVqwF zZ-5z~q)mhRkUu_S*k?Qxlm~>DFC8GWlGB3=C@5HvzXovFoGQ_8N&jmG_XV9e&eX_Ik_|8CI9cbc zkR-%t%YcINgze%b@bgPP@~*EKh%98HnWX;OuBpYvkF_-@D4f?2Xeca1T#zxFoq4$& zEwFK6pwN5q$1h1P_A$Ual0j{q_p(*_V(q; z{d#L=s?qbtTzh2ruU-EA61ZxB6S~~^{~Dmm{amOJtU~$D#YA~N1_nZg@?(BI`qBG~ zW53~kx;H%E6?b{Ix4@^s&+ob4VbZO=PeSte*Op3OY-zK|%a<=3+)gi-bMfgfJUq_( ztM#tOe_r})fFLqKr>QSjer>Db)rhbHNHFj%9YcK?OB#Xc%1RcjE zE<4%!3YZ<3+NGVc2$=3bKmsd0iS_~&K})}=4Hi}Ge6Y@-Rwy}v{?cJ~34Wpc!Aw&V zD`4T|bZZW11e9@UNeN{j+1kn3DQj+UppFVaJ8i;6SN=1COANbFH?VQAS$Ctg_aPwV ztg-JoUE_8?jYKU&R72$rqwzkG-QuB_YjT5oItP)YQF+#+d|Jl~eb;s~yqBJ7{ z{~wa<pblI4^Sl(`ep6(n~DOGMCk&B+SLGF#Q+ZR zMK#a~v;>i+eI4OQw;*D~?zeESOBt<*@jv zFZM3IZOyyJRF0}RSPuTKmdgzBvx_^e!6M_ zQQ7X2r@47P;FF}-hjWx7yQXG;u@|0BobhX8M_vgP1c>=&I{o%@846_=lG?-mmqai6>wnG96wO zKc@$7P7pZC@oMWL?P?EyNIMnxjfMYTv(?_u>>Jl%T@dmZ5{SGE~5sN8Kj? zz*5M8((=ssDPd_~cK_edDjl+F zSYiSwWH8^lsiCR)ys4FHc}Q~7M`4W zWm$0jef{{jxqZ-P(c8PUMeaZ5Xry?4CYo&eK3V0{-RacS)b6gXlq=O9R_tnb(JoS&DMNij7R&l>etYYmqUlW6H7kvdNO!bB#(vStGKv$0z+HxyNeO62uZH$)$&j` z(XDd)`vcRzKM*+XYwam~2K0!dfVRux-djkzQSz9J&~&l45FCE2Ky^`hO19ojWyXGt zF`&&jMh35xf7{C&)gi^-%VHapJlhi?M8C&G4;+(YVn4;jOq;@*c%tbcfn*4Yw=!^P zX};K)JzP*tT2@)}aVt&NmbCVKGAPPoEcibqRu%Inn-r>Qs~xZ3bn%`8?@3HwLHpLE zr&|fL4qd*>cQHMBi1x5!-dysasg$eZ*+8?p0CCcZV2e{szPpoyfEsifO zBeD$Yd7JV!zINqL?d@{T@rL@q+xVpXM%^T$J~(3*S@KC_jVWbBWB3&dTQjbJBtu2* zO3o=POaT0uoYKt9@O($KJqV`L(>rZ1`rad#2O%Iu%dg?p6kF>5o(-`n6z!tAu|M19 zHi5_H8#|BoKG#dNH<5?nd~mf;*t?4SY$s$W{*PR39#d%^4la6?VOMbNh=LNw8bOS6 zEF;UNQB#z|HH;z3uSk z-n~SOf86))<;8nL(~uf+HoNHi0qpKcKYDuVOa}PM>9I+j%m#BiGmu<-C_5`D+iB07 zQMqBZd1|1-Ibsf|oCLud5lgSyZ!*73j=}gipOByB<;c8XUHpX!dSy^KcvYhhI$&D+_hBO8g;QT&lXdO+1(giC0g`LP>>f>EG!UySc7J zF+!@#wc>GwK~@7D-NrzrE`R`{<)nzQt=@ipJQXNU0RbfJV9DCWYtnCTj-7D3cj=1U z(Q@AB*^+XXxZs}F=0M@J98d;1+#9aQ-v(7!%_dNY00}F-@DZU{h0+oJxkoxWGbJi zt#=_OYl5Bb4m{x->L+rTs3DNJfyG6Pvjg#n+u5}t=4gFko#w$X`%U5Z-mbYE+w1iq zgqcEUb=<9*2HhVHWOwQNK<PO6HkCzycDa;M|T|)|$zH*cYV$e3XKI+O_lQ6ls zd1)vR!9D8^K>y)p$8dhMN4i@HctD_3uvz{Q&|WUjhniZNV{)ZFv=hdt$zeB``$%?m zc>_pW0GE=&o0DLWZcOHUoOyC432p1)G}+E+M7ZqGMB6dOcRyKVToYLx9$eyF1*!W` zG2j$?huV;R@LM=X#gPMN;^ZN+bd&=2AVhtIJ<`4ZxGMg8wX%sBFq7su79E7dje`BP z^K-NnpkbKpX@!{-1|qo{yBM{&N*s5N%(?iQKYVb&C}bh%AAj(?q8ELPS%9DWaJ2hi zGiwFXViBJ$T<2PsR8R3@8Y4I;u#QC2k>7Q?&o@bL^8m7HUl)5IwFJ*{IxE4OhdTgi zK=LRWBSIpcrzB{yJK^|RWJ{p+D~k5cyB(%deezJ}y(8~-+%{zKJYl-ZRwKj&{7c~Pzu)2(uNobE)_>_Yq&2wH}V(g3qWbIk|>Y0Eg>4PTDq z%=5X~!wE3rCd7{b4Ws++TPCS7BEkAV15?d+^T#hur0~sso1A9gAK|$ z=~UT)fsq9ToHY+0F2eiaB&5^EXl7e7pFg1GwY%4^Tn(< zcR%k?Sh(E@<1|t9kxR9vcIuE%Jvq%X0W}2#Owg_NLKY6-{u+>+qjI@kXUJo7X&TX= z(CpuZ{IZxDr8clOnS1|_f|1SC5fmLS=247 zt#mYglyfd!lvVP-1X0FlJhimOEk7yY%>(=3_d&I{Kc?*8I@(dPS|<)+tDKHp3J#S6 z$Np6$*S^3Kp!_FbMN4(sNtq+vfAGwBU!;{#CeCl8U@ZO+c;+sd} zcOL=jHzA^o+^U}tZ4C`nk4pIrs7&tqq>H@vKwN9RKw~zZLsaH3PLozw@%ODT56`k# ziZpJ_4=_YJ7ZCLy641rw^0MzhX2pSObZ%~Gsrk(q?CtsFX!>-*#ND0%C{;-kQZ3*3 zMMFI&@BK+w=w1$JE|>(QncGNlp*glNF1wg&p6Z*}Z;6I4XWZ|&!W%vPa}w_;8dQ^z z#BSMhEm0M>;AZ=`iYNloJEvXV6b%Vda+*;|fE23yzp}6S7TkRRyClna0|Xf1>c% zPoz7~ho^{0v`9IVh;g7fV@LaH4I&y8pF#OQ>u2ZqbKda!wX@UBJEXAyW2OTI+A5tf z$ncA$vJ`G8=c&FoH5OczzAud1;Aou=%53>pXk=oGw0UC&7l2frcZADdG!(cQ-{J7a7;u*r4f`5Sy}m@ zlLENOvF<5iH8cg``y&S%!6q576jxamy*uEvz=GH=7v#U|5!D_4FJW^*t(!}H$ld7` zelF^7aS0x!o_bf4;`!$W|bn-(k=+ zRCM0m@jkCWIF#pilRl514wTq1Mx1CBkjC=N?>|D%`5N+BA5A29w&zZxHryE z#yUGA=B5l^Kbn#2cgxR=oRmqF8Zpi6kViY*n!!>lZPA|TA|zpGzP=XmdJWs=$x6jNKd7{Z5(naU+L0~F z?9iiov4D8kp;E!5)66Bhp8Mc}QM)`Q4>7TMrR$;H2^gl6wL)mLH)If3#0LFrSdSv6_C4h%W;!3y{s%bJ zn9}4EJV`7pyT_CK&AS+{UYCilo`u(uA}8)(0~GkLN6@hVl^5?W1o+6+{)~*-BpPDT z5B`3DijWe!7KTP)^4w{$8JS$z=*o|_YkhNdqA}^4A;zdfVqM0O5a|$>%~ne(#ymlvxs=sQ%wQcu#rPDGjZ<=fd`PR>icRjKOfbSK?1l-F zpruY9WF-*(fD*%O{~0{?lpf}K+-x%>t(Agv&CbXZZ3k4L`h$9_t^Lt3O^coH{6OQ| zxpn&_=Bm0`|N4Y=4l76#a2>+z2`B}kFH%y7ajP$|I!iQwTlj|I+6i0-E4U*qZi2pD z_@zr%BV(W|D|eHf>o9XnWuHo_cs{{d84(hNMc9Z&WVYd-{*#XbZkL$Is0-p^tKxNW3E( zPD=OJ;5Cn^L2}uZF>&3}_B0|fp*sWch2NPe7vYojfrj-!MfU_f>ygsY#t3WN>;C_! z^84MU7e`KNHu#EVDr=zw2~T%+gzrbD{LXUWy(om*_aF15@HANO%mJE`d_dS>KSC_l znk@LU6z7b#n2D)VPdKGY;FVMB%oRZou$O6 zx7JX9OZ(l!Sl+%Sw-bq7jSe5k@;9}S9{9JepViNR-oX)bAmKV9(-3%TD`KJto*15} z(QfhKyekNknRJR*;ocw4@>p{F*dQc|gXxTvioaaPHc33Fy;e-l&$7ClMWZ=AJ&qVs zLMk^|46VqAmHpoPh2EEUa|G1x0v1(U;#}dgOZOIeJ$z}oJVy6)zS)2GJY7;nKTQ7D zfaqlLgO4s*DLes=?90E3H~&eJV|ra_@WFG`P^n%~Z|qBVRZ2<}!f?~m>q@9pJe5jd z;wWIXTB(gG#BNZZ^IzWHwXe>~lvKZV4L)q=k(Zs5P>_rCsl zj=ppoU=8GEodm=RACTO^{AfNy^7G%E7yN=uV^P0AhbYKd%MnEkU+G-)0QhtFPIf`2Bd7%ehZFTB6L|i~DuUC9eOCM^nl_?=@=tejXCOTj07%5iPWWS#*(U+|vB7ZU*T`OE-@%gsxpf;`3oQLxH7f|?;;OE3 z&8abKJD}gJt+!Do&wk@ID8aPqV%8X5p72|NUn76C*1vmI#XtVAvf*4v)}P>!Vz%)M zc3rh13;)ZKOyv*IrUoirK)A~tyED_`zFr8l$_y`3jU_)GxihVE zhoXKtQ4d*Fce>k|V=w5!E1lThnsH7NA`OYK`O#P6Xl3=7a$FstouAd$zk4oV^Bi*N zhujJ>J*U|b$pg|ZWF=@$GV97&f&+<*sQmi=+63+SQ63A^E;NH@g zmLL`0>lyi+#DU~NCgS1p?2ql~rn(b8 zAj0M^2(JWUW_i=#OVw7@?q9vcwW37c35H6~sq{QiH_uaZ( zPXY!J%a;`WmLdSpcbl*Thx3u41+%T8bD-?5)YzCZ3Ywkr*;rXW1C3@3lJOCx_8oAE zexGkuq4{lt`LCNmdnP6->a@G~qWEQ__Dy0FRw;MO^?%E$o$^Y?vj{&y<2cO@!)Rt= zxGdt^0D%S?kAUd7NO!{S^yp43P^^o4p~o=k@V!S|cTb8SQJk!GH0&nXo@z{-ZmI!Q zngAJ@G421-MrVCsGiZ>GWJ6SR_?T;e&Zkb;#DA%^U_h5WB&Ekq2xP2woW{?azNYe2 zHv>sPNFYG0mx;PwofA4vOxE9m?$6b{C3_*nX@-Z#3eNkFzxI_>gIXRi`@T|T1)$=x z0KHhCrK9^3E02K7SrlUf2UIu7Rb6vBRXmBQ0FTi$)3KoNvgKvT7303&8!v!cdU{bF ziCtbMNrmLh%uG;P{n6D0WSZCzc%@E_T>()lUtKaO4Eo-Bb7aj(?UX^-NhUIOhXr8> zMf_;Xp&7su-km)I25sI8_{>pP#ceGriQVkyDIDkeE^@yF+Ny*=`!1i5tNg%cxZYJ? zwc28WV;+8TG7hAoU+CLJSrL_%)1LrqUD6J;VFQ(9!jsQdsE1qW>0}oNs;x0pGa37- z=i!=_xT3w!!aHtAQzQ&aE&5s&wvKJxvMQl`3w z#$b`2`}%nG!TQ9&p(viblSthE)Og1rUE?yL{FX0Yn3@V`(Ad?492Y@n$e;5#TDf+` zMrN~E#QWDc3#&SU>|-8IE59nXm(Rvzfw=<#?Ru}>Z+v~){BazwApBJAh6xagpCD{Q zZc&-hI3z{HKC@Po`HxOK7>H$86=of_>g6nJ%B_anXhAzagQ_f_jq$CrxF5VOOlGvd zSlFk5mMuCpB+qedG&#U(VH#gT5@t2AG{Tb&t~8b zMNP+*Q!f?vSGX0Q_ud8s{$s)(H9*HVy1_LdbOQh;Ip9B5*OrCrZqnu zP}Sz-9=nv0eY`jQWeWJ2vSm02{%OyTECsAt>fr2l8r|jx@_nADuH`_`TM2FpxHA?O z7NCeM2Y#UPZ4GZE8y5K~eaf8xK8B1%Jl0^t(R*mW)KBB??rtTcEcEv0w|HLbR>l`V z_u8c25`>9`m1U)_t`5FN0=&q}!&3z=ATGOd<}j#GGimNFJv*I^dHndXVOOm98>cR? zP#>Qgk)ZKS4HVXa97ic;Tm^iq#>vS^wrt@FXi~j}j-JX^&8m4`s8f?I%LEy(dh2tC zG}TI0HUI{*cM%Bm8($j88V2S*{S}q|e5-{VXc_9>&Y(pbDkvoI?Hz9E(>FM5c}&(j z?s&J8_e(Mx`+Vp$UE}`3|F!A(olnmdEc$ZYCFx)O0JN)Bg4QbC4FvhX23!&pA$}F7 zR}LT?p4HVF%0Jk)`572JU-S91x3{-q%s95| zUTA2ja*)5jR+Z&+QG?=%HMlm2s<%|U0`z(fZV84pwk!CNv|vc96+GxpzFIdJ`yR=~2;xyp3iNoBBFb>_LQMyy0&2Rn zSBU=puU%cf`BI9^&}f4#FP|$aT4YeFp|l;2;#? zc7%luz71tp1azmYt;GpBW7rxz?cY@@G&}D zcrGL)1mqrrp9Vte&-<}LRd{;oYoqk%b>Tnt6dA`6gn|Y z*Z2O(f$;s-YphCyCfmLbG#>}7HOIhgFH?HtYrq4y-v8zs&nh|UDegobDCouma8DSG zOr^=dJfZ~)b0{O^e*Xy)s1Zu;)T&jF|Dm!b=ffTU>++DA2tEWFUtH zXtZlm%gk(snGQ~YLKr>F_?7d4#iuKEl?|n}gpVg!WnZqayU;@}JG_JsP&ijdv6iw}uk=R{*6LCy*dKXZy_(5w zqWH|Lajt`|(rj3gT`tJNkJR9HdqsdqJK5u1J?Mbc0nKU3)qX0$_p#lm%3hwJjQ`_q zIX2*R<)Fr`vVO^+eYDlqgpmjIrUPVamf6-PSK=8UQXO@%i(c!`2IAIbj@}dZr*&Rm z2B^z^ZEP^@8J3cgQd3KK=aXJ~S#&bLIiS<{JtZNRkBr(?$@6k`puKK+kO6!#j;T;3 z*pM59o>q*%4CgHE4bw#Q?lpVbHzVXc==9+^Mph{_wYVhNqfJ#F`0dXx)0<3g4g*^8 zyV3jKBQaCMtl=QxUWQgaMCX1&t5V=#&0y z8{VGkiFzYngZ9AW0Wv<}>HfsWc9zCmhO$NG`NCqbh*!%o+Gf7eS2>+qDU2zu{nj3c z0mhC(m%AV+(?)64K&AD5gdo5nrBNFaFVPA*nKex;TJ6HCnJ-%~l7s}m;P-VsNQ-2a zFuTV$-4@Nv+`tpPUrUzsK*An^YdBkHj2THExwlW2Qhg@qjK66iRSa3mNCbj#oSEo2 zMv>&@#wwRMKIpoU)a4Em_4U3B5E;cm!(i$_TAZt1d+;wghLOP=KF2ESAPCbdN8K6!08_s|p=#v(FHLS{Pi4mJojXZVG!me6HZ`DiZ4Cj0J^s)77g9{I@h)b6t1;30l8(^aGmoj4?=^(Yo1e-1k4s} z?Ccq+$b#p{_DDu;KBVz~e+yH`LeP-F=1q%-O+VPHhp?~bx>;K5opB$q;&$A?vt@FL zyGV)uvx=VB4_;j}10vQYYGtkCHw{CkCjzD@fgl>6-XJ$d#Rz;AhmB>bSj5y=wh-vV zz9W3$8h~~Ue5FmH7WVjaZ(!;LG&hw`r{?QVpzHb%qp*O(J>>d+!H|@>aDR@`;{Yvd z_}13!eDszkCa5Og=!PjjiFhA#>wyPpkGTgb7it64s&L*+OaRLSZLh2Q8B=46A>*Km zrx`-eZ(}TK;j1US5!DZW?v!J+IMu>LKdUKoH{0n;mn#x6-tzo0`9D=prWT|{Ia`DA zoSjCcIi(!P(MmyD=;p#1?S@7uq!+MGDZ9RYnyXeMiSMK9eo`XL&h23)0~jle@BKe* zRuA!<6Jrb9n?P4mAXy`3Mzm8iNOIiG9@$@<*fopwj`MjT@7G9>z5Y)8y<6?mghMeg zk3P5QT^ikWf>*B_3c5ST7Fn9uXqOB16yR)0P7Tz$UU9juXCE$(t57z`Nb=sVqFkx3HB$1&5B5QB3+D0Jz2ICd*3E`mcjkpCwS@o#45gHO^$2h>H?JaS-N6H%^qNX1 zavzjYUos8h_P@-h0oiNH&=nSy>@6iU!K& z9GlACTUHd=yNHlgWF=&ibqJA7GD6n#Ios;6M8Q1&set)h4 zf>v`50&<&i60#|{Hr1ZbBrV=bdqG$<)~g(&NT!V*WrNeGWQt zLA1zPHzQ5|``(&tF#^;mP&<&aH;nE#$h(pkYf&4jNK5#fq_3{tiT7_TG$}_(LF^Ze zQUf3+j4Dmcp11gny8lrel}p(^E`b9|MK|=cS$}Q?(pERYwNaf1_xRdkB=M%`u#Dsu zM5N~zn=t=|q*=o7Gz`IY$8gM$`jf__ASQ-t%s%)}X0H?+tPuf4*M^iqs_)};BipO@ z&K6udHyEv}MQ3X$ioXS>A8miAe?pM@ubtbF93sVqFC0T51eEAGc31em?A~~9ve0Pg zTya6x7KmkBmxP~Ms4-)sm*ZSrz3^H3QH1k*%~Q_1n-8PUW3Tpg%qC)j45Akh~Mb zd8zT2i{fhi9vpR<9ypljsl45k-m|vY8xQzZ>3g6LPe>T|`KYD8a6)gK{~oDPj+23B z6#HG6v}EQbV6=i*AM|hSpKL6@y!_tQwp8_4RBST8_J4iRO&;`lo$5Lo^lYzZczodO z1dV~NrRthr(f!7)rk1{21FMbw|Fq{Nx#ISw`Yi6hAxau0qHB~PEy@&smm6;c8*Ba_ zEIM~YB|9+$cz`WRub%z8RsUl@`db`&qW=>a^8d%$M|=pxQ`)5fwHslnj-vSsp#9G? z6S_F`t~W6kCMQb+5dj)5kk;wTM>@5mc(Ejw{u_Y?iuJ8OE~0aeqWH=T=`b`%dc13U zZS?G`Jhq(nC#&QGwftC4J<=eSAUd(X1Lf7I>=!>`E43)|`2h|VU3h1)I@X`5?B1Px z3ft#a>>|huJ?=txg%VOIK|^Pvg^t(^8b|k<3gd;DbsoE31} zXamxqQHI_`7T=*$!<*>3G!!SXm9=$uH#N`h%2YirKWhBe;Q7n`?5S$^;w23WwIh%A z+b(JQaCN9r7KbU51z$pLGXI@sc3ap6sL}!hh+%trfCSn+@R{IVA6=dKton^vR5D6Yf~Ky%zw7j$5b_t#8$I9k z-cmh1J-fRr0ifee;^d@DPovY&IOwlZNPF^;z_fV!-O?n~yk#msZGWe(*FN7w`5=$L zPzCH(+qLO`cO35<)j>-(GKFjllURvJ9ku7Rdgq}f6PjQ4f$AjENp+GJ>kIqrqC(OO zr_KM#@GnZu#J>K$S4B>g*7AXt>!(f_^VMu7oT(|B#GQZQ>dT4Ri(*&fUjx3s8nFXF z=YUHmNS~C`%4z=3U+7*y2jXvp5Qx*I>5VM=e0?-@J+l-v9Pp;BVzDogL*Cnv-^v10?+W?#abXmx)Gem>sp-r5+mq+|0XB3H$$pJe{h zqTmE@x_EhINjaVKV;2^D1O0TarJkPb&lDgdCRfi z{3J0|RaMc^(IaJg!dnQu#gn7`o3HQW+=LPOpix@iBhNp&sZ~x1iM{do()XkTXqa!4QlYJ0r9ffr2+e@=VN;Ns$f22Wxe^kx7uqvd#tx;fOHfO&3CRH?6q1@ySWDw+A8 z(3b4EQXfdRRk+Nn-Mo1dR#pehz%nMXQ$kZ)dtvCtyNlaJ=P`;gFJm%G*pI*i@{tiO z(q5Z)%+0e$$|y2i<~!aZP;{e$V<2wK@=F=ZR>FpjfZ=yAhi_(P_Geb@?=w=fZpN3@}lkeNv$z^SK>Y=XcVeZ!<7!^5*_WSmFX?D2Ih)GWSDp z21&TYbmJ%#^N*P)tLl&Zb<;RtYe0)AzD#`z+Jl<)ynNYw`29c$S%R<4mFVZ;#d6)K z#lm1$1njw}s3^$4zsYX65b)A#(@|5_u=!z2d~D`Fw}qGp`K7jv;G4P-OKfH~BjGUW zb9|t`8U}JbQ|U+BmdeUOVnX(vkgsi#3keCO3f%=EW7ra8?N8XQ{AI=j7_)4gTwJe= zUU`1+rY&LS6w*l(PiP=a{0TU_O@AhA5i6{j6jl)R0p1OJoumhT-_6onV5+Jd7cZ7* zKNqW$CJJCd`^u%hj1{BRu!zs;Qce)B^O2#J?_pw)(+$M*LdgvrL^w@?pV1ynH{&vT z>PUKEJJTNXpAHNR#K%(z!dajKmk2+rW4<5^w@J_eIyDXU_g_!AQhU5Lr!rA#MH?Tj zOYVMp6XZ;nA8JffU>M@Fz6X0}q@?5kLyZh4XM6nkF$j8B2uVo=&6?z1H!xBh)Ceek zI&%Hqeew(CbVEv2fJxle`CB_-$!!jyBHfIr=;(L;XHDQ-XV1oE$t#NAyneFQ@NRRG zw!-U;V9ne8dy0nbHLr2`e{GtM3f;fC9!2^wjMPw%k`mXB4hPp5S0I}}3x5UCG(Y9E zl);L}Vx2g3-p#N7(PGz>W#T27uHGw4Jo}vY@m|wxplXXYaD^X2{~K^H?HM$)R3nIw z?3|pOVq%Fk^a6<~DTSnMDlIc0rrHG0XD1uPKG_OOO-f4ocD0*SDjdDJH*n25J39lS zQfufrF+I{>24qJ@MNwH1m(XEJXn+vXMUD<<4gX)11hyR)7gx<{ky>;;%X4$;c?~@aI)t4&xB278brdCzl4>VZthPu=9#vLV zL3QN&($WQfOi>#DGFw02RpmN#a`ygxB(7n>G9#=q#FA7AX2yvjx5FFHq^S~SY?+R&P(gn`ewmo zUY3y={1wDiSy@>v=#cT^1<9%)J39v3Jyi-Ei}d*TcqnA3d?X(B^z?+HZ?!xXLotdb zFuFE0G<2QH?^}E1>B-TsN8~j!HU&8-+DzWlo84U*o;>_S8R9ZDG}Pd}QVIRPU@!}X zG?VwX2nv2Ag@uQsowK(M4(Y1oRkYKB{%-Kawwaj^P)4k7%vMAqH`)A;IT957lu-0I zlp@Z<4i6r1ogLJBZjYJyTM%c<-L6G~dv9>OGYJAbCT8ZP@81KF)H8Jnr9llklx%ES zU}Xt*u$B;G2lnviNaB%HD@h}ajEt47rKP2Uw`5(! z_FrByGBJUgn|}8Mb`r$R%lF$Oz=Q{W>1t#n4HjUT^3-C32-TsZb1d^`q4CJbNW+tF zamB^F+gf(Ix^V>s+z79_#gP&NY98%)VMa;EaVYB89R{;w-3L9w-3Ir;$#cfF$my4F z&+cBGO|*aTU^w?GF*Y{#0AkAnDy7790@)j>@ru)ho#3YF1x;}hzeCIt6&0l_@d@m< zJ^Hm#eRn#t+!gR^HXS~7!`?-SOab4*f2ISG(C8Au;*RNlzsi|GQeEBJ#k^M+9CBiEN2bM;$ zI?z4IcW-YmR2EzMeS3ye@MUg3z9?`S1lE0S=xr~&fs>%l!N^8KV_1v4 z%f`kQCG-;~-qv#c!G#MKTrZJG5KbLC6m{UXa3shn4^QQLZ_hMpiRK>XgWYhc#oT)5 zDY*O$7Q~^SBE{I)Sg#%;?ZVR1(a}*`k!RB)*BMbOB!k>TH)E9G_vbCq1Z@!?TFMzF zf?p>iA<18(y6)`ZAt53X?;Dzdok|7qJW5C($AfuQQi%6q^#+hHeOm3{YRqQQf|>vb2C+R@(HKD69`nxVPD#UP4mIYu*aXKct-r%9P5Rj*!c z>Af=Ys#-o5Z&lLMgSkfKQmBt?bp^&pN$1&S8Mj48sJ5>R6--XVdRSZYbiEGL|z>X3bL}O&Q4pKR}^&P zzZ{YtrM95YU@-LM%a?%x3cgrq330zE*4)BE)Ol8MT(FuoN1O1e$JKk8{ebXg%DuVR z5brWAX*V<*h%MXk>0Pt?&q$11HMNbldfG}7e$bMHbwexWT!J*%Z!U6piv zX-#Ckr$i_xVVlK7P!4SpT8g0+X^msO(~QDU;LF%pQq+Se^Sw@*J6{!^>g8-}>w2Q9 zZ1m?lJhXMZ8@-qGRC5+SG;HjyyanPC|LtF?GyYD>)zhUWg{eX&iQG<8;}%F{uDj@= zPAcD?isL$~iKhFmpv{te;@N6VkV9wJ&onVBjgL`QFqyy;U@739m6R?oH)B2}aEvI` zva@jEzpk_@iTPILl3zsL8z!un=zwoQ1IlJ*A7FJLeuEK1CjH$y?;#V>PjP|E_Uwst z0t^Ok?X3oG=j5bD^Cmynu5A&ZxN&+~BSQMyake>5WURw_FP>w%GciwnU*6NPVCbWz z=hz_JJ)J^S^6R;8A9bKpMqISpqr;)sK8Io!7B`7f;`f^SL6u47kAF&Y{Fal* z=m}GF11T!!xqSPeGy!JERYeyII_)J9+-oZ@s9-o-=;6RU78i|H!%vP<7ZxAW-{rmZ z{I!OzCox$Qd%~g%T5v3`ct6)6l*sDFjj5sGY3LU~&-Mc*?0Mk0{TD5>5+|{{Iqsyt ze%)5ulDWLu)8j)>SgmTkr9S(kIjh0vk=tM>pPCNqblAqg%O7TVAP$(|I#UHqGvs_4P!98?HB0%KUTl>V! zdj(OnpMk5w6k^&!b&KRh_y-Js96tj8C`V;Gi#NH(a_F&@X3}E4d{(W+CUTBm`|1t_ zW`?hv)Cj`VNM4Le;`((5t~{ZJ2HM8PCl>|f9=jKmZCvJ!iE#(8_l7fNICNuJ+*5j} znNRhtc4jrnEYKFNdI2f{cK-_#;RG$Lf@sRmeZPRxFhtH~`dLfJ?CYJXLgeFycct5g z4S2WM6~5w5VayqQ@FR6tqs6`E;}aLWvqir!R$g6Er*B|XYav_xcw@kk<=ac*h*BZkx;*OA^@OkU77Wg3Bk|;&Q;|^_%spzEU z8`iXqDy%)sD|?uQxg|xpG8n@$+KgAH!@h8R#3*5v_#!AeXrxr6Y*i5DYGftKSr`2_ zEQW+URNky2)AQA|&N|5?(2Yj&Q!RQV+RrIG(nE*+;vK5` z1n5l2s0@sMV9OQgaq*^Vl z#j`%j5cmnyFOb+Sqn>TqvAPcBS3YcS^r z$50cIjJ6%#dArUXj5joIKlS^*b7VZNZHqd}c}>Lsf&N?N?~a$AbSmGOwIh+T?#t!# zpUzSkyW&2tN!C3G{OE`n>-t)hqQNF}G8dkxce<2?T^wE#Q7l@5s(ycHvU2+U0A3~X z&#SuSo`~T^EMeZiXg?n(oaXv?@#4$_%h1>58T->S-)SDQ7IIOw)qb5IaVyF&;kcc- zToY7pANc~wtnmJVW(^1!KMlF^JZEP0CH8Z$9S8ZqNtXYq{^(84so=Mc6SjRX5*8PE z9zTBSxsgV0cC#$4+9mH%Z(0L{FgMSy^WQ4VuSSP`d36&G_ngO;+m;V*b&T!fn6&j} z%=q26v1u_JVHifdl)Cbn1bLvWEL2p)Kk?zCSd)ZC9x@MEj5@F@Mpd`y)&86cDL~m?+i9TA|a#a z`g?bB1GUtOvwZ2sIr=3mz-Qj>l3z(a{+^lzPEWl_((%^tcpblX+e?s_V?)2hGaNHk zRxiMG2zXM2Sk*_(%?B_fPv+W43v)YSko?9wml%#kw*N-V(w5cNt z?BO$7#ebA>v_4@s{?Iq zNumzcf1p@P`|5CFW`<4@CrHzRoBeb4@t0T8M2N2aO;!=n6-@3gFO34_aj8Lp9Dfp( zMLP6iMbfl)*lTm0yUPM&6i;2Qi{X`pzP=RXtik64&-bhlo-Rw8PS`%0_Jr73@c`f> zY#Zw54pwisw&twTe%LfX%4O}5E@|U+P>8Bqxf*o#=O;_riv?5Tw~DWJCVya+4C{FR zv`mKYaObr*e#f~CGB@I;>!t$JDbJRPwlN$Rd*<4$dl*iKuNP>DMRXFHRF&MAR_jPj z8bfGm?knCs{&m~;*7fpxA1*OV;JM#^la{ryE?}-gq{0*Iu{^-i?KC}EHju)?@Gvf- z1|r}s$EmtNV0ou#-t?2yaLYs45(W{|H(jOh9C>M!WG?T2Jjm7*gmWH~?=@wk(7SY+ zEM(r(*pwAXNKPtl0vfWu1to!}U}s)kzVIh-;E? zx7~;Br_AcLzo~G`b)xd;aU^k-NHJ=>Z*!}P^2G-4D|&Y1;{*!TvQEzchM2SfA zzPCBh*k4;g-a9t$`=ac-S?aC27tJk-zlKZrz{rwR!+csU7Pf<|+ia}A`eq{G0+ zPBQDSu$ZAz1DeqV*IbjT$N6`zPUGR3hAva6ArqhX*Oq)eCaJwxkps^3VrjloFq7Wt zLS(G+ZD>xHKDSn^?@NSCttB0rT9)JsV!yP*Awa(N=x8*v6z8?*wbVFl7sYeOI4&Zd z>lgzQ(6degwu${S0ne30?x{!3tb8HoQZ5)#6+64ey|o>rAR`IgAyWO-nc&NJQ;0ke z+d}Y)7?(H4fSeF+KN;VIZ7xbc&?e>h*Va;POyx0=)e&PWz8h?syjQm=?Vr1T_X{nj z@U6VH)Q6|K)@GtsNt{2Yh#1D3?ojd!&x)OOR5xkFa2bdW(X+qGSHxjZL>o~x>VO|7 zE$7kmX5~SgZus?QVN|$-#^W-$wS|eT9;hE5qyp{m!x7tS^^ZM>30>fXv**rig3ZEU zZ*z}0nhCq1>{f5Tvt??$q(QeAt0vwymqY^0&GSoZbNmsJL8$MDU~#F2*eLdgaMB3b zt+`QhP45Tfa39=PvJ^1`h(fqYNo7?YxmGgYahknJOn-`5tE30;FbOZ4e1ouEHDa<_ zXvO57=RGA~)jn=L64haqJJJM!i!S;iU^lLIshInG+x&(Di01iE7v|RDSa-~U%>PE@ zWOwCarK{McbSX>I=}&e4w_dpOU`uL3B2$)L2NMK+p2=T`DexOL2nvkzU75rRP@P>8 z-H&yDY&*p@ONW@03h$zvVW9n2|vKCirf{C5_TI z7FJ~0<>W{E|N$OXB|t~e}6~D9YN0@fFw&#J?CAw z$wlq%@+EAqjd^vtrw6x5K7+FNlj9n|GWSatvY+VrNd{H1TJ2%AD+yC6m(Z5H2%9WH z-MPE3;!8|~KSE%zW_hnxGivylO({+rSGx?W^Ilna%&UKT@X5GUe8iY)#fYs?la!X}@gblVn3y)~-<)?$OK!--&*oc~ni$a2 zanX}U-XYyvh}0ph_gO`IUah?DiYcZr^a(*6(u+i_liCEe>vazmY0ke~krZ+5fn(p; z%clxIi9Bu(cIdF>96RFJ$ab&dMg-qGe;(`4q5$L~R^y(Y9ovH5{^=o!>;Y-tma_aq zOg2zb!IM$dBR$VVS*(>du!lkJD=Y2DEO&7G%A@?bFT=x3bPk{fzjF?D1%|`}^qntZ zX_95c(Jee0Oh%`P*!1V?#01S0EFcbiq#b@ggrMp}kFtR@M7G$OO7EGmey#8C1#w%w z3w5~xra~4U(mkj+GoF>JC<;vwd?|cr2AJ@>~#N6#yk{^C@MfvEm;Snsn3Zg5yb?7NfCEgZVnD4IX=@O0FhKhlayKXyB} zO~>qAWd0c<(rIP-Qdb;7Xj9?Cx}S%FW^(hkh~tvdW!07y>0W ztGVOUTfY+~I3{2sTsEih?!g&}Aw~@K&r{3fNg1UOqX-j|%$1c*rd7Bn$*nDHFPlMP z1hKwpro{HG75;WCE;xvw`npdEt_(a<$8h{b>etB6y?dDwpQ|B%WKTanL0r1T1^~oOaMcS3Ncx1gJ1 z4ZNh2Hsa!8#4-}sQk;W)@Kvu?AK;o}@r^;mu~f$&yR5;DkcXjGy)lvZSfzMIKv?gH zXuLo6`p|7DE~H#kv@d@@7_>zRevxy=3$-&%d&NMR%(-X~);Y>Pqs#ZXArQ&c?+KSG z5&9iKQVqUZ#_{7wb!yhk3jfWf*l#C`y+%XVvIJ&~okv57=_*_BCZd`AJ<_Eob1p(( zWXHeGSqBedq|ojUK}_Mzb7%V3nAvv1wyxI)VO?IuLh?fu||qSlz&1V^H^Prh)g{+<6x2M9-kTRKdhvdagdu zspzS5?7Mw5i1iJP*jyB$?fnaQd3esM^xUI!>}0uxy*x2~iXjeigNS1CXIL{_ulaU_q5~dKu0Ycfbb=&F4n|BAhXo>_&rG0RYG0jnF!( z{)G?yhPNrYZH>&LM>N6v03L_Q36L4e{Ck($$RD8pCk4GRfrt=R)IV<NjwTMG4Hn!NJDR%lKI=rqzIlzTd z@6I#ayq>?0>;>iu5f`@_aWXS$8L(D4^oWe*wR1fA(y+DQSpT_-9Q%AShQ)|aHmqQvdO=Gxq~w z;o%#8ri4AUc7bnbVCA0&W&Pl$89@N8BRngWf8XJ7+scxT%5~!Nn(gP5*v@h|2;R#J zBU@>`EZh(E{+E^k6ormmiC41ZWit}yFkkg{{ruKtSCEM|L8E=)YvIyN*EpK%2zUXA z)L(p*EUE}g6{gQWuB+vKTRWzzHF3M4>_&lW_Cja%tF_YvuA`B1GcK{AgalSv7N5Wv zE6#*C;##=UJ5%*PC_Vtc;wk?uE}*V~Ke)H1w6@f01>L?L4XfoDhx4?B|YX-;0G>9Wi_XqQmz|gB~o`ABV z6`aG@rnli)W8n57Xr};qV*Tg5f0CK}LuUeGTxz&)(!=ws3eoWJw8Q9#kyQ^B7)%o~ ziMZE)v7_VbprrtPVa)xi>PZ`1V{M@Sy4(Q^y9;}}?K)Q#?&oLk(1TIAk7PK<0(nV% z-SPfVFw~&)&YvMJ2m%}f(%_4vw^1Gd0PuuDz{Ss6(4g2XkqY?K~b1r3(kH_rXxvz~(VsKvHueKhh|ye3(Ct^}v}mOlU6 zmVwsZ*6pV6XDIAz2SlOUpNqGB(zR=$+S{b{lqmahbNACD4@lyuN|4y3>M1xbcvYRd zFh!|?%-0KVSKAUqx8NKv0M?SN_V|~hO3e`TEjio}GTB}NFynwi!Uz)Hje#FCvdKax zNy(chV$LH70VA6%dqLLT`6z$u~?>e*_-`oC-{eI&%Ue*>Z(f3sSyS2W@%eMg2E}jVr77nPdTgO(SV*7y= zw2rPEaVyn!iNCmkZeb7yHB#V)ZV%*qnB_06y8p3q8+EeNj|u0{1p)1=syf`$zotEx zp$P%pk!vt_^VQAkc(mLz%_OP(cc-HyC11^dyEFSuX~_JWLrP%*Y6ST*%$MvPQ=A5)78B#Flu(M7Rh(4dg{*CQ>Rb<-u{A-Fs)!YYBnIe?R0b6SA_IP1{UANi{Sdb z7^-k&n>*Q4UWXg`Xt7y0q6^fP8R~R&W^MtfrV#yDvJSz#?8ut&M}1 zdFj%nplG70=4xcw*|(1-l>v<>#s{XaQqE1SHWO+PJ=(sX{LDRl>blX%k)u0Bcle?c zGPhK7?^fwK?)IB(uGHDz)XHWe9|b>2XLCVWyEw>eH{T4!)fl0X_Cl&CP2+uwd0)w1 zb@$yOwNhaN5<6XP0-EoiO-Jsn?g5Fjeljya9Yy0)~G-&rFe zjxwjbPtNO-TW=iU2&TxS+y&rPvs?V2l+$KPhOTp6t$hJ`^z*b|iDfTfTAm{x2-E7g zqcUW@(eQmB_BE>yPv0gfOZy$eT8&4NLzKqYw-GrW(9-Svt&SFvJ3JW}n_Ns`vSl09QB1$K9Pc_&kE_-`6uCIaT zzo0F0ewe+~YS^&!VS~<7&*gPTVd>=Wzv#{YN^f+9Om_IM^>7o zkxqAHD!{zOudlu~hl)8zDOAdx`JIqRELlb(ARv$AsXH9V@M70VhlbwO)ON@1x9H8x z9EHRFZ%XSHLX1SLP4n3yW#i80k7w0t-=szHH0Y=owZ4$y%27_WGFb3no;piVuH$21 z5Dy^Kdx(waem)e$KRgKqnSs_9g?d_bE~_W^&P=I3Pd~@K`E^>j>34iOI)1ztD|S^< zR{WCo{7}#MS=J9A9xxB^iA*eIEE-)#V+=mRnuGX&h}X#K550y}61=`qtK7J_ zTu1FG3%!JDh;Q94U!I!4@FT;cWz_U{Ejd>=h$t=0wK|k6mYr=?yjPcSe6zMoO#FIQ zCg&?t2%J&0)S4FNvofx@x&Qe^pZbtV2WcPbBgLfTwIV9ftM)O9X@;bo@r4O^OWx!* zLIRhV*haU*%G|}d@u-t~tzM{{$QB(ETP$!e=5Ra}`#Gfe_n9l9=!$$I;rJXo8AuMXyqM4DC8aK5r~1e@YSHqi;Qk~v zGHQ8j-&|A;(WB_m5=%<9g8?}|rOZ6`^+B8nDd*dbl2oSc@CCdihZKhTvxwDfqi zY})xG;C5Hg9?g_*x9QsXA=zui+jaj8k?17gmT6ze>bYM&gAJr~&^je19i=pmg4-0I z-kn8z5DE|GsudP}$$v)Ykl zx19$EEaC4IZyen=5oD1p#h=J3ENoA~ni*0O2eXI4zBwYR>gwCZtfU@lJd^NM_!IqN$X*mT*uQzp6)cm zColJTl?tyK|K)Q@bvB9#@74Ys7#~1T>F#2#RBE&+qG<0huPCZE<(tQ1Kh4mlr<&K6 zcP>Fav~uPMT>FG}XV!&){p;$!(~$XJesquFUU5TY;a{GMRHqS*D0rQH;}CLsQG#Fg z1wm!!Wl&SIM#geW>#J`PBio-TOA<-zqqN$QlG3LewJVMqY)Geij=ZMTkea#KH`Hyk zGL~k9pZs@K-YHz#V_r?(whB34MQB*7Y3oJNy@Q@^f$rh>?&;(JcV(u#WL8_R2B zuk}^b)r*whdG>a4MQZtfyzya_MLJvD9`HGUI7Z+ccSWbJA@=pp_lN1}ygM?AtztRL zk`w9mT1!D9FYna9hy52>EtLXn$(9oR@$&KIu{3OaBJ`nZ5x(pJmGkQ=(}guZ>;HUT zP7zD&bh+lt)22-NrsRDFmam(e;ee+G>WYc3D22J!C z1!efpcn^KH+rwJ?%0NVZ2nY#284aC;E}Zy*8uu_F&xPU-7phf&!Rp_XySt(4v>&UI zvJJBPa=o0M5(5VXKX(>cPYgy2635{}#w(|{h?+K0wbF9OX|3fzg@M;t)|jmU=d$^_ zv~zYvv1lQhf3j1B#m`en0+T@s)is7y$xLQ8_jJB#lg~^nWuel_#F1 z0J3+d!kmPFl|rTB*>U*-{zJ=hGlyR+yqxwu%aXtYaXb?P(t-;emZ?jNA#`S6pa1Ki zr1vJbP|Ityl6bc@)L+14yQq|9!BDZ8@flDBeNA%m=KF>U{D}zb1%%Tr%O6w?mP??> zXeiM(4U~~FvffUPzU&-@Sp~?~(SZc=bu@U^wwh2?Tr!mLRvQD@xora#moCOcHJDUd z5{~OTbAX29`SJD^ZF|yt$3ze5ezgyyjl`P{viX89+s~`*z|Bfp`AqcfVWFWi+KRro z^xvV@#4XR9WL6@S9)&93J2?u!|KJDk_AJnuNSo*KkIT&?CV{^dsqq;I1DVkCf?r}w z*6dDZ(4m4R+2CXHAx8`u-zUT{;CYk3Oct}!f~!nuRhc!2#m1n*`ucMPhT(mn7hRCm z`}JyPN$MqU`uUIRW2V>3sY(ndJYgjv&$E!-^Dyz+tokshzldDV1?80 zp^3abxX6a86jDqqSyhW{k%`lg3c6qXM%rzDWfN}y^$gzoXJQ^esL3uS7ojby!7c?< zMkFII5}QSp@eiHHUOo1TTBF%oD+{lH{mdA8GNZ6VH_X(~ET$QcfD#HCepsi|*MEPt zZ3oSNv6oeZI1++P+R8?MRgX#H>DOz`p0;mMIgBzu2=W=jEL7Gj1qRgbcVrbzfHAm} z^$*M3l7G2@@o`v>w;}e-*m0Vt1?E#mZ~WA10q90sck!PQDZTj?RAOtyVlMoLA@r7Y zmZ$sgZ$ZE?D2zkSM-skfO-oQ=*$d<&6QK&a|M4n(46^8{CW~gYg}cYG>#7Kro{J7mO&tR&yDj3bcs8K2?PaL*lSSkqRP?9m ziXQ1W!!k2&0l~b)-^E92R^Qwbw;MVyC--7>^eQ&^CY@av6+qWn0F!o54==()vCb3Z zxiSH5wRH*FT-DE19~_t+SFomCTtMYS)031wduSqRap!=M-kMS?`7Ok-WQ?CPbyrAz zeSK~EUUdCbyGr8!N`J1>_sG-6#zw*~f|mLUKhIyV)xTb;1@t2`?;o}O^KmLhMiXGa z|MPL}tCvD2VO#PB+OP@tE0DzNVdc|!d3hc9Kt~{(+aq`fw_}OY1_t!HK7^O9W-FKz zDXd}VRQVqLs;iTpyeD#D2lT8s>5fKq#q|8IVl=&m#;&e4MKv~fSXyHX(>vtelx&_yXt&NoryJB$M zsdv4~>1!EL!}Sda((f#-tTgk>6^ruo2Yy{WJ^;q`5-25XWjS3zDRFXq+~jwng`(t0 zNK1o0R>qU}B3{6s_wVH<@7cUt4K6Ayz#Rd5M*&CsqGXAIULql;9!Vh}`vGKRMBvS|o2nN1<2|dD}jI)&h z!2mRP(>FC`f;qq)LAb;1mxqIS>UQ27eu+s*+(R~IwxF0HXj}OH-S==CH;XBsc*rmAaizY358_fQ{}?GdLg*fDgC zl=3-m5(wgqGzo`9BrYXh*XPfdBqb%Kq>A9DSHUfoaEacW?E9(UhFCH9N$Fx%L@?{* zD;STU_apB#Mc)=+C0?5>FgA@lcUTs^Rtxw7@)Ut zj!HN*eT%K3|8|~>YyS9f2X;-)1_7rlNG4xoWW0GE#0kPN85x;}mBU~gX3yZ^Kuovw z=5Wn^U0Yj=UlwzHuo9Cjm%Tq2pBx0#Iw;~dE-*4E&_h$a%o?uA&-t23kRMz{5tre? z6X0m+2h@G^yen37U%0RjJi<=v)bTJ5(9v*IU*Ypm41it&b z<7_a)bFe8m4!xY+LyTrq2ETlv4bQe_8Q=$X@VEr_I_7%ZGZU!M{Fr_h{^YHGdq;=b zw$qXp!BrsNkpcPuUI~nZC7vEGSMTcU)793_--sUH`uVfOxNH)XWp=X4Ne2fHxA{m~ z3GD3b&`tbcP3&ZI8(CyrEurUOb)#ZaU_-2zs+t-Zvt&#Sy=e<M0R##|@KN%O11-A!N8zk$2W2JcHIt_9qIeb=^$QG$_ru5Kk!V;H~MSBXYxng;_eNxh)` z46OWTQc4QmDrpio2^Re{AhUMY9ai$xpHwgPS9ZhH1K;1l#zq}QDfk`aR?rs_9BMAh z2%>cs`cH2i0v8`<>;>oqUmCpvuWLBVPNd-i*0Hm@OF~Qx+eH$rn3|Q9v`CPQukE&8 zEg>NnS6)B>271BO)zu?+-#msVgd4&(GtXeWWc@@;$OS~0rfIk^X3_X3Bogx2OT7n_Xrq3q=b);zb+W_07Q8pTGT`ltLo_0Muwnu zt+y%yKoNg>jb zyvsLLm;_pB->s>+bL8YtAnh6cg*6DZFV6FVf;ybOEzDWJte#?G<4rYsgF3X8M^u#3 zEOe9)-03?|Fv2y)5Ju@2o}$y0Ax|6&j1fexRci<#Tp9|S<5?j80La)}-Q3=+JRtm{enV_*!A1lfB`xjK zl$6EIOR4@CTU!9#Mb`@9HYE_ewVf%MUlJ43*3r4*f2s|#*o#E* z4$hKu*#x<;ap?5n64mT%c5qP7q2pRuNJw)*Mh#cc0{B0JBHizY^Ut7DAh;wNgm8$e zvN9I$HoB{Ur)o6ho&nx_{-=j9IRyOK$YIV|@eY)54an4@gM(GTgTW>@NPUM2Z*_qP?VzBzw7QbK0XL5VFD>2(6FMe zlofn9-u?_)R!9moo2;#@xOsSnJP4Jd*d-*s^!Jl{2T(~tfeCJ>kd?iB8GLAuVk04y zjDiA${Z=k9u}bis!uQ^@o4L8V!YUcQxqo$YW=0ztw;V2I2?_{+WmwzVqWvJW4}f<+ zeIOO`8U7j*8~esfr4KGReg}FxNHoEjRzUDaoR^nB0Y!77|0f2uadwdRb$1iJWB7st z+IPr-85kKsjl(RY!QylRj+K;2JYIu2)6vn9goFeL)ZQT5rr~^v@#c1u&m%1@BAAO% zxEdHTEu#O?+gry)*?#Y$gCG)uC<00-l7b)-(k&nzia|?A&(Mgpgn~#Y($d{M14xJ{ zf}pg-0D?3~NC{GVJ$%n^?-Tp8&p!X0_w)YY`#R6e{oJwcwXSuoYq|D|W<7*?ytBTs z0b_;6uqgTnEMLY9SVLD4I?lY9>kLHyC&dh(hBFNxDi?$`4 z!kwsC3Wn~U0()$03GoI(;`OSmU#F&mCr>16ZJn2%ZVHkh;9%2O0y`;k%9rB0QJoOj z$bgwN;1X_P#_QX&1?8{Yyh#(W4OG0h!b+ z8ylOD-H+2R=C8kkvGeIw1c4QiS5|I=!wgrNHp-1*{pge0aFd@596(^qnM+DZ*?2YE z$(C!RNFtsuS#buapg_ZB;5S~gNDR8VR8gml@^b!^^QxdqEFdK04dfqK@qn_j8`-5|tRoP=E4&^Z z9UU4Pf=i)=2%-r!@TvbKzhBMhwxnld?0oFNeDH6}#mz0)D;}Z-x0TV0UgEl{uC78P zhTcYrg0o$zN1#{?w}=o_&|f`O5(mZDALWGgPL#OAa%L|F--vP$JUPa}!21?Gf<=?l zDZ99AfS58n8=GUL4iVRBK0dxsp)-gT7RbX#$^ZHLH!>uI1XP)qLqt_HHJ@vdlar4` zkf3@k;ih{CN~hmF3G+>w4ueRkp}suWX!f zzr&tr&f;SsEF_-Z`}FA(Xjae@F~WW#9aZP#;LuDE2!>mfQ2Z9l)1cNgl_y+Uf7aIn zT4+*tr~K#Vt&NPve*d-~iC~rtXu3!E@fzHic0YGS6?Q1=0k3|yI=lUjwuK`-Fq0>NY@MMW_3@B9UP*Cym*&yO^oX8<-? zCY}o8=;#Qs3dpa3$Ny2H%vSa#f$~eR0$K?Iirr_-|IiKUU8HFZ}F z6{lNc9Iqobt1a5k(b3T%Q3u4QV0htbL@X0)eIY$n3gMd*LBU`!+?QL=O|^!TpFVy5 ze(o3GC$&y|=&9tQqNAZLUKqST0?{;vP*HtKPfu^ZW4)Kb4HUF`$y6XS zOFlKb>v|=wj#p%m0UPsrGX1M3Hx$2~bJnBQN|Ba2=|_9G{)GH#3Cx2ilu&}?0n9Uq zT&&R*(No;8|bW}ZC!BU)=#KR<(bVjp40 zN4Mkc%qu$13@f*0f?9&!1(xN=gv*$ z6W~j<;_>*F7Vw;Zv2k&=|M;=pm#bC9v`e{Ow+u3~%s$(zCU26Kj9g72w||EVXpe8% z*vAOj`zs!^W>i6;TlAY>u_-IY`FCn}Jm|8+xCYQ=l3Y$tWb7Yx%d!k=+M*jWfIj(< z=HbJk80eUAc8vI(2KG`sD5%8telx1G7|u|G6GoNZ%ec-%Z!lGBlW_rSAM!O zd?WzpG)Wkpv3!!{G@Ldec7A@H2M_2{-ONJ)dAn)d4Kc${x%A{sNLqr99;Q336|(w$ zy`y2sKHJ@Gv>Vh!!+rr&{*h@$)dzKT&!J(xA-n?mR=~-m4&I?z>*JJM1iIJ0Ua8gMsK$Rc&-CIL*O#zg!nGPyb2IUOw+?%;NKQ`F~PqEj^m!S`Hxy z$47XL+h39iiT6vNZS`?-c3Y+4rw5f>lX}0wi#~wfCv9ezrAHkdhjLtlrKP`2c6~JQ z-RagBR?Db{zlml8CWE;sld2xVUjY9jT! z-z;@J=Om{@MMc$9rIWFAAs;>z5SYFKhy}#4zO7|w{?!)vEr3biSJU&(O=^e)d z8S)5#3^v3fBi5+<(InAXIXQ0{zYzVQ&6;p@cYodm0cy9q!dZ=fV;btN_vYJA3u*WG zB+=OMXU8V~^H&E|0_yhc@mXi*`ZsS@+T-#X<;NGXU{L|AqWnp16=VKI_Q%G*$x}f% zWPQGXU=2hi9~b|a$f_p^FC%D0!_FC&OLH${O(pU}0H5U-5I|0lE}Wo;rk`KZfa#BS zGY^E@0Ahmf?O!qw3BJI9w*caE7aT5Uo~MY7jg7at)emUlM_O%u03S^`PuR<@qa!a# zWh}QH1=eX0)h)x`hPE=bpi=M!Kfnzz-KkXQBajVP*dy>+d7#nGDJdzb&bo31h`|X@ zoUr!#Ljl2VHxTgkcI*iYgPuPJ#SMUfLMFgdC<{wU!h;0qTMDE1(J9HSL89$~^?v-IA8C$VA!M&5aFLPF~@M!n3On9tud{$<-U#IOhyVy}6S+ zu1%@qo*9NkM11e)n6h-yC+YWM4s$xgs{X8wVlpH?{z8o;D1@C&O*aK7O&heAii&vj zDIIh0vhNZi>ny69r}leLFE*M#LA83Cp za9dUMnNUmQVEkEwzZ~DV*!-EgYX*0?_?hnNaP2lhXYk{{FrcHpb8 zZ|-9kgX-SZp3G_m@kN9M%%Oe*YSE%W3WF(`%w_gf=ht<%Ft~u}p!MZ1_5g8PwfMk*kemFS=5E9*W!w+%l7dcs2eu2FnHF*Wo zp_V%ue=s)?OwAPXTI0Rp8FrJoh$b@Pj;r&+Y8?s8BPg)1>vqxA(X%tVA4Y-6I=^_I zkw4=}t#i}I2MkFA7UkcQDJJZeM?9Itg%D{D^++ZOS)w{#Xe|6WjIIbHZ}*IQ1>$r7 z@Br8ba8`k2Q8wT_qWr+Vw4jtd6Yp)}e&h$Y^Z#$@xn0yIm zATc@G$!zL&!vlm1F;^JVwTht7&~^YjWE*buO ztF$!C5ftmdX$aTe=oxZEA0+aR2VPq=bKrt9he#>i~IcfGk{E!fn@fwRU?piEPs05^bD+phO8+-`azz5 z&400SaLj`C-n*Oe&Y5`4-%stO*MId-&T%Ha<7co`6ZUDjejz8F$o?P6d%+h+e^t49 z(4dDOumB8+s7}2*y;9kA8jxe>YV!4Yp^g(1wGUhXR(F)1)prtO++z!idXGOR@T)_p zsu2J%*?V7eTEp462t#-b38*_zYgaGzn6dj4h}M8A7S}2KFD0ChN1RaIYJRXKrNR9= zs3*oRGri?W@g|(5-IlgFE||0XFo+b)4WI$pzn+KxHD%OBP61^_;B!Dp(Ag^J(-sa~ z@Ra0arYSomw%(O6&^T2Fz;hpr_WTB{2Q=@}(gG+qBpfa;_-{x^mNi`Y{?9?8`e@-( z^W1$90yqEW^E63ha&hx4ooUJbM>3?!tqWX25)#qO3=H8?{{r5NwAyx|+BW+Ls-=Sp z@enSr{A>bUs!zXd&xUSZB9(@YJ1@@sW?_WDZju}VutYHz4#-$3IXgSc%gZ}D-Y7Jf zbgn0&va)QQi`95yD16Y`G)uxxmQkFB>FD|k@&{aRT^D*!Us>e^!)@7^7cIOqrgOUTMB}t&4bfkF5LzJ2oUVk1m7Vs@oPWXS$QQTVsCvtJ=2Y=AKBpx$0vXN>Mgi; z4KP89-qpaQBnF0JF_s@_a8O@`zXy@9Ot|l$i6jtS2}SUaRdLVmocjFyV}R2H$3~>g zVN{trUl4OJV(eJ~pn`g@N=V%z^72O+ieVQ_ibLEOc+C}%Q*qONXbmuw#8NUHW>HZO z5S0WxyXq|LOTXbNo9NO~K1g;bf(RW1ZtT7G1c8N$W57g-jf=Cgv-3JS^ih(3)wTm^ z86~CXZ~?%5$cva@6UZAv5?KqffN~=$e1PkA_#W} zCH)Q=r2#Tgz@IHIhl~*X%U=!EQ{dK~I&%s1y`&mtzw*HG1=(51r-LeB#sF+zBLD2{ z8CVhk1-JpPQ~9~_s@}5g)|mV5`t0M5)>NtY#?crFa9);wHYqsPA;Bmh8XD^A{gM?S zr-xD@)N1uo4ibkU5v;*w4Kcae+5j)@5NM$+e3zw$u|jzhR60P}2*iQUDVDB?jy=Dj z3H_=7um!D5L|G9YekR*14_W9e8S)@5NHfTej}H*Fx*1?f{(>9@==q!)o?dlGO4xNg z-0y+<38tF`kw8Lz_@T#X4z!9)F=4b6k&Jqjl~7{8ykNs?5C~Bg7<&b9%f~eW9EG%H(zXY@5Ei=4QGy3(%}emH9~zqDS57V}LWCUJ8<5O9zf26dHtv zmXKAJnEWL8E(EeC18y>Yu5d@20lHISSes!gd-iEX);=`B2Gk+S0cJBO2w>unv#cy`U5U`#kw_YE|$`txr+Vqu%EsNQ-Br0T9@iF1vupG3jAJlZB~e z0wRN!Pl2ai9|Pbsk0`LNM1-=O*+jgHdqhY`8VEw}%OG=J z?t9=FDpU&jM;(GVZ$iRA$cAnCey_poEtNW1eJ_gh0ZGK6YCC+p>kGc|V zMepy(L50PPn?bW)nPgGw1914>?eFhH=IdCNl1T3G)P0H&W<9XvNd5~pBqVRIL*t%t zYcgP%f~*-*pili@wSTs|>!iqz+k>`RUG0BPj47$g;$90GoIQ?rD=ib`Co8RTLouxX zO0BwtYiq}oB^dm(vud7Ejp7{mb=<)C`G-zSkf#ki%9!BkMl;dTKV}Ww!z~RImZaf-{W8?A?!7Er^dceQtc_)i@?B5X+uP4b zqf9tBe!j5=fXbd6J-h$kKVK(XuN;J&v>^&=KN(?$|($dB(QsfBd<16_8BuOy7GZ$_^L~jO}3+Mv4cjd|z z?(2~t#enJP=tvT@ikKa%VHU{9%yg>q2%19-krps4yp3y}PkPNfjslL#y;5VN&y#aH zIGr9e$y7X0c1m@C<%&X<>n;K^?B}1+S))cGcYcW&Y<~+fN_&A@9SAU#0VAy zz;9eh6P(xp8w>F{4ZxmH_jk&B_2A8V&|tX%WrPNXkHq>%b-ps8ptJJCG?dTNn}@Qm_UdlJ$*Wh z*8c3|wHa6ju(wFw_qp{+h-cS8!TjWJlN7msn+vzb_hFXbAe&53Na!6XtuJeb5!Cqg z_4ND)=?$<3?vX;+P=l9<@rjEFgYT6NlmOnKe98v{Vux&-`#Z&tAZh}vm)m%9A|$69 z;_d`$&O5IV(;1>15*qrf3-Zcv#DYN7d>hi2Lp7yh5DUO4A@xE5uM|W8uQZ|zxtFzP zSBPy!ssNeRLM$5OQ?@oY!B>N5)MIpP%+1wx0_aX8A5VilMgwW35Oiq4z?^~pe*fv` z2goPn-MZ>VuKMTtV2mH%*cSypXhWWuFY?M?;i@~&KE{9!! z@lukIJgjlNg1#Me8~n*fkC>$+v#&t<64+kB;3zXAnbuoT4xm;%^WhmG!k0;t6n9(P zJVw_@NFffDl4<~+9nA6&*gF}=>*nTCEN1W?Z6YvwaQY~yhmyrvL0uGts}Y7F?OmGQ zzCMTX`p_x9DjQx}E@bA}E--O!D&?6V1ho2_Qv^KWjQQHPu)D z)CFPv94AGIcF#bP1d<}G|6!+K0PX^Mjo00%Fim? zVaWSKBzr-|7w|@pQ`W=aR+*JvP6YMk!pzLT%o-LXOGTvf9V`|WGp33se;pMUCjyE- zp;d8IBaLf-I9^&O<3nHU8v66WVa%p+O!Pr@@?=X-Y$4k-jD1ij}y;C&!i8ENe1 zWM_X28$y&Qn#134V}1Q4lF26ta0K{~XqOV?j9uN_AaSK!hQ&e~0AVmS&9KTjnVHdV z--3@xG)WKM?K%^{6J1b@)GRFhe5m4a*z`|R?y6{D0(Qmo2SR3V7WO?rR6~+4t&#Y2 zdT)Am7E<4kO(rpUY4H-yS(tGhv`M*NVz@iq9=#q6`6B@7KQtHhx3;uQ?fjX_kny0( zx&ezBQh-2WV3T*YFSGsz4*_E1b#}N{KxTMNrGvdy3|JXJ%uEzNawIq53zYfSwzoA^RX?ssU2F!v+WKn8WoVI^r&l@a%2jn>_6opVz#{$4k|dux z_vL6nHv)>&r^{R}R)d6jjPeE=ITDG;w*B=wApuyn#bEGYT7y859UzKY#V}fs|4j>Z zb94L5kM*>$uz);iWkp5X0|Ns*2=h*8Gulqg&EZ@Z?jS?*L55Ub3*i_ThsSXi3e*T` z5!kb0F0)ak;2hISdy5*yT`+|WNtXElIFje^>H|4&CfI&HXV#}g_QMO{3+3hIA>>$h zg*8YXcK{Hz{mvKCzmSeqxFPO=;Mv&u_7QcRfILlES$~B@2RH)(Ymh`I$>4x!4lbKB z$CNMs@`?)Eo(x4*)tBCrFeD^5-NCLzLPmCCD}R%QR@5G3{PQw1TN)n7Ps3BKt*sE` zP+fwnQLY~XQxQr^O5nV~_Gc?w0v+Z*aFm1Bfouyp)F7nHZOs4iCCxQhXuYyg@Fl=f zGAlS{5z#<9Esl2F6%u)X>zL`m?t$=m0~>Gv6~7RD0)i&J zuswwPkl%wX97F(_G9PbmAQ*#rSH;skBe-J;z97J-fMVdF2SyR&HYbD|7TTK{Qk~zv zJ^4K(mtz9@`HHGw28~LI6z<=rWju#0V#o>P3;97idkBj*_N)G#~9?AxJimZ(LX)y{7Yt2h=fT<4?MCE$3B`wA}>i-S0c6 zA3 z>aqMvefvCmw_Cd29QxX%=VdAOYL8|7dwuR>l{HWLd3NsQqtfpVE31c#ws~GFwSTvt zHl++cmHI2z<@4P|pwvpb)MZs_?gup0$l6>v`o`K)Tbws9uc9L4oTR+Dj0XXM+lE~y zWE0yaKS~{5STVxgWPQC!dUuS)s(5Pgvs*niVBu*#bq~M=G-O)45_V^P#~D2 z-abJrS^D7Ye7J_tR||}qhQ^F18LIbq^fn0Z2QZ`I#?N_=FyyCQv*#=Qn(n%}$@hha zyD%tbZ@S9Za$Rp!R#Dbkb>XmaTj(v%Vyi29HCSyoH`kRJzh6W zch==A%#RHE!Udx7(4hL&t5??f?>PwU{gi>F>ey#AF<4$iC# z=_PrFNXFrb3<|v0KeKbDk(#nTt)h51T@eA8)rq+&Y zl<9;V9EX=-sLtN?5`J;rN*6oODCTnyNl>CL8?zd-D;Ps9h0Vm8Gi_T-((1o#MwM+k zyB&v?2Fq_pVi-l&mV?V1ydESaMwpl6={;0`M4zt>nQ70>mEz7()n%ixaZa3$j<&Uy zO%W`5w%V6|T?gAgTW&pld+%71yGJ=T9dQnOPv+Ac=OSbV9)MPst94WYsOHM)8f&@=$WK;?9uP}p}(o$oqFe7iF1W0#l zYak&kK;8xao^oz>o5@Z4!Gm-H@JHgq94UzH-Cy^P#wI0s?W|4S-)W;l#VXH$c~tw_ z(E+#eb@R*d*y+aiii&jfqwTK*wEO-F@1@#R?i4-vA8(udpUXIgA-sJu><{@;1Rkb|!KH*+S?# z^CMU5a*0(BOB=cvth25z6wvgS7JfgaKPvpJ}zWUQ>i^RF)-||hB z6uZ8rBm?=u8-~H7+kjbsq;U+^P>V=5R^^{Osyh)qTrmU8Q^T$dv7rw1_^DDILl@(x z@x|F@eUwtR`FlA&nf$h-L|?bRk+_yu z=4kZyF!g)4J&Ot1dk+R@s;gCsIYA^X``bIQXk@+8s-r#yqfqpDMMVg9aj&4DpeCim z%aj#YtarZ7+qZkMG%x{*K)KnXpVpemQPC{6xHh_cNv$2?aJ{N(J~DDZbAF^N@o`@6 zU$HGA{)-yRd?rc&<2@U%_S_ofH+RkV>4?ql$2`6n%EH{x-~YQqQZyzNe>IzesX*?% z(yQ)EH`3_tfj*nP)PF6HYhFo74jTMY6&2D!mt8OWX<;uHzodL)6RnLDna|N=E@=}} zBJpwk7^#^d7D1Vujp53sUdF3lq)Y{Q^B-TcGH9lZ%5Mb(Z1hL7&q`?;X7p~ULX--mVMmR7TWw_F|UqRn;V2~VchsJL<9hSfKInK-B^uce7u z+x_($w1%0u%Y&>*VcfZ`-+j5KZjLwkJrAJUkRWDCCOF!8aZ5$TwXYUE_noF++V*Wk zbe}hO=ir31ON)gB?(yTtKr`0#T)j)k+`wji1?B%2Zeck*FtHq^Ugwm(#z)i{ImP?* zj_(I0Cqx$Ki@2m|AGsFXC68gR-1nh8nB&ae-JP?hgsXookdB5tj1-Q8&(4jv+rEcS zFF)PI-pzR>?)Zo|_{O~ftpsUsK3rxmz|H+y#bGlx#|0n3^izB9!?S|cR@Pm12?=Ga z3j@mWBpe@IeZb3MY&9vLCCXppFU_7e&=ALt2oJfnoNP8{SD4f8`0Jit^|^tHe9I`J>Q5EtBip1BR4LEiUiY-cBmk8f^i(C2FE!Qoybc!f9z zJ`??~nMMs>*Y4s(9DXrOV+$WhhoQnhW2shH*bbkBm%De>upSo4dMpqbA^Jn znz#j9`{IQQj#6Py%oYyOU$!~@q?UJ{XIni%zdXxx4IL2MDX!vmQsS=fzxhmeq3Fq$ z>Z>g}y)0^RiGA0Sa6NoJ!4xfZZtm$>+WY_5(gFzYb3D?{;;`H zU;l5lF-9id>n74H@%XD5ZmZ*pa_JBP2}4_~iK9<)94>e$!3AvcKZE02feXz#1+cUJ z0h6N%PZs&Izx709R@lDCQiF3?jLN(T`zw9=AmN;>9M8MfcKG`dWEh9;YN~ z8zc!ir2P4E*-v3v_u@^}7aZ?mXq4Y?uNW0)3i=znFZ4p^5$G1^DR2utR`+Umdb2y- z&F#qRa@4g4hc_M5xR*2HMQwWNz(we=z+B_yJ(!A=vF=zFLg|Z53!@fhCnhH5=Duw4 z(3|b;W}U)u78yE@eD93JuDpMf=qqhw!?lWdiOcNlJpn&`sd-MGoMVt_EhxJIVyZuX zx}6`{`{%~vW%Uh>nfl`a1u<1Kj+7|v7o)_?%Vgx_#YIJ6zHb%HVt?p~cA_D73Eifu zW^7NOJ|G|2ikGO{-PyVE*CU#!4Gq2>U_b7&ofk)(on2AZs9FkHB~b|pq(){*Z~v5Y z5?BLoNit@eC_Ksn?zZs4Lc1}OxSut_qa1{_yg-S`%Tw0BR7~8h%8VmugSJ{p0Rbm4 zbN-_o%eA~*TsFYm`6bDMsy_p7u18Hp^~lbyW0^4upCyHZikp3?Z20egeepas^(_O+ z%X!StYI&I-;p^PUy?u;)|FxG42cD-h8EyKhf^{)~IuoOVE#W_mlqhKuX9oXH@c&d* zR3@jp&&A`pxv$5>{LzocW5y*hw&I%4UGRWgh&4SVM`_4n2&43Xw*e8_>~uFv7kXfT zG$MjlNvVZPI6KF)=_z%SZOlNGjX5tb=eoy>yju^4Fm_ArRnP@(d2Mp5s^f#~Q7`+G zLz2l!FD%BWbsF23i(4J74WI||5Qq8&RT}fD*L=qNnzwuUeQ2 zJ*ysg9u%vHX#5 z_6M5|*=MI-O5&b+9$Gla1ae=zNU*XZ13`rC=a<8q>#$8sTZEPtFVAb{M{t8Ln0t0+P z8A*OL^M*ag>ichtMOGzifbryOL1#|7;Z=n6BP)?)?!nT%_@qb&aa>I7di-c?;v(AI zyuvgPtsS-WmMhc!_s(9G0ItPF?tt3jKi3zvrqpaOfKQFLy=EO| zxQtQ&XF_&6=IvYi@%jXAGq1FOHWvenEd1htOFlG~1Zca6%c$7I;TE4s!^?#q%h3e| z9S}ayenoda#&S3tJW2zU_2kW*EDwl$+Wn@!oXIcIydb6j0(Oqj$!4FuMyoqx{sawq zZ(!Z@!nwnr=s?o|&hXk|EcVCn@Nr~$j*XJB+NmnH9F01gu5VTIe!!NEF#rwYNXudGh~>fNdT zz)!^iOo?v#&ST5%?F@bI`n{oYPj~k|I=&Q@$)b#3y&Z8qy2EvDdQ(Ps62WJ^binDf zIxZzld*)H;Bb7qR9v(3>*scUz6uXlD5m?4-c!B# z>-WhSYL@}@1A9?jUCna&BI;qlC~*Izi=+q}O@bIyli) zN>D-%fx=@4?`dJuE;M+*s%mN-U%#H4j7KpOx1mwRI#6DcqmeYkaJg3FjSEBMm%DfF ze2fuB*#yD&s{*B`dwaCj#r|}}C`Wm1aaI=F&6_b;mWzmUh)gJyI+#!CJ#=6 zjja2{0Tm5$6usD)TLdUhusizIK+aemZ!nl{!8UIRx4$1pJZcM+GlQ(%7jFw;K!wjn zgpP99)D}Ym4I(0J#y?JClqL-Sg8?+udxSa5a;^=1E(Q-}LUX@<1tcwl}n z0Eu3=ttTPYyVh;!H_>=V`>%hdGwH_892KEHAohBv6r40j8OFuLR68>6UzeL!SbtB1 zigHITKtC{+UY?%VwJ>e8V}r(t5*(B%xU7uUR-xNv*ip*o;R~#<^72ABk;i`2bQ?1z ziGz}*j**c>?6P%gzj_`nz&+%>czqNlHp@hVK{!v^5;9o&&~a zz!Dl&K?c5F;vFL+m>*~@LIIJoU*usqQbHCJ^BHb)e_mL~H6-lrz6Wx zSX034Ppm@FGc!B;JwY%Ri;Z2X^``=X1UWgmqkplHHzTdeSOE5x2!tyP#}|- z^E7a2z`rom%DU$Tt%Py7CzY$=r%}Bm$lI_&K@H?ygoWXUs_yJ~oKJI;#}N8ka&vJl z^kja40YUs_7i97RRiz0p*X<4I8eo6JPKWQKfok?cxZsa}(4P?bdzP7*8Mr8cyo&su zvZm%G(7Q&$Ka?XO{GNV6MTIk@b%D~!IY|B5$z$XK3ig*j3BsC$ZH2UrhRoog%WDk) z_(6bR&XX4Pfgf4B@R5-b=;I8s2HuZTpcUD64cK`2NoG~3wgEmY4|rpqEETiBDl^m~ zK-Iu4jbhmb8xJTj@J%5YCqG9`4N=)~m?_JG{OmleKX3}Ef4bSFLkSvm{tQE$XB68> z*b8MWLPDER(*Eggd}1+__@t%z|K~5^xUG`xwMt$5E?48_YWD2VjOo#KhvF zqK;B$RbIdvr`aHHNC{g9vIww<(1g#hOHm&7+hZ%MK4f$FPa{wA=Yu^R-G=75zkZpO z%&|B@Ni6K)|Ga9(6?oN$09r3XuRZH}5cq&7-ln7d?WY9@|KJ#97C$og_V$L*(xzje z2qmkJ%uUTQXq8k{tOH50Q*Bnw2wJbI#qvzLo0*kC!Wyy?q`slNkOjwc5kMPs7z1TL z#7SfCMa0Asjx_dR9FHH*z}@34b(0q1!)gjkNF@3F;Ns%a)YLTWB1dHr!#p}dA{}zh zI%{A1z=MJ;Ky5Njq3_l9Cm8RR)}3&obEAU#aI%%1p?<0}fLil+|%Tx$?X*8T$O# z)eoUh?-#v%^{T(GkGk#})PsKi9&yNFmI6<(9zOw_1v0--a%=@9+F%%AycFWvdys^v ziKjO}6iAkq@M%CXAMWkFqoM-SsR3*IPW?10iyWDg%(^=98#f&Hcm4o+3@t*T*#97+MEfOgbi z6$HboPlg|G`lf9~7s9vk#SI;Ps0%c9WpGh2RCENZn*2c!lN z)fMQC4h`ikCRB1D5$4JQYbbNLlUY!(_$ic{m6f$N=4^Nt8cL8yYzV&i{`;3%tX>e0d%6tgNtMcT8zesQXp_`&j^#?0y*; z3UzHf25)P7?v}i}QN!Y}Yo@3Rz_=%v3hO0Td|H9<>!PG2t7iG;o%buvSj}ArhSzvh z8bJ}n0WVu?muEVxMR2Rcl)BYr@lny#qYCDMqq8$JMcD(TcXK0OP!2q*NY2ds4A5{w zN_zTxsF4hEw|jT&SKCQ!;T`5&AqF!sIcTLYK}7RkM`Wj`>uWove31|WfH1?1Gx1DA zR)dXABRQRBlDONe97_{ILLaeOVes*U-gdWq{>*eq;(jS4HfB1k_~pv}_`4?R=E}`~ zTG&hwAww&GEhj#HNg@|K_=x9Yqz|eXW{NvI{W<6v=7dKShp*loNLqZ`#i4ac#Y;-c zFOh#rEhjf-fbC2q#W7xczH9^=vo{mRu9fmGdkXjj*pkCNTUVY$E%3**q!(Z>%X=;V z&XExNmfN7Ba(iY5UsuCJdFJP>&;r1CUcK_i;|>@uM<{9Ezn@i0L#x!YdG#3(UWYwo zbGn1#cm;F&a%E05l!q$8hL||s0#uzqfh;)>l~_*-N;IwO${~x8_ZA5SK7Xd;B3)SU z`Oa2+-AFw4twLPPpE~#D{r#tJyD{=E3|m(E9`(1x#R(UQq&eN59GPxfGts|Pg=}-| zeHjj%j>1&rt*!cclJpl6ZnlLbCG>sEJ(*$J>oU znln6PXW)aZ-v@u=qy4$W-aE$B;S|mWX!M)P%7*99ZM#y&@&%)-^5PT1H~#+g{HD`==A{CS{wea|6nUdK;v6uKrOm2NAY}zHIZ-oH;T;BR#)mywEP*|)5^exgVW7{ zWK2;b3y@7(__WZldHaz#IkI*rx#Ka&`^7mfyxHr|H-8&LLw!y%NEn*0G~@TIY_q)k zN|L?r4Ls)KvqCQ)LTl!{!Xs{cn%qIc6CLX$!7ptio)wXiYDNcf_~VVYbEU`$s$TGD z`~9D19$uEA%=K2P)o>Kzz>!LgJ|nbi+IPOuw>;U>Ju$%~e@b0_Uq)O{d}hbv$>H_% zaO8qV-6udjQl$P%Q0qJPLPav1fh+tXJ*C%y`1X8HIN_^i02g+cKbtw(WzKNOep*wuEPJkvf9df16|kj=H$++gg1R0D$gu(RMq=3 zb?6opQpdLq)VJKbXLS8~5K)q^*vo`Vzg&Ho+> z_3+B`QKiYw=Joz@lV6&QwU@kElDTwqX>IA~$3C|Ft;(lk@QT`CL_U9+tPq7N3s@eF z^}#v5PB{7=Ud|brLwf1&O1QV}@G_&CSH4!@lZ1qD1n-#@_G{#y6N3;0C4C;*8Yl6! z%WDw|b1|lPmxaqW4IIPCkpu*FsOV2y}aDEsQ?ngiSyf;wDSy0 z9&=rce(U=7qUqlioWq~LKVQN4i#{S#{Yc{f3Iz-O4=9**CzeT~FgrUxSv}sD8=39-C4vlS4q0^p@?M@7X|eck%Mt}edgk9= zrDY1rYL9FD;IIy&2Grp1QamSRB-g}>TBS@68Ug3vF3hJ_o7RMb7AnhZg46;oZ~lis1)4T^Q^;FxASv%$^~kTW{F4R?Q@=z z8aqt=q3n4Jpmjv#lU(`q@S`On4jdP^yP2n@)u|pevZtLLf2Lk^chuCh=*oDyvJMQE z;?nD0_c#{h=I%ktUFx1S@YDjy;`qvwbt}f3UrBneM-~}a_ZY-~$ z)z{u^pxAW?HfcU`W;imxn_kN+HC8HzxpuuVFRj}ba*#sbgGg@;QzGsIg6yGq&bA!j zBbK!eJxBgfsCBK3oM(M_e}srP!R^iVy4NMin%G&O+`gW`YiNAY0XdAq_|cr~fz?1~ zh8QF{x8(kUvKTqS{Kvb6;8d3l>_+lRHVIRcHYTzPLT0G1t2 z)NPms;YWyH81nyu{^dKbPt&Tp>4FiFwAS`3_|$sIu*#a)kEppzW%t3@RUE%o&B*^8 z{IfGUXeq6#{u$BUH2%W_S_jRRHqtjMnIWr3jM&8BHW&Oz^$%(3>-%wPvGFNlmC^Z; z7t#+VI*=K*u;u*2WzE7@+uXjs)sb-b zz9sg1p^wA>pD$?XUHho{yqg3y=#-#HL>eOq)ZPG_u4K3|ha3_iD#KrZs%~fC09fhvHJ%UQcJ4VSjJgX>U zpc0e}`v3TJWz`W7dg`!CjYU?_-=km67*#4q!mOdd<30TUBX);uGU4M*7VE2}f4|jk ztpY2YKb#4cbRRDb$rXV5DfGFo@sW>xwnakHw!Yaito#`imr@iWK{bh|64^-Q=vruQNVu# Du-~w* diff --git a/pom.xml b/pom.xml index 7f96043f5..79bb7e533 100644 --- a/pom.xml +++ b/pom.xml @@ -462,6 +462,7 @@ java-design-patterns singleton factory-method + abstract-factory From a1a40880873bc40f977a3cef7d5b9f45c70c9312 Mon Sep 17 00:00:00 2001 From: "mahendran.mookkiah" Date: Sun, 13 Aug 2017 10:19:48 -0400 Subject: [PATCH 20/45] =?UTF-8?q?As=20getAll=20method=20returns=20a=20Stre?= =?UTF-8?q?am,=20we=20cannot=20close=20the=20involved=20resources=20(Conne?= =?UTF-8?q?ction,=20Statement=20and=20resultSet)=20until=20the=20stream=20?= =?UTF-8?q?is=20closed=20by=20the=20consumer.=20So=20try-with-resources=20?= =?UTF-8?q?is=20not=20an=20option=20as=20per=20sonarqube=E2=80=99s=20recom?= =?UTF-8?q?mendation.=20But=20it=20is=20still=20recommended=20to=20close?= =?UTF-8?q?=20statement=20and=20result=20set.=20When=20connection=20pool?= =?UTF-8?q?=20used,=20connection=20is=20not=20closed=20when=20close()=20ca?= =?UTF-8?q?lled.=20It=20is=20just=20returned=20to=20the=20pool.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using //NOSONAR to avoid false blocker issue. --- dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java index c5dc7da3f..6e93207cc 100644 --- a/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java +++ b/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java @@ -65,8 +65,8 @@ public class DbCustomerDao implements CustomerDao { Connection connection; try { connection = getConnection(); - PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS"); - ResultSet resultSet = statement.executeQuery(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS"); //NOSONAR + ResultSet resultSet = statement.executeQuery(); //NOSONAR return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) { @@ -82,7 +82,7 @@ public class DbCustomerDao implements CustomerDao { throw new RuntimeException(e); } } - }, false).onClose(() -> mutedClose(connection)); + }, false).onClose(() -> mutedClose(connection, statement, resultSet)); } catch (SQLException e) { throw new Exception(e.getMessage(), e); } @@ -92,8 +92,10 @@ public class DbCustomerDao implements CustomerDao { return dataSource.getConnection(); } - private void mutedClose(Connection connection) { + private void mutedClose(Connection connection, PreparedStatement statement, ResultSet resultSet) { try { + resultSet.close(); + statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); From f6c8bfbc3950474999ada3488c60d09d0dba2216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 13 Aug 2017 17:34:05 +0300 Subject: [PATCH 21/45] #590 Add explanation for Builder --- builder/README.md | 98 ++++++++++++++++++++- builder/etc/builder.png | Bin 53747 -> 0 bytes builder/etc/builder.ucls | 162 ----------------------------------- builder/etc/builder.urm.puml | 100 --------------------- builder/etc/builder_1.png | Bin 106529 -> 0 bytes pom.xml | 1 + 6 files changed, 98 insertions(+), 263 deletions(-) delete mode 100644 builder/etc/builder.png delete mode 100644 builder/etc/builder.ucls delete mode 100644 builder/etc/builder.urm.puml delete mode 100644 builder/etc/builder_1.png diff --git a/builder/README.md b/builder/README.md index 335862676..d255ec2f6 100644 --- a/builder/README.md +++ b/builder/README.md @@ -16,7 +16,103 @@ Separate the construction of a complex object from its representation so that the same construction process can create different representations. -![alt text](./etc/builder_1.png "Builder") +## Explanation + +Real world example + +> Imagine a character generator for a role playing game. The easiest option is to let computer create the character for you. But if you want to select the character details like profession, gender, hair color etc. the character generation becomes a step-by-step process that completes when all the selections are ready. + +In plain words + +> Allows you to create different flavors of an object while avoiding constructor pollution. Useful when there could be several flavors of an object. Or when there are a lot of steps involved in creation of an object. + +Wikipedia says + +> The builder pattern is an object creation software design pattern with the intentions of finding a solution to the telescoping constructor anti-pattern. + +Having said that let me add a bit about what telescoping constructor anti-pattern is. At one point or the other we have all seen a constructor like below: + +``` +public Hero(Profession profession, String name, HairType hairType, HairColor hairColor, Armor armor, Weapon weapon) { +} +``` + +As you can see the number of constructor parameters can quickly get out of hand and it might become difficult to understand the arrangement of parameters. Plus this parameter list could keep on growing if you would want to add more options in future. This is called telescoping constructor anti-pattern. + +**Programmatic Example** + +The sane alternative is to use the Builder pattern. First of all we have our hero that we want to create + +``` +public final class Hero { + private final Profession profession; + private final String name; + private final HairType hairType; + private final HairColor hairColor; + private final Armor armor; + private final Weapon weapon; + + private Hero(Builder builder) { + this.profession = builder.profession; + this.name = builder.name; + this.hairColor = builder.hairColor; + this.hairType = builder.hairType; + this.weapon = builder.weapon; + this.armor = builder.armor; + } +} +``` + +And then we have the builder + +``` + public static class Builder { + private final Profession profession; + private final String name; + private HairType hairType; + private HairColor hairColor; + private Armor armor; + private Weapon weapon; + + public Builder(Profession profession, String name) { + if (profession == null || name == null) { + throw new IllegalArgumentException("profession and name can not be null"); + } + this.profession = profession; + this.name = name; + } + + public Builder withHairType(HairType hairType) { + this.hairType = hairType; + return this; + } + + public Builder withHairColor(HairColor hairColor) { + this.hairColor = hairColor; + return this; + } + + public Builder withArmor(Armor armor) { + this.armor = armor; + return this; + } + + public Builder withWeapon(Weapon weapon) { + this.weapon = weapon; + return this; + } + + public Hero build() { + return new Hero(this); + } + } +``` + +And then it can be used as: + +``` +Hero mage = new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK).withWeapon(Weapon.DAGGER).build(); +``` ## Applicability Use the Builder pattern when diff --git a/builder/etc/builder.png b/builder/etc/builder.png deleted file mode 100644 index a0280ba53f7d29a15f93436403cd4d48e9c4bcf3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53747 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 >6^@T4=dor1yBM13Kd$O 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 diff --git a/builder/etc/builder.ucls b/builder/etc/builder.ucls deleted file mode 100644 index 073c5cea7..000000000 --- a/builder/etc/builder.ucls +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/builder/etc/builder.urm.puml b/builder/etc/builder.urm.puml deleted file mode 100644 index df8d73f36..000000000 --- a/builder/etc/builder.urm.puml +++ /dev/null @@ -1,100 +0,0 @@ -@startuml -package com.iluwatar.builder { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } - enum Armor { - + CHAIN_MAIL {static} - + CLOTHES {static} - + LEATHER {static} - + PLATE_MAIL {static} - - title : String - + toString() : String - + valueOf(name : String) : Armor {static} - + values() : Armor[] {static} - } - enum HairColor { - + BLACK {static} - + BLOND {static} - + BROWN {static} - + RED {static} - + WHITE {static} - + toString() : String - + valueOf(name : String) : HairColor {static} - + values() : HairColor[] {static} - } - enum HairType { - + BALD {static} - + CURLY {static} - + LONG_CURLY {static} - + LONG_STRAIGHT {static} - + SHORT {static} - - title : String - + toString() : String - + valueOf(name : String) : HairType {static} - + values() : HairType[] {static} - } - class Hero { - - armor : Armor - - hairColor : HairColor - - hairType : HairType - - name : String - - profession : Profession - - weapon : Weapon - - Hero(builder : Builder) - + getArmor() : Armor - + getHairColor() : HairColor - + getHairType() : HairType - + getName() : String - + getProfession() : Profession - + getWeapon() : Weapon - + toString() : String - } - class Builder { - - armor : Armor - - hairColor : HairColor - - hairType : HairType - - name : String - - profession : Profession - - weapon : Weapon - + Builder(profession : Profession, name : String) - + build() : Hero - + withArmor(armor : Armor) : Builder - + withHairColor(hairColor : HairColor) : Builder - + withHairType(hairType : HairType) : Builder - + withWeapon(weapon : Weapon) : Builder - } - enum Profession { - + MAGE {static} - + PRIEST {static} - + THIEF {static} - + WARRIOR {static} - + toString() : String - + valueOf(name : String) : Profession {static} - + values() : Profession[] {static} - } - enum Weapon { - + AXE {static} - + BOW {static} - + DAGGER {static} - + SWORD {static} - + WARHAMMER {static} - + toString() : String - + valueOf(name : String) : Weapon {static} - + values() : Weapon[] {static} - } -} -Builder ..+ Hero -Hero --> "-profession" Profession -Hero --> "-armor" Armor -Builder --> "-hairColor" HairColor -Builder --> "-weapon" Weapon -Builder --> "-hairType" HairType -Hero --> "-hairColor" HairColor -Builder --> "-profession" Profession -Hero --> "-hairType" HairType -Hero --> "-weapon" Weapon -Builder --> "-armor" Armor -@enduml \ No newline at end of file diff --git a/builder/etc/builder_1.png b/builder/etc/builder_1.png deleted file mode 100644 index ec892c15f6c48e8e6585c308c19334018167033d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106529 zcmbTebzGHO)HSMfmneeLNU5lFx1=$|i48~zDBT@`ga{}|mz0!*bVy3qhE4Zf z8xNj%-+S+O?|5T~pRQv9;yKP6Q46pGK0s&tvR-FB3xTC|`COOOt|{1#o8VGu&$w0b z*=F=!k(sR(ESJnrn2G=c1<6O4iXCN0mHZmwzb^klk(hCs@b~{AzzDtG2|@gb@y<|z zx>(SStz7lJ20;|jUp`qFh(G8=Yv+D_gvul;bH0m#;!9#jObs3)IwpL?qWKOgNp*-U zNr-rI3~mhU-97LuU!lK$f(PAyAhz&?F&(ks`Bx=>#2c81`OTk9ds7CO&z6?(o^H(! z`l9M_*iKbyluCSMQh`p@@?77ms=A|D@$v(Fr_l1>t2jr%VAD$*(+%_A6J3vDV_Bvp z!}r%GC*FU0Oy2oO&(y=+C5hLWTZI&Uwm$ZdfImevF_xL`U+<+@2=zYacWixQQC=Qe zTQ~V~QYKcV<5az#f$n>0Y3blV!DNmc8_l+#Z!H8CM)eT??hB&Z%dKM}p5_k=$rRG= zW^&+D+~tM32E;()H!`#7Am0$KJx{zOTmj;iuTPrTu}?Eot=-d-&l-25mywltkI^`wc?JI9?4g?K)9q%Ui z_`Fn7TI`A+b6#5|xs~I{nT685F{4kb2iA>P8o+;K8zHZ*9`AcSEPQk@4f(vlXNC`K-kr)f-jZFE znK?Dz(JWltH7v}AK_P!#9>v8!nkI1O1~{%rUttAIhiWp88R$LQ$RdeJ<;S zQs*^jUabdLp{ZP9RMby@f4BX8wTuSR4%UNP4?ni+W=wiQe@cd}*V#-UNt9TpmXgj+ zR8;Zuj`Q%?f1&5$DKQZH75}I-AG)-Dos9Taj@a#thQg2E=jKF>t>AD@(Jecy^>d#4 zO7*k^WVm;qA}*OCrz*=d<|FM<3DpwodqMD*ljHTS_RxWxD&Tz?UPthJWONr3I!Iex z-K5k#g7Jjp+1QwwRoVZlz**Y_r?I`Axw+W`n@aWX z6!aYTdl6sg^NHFuzu8{x(hg*Q><|o%Z*FSZt@q?xT{gc%wi?OR%nx7 zkBk&KKIU~w3@x@TZuF~(EJ-nqp{CAC;^g3Z+!xSm+px!AwTaj*@NyD%fn_gj>>C(3 zEH{m`+1ad);$Jt*k|a ziMG(gXnqHrB%0~SSos(j28#C#qbP_B{v|$eoiG3X5##hz+5fLUp}uzHbv&1^wB2~7 zhVB$XHec0G*{PTX&l~(tAR1WkIBXos822kzz?DuF!&q>cMb6OuumEf>e8lmN=3il> z&-@6FtZt)8&;WgDqoI;vX>q$&i(!UscJNyOI?4EVmssVkbWgP#^84xDCFY@VYPflB zN6O<}(scjcQPTZs1wH_u6y=u^;=t@sL8YMbR_Y&K-4NKl5aRIkzQyJ3kZgj z`^?~98I)bU{y=wD$Tig)I;F<_HaUC;d9HyzrPgu$(B_5@EoX=i=NExUSYu;-so4pk zTCr|uJA`1(W}Mv*PNFxerIjo~&B}`5!o(;QSP~ZI5=u5?HFExdmX?#9{hFoaP=85j zslRAqre`APCCEK1eH&og>k#uFxw#e_v@QW3NNzPN)$F!p^oq5MqnXc^_g1 z`yMe2%%o(WhVff-WCHEp11(F%Z)U_ij31=j4{Y8yL+U&pQBp)ao~`*3)J`iqd!w_NE5uP_9#v~BbfF!h zxGEumHa=cv+Pk03u_l|hyS4lk>h3hu(-XDXU#O*}%;t4UrK4lR$iN`^;S`d0`$;S{ z!725WQudGNz~h~W}s>gFFfdoYC0?2+6kdzURt?JK$LLob2kMRUEaX6I6Q<>IU zBXbpO%gby~^fEQVDK<7I`P%I|4oDt_;ggT+C=_!J`pxMzc$Ig0`(WKrAw_DWoFjjl zBec#5~Bp+W8ia#^EqaT1s9&yO0kGcinpwo@suj(`5dE!5(AespBXerZpn z_OH2*(#XiTK5K>8hQlPAa;J0j_mdJG2zPlgc3G2SW9Fyol5;W@J}UpQ&9&&jyY=4b z72X#_`6S3)YHHO`N`diGh;4jRlM`bDG;w2P%wlzL_L)ihL8)1VFvvP4YFM${OVs`- z24?!%cmF&oFS>1KDe=DAv(hq~`Hc;iHMI{ZGK&px0cwM^)YSKBx*MD}Nrb_a#Pf9? z5EKiynXge_g&*~pu8Ub&47tMRF$&$bX8LBE?kYrGa#YU=-6MqL#C;|apE5z*rLbp>r}}(gr2(zL`-tMr0dGh&W4k7`lJbZ zd)n0*rG4 z7$edAy!~=t35(9%!oqGtBQs(Wv#xx)Z1`Dopvul-sLk-l$ozal_LpP*N$gwj)ub3= zJj0~h=dr^fTO)dq>;-?R37P5w1v+bWQ>?tWssua z=U!t#;%kzQ6th#qin_GFh^c-y&7ZS>#SngjVeWW;!`#{$m=ixG_73Owv1(^QRp4}L zr8#QS(l14u_&q%C_f3ZwCwjcSrDpu7Z&OfklU8zns@&!}twwpzSjg7Kgf=<(MoJ2| zW^~Hku}_)Xpg=@aqStV-um`Ad`li*?OzrKdOE}!z?ohjOqqScCRWUck+ z&z~rCu1ZQdpe(T(>G|@7z0UPXWTd$jA75AKod%N^kZB%|pm2O=2*m4PlTLMiWq_ik z+8Wm%w^5cntW-I#g$JLS4nq+620ephPtu-=;hb+@-zzK#d|d-k2tW5?iGBLa1QZ}3 z2nQR(XN(OD+^6fwot?hm;_kI48&C-H50=|FqNCsO@F-|+r}Fe9um1jRq+(>IaZ*Y{ zo~<(?LP;(;>CWxtrlpGM<7kcp#HlDMM`0&XI5h+WV4|SKW0i0)U;I#&zw}Kh)~#eN z2HpDai%ipx^rqxD-7)A|ll^Fh%ujQnx*iDtFhtRkQqfq0Zr; z#7iTGwtocy9R~~U0)e3ILC;TzM~WTk6(|-#Tv+bg92;B95CLU6u;J^%LQM{h1}{$Q z)&AD)mf(wqIM__%dqTor!B7Qhjk`D4f+LMNxhgmnmxsC*U=86-N+6;=OIv|WPAtqe zivdqSMsu=vD7m-!fxs^ypkugjhuT8cX1u{06J_9|MwU^VTEXd36A1W>xFAT9J#nLo zjJbMAP^TKT?FTmPt#ttJkd2p5W4FM7f-7q`QQl43u~shplP#*vzdf42ExeeVEk|g> zr_S~Dlpp%hOEWXffGS7H<}grsQ%z?&a=)pln7BBP|74~>Y+dK(SX_73Cb%*Q8I$9K zygpbz3h4A^1eWxVLgWI%Xmld!-^ncqhu?8g3O*<}TWODcu<@39;Zgmki=Eyxs_9$> z%IkV;Y$GTryGC@qB)DYrGLYFASZnK;czwE1!%%OpQP16rI*+X5T?A_0vkHY~nzX~@RYAc( z4TOQu$sF?mbEp5B&+`Ib(%{O9@^f>427ssT zTtd>@DDL_h2ww#|@LnCvQ7`tQ;42r(bCi_4L$DcQyp59!_1;}(kd;*dNue%-YO=A> zbmnW(`MGDu_#FucKkxR4O~q?BHy8G{Z+XbeYv;-rA|oAp?hRe*TL$UQ^_>3(7Vsq# zE<`WTg1H?=6PmyuAtiI^>u4r3pjUcdU(&tO*=5$t+G)LW?wK~YR-Um4;z^GjndH^g zv*?@8%0Y-Cg}@k1f?4$H_n5YD453OgRgb>? zeCm8hjLe@b&})OTWzZAO_@C{OD$Rk}Tuly>Ifj8sno@n#gV7@$Z{J)x<*bQ*w(p!nF{#}}v3Pp!Uuu@nv+ zydYFh$oBRnM-x2tt}A()gO_Rtn_7?Y;o|q z(;ThN=ns??&@z=SoSdBqfjdHqhmzXztw+BL(wa5obXk(=zoKoyJRB%E)}utq+y-g# z13eX@(!Q8+KHqlJnyq~)*n=N*kz@z&vG`RXhY~jW7;U_7UtAX*{iG*tLsBY787>h3 zN*0l$w~y9AX3ZcVB}J(rCe9Yqkd&;E2wg3+@{WrnyhBEIjib!cVr)!9G!wM?Y-V#~ zXJUSzJ_#TCquIF$e@B`n_>`}d)hpda&et@v28y?ND~q>gGc?zeIIPWalp+;_q3Zma zu@|9-rDUBD|5sH1J?<=>!)v)mb?U~RwI^OQ7hjrdbqgETF#SbqKGm}jrWO6r-Do=g zvAJkA{lO-=F*Dut?1yXPi1H~2z24U@7p~K291u|`BUsj zMN7hNo~M#{1Z1cGx-PIbCM;!v|Rw!)h>3 ze%=E#gN$EnryY)W357w2f9QVjl8mqgG>6%NgM;RWt1Dx{(0i5?gKQc#qQ~eKX#fWj z%mq!wP`G7QQ$B z>~7GqhbtiD>m&pj!2_MCX^}^%rppTFL+$K5% ze(;};DC|ESk@0&h&&R~Z$77{hQw_bez6kg-TTn@7%c0mE|!u-6H%LO@KIiex}*C;d;w}bp(saMF| zb7DfPapbFTF{pF|>c&kvA(f(^K$Fxh5weWh_TjngTN#(utee*^8=IT4un%|rdecl) zhbNp{pZy8V&+6HTP+{D~2Q$t_o?f??N)7HpMM*8QzwoIHzok`3pL#aW%D(m^i`;Eq zRgItlKw+R_5%>0ctqU41)e98Rt`6mAO;p&nIW7^k4`)fL4;2>RCnvF6RKA@2$hyEs zupjWPkI2&NaQ33u6I{~k1c)H3=+nv;70dR4)RUC-GeBQWP4}o#%dE^G+lDmx=|bM? zpzIobcyZ8x;&axZ_x?{;*Axv4F}~T|R~bBM2=#yp5ec4gqLz+)k9nK%N+ctG>|-|F z!R91;36X?7XvrWK=iv*unAtq*?F^cs^p`i#Z?oP{7(g!ari)|}Q8j8sDH3S~ZlD}Z zL3N|ORb!7Dm7Eupj{}eukRC-kA=$4kE0eqk=tadMd|?A5+uUc{Pgq&)oW4{!txS8& zVq)&BuRqw^wXCoh2pLt3h`T|L^E%G+_)BlEg1w`ak%2)8^hmWt)@7d;RHkBL0=Bjl z3<_Zpo${%gOY<#1ntg;vhKro%S{gX+-KzrUvBl$L4uOYsZ~t180BHF{g%RjMW-INe zctmotAG|JJT%>>UB)VPJwpHTFjv%31-nuk2oNcR&LN^9f3n9k2-W9&$MM_!6O##0) zr!Sr`w%6!2gxh|qv!^BXKRMdb0{yYMeug@1iY41*Z*@qRak{>)x1(dYC7Xp2hD}oL zlkIiJyR`kQ*?D!Do}T5E7ZTF3T)Lp|ZiDq$OfuI&$uEsB%WFv-Wf{Go+6f**rL~8= zE_L0SQPiE10O&jREvWO>jB>T>Yc{Fn;nC5@93021Lv&_leE08*)RAL@W<8S~6!U+- zK8OK))YzG%P#NM=?{Z((A}#gwn9|abGHVOmfTdoxV(qaGDT>EBpAE^})Ng(n92%m3 zX!iX!kG?R8GFkv`GQf6uK?TN#ba7}Dewu3{pFYKJ@&+H{CBee{qJR#+ zC|rlLeRPx*M5>5Rkh>8WaL^loE@3S2DVJUrF^nqp192(vR6z>&{q?xT?mJ?$zuUn8 zcNLW^&?^ROzm5aGn|;qZ6@VYgFNZ#0ns37D?;w}l8CL-v8~q)ecBg&6a|?@UE31)e zFM-5|)6zKKy%%b%BLEHukXxyRg|3PJWogB&%@e=nSg?4f$%l{|M2lk+T4%>=c#M?X zpR%7~-_MUL0kMa>j-*G5B5VnYC3Mf^b7?7g4O)Fuz4ehiUK^lCy3i71h~?G3A>X(` zk^$;Hf}4J>l7zsaO)o2wjKgsV>cRh{J$!ezU%&tyNSxO@lx&r$Q4Odqx;tUZ>%P;ly@**O<*8Rgpdt0;AtqUFo2E0zO ziB*d|sb2tYjsUl>7CnC^ALhS8kW+Wr&mpnR{ch)06%f%KDIMo~eu#)fh0Vmz#>Q_` zQ_KK~BzCd4FNYrC1#noIuC5HBHEt}MJA$6rxFA@1vN=%wQ#b}ugNZD{`GkwLG?Sv@ zrH};pd4(6k$PKVMA^K1#DQq{RN}}>w4F_InFI~S*O9zz;&KaBUKi> zyg1Ked;mow>lnxwihv_4`n%||`Sx|(njCoKe^$pPMH0$()<7gHtICwz43z}0vX4KU zoW3xF$`$~cioHv{ww`CaW}xLyOG|x?w~>~5_G9w#!;OUrvifccO zifZcc#-$XhcLAK)7xeu(Qg?icc|Ny`@t;*$25kUgh=BF++-;qh*zmrP9W7;e6IpvP zI(2T8zPnkoo|DSg?6H3;x*!yjbQ$%j#&J$(8Z!&EmfF7cP;qgHOZ|Bx7kEYrkK=r~ z4fgVg{V%l52@KV{SC_K@83DDUq8#Rn{6r=@zY*mNrBf@awoSR>?~CP zE@=!kAG>A6lsrPMv-HcBn#L39jhPV zzo-9S7Dva}1^F9LIeRMu=Y#oj#kyzwF4o?POJQN0R6j{O=1Ao)Spq;Sfw18LUujIQgRjzC3O|Nk{r9-zP7CdKROtd;jHTTGDh435GKcN-qQgs3<;$Az zG4k8EtMaC)136#gawn?Ay13NxU(;G9NBI)VnO*hs5 zL3D-Ca=TG+yuEDmzJGmp@2cdqTev4$`U+cuP*fB=$k5~u>OMQ~Gx*^D;eE{2&=8C$ zeA?pV*trKV*7wqpxXER%Jj`Nv-beiM&tu|zmU<~q7Q2H1KFe*G%3CcAlJfogrLczd zkNWs}-U994KMHPtD!2yf4}a5cvgi73D+7`#eDPa=usAz`urPI)*!H&!WL|ZqN^bP{ z-(Id)Q)8DSXHt#T%q3z6f4qGeRXQVKz(xF#eURwgsX8{CkWII$jVDP8#S%`vB{k*7ww6c*9X*{{y$Gq8$ zMxgpI*4o-9&TCjHxXQ}6_;?Y7WJ}942MB~d7640k?^@&F?g7?3jh_dJLoCoG5Sar6 zi*KO<)^*rU_7pRY_(JxS~IP+~Bbi4mwyFNRwb3x&Vm`c%^*eoRP8dH8ZCbWg3f>m9dqr z*_+v?0Htky{f+MMcfljw0ofBG2X+x(5UtJ1dk5EvMZ$~Xn71GL_Dc2U<*7NaZoO(D z&5AZVcXe~ro|0kws-BO=WxL72$@xq!wBDVgV{ELavlEAzQbqgr0(A&4z@#hZ>q_ZDjYJ9_aO-yt0OV5rtKf}%`KRDr z8{sk^>DioX^|rN$FiBmHJ0+o~8Hz^S2>*UoyDfz-XjINd)u-7Tzh>^MmP~-|9H4#y zFCOw6}Hs_r=#;cEUd&|mL;#*5yrA?Ce+1t!@J3Kjk!_4XMJE!$1NRtj%|Zx~?%Hx_N*zCMOJ{k_x!N9}`rT zaHzr@_VL~0r|ft$lIdu}-X^s1t0rgTa5ppnj)%=}oWgFX0x#+}50etruCKG3a^ z+`2XT;rR{a%iaIhOekL4z*Z;Dcxhra%A-+!(ZBn$&fQtxH^W}E`g|c?PO-gH^JKn* zFqH4_aPsWPi@}(h-A^Id_o7#=XTcMYN1`-FbodEHFP`9*P+Q~|6v%1zBs_8W`idnR zX9b_rzDV#vC?FWqSXP||Gz??0}%IfZj7K)I;561)japMT<9?N5TQzGMaiBLiG zCs;g*szkt+-qO;WAeT$id7iic#5ktVKq#DU!rQ`qq`MGz-bVSgAax>WxbJq-(>vo+ z>ShK()e8n10d%j*0-zayOMJPP3ys&AIsncDBDZK=e!fyXOPDx|nCzW9*!@K1fI_*) zBv#_b-&J+2$aylTz@KuSy2xt7b-LA5H9%zADi3p1i(*4A#-2S_iF6s^ea!^<%)SL11YTmQGk?V|*l{wcX zytY(w+&>isvEE5h22`&ex{5gM@x6VQ(z4j$z7lxdm)0a>XIg=urDmjk5BT{Bu==Pt zI5hS20)K8%b@ASehox9aM3P-1P)G_RL+JQ;Hj}(UoGxe@C5%$K)iDXlHP;t?=jYo$ z2*$Dgsj38{(Q{eRNGJcvL@AB}o&vtWr_yOCS5h76DIReMR#iNeC zd~|FJdyIzsp>c)8ia^aSm%v6D~;R~ zjw~q-1_Z)!eWB*>3eR4i!tezfv+AX7TM~UDaS#cKm1;_fZoESb$4UZK`V#y%XM6nr zR+qtr|3VlQG@S9ZVXWcqIGD1|Mhua3+ zbFXn7&CibaN`ZKa`OFT;F1R5q2*DBHlC_ni?w4`U(hh(7*7W_O*V!@J#`u^{Z9+R< z)MS*+OXkN{sOjGgx}rQ<&XkLIeR2}nWDO+3`UBRH*FtB{6Qkp3_*D^w>Z4n%OAa5O z2AnLwdQ5F>zTqi<*aijH2mTFJ)T=%~wa%RbMbz)wh2e7nbAlilF%BT(8J>+TYdYrr zi2Dl3%r7RU6%^&ap_iYNsnRBY;GDjNdGeY+r4^9Ci5UENS6o+H&C2?3=026@20lmp zBin-m7@t9tJ}s>ukb?n5252cie|oF|Qnf`JlDoUhyEt-SSuShy({&BB7(Qpq)aV=N zNIC#448CEXEpnBJsKP1rxZJ;(0R}Xg%NECgAkdnq17PC>m?`l0vcV2s*F*LHRL>ph zfar0iy@bHz(I_Igjhx`$DIeK}b!lOu9x@NjEOyrcAx?h&5A|Yt9=-{}gXOkx{E_^u zpPQO11Roxa;V0+7>XUo0QI*ct-Yd<+fBVX3NDX?OST{Yw~2{{0zJ(jSWHZvY7- z;hFTfBRaVWM}uaDZ;k4C#udS#sXq$hv6*bA?#i@S0lo$xyy-%{DCgU46cH;S-{(m4 zI)Hq^(h@}`wG(2lF!k;PFwQ_^322s1De=;xB2J!`5K>xnoMq8Ys(gbROP_%TV)$$MQA~w_&LKbXV`MmhTSVl_+xTK*_J=&2{zqNKvO&^E{68I;@gcI+ z!(EJCobdKHhw*K+m*pM``pIkm5SoRq_=+3b#{h{IKJjJG1!_n+HGtVZCnx9&?>xY# zlB8blxe zk33*IRr_SDGY+;(It&yl5ojq5uW|^k`m}{eSjaCyg|(_4xkYdLk6YQDj+DwNSNZ?W z!#&bu{)dNOtuf6S8K40&F3H*1b|ox#6A~(41*t1G@4jZIts=pzPEn~Ba^F<}3H&wA z3Scq*oe92}8?;J^vpw$z*Dc4H*G$=YF_FpjFQn6#(0cZ9f3S z9^T!$7CbE4d<&4c2?Vh6cJ#c)TBOw0`Q04mfw*b({$)}Tyi6*& z8C0og`IXS6Q&jeVtB}rI3^m*MaJ;J?9AocVc9Y?3sV}$2_E? zo&#KIcaTTSBmyZluYn6YK`$sc*xx_c)I|5V?`_dTjZ)K`G+moRARI-YWZC`ASz@4o z1JuPjEvT(V>OEy?rbW2^1+mdNUqWoU?{4ZgGBU0B@pL_GIk%|$M?rUnyI8f!OIzA+Ew#nVi zNofb6WVv^l3pe(WHaX*wLG$lAL>Tp2KZ-10=e$}=Urnj;^ zrC&7|sAG1i;049Q;p0yOcj_sZ)-tAO1Y5 zjAm>^dphj#^f|Z%nf8o~j9WW9j!sU4KYsWqFpA-hwJa@M2MPbyEqc%??g=D(K0j8LW@+o+;=p%o}3|ASjo2&m`c}IeutWtVG>%6q<%z2Ov`c70Kr>?6`RQ z@8NadrSdw0VxZ_vd(Dg8nI;mOi^DnYdzJvW*3hsr!B+>WhIn+vfh&pFu9MVP<+FHG z4beQ5JH+J&SRiHi&s93DLWT$++|0w#SM3MI4HPJvi3F+-B4H^m6d+K(Gre2! z@;%w@<(Fgd$y7dz`ue({rx=kiz^)4a071}ld@v=?vRt^gBbYWx*Jb;emzNAE5Ki`6 zUp+>>E;sLy82R`?G+{Y3uoRhEt03;yuA=EYsQXt}E%h4Gps*>CvF43`O46?S`P}9) zpv2Yz*deFo_{AFa5|$4}u2TXtn98J=q%07uwHYr`y=3A zUa{Nnwa}nx{ZKA4yQ|yCgYOgJr<5h}P`fh1Yojl-xg(lEnums_skayZpEaOh4z@R2a*E+mU{lRt4Hf6elk)EUo&B)1Bk~`IGO7w0?e`(xtVvq2l%N zq?i+ki;!34#Iy~1$m2e<#7MUEdA_Atz@aAdLB0e_>r^r)@Vnh!b{->h=S?|t)QnSP zZbN(8>4Cb$kMiyrH!p9RfJdAcIj__5=46dD>8io~PRQRFAoQ8od^<#*4}X6G3UG_@ z<}75U>4poVy;aKik5V0wjQ8)EoKX3cGphi+YXJu+%Zk&{A%OV*dOLBK4L*abmzoLm zO_P;zKy=K$+$=2O<*(E5%r4&7v4<-1a55@i8h8*F6dfMmP78q@@2(6mD5U*t@V+Q+ zIInhI8{S(R@jlt8kd0?KgLz+^EReL{u4)UX6mnS~1>Da-f4{PdN_2EIWb(3-SF*-dxg?f65 zM0&Wnfu)KSK)iR~wR3g`9y36q2mO&FmpojkrCzLCXEBhYrltlw5SNTS@1ajo(WY6t zCt9-Q@W)^vy8ova^1xFEdi);Ji17JN)j60f0R-2;zz0MC1HnR1@6*G_Qd$vB;AQ)N z{CIu7v!jw>2jl`$vj)xX+`QwDwc%&|@5Kq`Mv58y^!MPaGFO-B={%p={C9?<9=FQF zLq))DFbbbig^7IZ8vgXW%=+Se#{q!k!RSEe=igT+7{zwF-V+Eim6VhW3}&+=!-2ga zC;J=VkaTNYHb(Tk>i~KW!p9CA?%?21Qc@B|A>h8;mx+vymz|vrB%@Z~*O-`?ceq|^ zH+XqkTdxD0DE@&4(aoDTZ{6YqHHvM+nal7;je#7wlf`6PUtiz)_W*nzLb^i?e5~>;sVRqT3TYgBh4-?EG(?669`%T?uyYC+3EMuG*ZZU*@jZj(-8f;DPt>deecs%cspns-@QB7Mc0WtJfNP;HAW z+fJ0@iVI0yc%JN&^SctTps}*D0%83ud+{SJ=T|GhbJlkLq2w z=YX%+QTsrq|K{ztL6W#wB-P-~o*u~5`ZtdEaKCrUy~c-0PxGso(hVAm6CU-D^6W_0J5m&Z=_nv5YthQK zoel#$KnchC$mgzoy(B35p2Pa6WzMRN;wa)CF_FT6N`r+3Anq&8f%qb*zOT+VDyD@6 z{LYbApzEVg`nvP;^Qn?V6nzcRJTVte#XSrT4z|Pc0GfdYZ=n<=cXxMFQ~DGtZE8S9EuJ3j*mZB6 zz#1;L+bHdB+8=D{9CFN5&mHY7ZTjs1TtKrj?+;m}gdIknRqRCn}HjIJT`|7^(sMilBA=BMy0(Vr`{V{I{5Bk1D z4qaPVK#dxioFpgy^!6<_hM|XtM_=15yKQ4bLv!=ItSpr*30%c~#aG4Y-se2lzG!_o zWX&v}XxH&lamd&)c>P}johQm&3_NsAQas%2!nX-<{84;FTnXkutfbb*xZ@kB^6G}q zz;!vCTr>uZ-24xe8v3ACdL?wva|cKJ4UjOUMb^5Zo!`5^)6Le>SXgUHp2A}5hYq2g zaslIw1AyB%fm0?xrD}J$<>m%?*0F9Z@cmZzyTSsGiaUZ#?ZIGH?1X^@C*$+gI%Sq9 z9vHYQPoF+jNaL@9z@{$FrZ03r@Bx9utTzn+#>Q%D!;!R-cz3x!fqx+9b7^U7YikAd zQrRl7b9hitf{^z)u)VLJAA?*H`^%r)-rg5rJK$(M+<^>W47}9M!RN`GHkzPgF)|v+ zQ_4caB^xYIS5Q}vf6&`EJk0s{@ncR-PA;yB^75BJ1m)-FS6T|vL23;IwmCcd#BSzm zrdXgC2w6toLNKwgl2}bTKWdbUiitHhH-lgl|46UiWn&zSCjuhYW~4|5L`6Oj#y%Uh zfv}1AJ8Tk`)BOosF59WoHBd`|6au2h+}s@4a6YdzmFx9$lct800Bn+`28F|4zDa>r z%!jp3D@0izah_57F%{#*!Qg0BzNZcMyp>`6ue<2vZJHOwE~l6-wHOR^^t87M^TuY_hUlrrk+pmO~%F*@81%2RRF5Rdk%&kB!?S2x%oy zP*9)%jYFiqCr00XRyi6>=jG*r0NncR+xb>AJ_z#C($Y*!OhV^}zd-y3W1I@9yv`u2 zf<%gl&%Hty(5)E}kVoEUhaR6O90TN_tW}(_Qy3Tk8(UbP!d0i6Yzp=q_|V13+)yEuhh6oR0j9 zJf-}_FCWbzzr>y2%9f(*(U*1_I02wbKo-)%koDK}Ezcx6h8scOL1ia0+4LFAtb$Sp zT?8G#j8D_VeWipY8oW}QNhv1y!WBE|6%Pn^^;zgO)Qgr^jxxx2f~y0ddCDY~-;-D3jQdZ#If(abp4X@;6>LW0cZn zQSxo&Zf+1%K`Oz_)^=~Lm@fkgCbHlkG|KTz8~EcDWza!p$p*tS($TL!>hMKJF6$#B z>lij403`r`gTDUwKU|{?>R=b0!Ho2w+Ee3IzP|5asz~JL=_t-!9dfilsYLk$W#8|l1KLm zx2I5f(~-1kp?V?@yX z9-zI)?gsUM==Aq4Qm~lOxfPL_q4EKsNgd{E{$X{{myQ*Ywy^kbY)j|&nBHv>6BnTU zNNg6(D*en(`U@Dl0wbj(MH?(TEo1bRF~C;`QR08kq(MV=WY{!}WbDIKS{iZp-7f@- zo0=U58N*vzP_v&odKqLo(Ur`8uG?YOC(8Zs>F7`A3D(TFLep{7V1nx$QP5c4q4q|s zH_vw@WO%4u>+1Vf_ARTzT@ZsaxetwJ`kxJ}Hi1S0#7UH*S#YY<94R~v>?L(OF&0E^ zY}SJRtWp6LV*F4a@IgS!{%!{x&)hFDuvi&3kGs=zpgd_fGBpR#(0ExX?ScK!aEPCK zP@awdf-`62hB&jR`L*Pk;$I6xu})2Ku&=wj&*kOI6#;ha^MDgIO`yi4k4k+%xOBlo zrgIL6Y+h(4HFYQ->6+4kj;;kcjY|=P2i2#FQ+7AEy)WWrtn{5=lXu>`;;1^S{Dsva^< z_VcY-;+u}^t!!X^(zp$1*b(*q;82L)2KBo%LL%l(>!vYGz9xWHxvUN*#bjRJ-2ua< z;`JwomH3oXr3&f$xMa6|!pw-{Kr;&ON259wyzHnzv#<0o0s%CSRO}*)zIaySgZvyE zWa7HY%C5q~La*;Fjsj`ifZO@08ep3wbh^1mDQH$nsVy=pOEJwD)-goZN?~iw>3e`$ zRDNr=`BS>!x$J!)xP3V7eeUK7db!2#kw68PtpTKhG}B!nC_opQ_v$~*4b^fF7+eE5 z4w&P=Zo}(heKA=>o1i?;7i<2e9m26qpwx>YtzmC=qep&}kmX-AY60jwsqanufa16B z=DJjI%l>94vs`_#u0X1L=lUq21ftWK0i%aE73=@jx6B!lHAzvZ+Vp)53X)RP2ls5= zbAJ7Rfv6?|-g&v;1V$p9JK4^qDU1NGFjxJgGd2~F;EkCb{q!``vk=Ay&jK4}s+~)n zoW5jUoSqUh{;W$zvj@iWI}P{w2yJj;A}sPP(o=Z-mg`Y*(f@wxX*tv_DDyxmDFLUu z?|Ccw;dHQ$lyd(&hmOBqp=$vcI9Sym=s=yE%kFR--^Dv?qx48nfTv#Dd8R_qL0%I}#^L&pvT_gZ#0vL?uz=LetG$uA8K>f`54ipt3_&z?74Cme-7*Sl^Du~ zxvMY}skq=_;ue%=<}c&IsdWF6@;bb|^n}Qa9RwXm#~V`gAZBJO50i$DFNuuL!o<*h zU&t1ql|>lQZ7Q`8``*>*ycYJ*+oVFKs$2;?|8&u5l|Tp(W}=CR8Nm-w$-kyH1;4rd zPccdeQ!C=ZH%Ta$U}EvHWpQ_9<5JMn=#yZ$!#ku*vNgl|TK1Jk36Cix~S6(Cm z;931^=bc4G8fl)?AKABhw{|lp%B&*&{BX@i|9Xtc!T0j-w5mT-=RO%06jgz8E{K?{m&Ay?b95iC%>1prj))>QUk_(TP)LeS4yZA+0 zyH^IOy#ShfIgAD5jDP97wx0CJ0ug?Xd2ldx5Om2&LPfm({-)T$zD*Gz!ZZd%6E0^9 zpE&hc{2xB<{)1=WI|bd}wUIwmXjPO0*EijjSl?mp3ViwJ(+Q$Hk8HD2Q}1caHU0J2 z{Iq-%ip;r1CrhHgZIJ*i=EW!Ez<oB))__&% za+9=A-7AR6HpGZExVxl{X-W#!NtUa>z2&_ za`+B>HA5yi2A$j+Oqo{O`Hlyq2-cAzM$|I-Eo0D?TvuU@A_C%rLaI6Zw-{2USl01) z!lmXtR0sV*Rxn;*tlHPdcEWgN?mpJac67wFw{~ZJg2WMcf8W|wV7)G;uRuwCli^BV zh)Ah;|4pf_f2Gvemw%;HNyX3eiJlw>Gx{Dud2V_BZ?sbE+-pAZ&GXYl!oZXz2%+l( zxt@M#5*fcp0~Yx15+hM{&jivS;C4IkVSw9+4`KXc%S_CjD9+d)3M^E1z=%$SleF|K zs0we#IT>|9jv1E#=LC4W+hzaDdhZ7368Rwg;0p|$y$S|h2kG9r0FFuLaWuC3^vEJE zz9RCfbkNTL5b8f-H_GzrDlxghkKW#29nrMlT7cnB@GTi%rl<8PA~`@!0`v^!fk8=u zGI^D)n7I|$HDW!qGJi1FeydV2Oeqr$1HEl73mcz{KjB{`6$%dG<3ay8(8p2e&k^8u z6ya`MWaM?X6Yi6;;1-tbTDXoJKX+bW&~adAOxv9Qz(l|#^%7w)G>|eId;sV?2f&iP z1%%5&LPDrm5Liy*qsP`S@IkPCEnBZw9fJ`s24KnNg_L-8^{Wcu72=yCR}r63VSvC8 z$zjiuh}JEt%+U;8Q(=McGq$vhrYg%(5k1A-K{4?&v4`=kn9U0tG((x|U}*$2_W6B| zMD#bKZ@Ymv0`EujIG)Nz!@h!H0N_7BK8Zs)6)xlk2mQ8 zOfdtJ%x)nyWz@wf!w004fQqscushio1mbqUIRd>A35zxIy|ZIy`Kq6r81L8TZ+AF! zehB;5R;9XW5Y-0Qpsw{g&T;<`nBWM8F71jKJxT-f@_=lcY}W;7FPg^p(-B78Yy^YP z)SK`mN^pG&eEwlnm8F7Dl!=e$UP}hyA7}bA8u7J_`w{mj7o9ONlU{voD&Qw5*~_62 z2!xZB_0#9i*H+io4v+T@&(~Pcj}vN1aky=#Mm0+7=@vlmAzbQEHAyHl*1<%L7W&6y z{-6dZAU}Y+KZySDiT!mze+ina)=yVO=M)rpZfZBh-skgKSt$UDLx2p(x(OGM|`rK4#8sS z8#@~lBqbg%s-0MWv|!1Yc#Ivl zd@|9|X6{WYd!a%VNfL8o%}eW1C>rNM6l}h;kTX;)EqU=_hb2YF@OFh zc3W2b)PjpuRDW(1A-Ooj68RnfGh>Pr1Fnd++5MN#-J_ys_=NZF$`9vczdh;<7jKA*nnXyyV=Tw1nJ>n)770O@$!jOsr7kg;eW*H?X6{DwHKzQMfOf# zs4W3P&nPHJOw8t%^JYBYu0Zt%08C6n*}mx3@dAa?XV|U#17hNsfzf45k&mWL1l0a# z-t_lDzR*!c3=x6MN!l@leWdm2AH6CX`pIRp%ACH1NF6x*wi&{rqt(t{z_o8LGE*j7 z6IJkSk9ItNb!C3gq!58`fEahQEhK;`A~5Mpz=Y3x4mvHTMnp^P>CQ$h{6vftg!b6X-nIXWuJ4Y=x_#eI8QFv~vdfGlksH~gWrSpvl@X${3uTrOWh5gzBSoQP zRg}!!qKuLhbtgjE8NcK1`8>~Oynf&Rp3m!fKHm5HdSBOh9_Mi$$9W+m>~^}!z%;kL z1Czowku%>ZjXyZ^f7+K9VFJP0tt=};VsB?_EBo&nl_SKYUb0_P%f(0Vi2U}mBT5A? z>Hasz=KVXzp5FO)j{W~XiL)iN7*#uK5gnnkx%p!4Z2HP4Jyd7nLrLR;IdU~D;%S@6 z%|Lr?3BG>eO^ZyTRK0vt@8Cl}h?KenH{zv+!5WvW+DOLl!zAZMjLns(KY2NMlyZXtH=H|{Fx+_lwL)hi z*A>EF{-Cpq`WJpY|K=0oEAE zN1~_rpZNY3nGV;?`>563n-s7J)VKhc@^#l(Ny*2U#O z>a({n>_jle@~bRexmGLcJLjhQYVgv3x=F_|G_mmU1^*h%d+W+ofrO4}Yaci;Pp)_B z2ZPt@QCD+vaj8|r$L>G)F#A@?yTKykv>s6taxoWx5>pRDwZu99E`$ebANT&Z1#|ap z_O(5yGUw5D4GhdUKhKn$IFfqvP4KTT&o8sqJ#@ER=MGU!UP0-n_bcfC8#ex1L;hTu zDRI{ft!#Cf3^}B*K5^1dQ*<`Z)tM!G&N9{2KOln(O_wvya&kRVx@;Jz@q$cfi~c8t zPELj>5=d>w|5zF_x`Sh-Z(TYIJ>&fN6@vfI$XhB;E|#h;%e)+VG8w()rTXmVEl%ft zFpWYlE_?m!siP$+I=3#;>pun0f49?S_h1#^k9 zEBOcH|@{QWvJAI*A5(PHH^DWgJfTTQo$OxWqqiIx3~9tszV>b=-u8|sXIHX`T5zn)R3oK zK6 zSiXy!FK7w*iCC2-yJH87m%MRQhm}ie3ilZ6fyaYIriJ9pG#mEEUn>8mLq%)wlM&6I zedovh^~K9b3yW0DSEHm3=rZMh@YhoxNY@6hy@K>TFT?G_R*QnG(n-w^YC?aYMUIwP zY+aqHgF`$VrtmR}4U)5fTw|B|@7D^yS_j&bZeJ8l@984{O?=?0DChB#Y8Lpz0{=ALxS< zi`k+b&6l^2f@Ext^3>2@+w)@L*IwVqRH%nZW~r~~>GLfmoOi#J@40jFU52dYUAn); zoaBd-W?@2dIOd`JF>&(L$#!z(Dj{L6kRWk=awNEK_}ug-T4`yi*5$T8Gg3nhsHLS} zJ%sSL%F_w~!qv4rl;(!S?mcI2&z!yHUTBto+IRUso^UzNRMpnq+Z+-xXi;cX zJ>Ym%S*-N^EFVD_FCsKxgB6S89#yZ%vfw&r$jn+96?N^*ZpfknHrzc#`tmlS+4t4c zkEbYC3IB4GztUt|Qh*2iX;%V}GL~rbJyTnAna(HKrpNOhzeo$a&;BUK+bd)m$ zvc@U|Lup1X$HY{Wl|3zp)B4ZKoZ`ioZ;M7JeMrQ!ePw*8b!ocZVqzBRmBMCJ6BLIJ z`Czo!LB3y3JxwW^t(sbgbA%Gl;Pb^o{qD(Er$_Gfb} zMwx}2TncPJI=f{aI)71?yEf_h1EFo|2GrWgpeAQBGc(sy{p6=_jF=TzixrR@+G%|t zOfnPw$zh?6wmXu4{|dLha;Lca_owRvfA=N*7hxmENU@7X#i}m#x!x^@33P4W8ZYXP zYh1s+`An;?j(dzEx!1v#RFd`w@=%LxPd&+ectnYU^bd@u(`^im)OlM z;B`m;aakN4INo#hu2tSq)QHd0H?1c+|NV{iWPa9dLTD5%F80~oMYiM;+0#|dKeTO( z=<4b^JAfK6_qJcWn8QS$8b9>cgfl`{`4kR_N~dcfkg3Wo(l8<#i5E5eKy}!*BrW9D=H={D_!9@Za>;N)3WtpK=N$d zzrcKdEy&hVS5>~Hx$kU@(>C#Yy1Zqg$3V-G;!k1og1N{jZo~Fs$68bycP$w z(OyMGDoV;)|6e-KtjR0L+wSr*`TB#t{{E|jeDxs_j(41vgv{`$z)*JpoJvPB!1=!) zly~j}e8)U;&NA);6B7kGZ{2AV6CAQ#BNbzL?JZYw zk7mSJ@v|&OoKdFS!O)W&zU$$u@b zPU+Gem)~nI*M9HYH-Egh!!P2?{?ON1>JoB>ToSAYA`T@LwL2UT)6mnCP4I7J7rH5% zq-Yc+bRggV)~^%ubBn&eiJk!2TTG~+UO~F0 z%Q4U+ke9`3X!`BAE7&}$V#BRWU!PvuFrs={=9;O61>x+7-tOJy@84Uk&Z#}?R1F?% zZT->GdbanT_pkYRQkSNL@&(t%-ZW`%(H^QV7IbRg8GC&h*wRV+qA1NV`QG>B$(u#S z?ls=u9ZtScP+6J$`U7)bV>oRGrWhgEdiY4;_q2hyN7YoJOCU4-yTbhZyexsopmds+ zJ}eOg?)J`~pZA&narbrQoxVb&FN_{@wLyU;XUyYYzpi<5&n-k@!2NFRmpcDnw;@-( zefu_aNDlih%XG~w{&I46cZX^VqValPjp!vLk}xjrYJ!;at^iq&rP+x5A9}}Z?&YtW z8T1T%Df8^gk6gWYZB4^KT~%l_!(w8lS`zN^+}`JGK{OhE`^I#o>wU{^adBHWpBvFz zR$zgq_(mwkLl~c=%X^$Tt*9=@+Raw6>e&61;KCmWAhn=yzP{sdj7Jf25 zO9%NU2e{vT^5xB&HxtO}FYFeVmgtTY%anM>@u^(DetiJ{uZzF44+g&E8Roe+$tkk8 zE0CS`f%C><=oVKqBW?z=ZPL%S&Q|?(Y-oPm+|lv&yD9fem*~02&Zm99DA(hw@QC%- zS0&6*6J?y`ognrdD=#F;5A3_Jw^v5+O!rB33-f+T54iz9|Bl~Fvv)Ewtf8JXe7R}W zej}SAbgov?^G&flA(M2yzSsU|VLY6_GV(~Y?%(f}_ICdFyrxC*j!A5p$~@Q%+$nW zTdgjO$dR$JF=Z8%q{PHcY;3gsg7+qcYKE7t+J>+V>RuCwj>uY)mi|yT+?l!0TCGMx zqB@rQ+~<L=enE*#RY$8E-ejy?R9+E(M+Bq znEIvV`A0r=U!XmHm9EH^v`|(iGpur1hSkW*3R!gu^54;~U)d@<=X&P(30vF)O5_YJ z2Ir4{5T4Q%`at>qKQ{^Yt3ch@tsJ9o?pPl>*Pvh%(A zmoIoV537iObJKpYa!vR!Pv@V_a&$~->5jDZYQUoG%uCg_pV_%RZ}*+D7)rCoXQ_C% z;MZ|}VJf@2dg(H&@ayjG@M(btEez)=zJ2=(RE4Kbo!aZ(btC_VmZx^$0%rGR;+qZ2aW<*Y@JbF~GuxMnf@;s%&fiG!I>Ytyq zkRzzNdUJNPpp<>Hjwu|OzZUOQFWH`%p16Ht_zZ7+^231v-41E1*Hx7j4`@G-9?H@P)4~E;oowO1`V~ z?mLcdIe0L1ezLP-renh5TWQkW{?RqD2Y>G+);H4WLhigQwOw9pQ+rD5>w_RIcauN= zA_|Ih4lR|dGCIX~?^;)RW)~Nqf}%a1NwB$PcSGT1Ed5v7qWa#qtATI#Ex~~s#fLFYUp!swJDvKvGKjNB_$=0c}hr14q?c_RGn>%iHV5= z!qUl;riO+B&ew+*F3b-AU&fe+*rHPQCu#Ot0hh+ihz`ry6H@8!1Jr zRBtG_=SpRhBVte|)HG8$Ans^}&Yw7I!9-MMjk#?HMGR zr3P&nZtL4){pUq`=I`4}Wu%uxFzvY>Z6Li({G=AQ(&o& zvF;B4wQ*?CK(zD1O2Fv+&|1RvO(Mu%4Od+PnKE46)Iz3_QOdP3?XNgjT3Y3k&7s&u;U!mD7M9%I9J zt(r}LEuEXH)SB+Kf07=NO){cuWA#hA$zgmHI~VeJg5RHB&=2!c_{N4})6 z@N)a-)h9>C&hMBV00&S?yB?hFPXfs)4sRLlW$nbqj1vstG~ZO`Gb2C zA13D%?@AH0460FO{KzOlK|v0DXCR^{WjXNOzXsv_ zCHg0i+P-w8sa{xEch;GYS0x~^ZB*K-s;r`doj|V>F)}g&?YZ=^vWv^i$MHeWTHI8( zOg&AKRDL_pzbyUlpTTH&Le~^?B@QzV?f7evtMPpKKX78fC~QTAxg|?Iv{^X^p$p>! zTa@jDhb;{jg(YHWV$B^_G^Fk&%%J{?Bzr zM@L~mfl8c0aq08RIHS-luVs@dVJ0|=tcrYgBO`+mPmB8a(T0}x3W?-gxbAL`Z~WbF z4gT$YVl~VBe=_Z|SVNHWsZ;v`mlE5B;rCGz6T93lEYHEsJy3c=wJ;Zp$g;<8tTZ*O zNfBOy&z^fx>xaDxVJ*6SyJ>LHT2oVa&mImL>NjJ*1N?o{6DLaV+&TZ_y<*`yluU)shH8A7CDu(s0?xp|(B9Dj zi&A#E4P|p@=cBSRbS%ZCr6Ue&Jj2=fXHB+^!F@w;Z0EerOqR7ngq?7Kc>DBF{oTAg zO7F!TA=OH!rY;spPcbo0JoFfPWq1E==?P}PXxotUYpZn+9{jw%{h%J-Jq7xI(*CgS zwL)}uUt@dd?IV>tb%8GTKM;x=D*U@RIXmn{sRYY=jFv;Af~6M!%>7^nYnG-wk&yLL&J3` z!%&`!ZHT3tMv>CRizUq%QEb>nG0}Hl^T2^IycAJ=^}qgHUR~hthq`fm0+Fkb&Ohy} z&w$SZwk_M;?`!?p_AI2NaQ1Q5O77T^zAvykCZ;|A;Ek+u8}~c+?m@{O@$lgsypP%C z%gnW&x0*MN(Rp!-2;oQOQBhOp-0+FV7=D+!pcU>BVk~x7pPT&nGLIfOj#E?H3|57+ zu#HSjP0yeI9TUSq+Houzd%L5fV`6;#z<~o<Tjor6^a-j*l}Iz$RE#AAJvi>s5x**U`~STLYoeFEhI;FSc{%jpXF3v9aMy zKR>r7NfthPa$#{3LGSlA5fLU%8OSL(le9@Y`kve)kCpMf%Bw`po5%b1o;AD-h9vei z`~C+fonz=SJ_X0{tKuee{+GiWAfbcrtd+ zHx}k9n1Tk&&1KuXnVNURLoA}IY5{(>tk4Qe0BJZo9z2khO3t+_E-seXvSo``@aod6 zq*t;J+zzDv@~<~{J7IC-5XSX02uALAH_WuVI62W|EqB>t0t^;Ycph@Vf-8^%98JdA!cX}hwjDnB8*d2w~6=E{{8 zcu-nfTeHe5I;b? z2IePC2eb6SZ9WknTE!vo+4wSxt89A z3$-~ppNdWIkj`eG5|;DR(cIU^!I?TbJbeFT+h%OnJ9qEGjjD;_&@28+hHCI}P0dgt zk8m5#(BUQN9O>h=dmWlt`WTRP+B!PIJBXx-caN;3w=hazt$N{MH3~I2bSR9ep#US> zrKIkH7cz3MKBH58c9br%G5fP0t;#1u-zVPRH+#i97T&pI{OibBK%`UDt~U1es&RAyOn8y=OElblxvh9MPYz6sR{dmmB$t-q|~Hg1;4CIv_3uk z=|x3N@pVL`2Z$(NNhH0FrFSB77GKUjPFx|{v?hutTBsF^%Z+m>p55jZ^|l8JwNs}w z?$Tbi%~{v$YveWc@!6TrP3i>;@Z{@bQE_@VBpsx?6$vX7MbF1?tF~VH`d4A%2?=R{ zZ7Hjq_yHD5q*$1j==W{>ng(Mf=I3V{S8P=Iv=6`n2LKiz92%ndz!a%Vc*e@Y#DtQU zvN44g&kG}`9_+#T53ibFRkw-*tRc@&!5AN>m=~1I`fnI%6K$UudGi&uAOvq|0+h5-Xx#jeV98jAM zVV|TgEd|J@9S%3O{`C1XoTF5D5?XNs0|SME>NJb}$U1lzn18cEHx}2{zVGf%XdC6* zcY%{Yzp}8n*wWk#``voN#x?A!V>>n{Ihkt2RTdc+XcRcd-o7m|d&3EY>5ce!NGG|x zSQzXD@cCZhpd;_nW_>bMTLbauoEL5z=)MyKE=!!7aJQ}RNkaft`o<1c(llxMOXJFoL6}IJ0!ra z#;pd*;kIEo@gr^@YHt#DSDx9MUQ)7y#NNS4@DdwqC5oqB3Sd4p_3hg?qWZ>*sa7^N z0?{vi{`%GUy|#kM)Cayae0?LIIzB%4zOrWx4I!-s?Q8$wb#K}}7)Yu7G3hn1hdbM$PH|KJ$c+6PE5nWx~R%woJV`J5B{jzw^cMncRM@7-S7!q*1(OqD0P*2a# z&ky9Orc-t@0&(uO5qRbBap_bRvGMtod>9CNJj*L90Q&S9Ib_3lZnI*1?J;;yk*Bha zZ8&q0DlBqxa&Vq#GCrNSb?a85^>Lmg`_0kX{Rg!b+z0ZCiw|@d$1MP*e1zg&SQw(z zlcXIc!=FD3i;BLC;V4bsVJ-{!MPhg7k#*SUy)V;kKQOS5Hyr~_Ee6KyO9L6s)N_|aVN*{ zsif}Dl$y$}t%W1^K5|SuXSTMk?!f~GzI^$jLF2MP;yGM*5<7N;F};3xyeXm{?dyY~Mb+ym*czAoX*0R=e~Q zLz*UF;U-4eem5UIy^TqwXV`B6=K%USIXR7WPIN?n`ediA{Q?^wkA8<&fYUnLcdVU2dJzW2iEyJbnH5*&n+P?P`vE_f!Jap(#-onpIIOPfo3W&U^@P-0t zVKBNHjbIh9Kav1v6D2lIJg_PbyGFqRKaOAU@-$7-knLSuqtMfnx6t1QOXB!ojRN;A zbs9m=YWuLTu(EzP6XTTWeO_t$nfqcTUcq6T70N=rV#&_Iaq!^5?9i#a;I&ow;ECdX zAwMK4s*Wrwm%BK5#af7H~p4jb?gy*A7?L(b7>eDC@m;BjSxx_PzJJNWn;^2 zYhRk4o(5vWX`vZxiH(WD?GDV?Mb4-zSVL0PH8j?HMP+jF@Q}+Bf;JB|uE*TEl>s~b zVDgTx-rk+C=rRehBf&t-d&b-Q4+QGG%Y&MqIH8J&j8Y5dQ`1TCb#Lhjc=2!RXB@cUzs}za9679v-6Z~SzI~`! z@n-7Q))`j|uEUf|P*Tz?cq$V>ei%N^p})~r zqhExq4jqa~PEN)o{gVYF9$RKQ)jy9(Sw1B1CcyiCH~G5O?c8oe*Kb1zpio*<6SQlR zl9F0lS_U7VqakdJ=;FLLnPZ0qL6#0j;D(+5aa9#kv?csP(Jyiq0wx)im6c-L||IG%C8Dcobo9BaA08F&71uwxU)kmGyyIUGEcd>;(s&( zVPV$6hKvw0>O-cJTXLXoETl%gbx}h9(dj{1#Q#t^VOiPh(qGd8&Yvf{-3e3%;7Q+L zI05h;NkC%;Xc?IUg4OObMn_CMF{YwFSC?5wKbnh$#m3G~qx9Mv>_pudPKu12K!DWI zj~~}%gc#)N#9F|w3jCidi4dRxaxgi0vscuY>`f5|7`*6iWy$Xl7hgn|ktE=*IpNt9 z!&Ru!b+Tb!JuiA+ZKLqfC*QcC=`_r-l;8L6U0Q1DkzkG^`?4r#qhDZR0Gn6*+)Y%? zC<+k744})5h@keO+m~NZko$Z8*|V}pleydR;E>GBp%5y1Krn2uu{hP$tTv~&KmojR z&Mf3#K|Kk!-qEpXA-omuywA3Q5)lSzl(fSg2k|?O?a~|K=~pbrvw{<^UVQ~J1uM(L zt4do`Qi8F~8(w^^aDRbZv_ndY9M+`(P&ZLCZPgq7g}cm7!V1nn&T1*3xmo%6n0UiP z3!lNL%&{`(GV@Aq==A%l?5r%AGoQ31cB=hen6}@)zvbyuHIhKXgR`Rtl$4Z6>=U@- zN)%X!#J-GzKy*TfHKeD$#%1&M@2+LbVd`z5a|FmXfi^~oCWfr zE4&d$k8>|mH)A9h4s*kWI}3=ym4d8;LdfkQ&X6Ef)C4(%Vjlm)1xa#n?3W`Aoj!Y?#%2E zF>&$zxi`6t0=1}4VhjjQ7}31h(9)8Jh2^Q;efiVxHwHP%RA-{M$hdW{%+8(6@>dLz z?_2>`@lMZ2&$?8{JiWpu+H{qdK0`wQu7A?E8PpF%b(t7_&p@Yogbd^5o6|tVJyu7G zISPyX{QUt0X?mQy+G;B+D@pB@81e8G1%``@3#{oHCl|0c>157*IW%PyW~i;D)!f$B z?RCElPJ2{zY6Ty=k-fx}?r=^b@MAPc$N0;Q5v-s4F}Y(Ktm|f z!%_WUC&|@^=sy#!HrUtgjJ(@!d7iT|j0R6r3R+%3(TB4$jChHu0Qi0#ZEev$PV`wf z{JnxXciB-2J4w0i4+^S}j*dnezG+O2fg|ya!BggNIVZ>nWzp?{X?8(X;&%_5c32Eu%#KgS8>zO1Uo!P+; zA8z?5R9(c@Ehs5b2B@*!scL0r7CBaetRS{y|2d>~z>BW=RJxgw?)-yWBn;#SL}omh z=;=fC)h|Ly(0%5u5yOT{-<2BoA3PYmFhxPoeurdQwA*0gBp3=()wrIwH!c}yG`hx7 zNgZeL1;Me;Z4Mt8I6wT%Wk42u#q9IpV(sBKZrws`b-vGZ<{+PHP|2M;4{B8dC-um0+K$A& zUJ-MHFwG##m_-;}@EJ2N zfxT|3dspp6!&wF5lk1qZ5XPEZkIGE3bB=5<|(QS-{fV zc4H?#RJJh-b=~G2$I8|bs3MGb?@b5al1pQuv3 z4*HqWgk|iR{H3X z0@6&iC8hp|_LvTZqLzaDCoQNyD)2bfz_dx--L1+FZalA#XOTK$E^2D|&H!-3>! z_xPby13M(x@lt~xgy&l#v8=LE`^n+s^{R@B=BB3JtILZqiXNA?bY`l4J^Og3?vBDq z6k!Yg#wHh=1ihX_EQo@sA#s`ZovXFu3>;p1bqq)ha<(x2XLqoRFhwJ@zFc>0!D;Cs z=0+g^pD;JS31SGGhxX%VW@cu&++hKY$hH=1JA@=84p><&qh+6WGB+eDDhjCi78&Dg zq(IFFiAQ_PY#S2HxAQ-34<5Z|^=)K?GGl$C82Y=8IQN^`*fdKkK`*LnYmct{o+q#C z>2p0_!9C+$OHsyQu~8^(8l_(QocZWYM|(RsH;W~AY8o08UYNC&IbwrhqiG63%YG#G z=g>fvKYSRWuO0*F^_@h*N97DyIbvc0Docb61B8${zF~d~reTo*Emb{6&wJ5b$~vmx zH)Vq}2GqMtULH3qMl!9(U5TMvnViVNkIzpQB6J{Fw2@~4!v;Xx(%Biw zq`@$A9+6Pei_Q*J7L>G^?KM7B-o79+X7{m2TtmI(n2NQ)JT3&;POPIQcv9nyl-^1x zvMyiVND^2NQXO|AYxxS21g0><39L|QUY-}ISTsUUL*VUVZy$PEh~(@5HW?4e?^^V8 z*I+gk>Co@PNf;S%z}thhwRn7XJ2^vc#e43zwqAi64Db1}v(p0vDN!6;{Lhnz4$zZar*o-Ck7vx9RBVF>>i!{Vio9 zVquB>%d3b}`vPXfyf&}H_c1dvatYYPIv5@iK_Cz`3Iwhf6nw=jEv(Fod)76WU0sbMzKZF^?qsrvxkcz|;7s?~u5Q9lkU3Q_!>j?kzrjb^iP}z6r!sm5Kpq6VGyRc zH_7mP*b~Vb5hfR)2WXKfzVYJe;GQX{38{I*)*+V{KDlR6Nk`b&Z)nE3*YhLZ62UWQ z=?>^8MlM-OMmHQi>g%y`0JNa6o%+E%mJ8o{Rd$surMqu;-Smu5h@_SJJQsAJb(N*M2E$eNgtVBfy- z(8$^vq`?XrNC3}%*!KH^miKzmeKNPSJn{G}6(O7j-E(p&$3;JCmvRw_k-O(&V?zU0 zm6lN%i5aOAb#(+2FI`564Cc5&&p@vK)Wcjc8wq?HI(Wk?x@bw{0??C4DM?A&Yi+i@ zBPU(;&=g-;YVKsO$qy>Kce4>TPJ?m@334Thhq(fY#RSte$Q;L3MVd1u(;(!kw?Q;G zI9Q~^v!BW`0CcUfv9(uZnpmNeKx=#}>!(`H6QgFSbG( zipA;Bmq6pMPaFsYm z?m_CS=K&RN-=6RO?jd*$hT=hF0@8iq1)i_Yg`3&gpF5TZUbq1Gw(*Lttbu_+L~KqP zH+U*xGtm{n^$DGFg@~<5=RZiOE7*m*z!o6A~}(3$;pmQVJWeY zrWg$kq95(Wvfk?P+3?2UbY=hRPXlw_Il*g!DhH=+o9Cl#m#+3j^V%sTArZn9Vrzrlauv`GoL}{cq&3VJZj4@T(i+xOTvF;vfJ&k!}A7=P)==_U`S)X~ww-f%`K z!mv8KC!FsnA0Ho4T!w)GHQJfgWq(&!R}y;&&V0bi(jG6mkigaDn=kBkc|3@Qpw!=g z5$~)?Gpq|rKT+Hm%}=r#$2Sqs6!RZhpa$9Gi7L8K8m4ZC=>Bo70z8k z*mop$2TVtcM-}$^DNkb|*qSdXiswW&=<9-P-YeXB2!O`HVHfaGLVEgpU|&=g20lJM zYpW}~Ter5hwe8>g9!Cri4lTv{pp^p+!wcs|Taz##OvanGm>PrEYXX1Ed(jCJ&_3r* zMEq{SlsvGGc(d$K8_sn|L7L{~i&!lro;{dyNv>wupCf^doP8W)Zv3za-vMEwhX=VH zU_k%)@gP)W4#!6z@0s}iz0K}EBKrPkH!q_mL6_Fq_jXVXh*n=ft(=_ogv%@#!S?*= zQ-D(c9Xob#E(Tn(b#Iu>5Cj*nOSc`&!0+ehd4iDyv**xt(+_8iJb!rMnDFiGf z7{dGg;~?xpwyKDWx1d!)B*vc-oEwzagN%%)v78OKgTtD@3iLzudyr4nZN62ghdB_ntmQM@@cA_K_* zbP>4(CKvh?#i8i`3JY%lx}&3`BVg7db{;hYr{}_yEs4G1dP)kp3LoD(76MtS9N>)i zO`%C21&uui_4QAq&^G*4(%ajccJrqDhgz-?lEc#K%6W8kw1;Ie+-0+jhtbGeGAE{T zmGj|4>WE6FUSAPE92H0easF=OYb`D=;!tgump=+qKsv2~S}km5dltwvAI)MZIL4eC za~P$njz$eQjxozkn>GPSiLQ~b5x|NZTG?BOR*HV?R>e&ODlUkHL9WZ;q@45dnVXpj z16w@uY&L@yYyn)@$|Ux%t~YPAH*CVGLNe6qm*0OGtB8sz6D>JH^H8*)=iYP(`9NEt z9Yao4MQV0 zLMtUg(;>pIPL#fzUEfbJn&PuS8BWEkbs50p)Kpnre{ZjuzWxtn&Wl`rW`G+0zZ`oC zx`OxbeVJQb%^jQIA~#rY5lZAs5t8_HhK7bjG+{~X>+p_F06v8BA2vc*&w)GW1VO8i zQqk86!jvoc2U)KG6)X7cyNbDMkWSzu}q5-ctUFSf+K~_v0$+R){QFF;1i{zsP~tEij1G!x?>*G#+j{2E4FaIF zwz0{&dlwXB_W9Li#Zyxl+PVF!CvafGwQK!VXM`0a*>1gm|6bhqc5_P$>pof=lswn3 zzXp81GANaVHssaKu2HNfKh*kTClSSMc34-NN0UoKW znj!3Atf>>W61+5cP*ztFmdx1fWn-C6Rekq60HqqQZw+NFF+hJf;@C|L=qzdG?lh`; zDE&@_|SMJiu{}$J20%Ix56W`-53Um*F?EYTQ6DdhwDJm z&+?)>qT)A27FrOfQm}gBl9Ju??-dz7Q{9`K!Pu`N)CT~td}$q( zpaj+7#SK`NVUv$bO4^@2%SOrOEO&6>mH2vZBH(LkYARCXbX`JitujOdpd2>ch^7Wj z3fCk0hIy@>olbL~eBHS*c@lhFma$C=3qGO;-XBC3aJrL?4GS9^sA~q`vujC7C#NLz z53BqUL)mq10ioF2-JK?T@_?x+$EBM5EK~z1GaekOI~8;YV!jjOAA!Dhaj4MqKf z%gR_jJU&%X2F?LGUv=~sY!POf4A1D!@)E)g{Q?4HZGN)w<^Lhes52L)*?IB^=q~lUj9cB4OGUGHj9f^<9%LT!E+t)rM2=mdD4T&7+`V;hHqnt_@GLIX&hDE{l71^EUHV1_jk7Ej`JJzBEV$cJxZ?9p*(kNI5=1P>bKRK8X(0VtvK6di-WB&*HGDDNmCQT!hp=KJ@m@n{2+@&;cCjrJf=~ zjIJ)$K`ZQs;j@o(_p^?=i@>K_G4_LPf?MG())gNQPs+jfN-qyB(R>ydYwABJ8 zMnkQrJ?G5C;6N@R}VnZQ7}K-|j^e87vg6lL5=z zb@Nxfc+Xy=(75Pm*X35EH?U8RuhOq{TDq5l*Uwejw6wE&|4o9b>Gy_)hLXE?vyIiN zQG0>E%`!Hm;%+9ZQaa3!?uwB{B-uVwTx;7%4OCR=J9!+X9u5l1)n>c<0JB-4>-Gk( zDi^0QZaJ~fZ%R!=!wxZ=m`(bMbd9af*ln$Pey#+69AtpDy&%ad4_7b_{h^rjuG#S(zaQ!mC{1eu5$N_?_XLd%u?Oh` ze8`=2%BQm#LD)cV5eQF+`Z=b6cEZz1>@uJk`rLdVq3~i^N4o0n>iRo#ZTTzo3`BEh z7tGoI@#DvnAeHUgUm%&Anav}ujuZ%)gIVIfcX?o&{u3PQxTvTQeRV-nQBvFJL$4%d z=$LV`*togJ$W25I5~|0bwH4o{xFZ(mXeR@rqvEhMGP(wSIz0RZ3K)dX4^M)bGcG&g z`#|ar6`RFU1eqsZdf?oZbF@B^f|!s8Amc^n2h878khuZ|NH`D|-}jqsj@gB;mbpJc z1Pu%tfHemPhd+eO)54Mx{4vEJ7}Z!zNJ{3sdAd z3{oDZ66Tk1LIprR#gdZrv#6#`Do(wTxDddhG#D z?gWoa%d2$^9ceITrJy3vPfo6<;V|y`sO|ot(MP?Jr{^^w`@%whRn=Y)au|=_lwMHb z+A9sh8_#%Vcb{{SBKjiA5>Wn}7gjl&{O~x$r4HD75aCBa*&5$IgjaLxDKuJL1yLWC zQLtV-m!SbK$HST5$7>n#O@d5D67poZAuz)X5+)M<(Bxgl9xo0-dKp*>0$(YGV$ zUie?4Fxm6dXJejWcd*U04xoI9cymmPBH+!g-Md5eDRw9--t2JvN>;!K_JO8^3`-H7 z1wJRCp-R^qkgx&Jh4IGtkV^_@qQJA#Yif_s>$@8f(FD{$OG~|;Q5#X@s;H8O96E(F zeSphG2!FWG1Lv3FGt!IK*|pU`tOkjFWdGsAXg5UaQ+WJPMM?Ax;Q|{3S{9F91IU!I z*ZJ^T97iMwC{iF0r_?8UA#;Eg_4S>HVkT#9|84L@E)e7uWW@t6KxWQEpwixB#WRIF zsE}LULMz?ff`*vZ*xeB5ScZar-?cXTyz9v6)6xO4w(Uh^!>G<+#uLTx^&2+8GzDIQ z)<9bqyjEc`3Y^5gK@dKNV3xA5SbCj*@cECMl+aA1DtPcAVqJ-f!chm8V@>+j{QS9= zmdHXw3iwt6NOuGlun9-R#l$|E>#_s~ul*5bv9NPr@%Qt?p*t9V(*QyRbc!rnGv=N}2;fY^>5 z;}8RdiVC{CMdxBVXGnF`{Kfv`$5+ulMeF%SW~K)icPKa)%(|XIc=;4A#fnZ1GevLKeF2FQ_x&oDsR29(kEkl|locGR54Qm#z1FeBIMvY-&c`>J|>KKsN@leaN zS~@yREw_Unm>AT~izL%>b3T~0wk zcW30b+Woaq)`6%V8xjdCd-UkULpLrrYLi6d_h=o~L_!jMtmGekh@lZmUW7R>I&QU{ z3OhD`CrcvKWlCU!>JCjv=tc_?kQ$2Q-z)P&(=@4vaSGZqRrv|pt_YFX7=~@z#x&l@ z`v(Moi#48Dv1#B{JgWuXSBN?CAFVU(Y&XXTDHv7&=n$=o!J!Dr)^iY%H$YV|APWtE zPh#xp?Je(jyJqc%FRCam4&_fc2oJ+WsT_2tq;DKtu+Si1QD6k|9;dR4jfDkw03Yf` zMz8qbH$6QVFvB{?^T_?(QAy z9@gl{;ltnzI3*?Tpc=)Q+1zszx}OaY(HAzMz)}fX<{Tjb!jdIxMn|pI4I_76Y3bV78_7Zj5Cgb8VEaTj-@uu3=jdr^5k;9n*8yuY1PQORr^caJ zSLfJyb2m~u=S&0AKOc#`2W5_+s3?5I5WKAw-@E7I?fs^!3!;GyF_-wn!Qh6JGHCB{ zwvw}Xx=y0E8%j0sJvgT~l9H|k&p;N7u#*sMRjoFkiTs1p5sQn{$k$?^OgR^KA9LS(MB*;^fkr}KH-k`>+OZ?cn5biGn~i$wPhX3{6*5^9Gjnrs z5s{|mUle{`sJlQgkk}KAVeo+!75oE9Ko!LX>V7D<_Ger$&(EY#tMYkQYDx{o`PcI1+*s*N~Co;HL{@?*f=Fi~ImX?-C zW@w(#Wb--WPXG&Ps8DX;#ME(@Y5Ut6^Oo{yD}SWYoNpPdhKiW#R)@d7M^8MrwstFl ziUWV{?B1+VR%9}<>v?vEo7Z#YY+wHlMzNgF=)BmlOt%(P21mJ zu~-Yt66=@|K$@7a@Gl6Fv-!033`2cAJ)x}#&nS%4Me}<5VwjjLj;8@M7Bi$SY#z1? z9wgrYSZbcl3)3M#Pub;M0I>#o1C3P#^YIgS$6lbqskH5ksLyx*k!UAw=H`~DrPTq` ziEju0fu`P22&%A935=??_V(W6mHZa%tOwvIy_C%}eMx+y6B8Yd)h=p&b= z-?*V`BTv0sPA;$KNQc~m;I$x}-0JjQm#?hHuBERl+x59&&oh<4C6f~;_z6_`*}WV{ zO18C(H&Lq`e*~3V+eM8l10S&MCMG7t-+k=v?tX0b1AU3C(D-4z<;v=_`S5RrF=OAp zv8F{mgK#VAl$aNtg@!>H`pQE92OxQV@5IAgu^4F9LVQKbXy$|{SdEY^iCW(B5cbP< zQPHp8zaRX#&o=wr%U7?MRH_OUvr#a;folqgou)Deuz)G@GhXp!5-sW0V~|R=l=gX$ z(EcSjvWCfS^PrJS^~McN%2-bmya$>F)4R2Ev31biL-HV4TE0VfDQC`SxPfZsEF>`g zIX-%p}Y1B@&gw)_Yo-$S`^sCi(m_ZyM9kBsh>Od3rS8e-;T@~lRN1I zs#tj1pfsLFzi!-v{K$VPR_W+~T%MaTRf-D=QgHkLG5gFHu6&%H5_nZ<1ard4gMpGw`n2o9&oMnMn-g#uEYSCB?*` zBB2KxfU;!f3%ILY=Tpf`bYsH75M*m4ijZ zk4Ds9p$H6`G!#c6;e-epB2paeip364Kr*{`3k!1CBiZLtFehwg6BvS64q=@nOC{B0 zgZE5){8%v{6?jXKq>aB1md05?QZl;3vEcUYpYxv!AMkK?*2H+YlPqaZ(6f)9AUh4p(7WZ40^uP)1f<$*FrmHj?!%Sni&0_1#qW_Z^}}Y zJm&81nKDtyOVzkfMnY9xj$=k{Etk8XE*U zs7r^&Vw#wNEb+-i)`&g0C!H*Yh9dVXvWn`8DU<{NdE!bGVkZ}W|Ax61C~^Wt*@i)| zC^kayXiHd>**yCra4~E{i2|Vpu#r3y|2}2liw{qRUcS^t4T5jd5Uqu@coJ18Qs#)l z0_dkWEIX2a8(?9T)xClOr*7tL=nZ<{ezTOQ+YOD4k&Hal86k7%ePhMp#--z>WV6OM zMa%px`ePt+4&oO=zyshw9pDXW8y!OkER42uEBTb%zkmO7=Mf7FizsSk?3Zoj&&V?a zfb#|)?N<^yjHx1l*mLOWU%PgV@x)D)^FC^7>)a#=2T+hEB!uceqr`f#Y}xWsa@Ecd z*<@=^4$e1qkQ6Uf_R`g8rb#rekrFLcYXpRabHN58@A?T*p`ywIv?$zi{ah7@W|KTz zakc-|Fy}`&c)>5gjMCoH@~ywTpgHK+wvGRftM`t}@o&S&X>Scpg_0s#N?O{8ib6@! z){ZC??Y*d!v?on1O-XfE6p2bmnwlt;l9u`&m(Tb6{9do$^Vjoy9v}C8U)TG6j^jLz zKVl`m*@QOsTGEf0O8 zx%Hf}F&r4BaVJ>s9<=L%h2~9Gre;ArX9yL{OATT7u=A6Mgb$1vZi`2d5(87kI?n8= z^Wq_xq+{A3b%212k7>n}&V8Q`-3LUur^c7f&4-J?$uEJDy`9%af(4}qx>IV&`YQ5Y*HXJlw7OV>L07WNLz z{e65kafDYuY(;>^8m@kqOLuF*TNkKZTeizM z##dI#C~XV4iSknQ4xo1ztd0n5w?5RzFBu_?v#14zY2DWB-M~aDkylTu5|0Ii#4+zB zn85&ghbRU)Kkzt ze%!q5Gnn-n)4CK`6xjCS#aNDbW+}%?W<-Rxo13hr2oEL_gxC{vWmo3$+`_^m>YmaO z0Ze|O@Gsg+ahTF|x|coeLkIqL)`fgbtKu*e@xuB~WEEBFj5Lgb0N^83(AVudn}mLQ z2N&0#r6P^bpkAY0?wm3uN{jR7Ka)uOQc^LaXBRSaa)KXl@EagJ!fC8*p293%0;3#$ z)GDgGz;=v%X^r_)8S2O5ko19+297iG4=y4NUvL~cj9Xw-K_NEeC4(t9kbTAejGZ0K zxfiM~7w(rdIDh`z*jQldp2eU2;a9%LX(!9hp&01c8*h!7%F_4!|K3 zV2bz`>y2Cl3W-05+ylWmY7W@w%ZdVJLPrIvX+xRY!8R}wL9E25Wv9cRTJ0-XEhw0xeSRnef<1UlLjze|nwmP8813hz z2P4$s*gkvu^x)g$idbKlp1!l^>;f1TAJEESJo{^|j6k4VgMxxsQ%`iKe@ScEy9_or zMAe@i7cozn%l$2k;Me$m6HOE5VmQUKncui*5vszVx<;#58=>`spmf>vjJ*ITfxrZw z*}y_Lh9t&fRk^t|BJBN_tgZ8NbJOK}26lj6{0(m|faQ2MxY`vCg{2^JF>oKyKy#G# zz5gs8KfE8(&q%xn!URN?HigWRxN%?66i=E1tN4zkfdA(1e&5xA!RplGrWSjT{U!f7 zT7w7ZYFz0ehKVPNj%DOX_ZI*@9c4DB0F~&Y82QiSC?mV;byXqSWU%-jKC*a-Er6M) z-?kkaMMy`o6Vza(G}&Ob+JabnMqi&#%9_E;#TBL4KW!9A8@;P-033yN09D2yT+*WR zM_h$SJdjE4I(WLUVQZKt{S`TQQ2)#s7f7C*Odg&4r!Nc~bYs&6ZN$${&Dq&`-yqxe z?RSlol+6A2K+8yA=FY-+vI7GH@Z`a#XRc{K@%nqqV|&W1hK2^gepJ}z${bOO-xu&- z=Z|wqjmHn>8=wSMKE6Ab<4|PIEulOnw1u430@1VZ0R!I*6MpH{Dik#c4j6;&lw&^w zc3C*0^@m`9IbhIq;5mR=!umwL7xrU*DJguebV8_#NfbDG!qLAV&m;UtXFX^ zaIlC`2>=`rsgP`HH#9+dghdk;+y*{4p@D${W*?cu9mU>(RHIA%I%F50UVHKSbyx%6 zN7Q~9oWV_VzkcB)?{t1wK8wN#p>cAnHt5VG>#~@8_b@bm0~4Oz(5qw#pPAgcAOS57 z!Zdzx03cz^(lLy|PSC19HkfjtL!I^L@zX-<4hvcT+-y_DYoj5Rl{YYtKPxhxpzN*W z9rLqFOiBv;Bt7VAX5U|%q&$3k4LoVLU)&jl<=DSrRYZcbXK--M1B?+}>3R*J2~5qT z-YX*V1X23Q6EG@=u55vS&E>z{P7%kDBctNtE*l3biHhE78iodtlx@K!Dk?hM-tUF^ z9-cbL9HZmobl;e_1{{sY?F7Hw$~NL5yiSOb^iD4F;T5JW`nmr&?&)_hdja-|8ED-9 zb2H*q6}x%#?`dP>+Un}~1~UP)G_(hoa5L}_lai8FS69`AEn+cRM&C+zU9t_?1&`*0 zrY2a>+HS`(VsWEG-zsyQK=<(Qp_REgKhBRGe&ZpiAr$2&`UxP1kcz3)V7c&vwj)hk zq?>^+??7F`?4jHf>3ve@Xz_d0K)e!Wn@kR-7(Tq%w}IXi{SR74X*Ho?=MwCHo@+{@ z0P2JRA;z_mj72jI9c>-}$^mbt`*$3LlN2(NE1g7c1$y`_s#C24C@~E8e?$@n#C!vk zzKzxTjV7&ZwznTX90bOcYzg`Rux$3jVn`g#Q{n3H5>SQ{-{jUe@H_OOT5MGKP0yxN zT}K{%=MMfX7|z0ozV#dH&uHqNg&Ms;umCKGai`|c<>$|zWA~}X5YrKk{9Aa!NQd{M zqGZw4yYe2@)77=L<2UDDhH|RJys0Bb>QTlxXL*rK>Pns4b^I3Zc6% z_+OwcFr!LoZEXd{0j-95L8UQyP7cN3Q4;|_s$?Q;XwgSocBHF
    X-iNQ-lhx*DtDx9r# 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 diff --git a/pom.xml b/pom.xml index 79bb7e533..df01809f4 100644 --- a/pom.xml +++ b/pom.xml @@ -463,6 +463,7 @@ singleton factory-method abstract-factory + builder From 3eab4d75a69eb6d44a1e1a75b57aa9db9021a837 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Mon, 14 Aug 2017 00:16:29 +0530 Subject: [PATCH 22/45] Revert "#348 - Data Tranfer Object : Added module to project." This reverts commit db10b937f2b07e8357ebb0b4eb02ca0972d83b25. --- data-bus/pom.xml | 4 ---- data-transfer-object/pom.xml | 16 ---------------- 2 files changed, 20 deletions(-) delete mode 100644 data-transfer-object/pom.xml diff --git a/data-bus/pom.xml b/data-bus/pom.xml index 22b3f0229..a77b59106 100644 --- a/data-bus/pom.xml +++ b/data-bus/pom.xml @@ -27,10 +27,6 @@ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - pom - - ../data-transfer-object - 1.16.14 diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml deleted file mode 100644 index c5bfc7fa8..000000000 --- a/data-transfer-object/pom.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - data-bus - com.iluwatar - 1.17.0-SNAPSHOT - ../data-bus/pom.xml - - 4.0.0 - - data-transfer-object - - - \ No newline at end of file From 9c088b5f478360e4a7038662b49eac62af341445 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Mon, 14 Aug 2017 00:23:03 +0530 Subject: [PATCH 23/45] #348 - Data Tranfer Object : Mofidy maven dependancies. --- data-transfer-object/pom.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 data-transfer-object/pom.xml diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml new file mode 100644 index 000000000..51151349c --- /dev/null +++ b/data-transfer-object/pom.xml @@ -0,0 +1,16 @@ + + + + data-transfer-object + com.iluwatar + 1.17.0-SNAPSHOT + ../data-transfer-object/pom.xml + + 4.0.0 + + data-transfer-object + + + \ No newline at end of file From 8525bfd323614ffcd15061802c7c60c3a2cbd702 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Mon, 14 Aug 2017 00:40:01 +0530 Subject: [PATCH 24/45] #348 - Data Tranfer Object : Add dto module to main pom.xml --- data-transfer-object/pom.xml | 57 +++++++++++++++++++++++++++--------- pom.xml | 1 + 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml index 51151349c..2f4871cb6 100644 --- a/data-transfer-object/pom.xml +++ b/data-transfer-object/pom.xml @@ -1,16 +1,45 @@ - - - - data-transfer-object - com.iluwatar - 1.17.0-SNAPSHOT - ../data-transfer-object/pom.xml - + + + 4.0.0 - + + com.iluwatar + java-design-patterns + 1.17.0-SNAPSHOT + data-transfer-object - - - \ No newline at end of file + + + junit + junit + test + + + log4j + log4j + + + diff --git a/pom.xml b/pom.xml index 4f4b5dee6..cecb0f75c 100644 --- a/pom.xml +++ b/pom.xml @@ -143,6 +143,7 @@ extension-objects marker cqrs + data-transfer-object From b62d431d62e22b54131a479221c7321097af7b40 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Mon, 14 Aug 2017 00:40:29 +0530 Subject: [PATCH 25/45] #348 - Data Tranfer Object : Use logger instead of print statements. --- .../datatransfer/CustomerClientApp.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java index 3a9e8b88f..f5fcebe03 100644 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java @@ -24,6 +24,9 @@ package com.iluwatar.datatransfer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.List; @@ -38,6 +41,9 @@ import java.util.List; * And The CustomerDto ({@link CustomerDto} is data transfer object to share customer information. */ public class CustomerClientApp { + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomerClientApp.class); + /** * Method as act client and request to server for details. * @@ -52,20 +58,20 @@ public class CustomerClientApp { CustomerResource customerResource = new CustomerResource(customers); - System.out.println("All customers:-"); + LOGGER.info("All customers:-"); List allCustomers = customerResource.getAllCustomers(); printCustomerDetails(allCustomers); - System.out.println("----------------------------------------------------------"); + LOGGER.info("----------------------------------------------------------"); - System.out.println("Deleting customer with id {1}"); + LOGGER.info("Deleting customer with id {1}"); customerResource.delete(customerOne.getId()); allCustomers = customerResource.getAllCustomers(); printCustomerDetails(allCustomers); - System.out.println("----------------------------------------------------------"); + LOGGER.info("----------------------------------------------------------"); - System.out.println("Adding customer three}"); + LOGGER.info("Adding customer three}"); CustomerDto customerThree = new CustomerDto("3", "Lynda", "Blair"); customerResource.save(customerThree); allCustomers = customerResource.getAllCustomers(); @@ -73,6 +79,6 @@ public class CustomerClientApp { } private static void printCustomerDetails(List allCustomers) { - allCustomers.forEach(customer -> System.out.println(customer.getFirstName())); + allCustomers.forEach(customer -> LOGGER.info(customer.getFirstName())); } } From 4a81453da403fd76744d05e72b36ca84155ffea0 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Mon, 14 Aug 2017 00:46:31 +0530 Subject: [PATCH 26/45] #348 - Data Tranfer Object : Make private varialbes final in immutalbe model. --- .../main/java/com/iluwatar/datatransfer/CustomerDto.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java index ce9ffdb78..7dedf891c 100644 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java @@ -31,9 +31,9 @@ package com.iluwatar.datatransfer; * Dto will not have any business logic in it. */ public class CustomerDto { - private String id; - private String firstName; - private String lastName; + private final String id; + private final String firstName; + private final String lastName; /** * @param id customer id From f9789d6926ffaadadd1169dea65abd2fd69d06f7 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Mon, 14 Aug 2017 16:14:23 +0530 Subject: [PATCH 27/45] #348 - Data Tranfer Object : Add class diagram. --- .../etc/data-transfer-object.ucls | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 data-transfer-object/etc/data-transfer-object.ucls diff --git a/data-transfer-object/etc/data-transfer-object.ucls b/data-transfer-object/etc/data-transfer-object.ucls new file mode 100644 index 000000000..15f777aad --- /dev/null +++ b/data-transfer-object/etc/data-transfer-object.ucls @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From b639f3630e6b842e6f9dde50d21069abd5d61131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 16 Aug 2017 21:09:28 +0300 Subject: [PATCH 28/45] #590 Add explanation for Prototype --- pom.xml | 1 + prototype/README.md | 49 ++++++++- prototype/etc/prototype.png | Bin 37751 -> 0 bytes prototype/etc/prototype.ucls | 182 ------------------------------- prototype/etc/prototype.urm.puml | 82 -------------- prototype/etc/prototype_1.png | Bin 97668 -> 0 bytes 6 files changed, 47 insertions(+), 267 deletions(-) delete mode 100644 prototype/etc/prototype.png delete mode 100644 prototype/etc/prototype.ucls delete mode 100644 prototype/etc/prototype.urm.puml delete mode 100644 prototype/etc/prototype_1.png diff --git a/pom.xml b/pom.xml index df01809f4..4976c14d5 100644 --- a/pom.xml +++ b/pom.xml @@ -464,6 +464,7 @@ factory-method abstract-factory builder + prototype diff --git a/prototype/README.md b/prototype/README.md index fe9e17917..e6d5d8b8b 100644 --- a/prototype/README.md +++ b/prototype/README.md @@ -15,14 +15,57 @@ tags: Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. -![alt text](./etc/prototype_1.png "Prototype") +## Explanation +Real world example + +> Remember Dolly? The sheep that was cloned! Lets not get into the details but the key point here is that it is all about cloning. + +In plain words + +> Create object based on an existing object through cloning. + +Wikipedia says + +> The prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. + +In short, it allows you to create a copy of an existing object and modify it to your needs, instead of going through the trouble of creating an object from scratch and setting it up. + +**Programmatic Example** + +In Java, it can be easily done by implementing `Cloneable` and overriding `clone` from `Object` + +``` +class Sheep implements Cloneable { + privage String name; + public Sheep(String name) { this.name = name; } + public void setName(String name) { this.name = name; } + public String getName() { return name; } + @Override + public Sheep clone() throws CloneNotSupportedException { + return new Sheep(name); + } +} +``` + +Then it can be cloned like below + +``` +Sheep original = new Sheep("Jolly"); +System.out.println(original.getName()); // Jolly + +// Clone and modify what is required +Sheep cloned = original.clone(); +cloned.setName("Dolly"); +System.out.println(cloned.getName()); // Dolly +``` ## Applicability Use the Prototype pattern when a system should be independent of how its products are created, composed and represented; and -* when the classes to instantiate are specified at run-time, for example, by dynamic loading; or -* to avoid building a class hierarchy of factories that parallels the class hierarchy of products; or +* when the classes to instantiate are specified at run-time, for example, by dynamic loading +* to avoid building a class hierarchy of factories that parallels the class hierarchy of products * when instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state +* when object creation is expensive compared to cloning ## Real world examples diff --git a/prototype/etc/prototype.png b/prototype/etc/prototype.png deleted file mode 100644 index 073b472e5cc3b7899160c3780a9a050fba0d6544..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37751 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 diff --git a/prototype/etc/prototype.ucls b/prototype/etc/prototype.ucls deleted file mode 100644 index 6d19fdc23..000000000 --- a/prototype/etc/prototype.ucls +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/prototype/etc/prototype.urm.puml b/prototype/etc/prototype.urm.puml deleted file mode 100644 index 801679fb7..000000000 --- a/prototype/etc/prototype.urm.puml +++ /dev/null @@ -1,82 +0,0 @@ -@startuml -package com.iluwatar.prototype { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } - abstract class Beast { - + Beast() - + clone() : Beast {abstract} - } - class ElfBeast { - + ElfBeast() - + clone() : Beast - + toString() : String - } - class ElfMage { - + ElfMage() - + clone() : Mage - + toString() : String - } - class ElfWarlord { - + ElfWarlord() - + clone() : Warlord - + toString() : String - } - interface HeroFactory { - + createBeast() : Beast {abstract} - + createMage() : Mage {abstract} - + createWarlord() : Warlord {abstract} - } - class HeroFactoryImpl { - - beast : Beast - - mage : Mage - - warlord : Warlord - + HeroFactoryImpl(mage : Mage, warlord : Warlord, beast : Beast) - + createBeast() : Beast - + createMage() : Mage - + createWarlord() : Warlord - } - abstract class Mage { - + Mage() - + clone() : Mage {abstract} - } - class OrcBeast { - + OrcBeast() - + clone() : Beast - + toString() : String - } - class OrcMage { - + OrcMage() - + clone() : Mage - + toString() : String - } - class OrcWarlord { - + OrcWarlord() - + clone() : Warlord - + toString() : String - } - abstract class Prototype { - + Prototype() - + clone() : Object {abstract} - } - abstract class Warlord { - + Warlord() - + clone() : Warlord {abstract} - } -} -HeroFactoryImpl --> "-beast" Beast -HeroFactoryImpl --> "-warlord" Warlord -HeroFactoryImpl --> "-mage" Mage -Beast --|> Prototype -ElfBeast --|> Beast -ElfMage --|> Mage -ElfWarlord --|> Warlord -HeroFactoryImpl ..|> HeroFactory -Mage --|> Prototype -OrcBeast --|> Beast -OrcMage --|> Mage -OrcWarlord --|> Warlord -Warlord --|> Prototype -@enduml \ No newline at end of file diff --git a/prototype/etc/prototype_1.png b/prototype/etc/prototype_1.png deleted file mode 100644 index 8b513c8d20f3dc21ad8377e041223e9b554c79ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97668 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

    NDS-aRNdDlf;n|O{E&gm- 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 Mtg1`};!)852fNqrh5!Hn From 2a7feba427873136bb96c6dbdeb3ee11d6374718 Mon Sep 17 00:00:00 2001 From: "mahendran.mookkiah" Date: Fri, 18 Aug 2017 14:18:43 -0400 Subject: [PATCH 29/45] #587 SonarQube reports bugs As recommended in https://sonarcloud.io/organizations/default/rules#rule_key=squid%3AS2274 Used while insteadof if - for waiting upon a condition. --- .../iluwatar/async/method/invocation/ThreadAsyncExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java index f92792c39..d12ebbe19 100644 --- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java +++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java @@ -139,7 +139,7 @@ public class ThreadAsyncExecutor implements AsyncExecutor { @Override public void await() throws InterruptedException { synchronized (lock) { - if (!isCompleted()) { + while (!isCompleted()) { lock.wait(); } } From 51751ec821edba15c59649ca7a594e4e517c47f1 Mon Sep 17 00:00:00 2001 From: "mahendran.mookkiah" Date: Fri, 18 Aug 2017 20:44:28 -0400 Subject: [PATCH 30/45] #587 SonarQube reports bugs reader-writer-lock and refactor Keeping wait() calls with in synchronized block closely to adhere SonarQube rules. Avoid nested synchronized block by extracting method. Added writing and reading time to simulate testing to ensure 1) writers are waiting for globalMutex to be empty 2) readers to confirm there is no writers. --- .../com/iluwatar/reader/writer/lock/App.java | 40 ++++++-- .../iluwatar/reader/writer/lock/Reader.java | 33 +++++-- .../reader/writer/lock/ReaderWriterLock.java | 96 ++++++++----------- .../iluwatar/reader/writer/lock/Writer.java | 33 +++++-- .../writer/lock/utils/InMemoryAppender.java | 2 +- 5 files changed, 128 insertions(+), 76 deletions(-) diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java index af7b5df2c..42335f313 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java @@ -23,14 +23,15 @@ package com.iluwatar.reader.writer.lock; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * * In a multiple thread applications, the threads may try to synchronize the shared resources @@ -62,21 +63,42 @@ public class App { ExecutorService executeService = Executors.newFixedThreadPool(10); ReaderWriterLock lock = new ReaderWriterLock(); - - // Start 5 readers + + // Start writers IntStream.range(0, 5) - .forEach(i -> executeService.submit(new Reader("Reader " + i, lock.readLock()))); + .forEach(i -> executeService.submit(new Writer("Writer " + i, lock.writeLock(), + ThreadLocalRandom.current().nextLong(5000)))); + LOGGER.info("Writers added..."); - // Start 5 writers + // Start readers IntStream.range(0, 5) - .forEach(i -> executeService.submit(new Writer("Writer " + i, lock.writeLock()))); + .forEach(i -> executeService.submit(new Reader("Reader " + i, lock.readLock(), + ThreadLocalRandom.current().nextLong(10)))); + LOGGER.info("Readers added..."); + + try { + Thread.sleep(5000L); + } catch (InterruptedException e) { + LOGGER.error("Error sleeping before adding more readers", e); + Thread.currentThread().interrupt(); + } + + // Start readers + IntStream.range(6, 10) + .forEach(i -> executeService.submit(new Reader("Reader " + i, lock.readLock(), + ThreadLocalRandom.current().nextLong(10)))); + LOGGER.info("More readers added..."); + + + // In the system console, it can see that the read operations are executed concurrently while // write operations are exclusive. executeService.shutdown(); try { executeService.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { - LOGGER.error("Error waiting for ExecutorService shutdown"); + LOGGER.error("Error waiting for ExecutorService shutdown", e); + Thread.currentThread().interrupt(); } } diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java index 006aff7d7..b0ccecaba 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java @@ -22,11 +22,11 @@ */ package com.iluwatar.reader.writer.lock; +import java.util.concurrent.locks.Lock; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.locks.Lock; - /** * Reader class, read when it acquired the read lock */ @@ -37,10 +37,30 @@ public class Reader implements Runnable { private Lock readLock; private String name; + + private long readingTime; - public Reader(String name, Lock readLock) { + /** + * Create new Reader + * + * @param name - Name of the thread owning the reader + * @param readLock - Lock for this reader + * @param readingTime - amount of time (in milliseconds) for this reader to engage reading + */ + public Reader(String name, Lock readLock, long readingTime) { this.name = name; this.readLock = readLock; + this.readingTime = readingTime; + } + + /** + * Create new Reader who reads for 250ms + * + * @param name - Name of the thread owning the reader + * @param readLock - Lock for this reader + */ + public Reader(String name, Lock readLock) { + this(name, readLock, 250L); } @Override @@ -49,7 +69,8 @@ public class Reader implements Runnable { try { read(); } catch (InterruptedException e) { - e.printStackTrace(); + LOGGER.info("InterruptedException when reading", e); + Thread.currentThread().interrupt(); } finally { readLock.unlock(); } @@ -61,7 +82,7 @@ public class Reader implements Runnable { */ public void read() throws InterruptedException { LOGGER.info("{} begin", name); - Thread.sleep(250); - LOGGER.info("{} finish", name); + Thread.sleep(readingTime); + LOGGER.info("{} finish after reading {}ms", name, readingTime); } } diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java index e7b3c4451..b377b2273 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java @@ -29,13 +29,18 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Class responsible for control the access for reader or writer * - * Allows multiple readers to hold the lock at same time, but if any writer holds the lock then - * readers wait. If reader holds the lock then writer waits. This lock is not fair. + * Allows multiple readers to hold the lock at same time, but if any writer holds the lock then readers wait. If reader + * holds the lock then writer waits. This lock is not fair. */ public class ReaderWriterLock implements ReadWriteLock { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReaderWriterLock.class); private Object readerMutex = new Object(); @@ -45,10 +50,10 @@ public class ReaderWriterLock implements ReadWriteLock { /** * Global mutex is used to indicate that whether reader or writer gets the lock in the moment. *

    - * 1. When it contains the reference of {@link readerLock}, it means that the lock is acquired by - * the reader, another reader can also do the read operation concurrently.
    - * 2. When it contains the reference of reference of {@link writerLock}, it means that the lock is - * acquired by the writer exclusively, no more reader or writer can get the lock. + * 1. When it contains the reference of {@link readerLock}, it means that the lock is acquired by the reader, another + * reader can also do the read operation concurrently.
    + * 2. When it contains the reference of reference of {@link writerLock}, it means that the lock is acquired by the + * writer exclusively, no more reader or writer can get the lock. *

    * This is the most important field in this class to control the access for reader/writer. */ @@ -74,13 +79,6 @@ public class ReaderWriterLock implements ReadWriteLock { return globalMutex.contains(writerLock); } - /** - * return true when globalMutex hold the reference of readerLock - */ - private boolean doesReaderOwnThisLock() { - return globalMutex.contains(readerLock); - } - /** * Nobody get the lock when globalMutex contains nothing * @@ -89,14 +87,6 @@ public class ReaderWriterLock implements ReadWriteLock { return globalMutex.isEmpty(); } - private static void waitUninterruptibly(Object o) { - try { - o.wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - /** * Reader Lock, can be access for more than one reader concurrently if no writer get the lock */ @@ -104,31 +94,35 @@ public class ReaderWriterLock implements ReadWriteLock { @Override public void lock() { - synchronized (readerMutex) { - currentReaderCount++; if (currentReaderCount == 1) { - // Try to get the globalMutex lock for the first reader - synchronized (globalMutex) { - while (true) { - // If the no one get the lock or the lock is locked by reader, just set the reference - // to the globalMutex to indicate that the lock is locked by Reader. - if (isLockFree() || doesReaderOwnThisLock()) { - globalMutex.add(this); - break; - } else { - // If lock is acquired by the write, let the thread wait until the writer release - // the lock - waitUninterruptibly(globalMutex); - } - } - } - + acquireForReaders(); } } } + /** + * Acquire the globalMutex lock on behalf of current and future concurrent readers. Make sure no writers currently + * owns the lock. + */ + private void acquireForReaders() { + // Try to get the globalMutex lock for the first reader + synchronized (globalMutex) { + // If the no one get the lock or the lock is locked by reader, just set the reference + // to the globalMutex to indicate that the lock is locked by Reader. + while (doesWriterOwnThisLock()) { + try { + globalMutex.wait(); + } catch (InterruptedException e) { + LOGGER.info("InterruptedException while waiting for globalMutex in acquireForReaders", e); + Thread.currentThread().interrupt(); + } + } + globalMutex.add(this); + } + } + @Override public void unlock() { @@ -179,23 +173,17 @@ public class ReaderWriterLock implements ReadWriteLock { synchronized (globalMutex) { - while (true) { - // When there is no one acquired the lock, just put the writeLock reference to the - // globalMutex to indicate that the lock is acquired by one writer. - // It is ensure that writer can only get the lock when no reader/writer acquired the lock. - if (isLockFree()) { - globalMutex.add(this); - break; - } else if (doesWriterOwnThisLock()) { - // Wait when other writer get the lock - waitUninterruptibly(globalMutex); - } else if (doesReaderOwnThisLock()) { - // Wait when other reader get the lock - waitUninterruptibly(globalMutex); - } else { - throw new AssertionError("it should never reach here"); + // Wait until the lock is free. + while (!isLockFree()) { + try { + globalMutex.wait(); + } catch (InterruptedException e) { + LOGGER.info("InterruptedException while waiting for globalMutex to begin writing", e); + Thread.currentThread().interrupt(); } } + // When the lock is free, acquire it by placing an entry in globalMutex + globalMutex.add(this); } } diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java index c468a61f8..dc379eef9 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java @@ -22,11 +22,11 @@ */ package com.iluwatar.reader.writer.lock; +import java.util.concurrent.locks.Lock; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.locks.Lock; - /** * Writer class, write when it acquired the write lock */ @@ -37,10 +37,30 @@ public class Writer implements Runnable { private Lock writeLock; private String name; + + private long writingTime; + /** + * Create new Writer who writes for 250ms + * + * @param name - Name of the thread owning the writer + * @param writeLock - Lock for this writer + */ public Writer(String name, Lock writeLock) { + this(name, writeLock, 250L); + } + + /** + * Create new Writer + * + * @param name - Name of the thread owning the writer + * @param writeLock - Lock for this writer + * @param writingTime - amount of time (in milliseconds) for this reader to engage writing + */ + public Writer(String name, Lock writeLock, long writingTime) { this.name = name; this.writeLock = writeLock; + this.writingTime = writingTime; } @@ -50,18 +70,19 @@ public class Writer implements Runnable { try { write(); } catch (InterruptedException e) { - e.printStackTrace(); + LOGGER.info("InterruptedException when writing", e); + Thread.currentThread().interrupt(); } finally { writeLock.unlock(); } } - + /** * Simulate the write operation */ public void write() throws InterruptedException { LOGGER.info("{} begin", name); - Thread.sleep(250); - LOGGER.info("{} finish", name); + Thread.sleep(writingTime); + LOGGER.info("{} finished after writing {}ms", name, writingTime); } } diff --git a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java index 30624a650..b8ad531ce 100644 --- a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java +++ b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java @@ -52,6 +52,6 @@ public class InMemoryAppender extends AppenderBase { } public boolean logContains(String message) { - return log.stream().anyMatch(event -> event.getFormattedMessage().equals(message)); + return log.stream().anyMatch(event -> event.getFormattedMessage().contains(message)); } } From fbf5ffe67a63ddb43f003efeb6a1fc81bdf05ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 19 Aug 2017 10:00:18 +0300 Subject: [PATCH 31/45] #590 Add explanation for Adapter --- adapter/README.md | 82 +++++++++++++++++- adapter/etc/adapter.png | Bin 12086 -> 0 bytes adapter/etc/adapter.ucls | 70 --------------- adapter/etc/adapter.urm.puml | 37 -------- .../main/java/com/iluwatar/adapter/App.java | 14 +-- .../java/com/iluwatar/adapter/Captain.java | 27 +++--- .../com/iluwatar/adapter/FishingBoat.java | 9 +- ...shingBoat.java => FishingBoatAdapter.java} | 20 ++--- .../{BattleShip.java => RowingBoat.java} | 8 +- .../iluwatar/adapter/AdapterPatternTest.java | 29 +++---- pom.xml | 1 + 11 files changed, 121 insertions(+), 176 deletions(-) delete mode 100644 adapter/etc/adapter.png delete mode 100644 adapter/etc/adapter.ucls delete mode 100644 adapter/etc/adapter.urm.puml rename adapter/src/main/java/com/iluwatar/adapter/{BattleFishingBoat.java => FishingBoatAdapter.java} (70%) rename adapter/src/main/java/com/iluwatar/adapter/{BattleShip.java => RowingBoat.java} (92%) diff --git a/adapter/README.md b/adapter/README.md index 4059ea852..6de04a72c 100644 --- a/adapter/README.md +++ b/adapter/README.md @@ -19,10 +19,85 @@ Convert the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. -![alt text](./etc/adapter.png "Adapter") +## Explanation -## General usage of Adapter Pattern: -+ Wrappers used to adopt 3rd parties libraries and frameworks - most of the applications using third party libraries use adapters as a middle layer between the application and the 3rd party library to decouple the application from the library. If another library has to be used only an adapter for the new library is required without having to change the application code. +Real world example + +> Consider that you have some pictures in your memory card and you need to transfer them to your computer. In order to transfer them you need some kind of adapter that is compatible with your computer ports so that you can attach memory card to your computer. In this case card reader is an adapter. +> Another example would be the famous power adapter; a three legged plug can't be connected to a two pronged outlet, it needs to use a power adapter that makes it compatible with the two pronged outlet. +> Yet another example would be a translator translating words spoken by one person to another + +In plain words + +> Adapter pattern lets you wrap an otherwise incompatible object in an adapter to make it compatible with another class. + +Wikipedia says + +> In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code. + +**Programmatic Example** + +Consider a captain that can only use rowing boats and cannot sail at all. + +First we have interfaces `RowingBoat` and `FishingBoat` + +``` +public interface RowingBoat { + void row(); +} + +public class FishingBoat { + private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class); + public void sail() { + LOGGER.info("The fishing boat is sailing"); + } +} +``` + +And captain expects an implementation of `RowingBoat` interface to be able to move + +``` +public class Captain implements RowingBoat { + + private RowingBoat rowingBoat; + + public Captain(RowingBoat rowingBoat) { + this.rowingBoat = rowingBoat; + } + + @Override + public void row() { + rowingBoat.row(); + } +} +``` + +Now let's say the pirates are coming and our captain needs to escape but there is only fishing boat available. We need to create an adapter that allows the captain to operate the fishing boat with his rowing boat skills. + +``` +public class FishingBoatAdapter implements RowingBoat { + + private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class); + + private FishingBoat boat; + + public FishingBoatAdapter() { + boat = new FishingBoat(); + } + + @Override + public void row() { + boat.sail(); + } +} +``` + +And now the `Captain` can use the `FishingBoat` to escape the pirates. + +``` +Captain captain = new Captain(new FishingBoatAdapter()); +captain.row(); +``` ## Applicability Use the Adapter pattern when @@ -30,6 +105,7 @@ Use the Adapter pattern when * you want to use an existing class, and its interface does not match the one you need * you want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don't necessarily have compatible interfaces * you need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class. +* most of the applications using third party libraries use adapters as a middle layer between the application and the 3rd party library to decouple the application from the library. If another library has to be used only an adapter for the new library is required without having to change the application code. ## Consequences: Class and object adapters have different trade-offs. A class adapter diff --git a/adapter/etc/adapter.png b/adapter/etc/adapter.png deleted file mode 100644 index f43358b042e73edcbcb9589e540a8d306fa1d6c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12086 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 diff --git a/adapter/etc/adapter.ucls b/adapter/etc/adapter.ucls deleted file mode 100644 index 290ff544e..000000000 --- a/adapter/etc/adapter.ucls +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/adapter/etc/adapter.urm.puml b/adapter/etc/adapter.urm.puml deleted file mode 100644 index 847427a44..000000000 --- a/adapter/etc/adapter.urm.puml +++ /dev/null @@ -1,37 +0,0 @@ -@startuml -package com.iluwatar.adapter { - class App { - + App() - + main(args : String[]) {static} - } - class BattleFishingBoat { - - LOGGER : Logger {static} - - boat : FishingBoat - + BattleFishingBoat() - + fire() - + move() - } - interface BattleShip { - + fire() {abstract} - + move() {abstract} - } - class Captain { - - battleship : BattleShip - + Captain() - + Captain(battleship : BattleShip) - + fire() - + move() - + setBattleship(battleship : BattleShip) - } - class FishingBoat { - - LOGGER : Logger {static} - + FishingBoat() - + fish() - + sail() - } -} -BattleFishingBoat --> "-boat" FishingBoat -Captain --> "-battleship" BattleShip -BattleFishingBoat ..|> BattleShip -Captain ..|> BattleShip -@enduml \ No newline at end of file diff --git a/adapter/src/main/java/com/iluwatar/adapter/App.java b/adapter/src/main/java/com/iluwatar/adapter/App.java index 239424da9..a624cc38f 100644 --- a/adapter/src/main/java/com/iluwatar/adapter/App.java +++ b/adapter/src/main/java/com/iluwatar/adapter/App.java @@ -34,14 +34,14 @@ package com.iluwatar.adapter; * object. This example uses the object adapter approach. * *

    - * The Adapter ({@link BattleFishingBoat}) converts the interface of the adaptee class ( - * {@link FishingBoat}) into a suitable one expected by the client ( {@link BattleShip} ). + * The Adapter ({@link FishingBoatAdapter}) converts the interface of the adaptee class ( + * {@link FishingBoat}) into a suitable one expected by the client ( {@link RowingBoat} ). * *

    * The story of this implementation is this.
    - * Pirates are coming! we need a {@link BattleShip} to fight! We have a {@link FishingBoat} and our + * Pirates are coming! we need a {@link RowingBoat} to flee! We have a {@link FishingBoat} and our * captain. We have no time to make up a new ship! we need to reuse this {@link FishingBoat}. The - * captain needs a battleship which can fire and move. The spec is in {@link BattleShip}. We will + * captain needs a rowing boat which he can operate. The spec is in {@link RowingBoat}. We will * use the Adapter pattern to reuse {@link FishingBoat}. * */ @@ -53,8 +53,8 @@ public class App { * @param args command line args */ public static void main(String[] args) { - Captain captain = new Captain(new BattleFishingBoat()); - captain.move(); - captain.fire(); + // The captain can only operate rowing boats but with adapter he is able to use fishing boats as well + Captain captain = new Captain(new FishingBoatAdapter()); + captain.row(); } } diff --git a/adapter/src/main/java/com/iluwatar/adapter/Captain.java b/adapter/src/main/java/com/iluwatar/adapter/Captain.java index 6d88b1975..369016980 100644 --- a/adapter/src/main/java/com/iluwatar/adapter/Captain.java +++ b/adapter/src/main/java/com/iluwatar/adapter/Captain.java @@ -23,33 +23,26 @@ package com.iluwatar.adapter; /** - * The Captain uses {@link BattleShip} to fight.
    + * The Captain uses {@link RowingBoat} to sail.
    * This is the client in the pattern. */ -public class Captain implements BattleShip { +public class Captain implements RowingBoat { - private BattleShip battleship; + private RowingBoat rowingBoat; - public Captain() { + public Captain() {} + public Captain(RowingBoat rowingBoat) { + this.rowingBoat = rowingBoat; } - public Captain(BattleShip battleship) { - this.battleship = battleship; - } - - public void setBattleship(BattleShip battleship) { - this.battleship = battleship; + public void setRowingBoat(RowingBoat rowingBoat) { + this.rowingBoat = rowingBoat; } @Override - public void fire() { - battleship.fire(); - } - - @Override - public void move() { - battleship.move(); + public void row() { + rowingBoat.row(); } } diff --git a/adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java b/adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java index 2124d9d9f..c46814d18 100644 --- a/adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java +++ b/adapter/src/main/java/com/iluwatar/adapter/FishingBoat.java @@ -27,7 +27,8 @@ import org.slf4j.LoggerFactory; /** * - * Device class (adaptee in the pattern). We want to reuse this class + * Device class (adaptee in the pattern). We want to reuse this class. + * Fishing boat moves by sailing. * */ public class FishingBoat { @@ -35,11 +36,7 @@ public class FishingBoat { private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class); public void sail() { - LOGGER.info("The Boat is moving to that place"); - } - - public void fish() { - LOGGER.info("fishing ..."); + LOGGER.info("The fishing boat is sailing"); } } diff --git a/adapter/src/main/java/com/iluwatar/adapter/BattleFishingBoat.java b/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java similarity index 70% rename from adapter/src/main/java/com/iluwatar/adapter/BattleFishingBoat.java rename to adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java index 5e4da91f8..c94932b2b 100644 --- a/adapter/src/main/java/com/iluwatar/adapter/BattleFishingBoat.java +++ b/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java @@ -27,30 +27,22 @@ import org.slf4j.LoggerFactory; /** * - * Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link BattleShip} - * interface expected by the client ({@link Captain}).
    - * In this case we added a new function fire to suit the interface. We are reusing the - * {@link FishingBoat} without changing itself. The Adapter class can just map the functions of the - * Adaptee or add, delete features of the Adaptee. + * Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link RowingBoat} + * interface expected by the client ({@link Captain}). * */ -public class BattleFishingBoat implements BattleShip { +public class FishingBoatAdapter implements RowingBoat { - private static final Logger LOGGER = LoggerFactory.getLogger(BattleFishingBoat.class); + private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class); private FishingBoat boat; - public BattleFishingBoat() { + public FishingBoatAdapter() { boat = new FishingBoat(); } @Override - public void fire() { - LOGGER.info("fire!"); - } - - @Override - public void move() { + public void row() { boat.sail(); } } diff --git a/adapter/src/main/java/com/iluwatar/adapter/BattleShip.java b/adapter/src/main/java/com/iluwatar/adapter/RowingBoat.java similarity index 92% rename from adapter/src/main/java/com/iluwatar/adapter/BattleShip.java rename to adapter/src/main/java/com/iluwatar/adapter/RowingBoat.java index 62ee366e7..a9ca9ad39 100644 --- a/adapter/src/main/java/com/iluwatar/adapter/BattleShip.java +++ b/adapter/src/main/java/com/iluwatar/adapter/RowingBoat.java @@ -24,13 +24,11 @@ package com.iluwatar.adapter; /** * The interface expected by the client.
    - * A Battleship can fire and move. + * A rowing boat is rowed to move. * */ -public interface BattleShip { +public interface RowingBoat { - void fire(); - - void move(); + void row(); } diff --git a/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java b/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java index 89c9bc5d5..9938f0559 100644 --- a/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java +++ b/adapter/src/test/java/com/iluwatar/adapter/AdapterPatternTest.java @@ -39,9 +39,9 @@ public class AdapterPatternTest { private Map beans; - private static final String BATTLESHIP_BEAN = "engineer"; + private static final String FISHING_BEAN = "fisher"; - private static final String CAPTAIN_BEAN = "captain"; + private static final String ROWING_BEAN = "captain"; /** * This method runs before the test execution and sets the bean objects in the beans Map. @@ -50,34 +50,29 @@ public class AdapterPatternTest { public void setup() { beans = new HashMap<>(); - BattleFishingBoat battleFishingBoat = spy(new BattleFishingBoat()); - beans.put(BATTLESHIP_BEAN, battleFishingBoat); + FishingBoatAdapter fishingBoatAdapter = spy(new FishingBoatAdapter()); + beans.put(FISHING_BEAN, fishingBoatAdapter); Captain captain = new Captain(); - captain.setBattleship((BattleFishingBoat) beans.get(BATTLESHIP_BEAN)); - beans.put(CAPTAIN_BEAN, captain); + captain.setRowingBoat((FishingBoatAdapter) beans.get(FISHING_BEAN)); + beans.put(ROWING_BEAN, captain); } /** - * This test asserts that when we use the move() method on a captain bean(client), it is - * internally calling move method on the battleship object. The Adapter ({@link BattleFishingBoat} + * This test asserts that when we use the row() method on a captain bean(client), it is + * internally calling sail method on the fishing boat object. The Adapter ({@link FishingBoatAdapter} * ) converts the interface of the target class ( {@link FishingBoat}) into a suitable one * expected by the client ({@link Captain} ). */ @Test public void testAdapter() { - BattleShip captain = (BattleShip) beans.get(CAPTAIN_BEAN); + RowingBoat captain = (RowingBoat) beans.get(ROWING_BEAN); // when captain moves - captain.move(); + captain.row(); // the captain internally calls the battleship object to move - BattleShip battleship = (BattleShip) beans.get(BATTLESHIP_BEAN); - verify(battleship).move(); - - // same with above with firing - captain.fire(); - verify(battleship).fire(); - + RowingBoat adapter = (RowingBoat) beans.get(FISHING_BEAN); + verify(adapter).row(); } } diff --git a/pom.xml b/pom.xml index 992537f9b..347a6bc15 100644 --- a/pom.xml +++ b/pom.xml @@ -466,6 +466,7 @@ abstract-factory builder prototype + adapter From 5db6776971094dc4e67287cc735c3e47a0dbfb9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 19 Aug 2017 10:10:49 +0300 Subject: [PATCH 32/45] #590 Fix PMD issue --- .../main/java/com/iluwatar/adapter/FishingBoatAdapter.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java b/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java index c94932b2b..1e758e917 100644 --- a/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java +++ b/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java @@ -22,9 +22,6 @@ */ package com.iluwatar.adapter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * * Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link RowingBoat} @@ -33,8 +30,6 @@ import org.slf4j.LoggerFactory; */ public class FishingBoatAdapter implements RowingBoat { - private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class); - private FishingBoat boat; public FishingBoatAdapter() { From ed1a0022b9875dd8b168bd48eded37218940f103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 19 Aug 2017 11:00:34 +0300 Subject: [PATCH 33/45] #596 Add more logging to Reactor --- .../java/com/iluwatar/reactor/app/AppClient.java | 10 ++++++---- .../com/iluwatar/reactor/framework/NioReactor.java | 5 +++-- .../java/com/iluwatar/reactor/app/ReactorTest.java | 13 +++++++++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/reactor/src/main/java/com/iluwatar/reactor/app/AppClient.java b/reactor/src/main/java/com/iluwatar/reactor/app/AppClient.java index 4db4f5e2a..446628769 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/app/AppClient.java +++ b/reactor/src/main/java/com/iluwatar/reactor/app/AppClient.java @@ -65,6 +65,7 @@ public class AppClient { * @throws IOException if any I/O error occurs. */ public void start() throws IOException { + LOGGER.info("Starting logging clients"); service.execute(new TcpLoggingClient("Client 1", 6666)); service.execute(new TcpLoggingClient("Client 2", 6667)); service.execute(new UdpLoggingClient("Client 3", 6668)); @@ -81,16 +82,17 @@ public class AppClient { try { service.awaitTermination(1000, TimeUnit.SECONDS); } catch (InterruptedException e) { - e.printStackTrace(); + LOGGER.error("exception awaiting termination", e); } } + LOGGER.info("Logging clients stopped"); } private static void artificialDelayOf(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { - e.printStackTrace(); + LOGGER.error("sleep interrupted", e); } } @@ -119,7 +121,7 @@ public class AppClient { PrintWriter writer = new PrintWriter(outputStream); sendLogRequests(writer, socket.getInputStream()); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("error sending requests", e); throw new RuntimeException(e); } } @@ -185,7 +187,7 @@ public class AppClient { artificialDelayOf(100); } } catch (IOException e1) { - e1.printStackTrace(); + LOGGER.error("error sending packets", e1); } } } diff --git a/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java b/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java index bc5b27494..a315389a3 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java +++ b/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java @@ -94,7 +94,7 @@ public class NioReactor { LOGGER.info("Reactor started, waiting for events..."); eventLoop(); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("exception in event loop", e); } }); } @@ -112,6 +112,7 @@ public class NioReactor { selector.wakeup(); reactorMain.awaitTermination(4, TimeUnit.SECONDS); selector.close(); + LOGGER.info("Reactor stopped"); } /** @@ -206,7 +207,7 @@ public class NioReactor { try { key.channel().close(); } catch (IOException e1) { - e1.printStackTrace(); + LOGGER.error("error closing channel", e1); } } } diff --git a/reactor/src/test/java/com/iluwatar/reactor/app/ReactorTest.java b/reactor/src/test/java/com/iluwatar/reactor/app/ReactorTest.java index 413bbc017..7aa80f8cc 100644 --- a/reactor/src/test/java/com/iluwatar/reactor/app/ReactorTest.java +++ b/reactor/src/test/java/com/iluwatar/reactor/app/ReactorTest.java @@ -24,10 +24,13 @@ package com.iluwatar.reactor.app; import java.io.IOException; +import com.iluwatar.reactor.framework.NioReactor; import org.junit.Test; import com.iluwatar.reactor.framework.SameThreadDispatcher; import com.iluwatar.reactor.framework.ThreadPoolDispatcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -36,6 +39,8 @@ import com.iluwatar.reactor.framework.ThreadPoolDispatcher; */ public class ReactorTest { + private static final Logger LOGGER = LoggerFactory.getLogger(ReactorTest.class); + /** * Test the application using pooled thread dispatcher. * @@ -44,6 +49,7 @@ public class ReactorTest { */ @Test public void testAppUsingThreadPoolDispatcher() throws IOException, InterruptedException { + LOGGER.info("testAppUsingThreadPoolDispatcher start"); App app = new App(new ThreadPoolDispatcher(2)); app.start(); @@ -54,12 +60,13 @@ public class ReactorTest { try { Thread.sleep(2000); } catch (InterruptedException e) { - e.printStackTrace(); + LOGGER.error("sleep interrupted", e); } client.stop(); app.stop(); + LOGGER.info("testAppUsingThreadPoolDispatcher stop"); } /** @@ -70,6 +77,7 @@ public class ReactorTest { */ @Test public void testAppUsingSameThreadDispatcher() throws IOException, InterruptedException { + LOGGER.info("testAppUsingSameThreadDispatcher start"); App app = new App(new SameThreadDispatcher()); app.start(); @@ -80,11 +88,12 @@ public class ReactorTest { try { Thread.sleep(2000); } catch (InterruptedException e) { - e.printStackTrace(); + LOGGER.error("sleep interrupted", e); } client.stop(); app.stop(); + LOGGER.info("testAppUsingSameThreadDispatcher stop"); } } From 82d7e57e8eb8a425f5af87bc33ed850ec72f382b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serdar=20Hamzao=C4=9Fullar=C4=B1?= Date: Sat, 19 Aug 2017 22:06:35 +0300 Subject: [PATCH 34/45] Integration Test --- event-sourcing/etc/event-sourcing.ucls | 4 +- .../{service => }/AccountService.java | 4 +- .../MoneyTransactionService.java | 4 +- .../{service => }/SequenceIdGenerator.java | 4 +- .../event/sourcing/api/DomainEvent.java | 2 +- .../event/sourcing/api/EventProcessor.java | 2 +- .../event/sourcing/api/ProcessorJournal.java | 2 +- .../com/iluwatar/event/sourcing/app/App.java | 66 ++++++---- .../event/sourcing/domain/Account.java | 2 +- .../event/sourcing/domain/Transaction.java | 2 +- .../sourcing/event/AccountCreateEvent.java | 2 +- .../sourcing/event/MoneyDepositEvent.java | 2 +- .../sourcing/event/MoneyTransferEvent.java | 2 +- .../sourcing/event/MoneyWithdrawalEvent.java | 2 +- .../gateway/AccountCreateContractSender.java | 2 +- .../event/sourcing/gateway/Gateways.java | 2 +- .../sourcing/gateway/TransactionLogger.java | 2 +- .../sourcing/journal/JsonFileJournal.java | 2 +- .../processor/DomainEventProcessor.java | 2 +- .../sourcing/state/AccountAggregate.java | 2 +- .../event/sourcing/IntegrationTest.java | 115 ++++++++++++++++++ 21 files changed, 181 insertions(+), 46 deletions(-) rename event-sourcing/src/main/java/com/iluwatar/event/sourcing/{service => }/AccountService.java (95%) rename event-sourcing/src/main/java/com/iluwatar/event/sourcing/{service => }/MoneyTransactionService.java (97%) rename event-sourcing/src/main/java/com/iluwatar/event/sourcing/{service => }/SequenceIdGenerator.java (94%) create mode 100644 event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java diff --git a/event-sourcing/etc/event-sourcing.ucls b/event-sourcing/etc/event-sourcing.ucls index d187b1bb0..e6944ef70 100644 --- a/event-sourcing/etc/event-sourcing.ucls +++ b/event-sourcing/etc/event-sourcing.ucls @@ -122,7 +122,7 @@ - @@ -132,7 +132,7 @@ - diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/AccountService.java similarity index 95% rename from event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java rename to event-sourcing/src/main/java/com/iluwatar/event/sourcing/AccountService.java index 59cefaaee..2d6f585a5 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/AccountService.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/AccountService.java @@ -20,14 +20,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.event.sourcing.service; +package com.iluwatar.event.sourcing; import com.iluwatar.event.sourcing.api.EventProcessor; import com.iluwatar.event.sourcing.event.AccountCreateEvent; import java.util.Date; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class AccountService { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/MoneyTransactionService.java similarity index 97% rename from event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java rename to event-sourcing/src/main/java/com/iluwatar/event/sourcing/MoneyTransactionService.java index 5f7c0e9c7..0e3cb67bd 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/MoneyTransactionService.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/MoneyTransactionService.java @@ -20,7 +20,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.event.sourcing.service; +package com.iluwatar.event.sourcing; import com.iluwatar.event.sourcing.api.EventProcessor; import com.iluwatar.event.sourcing.event.MoneyDepositEvent; @@ -30,7 +30,7 @@ import java.math.BigDecimal; import java.util.Date; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class MoneyTransactionService { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/SequenceIdGenerator.java similarity index 94% rename from event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java rename to event-sourcing/src/main/java/com/iluwatar/event/sourcing/SequenceIdGenerator.java index 6e1730679..c928a8737 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/service/SequenceIdGenerator.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/SequenceIdGenerator.java @@ -20,10 +20,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.event.sourcing.service; +package com.iluwatar.event.sourcing; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class SequenceIdGenerator { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java index 693ea1755..6eb5141a2 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java @@ -25,7 +25,7 @@ package com.iluwatar.event.sourcing.api; import java.io.Serializable; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public abstract class DomainEvent implements Serializable { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java index afa218939..512f9d7f8 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java @@ -23,7 +23,7 @@ package com.iluwatar.event.sourcing.api; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public interface EventProcessor { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java index 8814b82d9..2212580dc 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java @@ -23,7 +23,7 @@ package com.iluwatar.event.sourcing.api; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public interface ProcessorJournal { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java index f62cebb62..77be00cf6 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/app/App.java @@ -24,62 +24,82 @@ package com.iluwatar.event.sourcing.app; import com.iluwatar.event.sourcing.journal.JsonFileJournal; import com.iluwatar.event.sourcing.processor.DomainEventProcessor; -import com.iluwatar.event.sourcing.service.AccountService; -import com.iluwatar.event.sourcing.service.MoneyTransactionService; +import com.iluwatar.event.sourcing.AccountService; +import com.iluwatar.event.sourcing.MoneyTransactionService; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * Created by serdarh on 06.08.2017. + * Event Sourcing : Instead of storing just the current state of the data in a domain, use an + * append-only store to record the full series of actions taken on that data. The store acts as the + * system of record and can be used to materialize the domain objects. This can simplify tasks in + * complex domains, by avoiding the need to synchronize the data model and the business domain, + * while improving performance, scalability, and responsiveness. It can also provide consistency for + * transactional data, and maintain full audit trails and history that can enable compensating + * actions. + * + * This App class is an example usage of Event Sourcing pattern. As an example, two bank account is + * created, then some money deposit and transfer actions are taken so a new state of accounts is + * created. At that point, state is cleared in order to represent a system shot down. After the shot + * down, system state is recovered by re-creating the past events from event journal. Then state is + * printed so a user can view the last state is same with the state before system shot down. + * + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class App { + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + public static final int ACCOUNT_OF_DAENERYS = 1; + public static final int ACCOUNT_OF_JON = 2; + /** * The entry point of application. * * @param args the input arguments */ public static void main(String[] args) { - System.out.println("Running the system first time............"); DomainEventProcessor domainEventProcessor = new DomainEventProcessor(); JsonFileJournal jsonFileJournal = new JsonFileJournal(); - jsonFileJournal.reset(); domainEventProcessor.setPrecessorJournal(jsonFileJournal); - - System.out.println("Creating th accounts............"); - AccountService accountService = new AccountService(domainEventProcessor); MoneyTransactionService moneyTransactionService = new MoneyTransactionService( domainEventProcessor); - accountService.createAccount(1, "Daenerys Targaryen"); - accountService.createAccount(2, "Jon Snow"); - System.out.println("Do some money operations............"); + LOGGER.info("Running the system first time............"); + jsonFileJournal.reset(); - moneyTransactionService.depositMoney(1, new BigDecimal("100000")); - moneyTransactionService.depositMoney(2, new BigDecimal("100")); + LOGGER.info("Creating th accounts............"); - moneyTransactionService.transferMoney(1, 2, new BigDecimal("10000")); - moneyTransactionService.withdrawalMoney(2, new BigDecimal("1000")); + accountService.createAccount(ACCOUNT_OF_DAENERYS, "Daenerys Targaryen"); + accountService.createAccount(ACCOUNT_OF_JON, "Jon Snow"); - System.out.println("...............State:............"); - System.out.println(AccountAggregate.getAccount(1)); - System.out.println(AccountAggregate.getAccount(2)); + LOGGER.info("Do some money operations............"); - System.out.println("At that point system goes down state in memory cleared............"); + moneyTransactionService.depositMoney(ACCOUNT_OF_DAENERYS, new BigDecimal("100000")); + moneyTransactionService.depositMoney(ACCOUNT_OF_JON, new BigDecimal("100")); + moneyTransactionService.transferMoney(ACCOUNT_OF_DAENERYS, ACCOUNT_OF_JON, new BigDecimal("10000")); + moneyTransactionService.withdrawalMoney(ACCOUNT_OF_JON, new BigDecimal("1000")); + + LOGGER.info("...............State:............"); + LOGGER.info(AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS).toString()); + LOGGER.info(AccountAggregate.getAccount(ACCOUNT_OF_JON).toString()); + + LOGGER.info("At that point system had a shot down, state in memory is cleared............"); AccountAggregate.resetState(); - System.out.println("Recover the syste by the events in journal file............"); + LOGGER.info("Recover the system by the events in journal file............"); domainEventProcessor = new DomainEventProcessor(); jsonFileJournal = new JsonFileJournal(); domainEventProcessor.setPrecessorJournal(jsonFileJournal); domainEventProcessor.recover(); - System.out.println("...............State Recovered:............"); - System.out.println(AccountAggregate.getAccount(1)); - System.out.println(AccountAggregate.getAccount(2)); + LOGGER.info("...............Recovered State:............"); + LOGGER.info(AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS).toString()); + LOGGER.info(AccountAggregate.getAccount(ACCOUNT_OF_JON).toString()); } } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java index 9e1bc560e..b6aab7791 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java @@ -33,7 +33,7 @@ import java.util.ArrayList; import java.util.List; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class Account { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java index 29cdc4d15..a0d921f5f 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java @@ -25,7 +25,7 @@ package com.iluwatar.event.sourcing.domain; import java.math.BigDecimal; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class Transaction { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java index 8356cd3e8..350104267 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java @@ -27,7 +27,7 @@ import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class AccountCreateEvent extends DomainEvent { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java index 9d73639eb..3fb61bd08 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java @@ -28,7 +28,7 @@ import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class MoneyDepositEvent extends DomainEvent { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java index 995fb9326..bbba89988 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java @@ -28,7 +28,7 @@ import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class MoneyTransferEvent extends DomainEvent { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java index 64fddc16e..d8c295002 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java @@ -28,7 +28,7 @@ import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class MoneyWithdrawalEvent extends DomainEvent { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java index aa15f746f..baaf41f56 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java @@ -25,7 +25,7 @@ package com.iluwatar.event.sourcing.gateway; import com.iluwatar.event.sourcing.domain.Account; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class AccountCreateContractSender { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java index 932338c32..84bdff3b2 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java @@ -23,7 +23,7 @@ package com.iluwatar.event.sourcing.gateway; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class Gateways { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java index 3cfea0751..42ae7a1f5 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java @@ -25,7 +25,7 @@ package com.iluwatar.event.sourcing.gateway; import com.iluwatar.event.sourcing.domain.Transaction; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class TransactionLogger { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java index a5d82e5be..9379e7b5c 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java @@ -44,7 +44,7 @@ import java.util.ArrayList; import java.util.List; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class JsonFileJournal implements ProcessorJournal { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java index 81ec2e761..38e72995d 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java @@ -27,7 +27,7 @@ import com.iluwatar.event.sourcing.api.EventProcessor; import com.iluwatar.event.sourcing.api.ProcessorJournal; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class DomainEventProcessor implements EventProcessor { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java index a42826160..cfe0cfbb3 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java @@ -27,7 +27,7 @@ import java.util.HashMap; import java.util.Map; /** - * Created by serdarh on 06.08.2017. + * Created by Serdar Hamzaogullari on 06.08.2017. */ public class AccountAggregate { diff --git a/event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java b/event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java new file mode 100644 index 000000000..8fbed333d --- /dev/null +++ b/event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java @@ -0,0 +1,115 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.event.sourcing; + +import static com.iluwatar.event.sourcing.app.App.ACCOUNT_OF_DAENERYS; +import static com.iluwatar.event.sourcing.app.App.ACCOUNT_OF_JON; + +import com.iluwatar.event.sourcing.domain.Account; +import com.iluwatar.event.sourcing.journal.JsonFileJournal; +import com.iluwatar.event.sourcing.processor.DomainEventProcessor; +import com.iluwatar.event.sourcing.state.AccountAggregate; +import java.math.BigDecimal; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Intergartion Test for Event Sourcing state recovery + * + * Created by Serdar Hamzaogullari on 19.08.2017. + */ +public class IntegrationTest { + + /** + * The Domain event processor. + */ + DomainEventProcessor domainEventProcessor; + /** + * The Json file journal. + */ + JsonFileJournal jsonFileJournal; + /** + * The Account service. + */ + AccountService accountService; + /** + * The Money transaction service. + */ + MoneyTransactionService moneyTransactionService; + + /** + * Initialize. + */ + @Before + public void initialize() { + domainEventProcessor = new DomainEventProcessor(); + jsonFileJournal = new JsonFileJournal(); + domainEventProcessor.setPrecessorJournal(jsonFileJournal); + accountService = new AccountService(domainEventProcessor); + moneyTransactionService = new MoneyTransactionService( + domainEventProcessor); + } + + /** + * Test state recovery. + */ + @Test + public void testStateRecovery() { + jsonFileJournal.reset(); + + accountService.createAccount(ACCOUNT_OF_DAENERYS, "Daenerys Targaryen"); + accountService.createAccount(ACCOUNT_OF_JON, "Jon Snow"); + + moneyTransactionService.depositMoney(ACCOUNT_OF_DAENERYS, new BigDecimal("100000")); + moneyTransactionService.depositMoney(ACCOUNT_OF_JON, new BigDecimal("100")); + + moneyTransactionService + .transferMoney(ACCOUNT_OF_DAENERYS, ACCOUNT_OF_JON, new BigDecimal("10000")); + moneyTransactionService.withdrawalMoney(ACCOUNT_OF_JON, new BigDecimal("1000")); + + Account accountOfDaenerysBeforeShotDown = AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS); + Account accountOfJonBeforeShotDown = AccountAggregate.getAccount(ACCOUNT_OF_JON); + + AccountAggregate.resetState(); + + domainEventProcessor = new DomainEventProcessor(); + jsonFileJournal = new JsonFileJournal(); + domainEventProcessor.setPrecessorJournal(jsonFileJournal); + domainEventProcessor.recover(); + + Account accountOfDaenerysAfterShotDown = AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS); + Account accountOfJonAfterShotDown = AccountAggregate.getAccount(ACCOUNT_OF_JON); + + Assert.assertEquals(accountOfDaenerysBeforeShotDown.getMoney(), + accountOfDaenerysAfterShotDown.getMoney()); + Assert + .assertEquals(accountOfJonBeforeShotDown.getMoney(), accountOfJonAfterShotDown.getMoney()); + Assert.assertEquals(accountOfDaenerysBeforeShotDown.getTransactions().size(), + accountOfDaenerysAfterShotDown.getTransactions().size()); + Assert.assertEquals(accountOfJonBeforeShotDown.getTransactions().size(), + accountOfJonAfterShotDown.getTransactions().size()); + + } + +} \ No newline at end of file From a5ec376089b17ab35cbcc3dd63a411ee188a9f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 22 Aug 2017 09:11:18 +0300 Subject: [PATCH 35/45] Work on improved Bridge example --- bridge/etc/bridge.png | Bin 53487 -> 0 bytes bridge/etc/bridge.ucls | 157 ------------------ bridge/etc/bridge.urm.puml | 92 ---------- .../main/java/com/iluwatar/bridge/App.java | 42 ++--- .../iluwatar/bridge/BlindingMagicWeapon.java | 59 ------- ...gMagicWeaponImpl.java => Enchantment.java} | 11 +- ...{Excalibur.java => FlyingEnchantment.java} | 23 +-- .../{FlyingMagicWeapon.java => Hammer.java} | 31 ++-- .../java/com/iluwatar/bridge/MagicWeapon.java | 47 ------ .../com/iluwatar/bridge/MagicWeaponImpl.java | 38 ----- .../java/com/iluwatar/bridge/Mjollnir.java | 56 ------- ...ringer.java => SoulEatingEnchantment.java} | 23 +-- .../bridge/SoulEatingMagicWeaponImpl.java | 34 ---- ...{SoulEatingMagicWeapon.java => Sword.java} | 32 ++-- ...indingMagicWeaponImpl.java => Weapon.java} | 11 +- .../bridge/BlindingMagicWeaponTest.java | 16 +- .../bridge/FlyingMagicWeaponTest.java | 16 +- .../com/iluwatar/bridge/MagicWeaponTest.java | 36 ++-- .../bridge/SoulEatingMagicWeaponTest.java | 16 +- pom.xml | 1 + 20 files changed, 129 insertions(+), 612 deletions(-) delete mode 100644 bridge/etc/bridge.png delete mode 100644 bridge/etc/bridge.ucls delete mode 100644 bridge/etc/bridge.urm.puml delete mode 100644 bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java rename bridge/src/main/java/com/iluwatar/bridge/{FlyingMagicWeaponImpl.java => Enchantment.java} (90%) rename bridge/src/main/java/com/iluwatar/bridge/{Excalibur.java => FlyingEnchantment.java} (73%) rename bridge/src/main/java/com/iluwatar/bridge/{FlyingMagicWeapon.java => Hammer.java} (71%) delete mode 100644 bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java delete mode 100644 bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java delete mode 100644 bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java rename bridge/src/main/java/com/iluwatar/bridge/{Stormbringer.java => SoulEatingEnchantment.java} (76%) delete mode 100644 bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java rename bridge/src/main/java/com/iluwatar/bridge/{SoulEatingMagicWeapon.java => Sword.java} (71%) rename bridge/src/main/java/com/iluwatar/bridge/{BlindingMagicWeaponImpl.java => Weapon.java} (89%) diff --git a/bridge/etc/bridge.png b/bridge/etc/bridge.png deleted file mode 100644 index 00d3e611c1f72e1b3411c3c5b327f81a49f3a78e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53487 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 Sl~`f)|MIdbw@Rc<9{(RdGq(Q# diff --git a/bridge/etc/bridge.ucls b/bridge/etc/bridge.ucls deleted file mode 100644 index 2eda6e1d1..000000000 --- a/bridge/etc/bridge.ucls +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/bridge/etc/bridge.urm.puml b/bridge/etc/bridge.urm.puml deleted file mode 100644 index 82e3b14af..000000000 --- a/bridge/etc/bridge.urm.puml +++ /dev/null @@ -1,92 +0,0 @@ -@startuml -package com.iluwatar.bridge { - class App { - + App() - + main(args : String[]) {static} - } - class BlindingMagicWeapon { - + BlindingMagicWeapon(imp : BlindingMagicWeaponImpl) - + blind() - + getImp() : BlindingMagicWeaponImpl - + swing() - + unwield() - + wield() - } - abstract class BlindingMagicWeaponImpl { - + BlindingMagicWeaponImpl() - + blindImp() {abstract} - } - class Excalibur { - - LOGGER : Logger {static} - + Excalibur() - + blindImp() - + swingImp() - + unwieldImp() - + wieldImp() - } - class FlyingMagicWeapon { - + FlyingMagicWeapon(imp : FlyingMagicWeaponImpl) - + fly() - + getImp() : FlyingMagicWeaponImpl - + swing() - + unwield() - + wield() - } - abstract class FlyingMagicWeaponImpl { - + FlyingMagicWeaponImpl() - + flyImp() {abstract} - } - abstract class MagicWeapon { - # imp : MagicWeaponImpl - + MagicWeapon(imp : MagicWeaponImpl) - + getImp() : MagicWeaponImpl - + swing() {abstract} - + unwield() {abstract} - + wield() {abstract} - } - abstract class MagicWeaponImpl { - + MagicWeaponImpl() - + swingImp() {abstract} - + unwieldImp() {abstract} - + wieldImp() {abstract} - } - class Mjollnir { - - LOGGER : Logger {static} - + Mjollnir() - + flyImp() - + swingImp() - + unwieldImp() - + wieldImp() - } - class SoulEatingMagicWeapon { - + SoulEatingMagicWeapon(imp : SoulEatingMagicWeaponImpl) - + eatSoul() - + getImp() : SoulEatingMagicWeaponImpl - + swing() - + unwield() - + wield() - } - abstract class SoulEatingMagicWeaponImpl { - + SoulEatingMagicWeaponImpl() - + eatSoulImp() {abstract} - } - class Stormbringer { - - LOGGER : Logger {static} - + Stormbringer() - + eatSoulImp() - + swingImp() - + unwieldImp() - + wieldImp() - } -} -MagicWeapon --> "-imp" MagicWeaponImpl -BlindingMagicWeapon --|> MagicWeapon -BlindingMagicWeaponImpl --|> MagicWeaponImpl -Excalibur --|> BlindingMagicWeaponImpl -FlyingMagicWeapon --|> MagicWeapon -FlyingMagicWeaponImpl --|> MagicWeaponImpl -Mjollnir --|> FlyingMagicWeaponImpl -SoulEatingMagicWeapon --|> MagicWeapon -SoulEatingMagicWeaponImpl --|> MagicWeaponImpl -Stormbringer --|> SoulEatingMagicWeaponImpl -@enduml \ No newline at end of file diff --git a/bridge/src/main/java/com/iluwatar/bridge/App.java b/bridge/src/main/java/com/iluwatar/bridge/App.java index 4fc336042..c986de656 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/App.java +++ b/bridge/src/main/java/com/iluwatar/bridge/App.java @@ -22,40 +22,42 @@ */ package com.iluwatar.bridge; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * - * The Bridge pattern can also be thought of as two layers of abstraction. With Bridge, you can - * decouple an abstraction from its implementation so that the two can vary independently. + * Composition over inheritance. The Bridge pattern can also be thought of as two layers of abstraction. + * With Bridge, you can decouple an abstraction from its implementation so that the two can vary independently. *

    - * In Bridge pattern both abstraction ({@link MagicWeapon}) and implementation ( - * {@link MagicWeaponImpl}) have their own class hierarchies. The interface of the implementations + * In Bridge pattern both abstraction ({@link Weapon}) and implementation ( + * {@link Enchantment}) have their own class hierarchies. The interface of the implementations * can be changed without affecting the clients. + *

    + * In this example we have two class hierarchies. One of weapons and another one of enchantments. We can easily + * combine any weapon with any enchantment using composition instead of creating deep class hierarchy. * */ public class App { + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + /** * Program entry point * * @param args command line args */ public static void main(String[] args) { - BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(new Excalibur()); - blindingMagicWeapon.wield(); - blindingMagicWeapon.blind(); - blindingMagicWeapon.swing(); - blindingMagicWeapon.unwield(); + LOGGER.info("The knight receives an enchanted sword."); + Sword enchantedSword = new Sword(new SoulEatingEnchantment()); + enchantedSword.wield(); + enchantedSword.swing(); + enchantedSword.unwield(); - FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(new Mjollnir()); - flyingMagicWeapon.wield(); - flyingMagicWeapon.fly(); - flyingMagicWeapon.swing(); - flyingMagicWeapon.unwield(); - - SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(new Stormbringer()); - soulEatingMagicWeapon.wield(); - soulEatingMagicWeapon.swing(); - soulEatingMagicWeapon.eatSoul(); - soulEatingMagicWeapon.unwield(); + LOGGER.info("The valkyrie receives an enchanted hammer."); + Hammer hammer = new Hammer(new FlyingEnchantment()); + hammer.wield(); + hammer.swing(); + hammer.unwield(); } } diff --git a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java deleted file mode 100644 index e70cbb96e..000000000 --- a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeapon.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -/** - * - * BlindingMagicWeapon - * - */ -public class BlindingMagicWeapon extends MagicWeapon { - - public BlindingMagicWeapon(BlindingMagicWeaponImpl imp) { - super(imp); - } - - @Override - public BlindingMagicWeaponImpl getImp() { - return (BlindingMagicWeaponImpl) imp; - } - - @Override - public void wield() { - getImp().wieldImp(); - } - - @Override - public void swing() { - getImp().swingImp(); - } - - @Override - public void unwield() { - getImp().unwieldImp(); - } - - public void blind() { - getImp().blindImp(); - } -} diff --git a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/Enchantment.java similarity index 90% rename from bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java rename to bridge/src/main/java/com/iluwatar/bridge/Enchantment.java index c7b47e780..dd0c17205 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeaponImpl.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Enchantment.java @@ -24,11 +24,14 @@ package com.iluwatar.bridge; /** * - * FlyingMagicWeaponImpl - * + * Enchantment + * */ -public abstract class FlyingMagicWeaponImpl extends MagicWeaponImpl { +public interface Enchantment { - public abstract void flyImp(); + void onActivate(); + void apply(); + + void onDeactivate(); } diff --git a/bridge/src/main/java/com/iluwatar/bridge/Excalibur.java b/bridge/src/main/java/com/iluwatar/bridge/FlyingEnchantment.java similarity index 73% rename from bridge/src/main/java/com/iluwatar/bridge/Excalibur.java rename to bridge/src/main/java/com/iluwatar/bridge/FlyingEnchantment.java index ddd2ac540..8b12c6114 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/Excalibur.java +++ b/bridge/src/main/java/com/iluwatar/bridge/FlyingEnchantment.java @@ -27,30 +27,25 @@ import org.slf4j.LoggerFactory; /** * - * Excalibur + * FlyingEnchantment * */ -public class Excalibur extends BlindingMagicWeaponImpl { +public class FlyingEnchantment implements Enchantment { - private static final Logger LOGGER = LoggerFactory.getLogger(Excalibur.class); + private static final Logger LOGGER = LoggerFactory.getLogger(FlyingEnchantment.class); @Override - public void wieldImp() { - LOGGER.info("wielding Excalibur"); + public void onActivate() { + LOGGER.info("The item begins to glow faintly."); } @Override - public void swingImp() { - LOGGER.info("swinging Excalibur"); + public void apply() { + LOGGER.info("The item flies and strikes the enemies finally returning to owner's hand."); } @Override - public void unwieldImp() { - LOGGER.info("unwielding Excalibur"); - } - - @Override - public void blindImp() { - LOGGER.info("bright light streams from Excalibur blinding the enemy"); + public void onDeactivate() { + LOGGER.info("The item's glow fades."); } } diff --git a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/Hammer.java similarity index 71% rename from bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java rename to bridge/src/main/java/com/iluwatar/bridge/Hammer.java index 85532d410..557ef6691 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/FlyingMagicWeapon.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Hammer.java @@ -22,38 +22,39 @@ */ package com.iluwatar.bridge; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * - * FlyingMagicWeapon + * Hammer * */ -public class FlyingMagicWeapon extends MagicWeapon { +public class Hammer implements Weapon { - public FlyingMagicWeapon(FlyingMagicWeaponImpl imp) { - super(imp); - } + private static final Logger LOGGER = LoggerFactory.getLogger(Hammer.class); - public FlyingMagicWeaponImpl getImp() { - return (FlyingMagicWeaponImpl) imp; + private final Enchantment enchantment; + + public Hammer(Enchantment enchantment) { + this.enchantment = enchantment; } @Override public void wield() { - getImp().wieldImp(); + LOGGER.info("The hammer is wielded."); + enchantment.onActivate(); } @Override public void swing() { - getImp().swingImp(); + LOGGER.info("The hammer is swinged."); + enchantment.apply(); } @Override public void unwield() { - getImp().unwieldImp(); + LOGGER.info("The hammer is unwielded."); + enchantment.onDeactivate(); } - - public void fly() { - getImp().flyImp(); - } - } diff --git a/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java deleted file mode 100644 index 049133d91..000000000 --- a/bridge/src/main/java/com/iluwatar/bridge/MagicWeapon.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -/** - * - * MagicWeapon - * - */ -public abstract class MagicWeapon { - - protected MagicWeaponImpl imp; - - public MagicWeapon(MagicWeaponImpl imp) { - this.imp = imp; - } - - public abstract void wield(); - - public abstract void swing(); - - public abstract void unwield(); - - public MagicWeaponImpl getImp() { - return imp; - } -} diff --git a/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java deleted file mode 100644 index b0d3070c1..000000000 --- a/bridge/src/main/java/com/iluwatar/bridge/MagicWeaponImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -/** - * - * MagicWeaponImpl - * - */ -public abstract class MagicWeaponImpl { - - public abstract void wieldImp(); - - public abstract void swingImp(); - - public abstract void unwieldImp(); - -} diff --git a/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java b/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java deleted file mode 100644 index 7cec530eb..000000000 --- a/bridge/src/main/java/com/iluwatar/bridge/Mjollnir.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * Mjollnir - * - */ -public class Mjollnir extends FlyingMagicWeaponImpl { - - private static final Logger LOGGER = LoggerFactory.getLogger(Mjollnir.class); - - @Override - public void wieldImp() { - LOGGER.info("wielding Mjollnir"); - } - - @Override - public void swingImp() { - LOGGER.info("swinging Mjollnir"); - } - - @Override - public void unwieldImp() { - LOGGER.info("unwielding Mjollnir"); - } - - @Override - public void flyImp() { - LOGGER.info("Mjollnir hits the enemy in the air and returns back to the owner's hand"); - } -} diff --git a/bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingEnchantment.java similarity index 76% rename from bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java rename to bridge/src/main/java/com/iluwatar/bridge/SoulEatingEnchantment.java index 0c7a6ce6b..8b08d155c 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/Stormbringer.java +++ b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingEnchantment.java @@ -27,30 +27,25 @@ import org.slf4j.LoggerFactory; /** * - * Stormbringer + * SoulEatingEnchantment * */ -public class Stormbringer extends SoulEatingMagicWeaponImpl { +public class SoulEatingEnchantment implements Enchantment { - private static final Logger LOGGER = LoggerFactory.getLogger(Stormbringer.class); + private static final Logger LOGGER = LoggerFactory.getLogger(SoulEatingEnchantment.class); @Override - public void wieldImp() { - LOGGER.info("wielding Stormbringer"); + public void onActivate() { + LOGGER.info("The item spreads bloodlust."); } @Override - public void swingImp() { - LOGGER.info("swinging Stormbringer"); + public void apply() { + LOGGER.info("The item eats the soul of enemies."); } @Override - public void unwieldImp() { - LOGGER.info("unwielding Stormbringer"); - } - - @Override - public void eatSoulImp() { - LOGGER.info("Stormbringer devours the enemy's soul"); + public void onDeactivate() { + LOGGER.info("Bloodlust slowly disappears."); } } diff --git a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java deleted file mode 100644 index 2ed27242a..000000000 --- a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeaponImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -/** - * - * SoulEatingMagicWeaponImpl - * - */ -public abstract class SoulEatingMagicWeaponImpl extends MagicWeaponImpl { - - public abstract void eatSoulImp(); - -} diff --git a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java b/bridge/src/main/java/com/iluwatar/bridge/Sword.java similarity index 71% rename from bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java rename to bridge/src/main/java/com/iluwatar/bridge/Sword.java index 927ac2d66..73463b1f8 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/SoulEatingMagicWeapon.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Sword.java @@ -22,39 +22,39 @@ */ package com.iluwatar.bridge; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * - * SoulEatingMagicWeapon + * Sword * */ -public class SoulEatingMagicWeapon extends MagicWeapon { +public class Sword implements Weapon { - public SoulEatingMagicWeapon(SoulEatingMagicWeaponImpl imp) { - super(imp); - } + private static final Logger LOGGER = LoggerFactory.getLogger(Sword.class); - @Override - public SoulEatingMagicWeaponImpl getImp() { - return (SoulEatingMagicWeaponImpl) imp; + private final Enchantment enchantment; + + public Sword(Enchantment enchantment) { + this.enchantment = enchantment; } @Override public void wield() { - getImp().wieldImp(); + LOGGER.info("The sword is wielded."); + enchantment.onActivate(); } @Override public void swing() { - getImp().swingImp(); + LOGGER.info("The sword is swinged."); + enchantment.apply(); } @Override public void unwield() { - getImp().unwieldImp(); + LOGGER.info("The sword is unwielded."); + enchantment.onDeactivate(); } - - public void eatSoul() { - getImp().eatSoulImp(); - } - } diff --git a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java b/bridge/src/main/java/com/iluwatar/bridge/Weapon.java similarity index 89% rename from bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java rename to bridge/src/main/java/com/iluwatar/bridge/Weapon.java index 0bd7d7b52..9bdd715a1 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/BlindingMagicWeaponImpl.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Weapon.java @@ -24,11 +24,14 @@ package com.iluwatar.bridge; /** * - * BlindingMagicWeaponImpl - * + * Weapon + * */ -public abstract class BlindingMagicWeaponImpl extends MagicWeaponImpl { +public interface Weapon { - public abstract void blindImp(); + void wield(); + void swing(); + + void unwield(); } diff --git a/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java index 97298a161..295641a10 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java @@ -42,14 +42,14 @@ public class BlindingMagicWeaponTest extends MagicWeaponTest { */ @Test public void testExcalibur() throws Exception { - final Excalibur excalibur = spy(new Excalibur()); - final BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(excalibur); - - testBasicWeaponActions(blindingMagicWeapon, excalibur); - - blindingMagicWeapon.blind(); - verify(excalibur, times(1)).blindImp(); - verifyNoMoreInteractions(excalibur); +// final Excalibur excalibur = spy(new Excalibur()); +// final Hammer blindingMagicWeapon = new Hammer(excalibur); +// +// testBasicWeaponActions(blindingMagicWeapon, excalibur); +// +// blindingMagicWeapon.blind(); +// verify(excalibur, times(1)).blindImp(); +// verifyNoMoreInteractions(excalibur); } } diff --git a/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java index fca3ea9ab..76bb77047 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java @@ -42,14 +42,14 @@ public class FlyingMagicWeaponTest extends MagicWeaponTest { */ @Test public void testMjollnir() throws Exception { - final Mjollnir mjollnir = spy(new Mjollnir()); - final FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(mjollnir); - - testBasicWeaponActions(flyingMagicWeapon, mjollnir); - - flyingMagicWeapon.fly(); - verify(mjollnir, times(1)).flyImp(); - verifyNoMoreInteractions(mjollnir); +// final Mjollnir mjollnir = spy(new Mjollnir()); +// final FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(mjollnir); +// +// testBasicWeaponActions(flyingMagicWeapon, mjollnir); +// +// flyingMagicWeapon.fly(); +// verify(mjollnir, times(1)).flyImp(); +// verifyNoMoreInteractions(mjollnir); } } \ No newline at end of file diff --git a/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java index e883f03d3..901880cc1 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java @@ -41,24 +41,24 @@ public abstract class MagicWeaponTest { * @param weaponImpl The spied weapon implementation where actions are bridged to * @param weapon The weapon, handled by the app */ - protected final void testBasicWeaponActions(final MagicWeapon weapon, - final MagicWeaponImpl weaponImpl) { - assertNotNull(weapon); - assertNotNull(weaponImpl); - assertNotNull(weapon.getImp()); - - weapon.swing(); - verify(weaponImpl, times(1)).swingImp(); - verifyNoMoreInteractions(weaponImpl); - - weapon.wield(); - verify(weaponImpl, times(1)).wieldImp(); - verifyNoMoreInteractions(weaponImpl); - - weapon.unwield(); - verify(weaponImpl, times(1)).unwieldImp(); - verifyNoMoreInteractions(weaponImpl); - + protected final void testBasicWeaponActions(final Weapon weapon, + final Enchantment weaponImpl) { +// assertNotNull(weapon); +// assertNotNull(weaponImpl); +// assertNotNull(weapon.getEnchantment()); +// +// weapon.swing(); +// verify(weaponImpl, times(1)).swingImp(); +// verifyNoMoreInteractions(weaponImpl); +// +// weapon.wield(); +// verify(weaponImpl, times(1)).wieldImp(); +// verifyNoMoreInteractions(weaponImpl); +// +// weapon.unwield(); +// verify(weaponImpl, times(1)).unwieldImp(); +// verifyNoMoreInteractions(weaponImpl); +// } } diff --git a/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java index b71fe2228..e3c5669ed 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java @@ -42,14 +42,14 @@ public class SoulEatingMagicWeaponTest extends MagicWeaponTest { */ @Test public void testStormBringer() throws Exception { - final Stormbringer stormbringer = spy(new Stormbringer()); - final SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(stormbringer); - - testBasicWeaponActions(soulEatingMagicWeapon, stormbringer); - - soulEatingMagicWeapon.eatSoul(); - verify(stormbringer, times(1)).eatSoulImp(); - verifyNoMoreInteractions(stormbringer); +// final Stormbringer stormbringer = spy(new Stormbringer()); +// final Sword soulEatingMagicWeapon = new Sword(stormbringer); +// +// testBasicWeaponActions(soulEatingMagicWeapon, stormbringer); +// +// soulEatingMagicWeapon.eatSoul(); +// verify(stormbringer, times(1)).eatSoulImp(); +// verifyNoMoreInteractions(stormbringer); } } \ No newline at end of file diff --git a/pom.xml b/pom.xml index 347a6bc15..06148064f 100644 --- a/pom.xml +++ b/pom.xml @@ -467,6 +467,7 @@ builder prototype adapter + bridge From 2a98a1399ec516cb3904d727384356f912e7f7e7 Mon Sep 17 00:00:00 2001 From: Gopinath Langote Date: Tue, 22 Aug 2017 14:21:05 +0530 Subject: [PATCH 36/45] #348 - Data Tranfer Object : Add Puml id to README.md. --- data-transfer-object/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/data-transfer-object/README.md b/data-transfer-object/README.md index ad9b9f4e2..7fe2d9cdc 100644 --- a/data-transfer-object/README.md +++ b/data-transfer-object/README.md @@ -3,6 +3,7 @@ layout: pattern title: Data Transfer Object folder: data-transfer-object permalink: /patterns/data-transfer-object/ +pumlid: RSh14SCW30NHLk82GFTq8uDYum71I5zn-t41kUtCswrfwL4bhBzEOFcRoFZEHyCPUxXOcGfHv387jHutWuqk_dAguktGj1WGKwV1_WJLvqWmLl-8fRbVKa22yXTosCWhHly1 categories: Architectural tags: - Java From 6f1736d2e6421241e3e15ba764c3e5303962b6f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 22 Aug 2017 22:01:52 +0300 Subject: [PATCH 37/45] Refactored tests for Bridge --- .../main/java/com/iluwatar/bridge/Hammer.java | 5 ++ .../main/java/com/iluwatar/bridge/Sword.java | 5 ++ .../main/java/com/iluwatar/bridge/Weapon.java | 2 + ...ngMagicWeaponTest.java => HammerTest.java} | 22 ++------ .../bridge/SoulEatingMagicWeaponTest.java | 55 ------------------- ...ingMagicWeaponTest.java => SwordTest.java} | 24 +++----- .../{MagicWeaponTest.java => WeaponTest.java} | 47 +++++++--------- 7 files changed, 46 insertions(+), 114 deletions(-) rename bridge/src/test/java/com/iluwatar/bridge/{FlyingMagicWeaponTest.java => HammerTest.java} (69%) delete mode 100644 bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java rename bridge/src/test/java/com/iluwatar/bridge/{BlindingMagicWeaponTest.java => SwordTest.java} (69%) rename bridge/src/test/java/com/iluwatar/bridge/{MagicWeaponTest.java => WeaponTest.java} (65%) diff --git a/bridge/src/main/java/com/iluwatar/bridge/Hammer.java b/bridge/src/main/java/com/iluwatar/bridge/Hammer.java index 557ef6691..51bfda2a1 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/Hammer.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Hammer.java @@ -57,4 +57,9 @@ public class Hammer implements Weapon { LOGGER.info("The hammer is unwielded."); enchantment.onDeactivate(); } + + @Override + public Enchantment getEnchantment() { + return enchantment; + } } diff --git a/bridge/src/main/java/com/iluwatar/bridge/Sword.java b/bridge/src/main/java/com/iluwatar/bridge/Sword.java index 73463b1f8..6f52943a6 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/Sword.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Sword.java @@ -57,4 +57,9 @@ public class Sword implements Weapon { LOGGER.info("The sword is unwielded."); enchantment.onDeactivate(); } + + @Override + public Enchantment getEnchantment() { + return enchantment; + } } diff --git a/bridge/src/main/java/com/iluwatar/bridge/Weapon.java b/bridge/src/main/java/com/iluwatar/bridge/Weapon.java index 9bdd715a1..a2d21b88f 100644 --- a/bridge/src/main/java/com/iluwatar/bridge/Weapon.java +++ b/bridge/src/main/java/com/iluwatar/bridge/Weapon.java @@ -34,4 +34,6 @@ public interface Weapon { void swing(); void unwield(); + + Enchantment getEnchantment(); } diff --git a/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/HammerTest.java similarity index 69% rename from bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java rename to bridge/src/test/java/com/iluwatar/bridge/HammerTest.java index 76bb77047..a650bae04 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/FlyingMagicWeaponTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/HammerTest.java @@ -24,32 +24,22 @@ package com.iluwatar.bridge; import org.junit.Test; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.internal.verification.VerificationModeFactory.times; /** - * Date: 12/6/15 - 11:26 PM - * - * @author Jeroen Meulemeester + * Tests for hammer */ -public class FlyingMagicWeaponTest extends MagicWeaponTest { +public class HammerTest extends WeaponTest { /** * Invoke all possible actions on the weapon and check if the actions are executed on the actual * underlying weapon implementation. */ @Test - public void testMjollnir() throws Exception { -// final Mjollnir mjollnir = spy(new Mjollnir()); -// final FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(mjollnir); -// -// testBasicWeaponActions(flyingMagicWeapon, mjollnir); -// -// flyingMagicWeapon.fly(); -// verify(mjollnir, times(1)).flyImp(); -// verifyNoMoreInteractions(mjollnir); + public void testHammer() throws Exception { + final Hammer hammer = spy(new Hammer(mock(FlyingEnchantment.class))); + testBasicWeaponActions(hammer); } - } \ No newline at end of file diff --git a/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java deleted file mode 100644 index e3c5669ed..000000000 --- a/bridge/src/test/java/com/iluwatar/bridge/SoulEatingMagicWeaponTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.bridge; - -import org.junit.Test; - -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.internal.verification.VerificationModeFactory.times; - -/** - * Date: 12/6/15 - 11:43 PM - * - * @author Jeroen Meulemeester - */ -public class SoulEatingMagicWeaponTest extends MagicWeaponTest { - - /** - * Invoke all possible actions on the weapon and check if the actions are executed on the actual - * underlying weapon implementation. - */ - @Test - public void testStormBringer() throws Exception { -// final Stormbringer stormbringer = spy(new Stormbringer()); -// final Sword soulEatingMagicWeapon = new Sword(stormbringer); -// -// testBasicWeaponActions(soulEatingMagicWeapon, stormbringer); -// -// soulEatingMagicWeapon.eatSoul(); -// verify(stormbringer, times(1)).eatSoulImp(); -// verifyNoMoreInteractions(stormbringer); - } - -} \ No newline at end of file diff --git a/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/SwordTest.java similarity index 69% rename from bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java rename to bridge/src/test/java/com/iluwatar/bridge/SwordTest.java index 295641a10..7ffd0e492 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/BlindingMagicWeaponTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/SwordTest.java @@ -24,32 +24,22 @@ package com.iluwatar.bridge; import org.junit.Test; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.internal.verification.VerificationModeFactory.times; /** - * Date: 12/6/15 - 11:15 PM - * - * @author Jeroen Meulemeester + * Tests for sword */ -public class BlindingMagicWeaponTest extends MagicWeaponTest { +public class SwordTest extends WeaponTest { /** * Invoke all possible actions on the weapon and check if the actions are executed on the actual * underlying weapon implementation. */ @Test - public void testExcalibur() throws Exception { -// final Excalibur excalibur = spy(new Excalibur()); -// final Hammer blindingMagicWeapon = new Hammer(excalibur); -// -// testBasicWeaponActions(blindingMagicWeapon, excalibur); -// -// blindingMagicWeapon.blind(); -// verify(excalibur, times(1)).blindImp(); -// verifyNoMoreInteractions(excalibur); + public void testSword() throws Exception { + final Sword sword = spy(new Sword(mock(FlyingEnchantment.class))); + testBasicWeaponActions(sword); } - -} +} \ No newline at end of file diff --git a/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java b/bridge/src/test/java/com/iluwatar/bridge/WeaponTest.java similarity index 65% rename from bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java rename to bridge/src/test/java/com/iluwatar/bridge/WeaponTest.java index 901880cc1..daec1014a 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/MagicWeaponTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/WeaponTest.java @@ -28,37 +28,32 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.internal.verification.VerificationModeFactory.times; /** - * Date: 12/6/15 - 11:28 PM - * - * @author Jeroen Meulemeester + * Base class for weapon tests */ -public abstract class MagicWeaponTest { +public abstract class WeaponTest { /** - * Invoke the basic actions of the given weapon, and test if the underlying weapon implementation + * Invoke the basic actions of the given weapon, and test if the underlying enchantment implementation * is invoked * - * @param weaponImpl The spied weapon implementation where actions are bridged to - * @param weapon The weapon, handled by the app */ - protected final void testBasicWeaponActions(final Weapon weapon, - final Enchantment weaponImpl) { -// assertNotNull(weapon); -// assertNotNull(weaponImpl); -// assertNotNull(weapon.getEnchantment()); -// -// weapon.swing(); -// verify(weaponImpl, times(1)).swingImp(); -// verifyNoMoreInteractions(weaponImpl); -// -// weapon.wield(); -// verify(weaponImpl, times(1)).wieldImp(); -// verifyNoMoreInteractions(weaponImpl); -// -// weapon.unwield(); -// verify(weaponImpl, times(1)).unwieldImp(); -// verifyNoMoreInteractions(weaponImpl); -// - } + protected final void testBasicWeaponActions(final Weapon weapon) { + assertNotNull(weapon); + Enchantment enchantment = weapon.getEnchantment(); + assertNotNull(enchantment); + assertNotNull(weapon.getEnchantment()); + weapon.swing(); + verify(enchantment, times(1)).apply(); + verifyNoMoreInteractions(enchantment); + + weapon.wield(); + verify(enchantment, times(1)).onActivate(); + verifyNoMoreInteractions(enchantment); + + weapon.unwield(); + verify(enchantment, times(1)).onDeactivate(); + verifyNoMoreInteractions(enchantment); + + } } From 1dc038bc30798d849a127d5bbec62dffc32baebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 23 Aug 2017 21:25:48 +0300 Subject: [PATCH 38/45] Add explanation for Bridge pattern --- bridge/README.md | 166 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 3 deletions(-) diff --git a/bridge/README.md b/bridge/README.md index 6c1e70631..a37c35174 100644 --- a/bridge/README.md +++ b/bridge/README.md @@ -15,10 +15,170 @@ tags: Handle/Body ## Intent -Decouple an abstraction from its implementation so that the two can -vary independently. +Decouple an abstraction from its implementation so that the two can vary independently. -![alt text](./etc/bridge.png "Bridge") +## Explanation + +Real world example + +> Consider you have a weapon with different enchantments and you are supposed to allow mixing different weapons with different enchantments. What would you do? Create multiple copies of each of the weapons for each of the enchantments or would you just create separate enchantment and set it for the weapon as needed? Bridge pattern allows you to do the second. + +In Plain Words + +> Bridge pattern is about preferring composition over inheritance. Implementation details are pushed from a hierarchy to another object with a separate hierarchy. + +Wikipedia says + +> The bridge pattern is a design pattern used in software engineering that is meant to "decouple an abstraction from its implementation so that the two can vary independently" + +**Programmatic Example** + +Translating our weapon example from above. Here we have the `Weapon` hierarchy + +``` +public interface Weapon { + void wield(); + void swing(); + void unwield(); + Enchantment getEnchantment(); +} + +public class Sword implements Weapon { + + private final Enchantment enchantment; + + public Sword(Enchantment enchantment) { + this.enchantment = enchantment; + } + + @Override + public void wield() { + LOGGER.info("The sword is wielded."); + enchantment.onActivate(); + } + + @Override + public void swing() { + LOGGER.info("The sword is swinged."); + enchantment.apply(); + } + + @Override + public void unwield() { + LOGGER.info("The sword is unwielded."); + enchantment.onDeactivate(); + } + + @Override + public Enchantment getEnchantment() { + return enchantment; + } +} + +public class Hammer implements Weapon { + + private final Enchantment enchantment; + + public Hammer(Enchantment enchantment) { + this.enchantment = enchantment; + } + + @Override + public void wield() { + LOGGER.info("The hammer is wielded."); + enchantment.onActivate(); + } + + @Override + public void swing() { + LOGGER.info("The hammer is swinged."); + enchantment.apply(); + } + + @Override + public void unwield() { + LOGGER.info("The hammer is unwielded."); + enchantment.onDeactivate(); + } + + @Override + public Enchantment getEnchantment() { + return enchantment; + } +} +``` + +And the separate enchantment hierarchy + +``` +public interface Enchantment { + void onActivate(); + void apply(); + void onDeactivate(); +} + +public class FlyingEnchantment implements Enchantment { + + @Override + public void onActivate() { + LOGGER.info("The item begins to glow faintly."); + } + + @Override + public void apply() { + LOGGER.info("The item flies and strikes the enemies finally returning to owner's hand."); + } + + @Override + public void onDeactivate() { + LOGGER.info("The item's glow fades."); + } +} + +public class SoulEatingEnchantment implements Enchantment { + + @Override + public void onActivate() { + LOGGER.info("The item spreads bloodlust."); + } + + @Override + public void apply() { + LOGGER.info("The item eats the soul of enemies."); + } + + @Override + public void onDeactivate() { + LOGGER.info("Bloodlust slowly disappears."); + } +} +``` + +And both the hierarchies in action + +``` +Sword enchantedSword = new Sword(new SoulEatingEnchantment()); +enchantedSword.wield(); +enchantedSword.swing(); +enchantedSword.unwield(); +// The sword is wielded. +// The item spreads bloodlust. +// The sword is swinged. +// The item eats the soul of enemies. +// The sword is unwielded. +// Bloodlust slowly disappears. + +Hammer hammer = new Hammer(new FlyingEnchantment()); +hammer.wield(); +hammer.swing(); +hammer.unwield(); +// The hammer is wielded. +// The item begins to glow faintly. +// The hammer is swinged. +// The item flies and strikes the enemies finally returning to owner's hand. +// The hammer is unwielded. +// The item's glow fades. +``` ## Applicability Use the Bridge pattern when From 08cc50e875f049d227610b8c7866249f3aa554f4 Mon Sep 17 00:00:00 2001 From: Chandan Rai Date: Thu, 31 Aug 2017 01:50:33 +0530 Subject: [PATCH 39/45] corrected typos --- balking/README.md | 2 +- event-queue/README.md | 4 ++-- feature-toggle/README.md | 2 +- layers/README.md | 2 +- promise/README.md | 4 ++-- prototype/README.md | 2 +- tls/README.md | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/balking/README.md b/balking/README.md index 1ca7ccfb1..f720c0d02 100644 --- a/balking/README.md +++ b/balking/README.md @@ -23,5 +23,5 @@ Use the Balking pattern when but for an unknown amount of time ## Related patterns -* Guarded Suspendion Pattern +* Guarded Suspension Pattern * Double Checked Locking Pattern \ No newline at end of file diff --git a/event-queue/README.md b/event-queue/README.md index 35fdac45c..081c01449 100644 --- a/event-queue/README.md +++ b/event-queue/README.md @@ -11,7 +11,7 @@ tags: --- ## Intent -Event Queue is a good pattern if You have a limited accesibility resource (for example: +Event Queue is a good pattern if You have a limited accessibility resource (for example: Audio or Database), but You need to handle all the requests that want to use that. It puts all the requests in a queue and process them asynchronously. Gives the resource for the event when it is the next in the queue and in same time @@ -22,7 +22,7 @@ removes it from the queue. ## Applicability Use the Event Queue pattern when -* You have a limited accesibility resource and the asynchronous process is acceptable to reach that +* You have a limited accessibility resource and the asynchronous process is acceptable to reach that ## Credits diff --git a/feature-toggle/README.md b/feature-toggle/README.md index 3bb91ad5a..06d956178 100644 --- a/feature-toggle/README.md +++ b/feature-toggle/README.md @@ -22,7 +22,7 @@ going to phase out is never removed, causing redundant code smells and increased ![alt text](./etc/feature-toggle.png "Feature Toggle") ## Applicability -Use the Feature Toogle pattern when +Use the Feature Toggle pattern when * Giving different features to different users. * Rolling out a new feature incrementally. diff --git a/layers/README.md b/layers/README.md index 8eac62412..62b562938 100644 --- a/layers/README.md +++ b/layers/README.md @@ -21,7 +21,7 @@ Layers is an architectural style where software responsibilities are ## Applicability Use the Layers architecture when -* you want clearly divide software responsibilities into differents parts of the program +* you want clearly divide software responsibilities into different parts of the program * you want to prevent a change from propagating throughout the application * you want to make your application more maintainable and testable diff --git a/promise/README.md b/promise/README.md index 65d463550..37fd214b7 100644 --- a/promise/README.md +++ b/promise/README.md @@ -27,7 +27,7 @@ in a synchronous way. Promise pattern is applicable in concurrent programming when some work needs to be done asynchronously and: -* code maintainablity and readability suffers due to callback hell. +* code maintainability and readability suffers due to callback hell. * you need to compose promises and need better error handling for asynchronous tasks. * you want to use functional style of programming. @@ -44,4 +44,4 @@ and: ## Credits * [You are missing the point to Promises](https://gist.github.com/domenic/3889970) -* [Functional style callbacks using CompleteableFuture](https://www.infoq.com/articles/Functional-Style-Callbacks-Using-CompletableFuture) +* [Functional style callbacks using CompletableFuture](https://www.infoq.com/articles/Functional-Style-Callbacks-Using-CompletableFuture) diff --git a/prototype/README.md b/prototype/README.md index e6d5d8b8b..477cd6e6f 100644 --- a/prototype/README.md +++ b/prototype/README.md @@ -36,7 +36,7 @@ In Java, it can be easily done by implementing `Cloneable` and overriding `clone ``` class Sheep implements Cloneable { - privage String name; + private String name; public Sheep(String name) { this.name = name; } public void setName(String name) { this.name = name; } public String getName() { return name; } diff --git a/tls/README.md b/tls/README.md index 02d889f50..3fb5e9a6b 100644 --- a/tls/README.md +++ b/tls/README.md @@ -19,4 +19,4 @@ Securing variables global to a thread against being spoiled by other threads. Th Use the Thread Local Storage in any of the following situations * when you use class variables in your Callable / Runnable object that are not read-only and you use the same Callable instance in more than one thread running in parallel. -* when you use static variables in your Callable / Runnable object that are not read-only and more than one instances of the Callable / Runnalbe may run in parallel threads. +* when you use static variables in your Callable / Runnable object that are not read-only and more than one instances of the Callable / Runnable may run in parallel threads. From f28ed7b46e5897f53efb20041e92f13a90fb9209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 31 Aug 2017 22:11:58 +0300 Subject: [PATCH 40/45] #590 Add explanation for Composite pattern --- composite/README.md | 114 +++++++++++++++++- composite/etc/composite.png | Bin 16195 -> 0 bytes composite/etc/composite.ucls | 75 ------------ composite/etc/composite.urm.puml | 43 ------- composite/etc/composite_1.png | Bin 33933 -> 0 bytes .../main/java/com/iluwatar/composite/App.java | 4 +- .../java/com/iluwatar/composite/Letter.java | 5 - .../iluwatar/composite/LetterComposite.java | 4 +- .../java/com/iluwatar/composite/Sentence.java | 5 - .../java/com/iluwatar/composite/Word.java | 5 - pom.xml | 1 + 11 files changed, 117 insertions(+), 139 deletions(-) delete mode 100644 composite/etc/composite.png delete mode 100644 composite/etc/composite.ucls delete mode 100644 composite/etc/composite.urm.puml delete mode 100644 composite/etc/composite_1.png diff --git a/composite/README.md b/composite/README.md index fce6ed6af..fbb21ecb3 100644 --- a/composite/README.md +++ b/composite/README.md @@ -16,7 +16,119 @@ Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. -![alt text](./etc/composite_1.png "Composite") +## Explanation + +Real world example + +> Every sentence is composed of words which are in turn composed of characters. Each of these objects is printable and they can have something printed before or after them like sentence always ends with full stop and word always has space before it + +In plain words + +> Composite pattern lets clients treat the individual objects in a uniform manner. + +Wikipedia says + +> In software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly. + +**Programmatic Example** + +Taking our sentence example from above. Here we have the base class and different printable types + +``` +public abstract class LetterComposite { + private List children = new ArrayList<>(); + public void add(LetterComposite letter) { + children.add(letter); + } + public int count() { + return children.size(); + } + protected void printThisBefore() {} + protected void printThisAfter() {} + public void print() { + printThisBefore(); + for (LetterComposite letter : children) { + letter.print(); + } + printThisAfter(); + } +} + +public class Letter extends LetterComposite { + private char c; + public Letter(char c) { + this.c = c; + } + @Override + protected void printThisBefore() { + System.out.print(c); + } +} + +public class Word extends LetterComposite { + public Word(List letters) { + for (Letter l : letters) { + this.add(l); + } + } + @Override + protected void printThisBefore() { + System.out.print(" "); + } +} + +public class Sentence extends LetterComposite { + public Sentence(List words) { + for (Word w : words) { + this.add(w); + } + } + @Override + protected void printThisAfter() { + System.out.print("."); + } +} +``` + +Then we have a messenger to carry messages + +``` +public class Messenger { + LetterComposite messageFromOrcs() { + List words = new ArrayList<>(); + words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e')))); + words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e')))); + words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s')))); + words.add(new Word(Arrays.asList(new Letter('a')))); + words.add(new Word(Arrays.asList(new Letter('w'), new Letter('h'), new Letter('i'), new Letter('p')))); + words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e')))); + words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s')))); + words.add(new Word(Arrays.asList(new Letter('a')))); + words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'), new Letter('y')))); + return new Sentence(words); + } + + LetterComposite messageFromElves() { + List words = new ArrayList<>(); + words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'), new Letter('c'), new Letter('h')))); + words.add(new Word(Arrays.asList(new Letter('w'), new Letter('i'), new Letter('n'), new Letter('d')))); + words.add(new Word(Arrays.asList(new Letter('p'), new Letter('o'), new Letter('u'), new Letter('r'), new Letter('s')))); + words.add(new Word(Arrays.asList(new Letter('f'), new Letter('r'), new Letter('o'), new Letter('m')))); + words.add(new Word(Arrays.asList(new Letter('y'), new Letter('o'), new Letter('u'), new Letter('r')))); + words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'), new Letter('u'), new Letter('t'), new Letter('h')))); + return new Sentence(words); + } +} +``` + +And then it can be used as + +``` +LetterComposite orcMessage = new Messenger().messageFromOrcs(); +orcMessage.print(); // Where there is a whip there is a way. +LetterComposite elfMessage = new Messenger().messageFromElves(); +elfMessage.print(); // Much wind pours from your mouth. +``` ## Applicability Use the Composite pattern when diff --git a/composite/etc/composite.png b/composite/etc/composite.png deleted file mode 100644 index 1e6e6258ab696029a676688710bdcec0d95cbcc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16195 zcmbWeWmH^UlQ4>Fa2g0shmg<&m*C#G1$Wor9^9>Q4estvfS|$MHINWo6EryYB+onV ze6#M{nf2X2y*P)e+O^Af?K%-k3X)hDq!@5;a9Gk(;>vJv2*hx3@a|{`z?-y^$0ay8 zAq;785!DZw$38w|dTLoG5d{&CMl-s*>kb5hykD_N5_`;3^X6HnD%da4SUGfq`ZZ*x z+1zkVB2cyUU;lE0F)HLCU)VB8!uGNhsI3AZRfrd~>3Q2Vq$Ys{q6WL>-85+|*Emm( zCo2ZlH9tER1n*3$I&xkqt{=JQbSyq_zjS@W2xU4G4A8K(-Mm5jRJi&L@k$43c;30huS)Asd{y{{eS}TIPhKvLu=OZ)C}x;TCE`UGw2AVDM37T# zd&q^x$|617=~Yp|&pi&Wa&YZU;DbQ@m-MMupy{S8%+r{;p;Z-^yvz~f;ge^Dv7e-`RH4efJ3e(DrBWX)vuhGoedc@>WiUlK)rD{}&)PZD_F{e;043>fO)h z90U-Az`S}g$l2MXqTbU|m4?9QQDN} zQy_2tJ31l`b{7!M)y?j2U(b!Ds}jG*IYmD{kNu{c_^#L-PnYs{@z>6$0gc+mL0b#` z5M7}T8^FB_OngXXeMc-w?dX1;kGcdts)U;CH-1*L~l@(RC$x z%BbV`UtR7!DqiEa1N?}5i#x9))GyEa7C1%9YSWKe~%e0icI{|f& zdVG`DTiu3F8+9K$6_xLfGivO-kL(E&{4{*6DQ>*hddT*`Td8=><~^^Z4l9icW88G%J2=Z}I;1 z>!_CQLKf-*J+*%Nw9TOSRZa>9<_T@Nn`3?zeY*6*qMEr+{`j-=b|$3aOaWK6^$(ma$ zZr%Qe3I^SQoWdpw`aM|h$nRXgUvS5N`6Z78tHpnK!Id>cKl`4T0bO)Hic`Lod;f|o zVI(R;E7Gg`O_D%v6QugETd;?+wtt4tYXh8|(Y4}wx$vT0>iyHzLYIN#6X(aD+LG6O zqmtRY&NdI%);a6#*=2BM=DEMzy)*nHJ7_ozmi#U)%zV>Gm6aV?m(;WyhQ|`x=ifAW z2Y3!Nx5j5*NUa}P(aaa-JkoX$`O*ch1)&0QInMy{LzD14dwc0Re7|o8TJg#Q4&^xq zZ(yTy`8RthnJ6||D>Z$V!kkL{BSD=v9Sy|Q%tCdSXKROCQTD!fSweA02G{e7U7jBv zdx#5er~Eq3uP!$;YP7z77!_ii+PtjRoi9~W_x$A7WHId9YN=|##=j#Pczvqa6MYfR zmiEe6#$YY0Xs#q573WX-=u+*gd(Ea!_FSF(Dc+3$>Dy7`RA&6fCnyGGloY4^>f~bCobhvECl8bc&g)j zu$%~2)2d@qe!hKKq!Hgs$*2;j6i=rly`lZV?b}QDD!se!yKe;_-Q5M+&pQdch79T- zZh|tH?(QmvYuwT@)T;^jOd0M1ea@Z^CX}N$&O4M<>P%p=F!d5sdnURG*GY5vU{$gu z4y=7=)47RU#g#?SKTHhGRlTm~k|%41ouc&5eXwPRF7ABy^aV+4U1(Vh))*%jycQ{y zdeL8*-wQoDFIZjFZ@4b9?rPs(3CaMtkiYunRzayB<3q#FMZFUAizew>FX{G;170Tpo2ZdPy=HL$bp+tC-j<@*40HU0j)8w1I z`11a@bs}5okd^*c-$5ShKTFTJHVV3b-{JgS^Ry-89dQ5fL$m2aZ0kq0hDU@fya_qU zu_v{hqNi$69q_ev-F^kC`86e%og4a%bSkcmLe4kl7)cC0j~!H;SwQJjYNqeC2ocS& z1X|Y&->M>I-qwB^eHIM!e|)#xR|loa!Kc#s)Ty3pwF ztp6VgMij~|LD07^`fPsOy_~CQ>RTubNF4Yt%L7`bx$?ls%g09V^SZD=d0@R)GO8a> zaxAVPqKmC~3k;@0+1$L8#nU{qHSI;$RK`0H2CRLz3m>Y6N}2}Ka6&QQ;D8L>%Wllej5o?q?i#2~q$E}9tio52Ca}E>9+JizOS-Zxz z=w6uX(YvvVxHYwSXH0T4WW+9z8hxD4?1usnpDR3{ zmntgUqZq&`l9J?qEA+;JuM$0=98E@5QbslLnGTfjxR>9Z1ToT@M0PH7sST~`tT=0Y z&^47SSzTn2vqPLKYb zJlh8l9#Qi~Wyp@xJXemn`~BOs;pcD-ZZ*B-<6Y{vx?d3!4$a}cwhEVG;LX-z%3#~2 zHka0=;Z))g2Qomp)>9$Hz**AgJ8&+hZ6R~0SkgKI8!*4;I6AV-Y_oajP8!CY_$hf3@0^O*L|+Kf%i=y+UrvHFToQUy zbBbhOH}jU~BdchufK8=B0`cdQ@#kp~HR9jsv^M9O?}YSlMS zh3`hNB+BHQ5O$SUD5>#ld}bxp8h?%Fh5YGm_@{xZiP5T&Jen$0DW6w4Ki%{if0Ags^jMg@z z18P0K?)=T@y_4|MhL%jlW2z1v6an$h93Ony_TZ34q!_RMnBey!hrMg=M1Z)i3u0`t zXTrrtV8Cxz&ML?r)Bv4I_AMW>@cR`_mQDV!NBoWN*NkAj$fMarWbCx(Okq_H=kK(~ z(obK_Rte^NhEKn=PP43k;S{Icp;yt1AZ55wld3R_SXRK%qneje=W?N`J_%Js9kw4moWael)JCoD}c@}g#Wh_F?WhYY@s=@x zyGKz;-%AEXc6#np`2C(~c*j#!y8a|iPqK@hs_Z}?9?3zmZ+!T-rC_GeiECqHTq~@X zZ~3MXl28iQ%NSA0J~&7Wlc(7cC+EZ2;<*%sLCz$9W4nL;WU@P)MgNL#xXbjFd#WtdL3%=PjF+6ADnRVDQF}e!6FF^-;xpE2hZTR3HC-f|M3h zi8OAZymI8(?3B@)`C`Hl^T=EV0o8bU$&>aU-B|5@^|g0>y$`R5h6X@)Zxgb<8ui=a z%}?~kyOp)1)wDggHdJedk|?t>*hN}?3wnCl5)1iZxmV{XR}YWxsv{0Hvz2Nt?`2c@ zN<wjpi-O{nm0lJd;VTKo_p2aH6R$~v962wB!=E3jM@N>*_t~h0p!5x=TIu#xrxW-y z23B9FK+(D$$66B5<4naI{g)DoFUeL+cRPek&Jp{M=*kFE*>dK4{odqf6mYWI43ZV_ zJcd&2T1F@q`j~c-efjOdDxikPCuVV{nVbUA5pLztF7HczC@E--&p(v&u;2Kj0(-T> zNSkU(qOar+kL6OSF1SJ80f&64S}4M`oQ`wkWmFpen`7cL8ygE?m*^m?xaceNU2EbH zrJEoaQg_i2UtfSpjjAT#iue$OTj5ePv{0E+v^~T;AV5L#z_~d8HPHMUXyl|k+)0A3 zg*}I7My?R$N_JSOmyT&1H(S96bomiQDV~Mi=YdbD5#mda+Sue{`14BFPG?PGUeB+%k*h5W69*yl5X`*+{`7D#WHKZ6A$9cZ|#)V9|K z0XswUa(6%}o~cd(^v+wazlK3Kw4Z9`3&p3Ly%JcdXt#72y~d|}zU5?JLcX+8p%sm= z+6Wg5PvbVq3a2dEo0%W@O3IzrMq!*iB2cEz?O#v>fy$evDMF5A^RAebdg^TrdJOB* zMw^A((X>x)P2X)!JzQ@^SD~GyyuXY)XIQ?91n?<2e9wVthWHcwXqK+?NZtOR#ur(E zhn7(q^xe^R3`G{a!;<87puLN>zU z*&^-cd0|1I@$tDE)Kl%YSM-**eNmh1t4JQ7(v%pe4g>yGr^oUym|Gh%>Av++-?ae` zt+*%j@)`2JD}6&Z84!+|Ax@9QRNgkLvsA0M7dLMogk6Q>>6dofJWJ$7*upsH8ljD& zIIC$N>R_p|9}kRd5tw@^QcuL?an$-CNMBV;QJ|AUvgWtnN3wJU-;akv4ZhHkj%d47 zRfY+B?7wkzCHi0jNJ|F#xciYx$bI(rWXFDlv;FO3YeqKplg!{!X*k>Jkue1kG3{Y( zsLY`1O5Zs9eX7AFr`i5LixIXWrZJ}I>uuCy!w;qq4>n5~#j0;8v=9bjWt1{lPb;Wx z32e(s=!k3FKi*-*KK!hbq<O@t?UqaLVMvM1SW2h0jMTn#gO0XuZ~GZ{#S8F zbEL+3sPA?vmI*5{5^hAH5apS^Xm%gh{aFi+)sCL}4Q!0B0f9gsX=FjtCHl$iW*T{a zPRF+^sY`^(7duj-L~WB#h@qH1oN!`6snpq6?lZO>N#&+V08=wvCLWY||M1bxD@8L5 z8F~0+W!^gRM^?uTSWrM}E}M^t>oekcO+dAP{QyTl;0!q)m%&X*$$1>ayCn6YO|V>w z`bafuH3miBW{RS8Ne6^iF%wY7(_lr%PodiP3UVjF+pB=09}H_8h|72(pEj;6wy~cJ z_N{Z#6nk3k?~VkD<3CN5#|oudaiz{sA-NCz z`cY!&^9x)^zF%0w_?xhSPk(?88=S;O=5+~0aAZ5YK^_Px5!)KUm|_9(=QT`A_#FMU2zANXyuvfsPVvM7OdwGf4<4hmR$xa-gj^)_!) z@vd@Aqyxg2n$q;p_Bt<++MAQe+%UnUKNbda)%=RW8H$fb?3$vVrJ~x{JJ$`q(tzR~ zPVv~uTqUaY$s-9g`Z3Dv774C>{G$b~I_&v;%cxHp_bEuAx>%TcDye2)b~&0c1!+!& zrLJj2>?f-y2=0Z_jdmlY{Ed3Y>yEZwGtgmeU~~AI0vUS{Y;5c=c!~$p&MTij`OOLk z$hrbww1W60S1^i5oCpq(z{=z+#mv0fZBeOL2d%H}+H%=KHo*gbczXx%=HLd}cwxue z0n-|UUc?l*i{Lz{##=d7id7exr5E&9I#Hmmuv=D1OW@;el>oxa;1G${?ZZ zyZj}xT5k}Vr>5D|7b4l3Y6p+r7zyZk65|TcDIEI^&Vsp0El>YgQ^>_D4bRSsg6#ku zA;EXcYtx)=^&iBbpG}Ah@;ziq!wrrcD#fmz^J#p}0~`7Q?b`pNXKTg{VSCuTnLqV7 z?&7F*`rFw>$p_E!DGJJ|2H!_3+CFsz%-4@X>TQ-$)tuGgb6-#st!uM7zl$%V3EYv= z;MuE%!NDmJkSfLJ(|bo2Y%x$>wNs%KMAZ5>>eY+B4~eK!56 z_3{#^YT^9ZE7fR^CuB5@N>ch)czVO?nuqJFbsdv?R~>eYALV^78;CMe1%MtiT=(-3 zh?CR3QSaZjSjEwtGLPiOiv>0X9+?z1K_P+cCqhTG<_i*LrsBoqF8sJTc2fhYD9^K1!)5C5+Sb z!M>C2MdW89s+;YL4?CiA&S5;%i|kjFN%X&LDa=MgpRWxwm9(oT(48|7yu*V02&@*s zf%|}#1;2GuD*33&9YuyZ0hvA`LDbn#aaRB#P8%;`d7-DHHLz># zCnSRDy;C54&%IpRXiBx|-rbWHIAH|Zl-><4Y2<0TX0)nbF);f!L@$X!;owS9P zl;)O`#SVW&a4dg9?{%{^d)NQT)Y%N5c(s^yd+C?@41BLZs!CjAv{%YTc^(h_$@CeK z4tr#qC?FFDi4D1LU)*zKOYiBcbtf%m!z~9Jlkzfq`_Jcf{lmw&Mh$&dw{l(rW1*0*|nEk~Hjf7Dz7!3lh4!Dj2Bv3PKjZPH_4$guj7ku2uD@RgNrd@6w z=jV3PIAZjD`q_B!U;DKNp}$!$8oQRgj^8^CnGew;cmMSt|BMm^p|dX-rC>YW{@6bP zt&zK<=08vWX9aT*I@iL66p!*EP^7!e5n-nrk`25Mdjv@ z!*^RYc?|*B!a?tHg9Q!+ugjY2;{IPm7kO9nVvY46TI&SCz&y|6-wp-On`^+xUBJ@a zCbT1Uj++D9tkqqQw>aM45ko1f3{5Cx;^EJ~Ajz|FL~O~r)1=eA38VRIJ0yZ%Hi{=jd?&q9fh8|3?Ikz zo%#4E!b>n-%LR&<_rte$;_WGiW2S6{ZS4+Nm_op>Q3R;pMcpf%{6NSB!+nq9v|iXt z3i`3;{*3}VY%rE82fUES$cH~ZHFgHcKMEhw>y+W&LvcT$wT~Ry)u!kMF6`hYmfGEa zrZDOp#iofsZ-Mki258hpIsP-MHHVQNuV3(7W*pbGvsS#}q*)$69Dp%zv^|n+F_Ag_ za67_K6Nk9&v75E^?YU~9MIAOD9vgyHlyCJAZ1tq9pgdq%E# z++Uw=IJ_nYY>+;J)n=)7LyYQnN=-wr$!@I;$M5=!>0~;mHJAOm9E2)yIM^*X6anxU z?#<}8>(t63D_}q_=3&djkEZWy9Qaj{3TX#~-)se9GJV=F&RD21$e9xj|8VrJD`yEm zKJjLuU380yqgG^?052A%g=?&}`g z$r|AgaiLP|T)L>hN`@hY==tOduV(6PSGnBY*Z6a-f^Snp)%+6SL3QA)0;q)%Zo~3t z5BB3V3~WHauiZ7%wc6^;beSqtbEk3egiA%dk4LnD^L`WA-7)&$1 z9L+X{_9=9=9U1UKf@ku$UL>kp4MNugSc);e7m+_HK3GvL|2YWs<v;nX-q}T>&@9D9B@L zCc)Dis)?7U61kjMZQB3lbEy>jQ!@Gx+Ddu&6nR?c@?W-*6|#7noVG`vXHXOJf^G`D z!ua&R)}3!nBqe5T8Puz&;~gB%zE(SGYtDqdb{~PaQyF=eVL7(qjjOM}lXbFn+c#CP zT?tm1e_KBL$vraF;AQh793c1Z09BM0+tp^z%l9p@u;{6>ArG(WhnYkjJD;7a)Ry=z zfcR`KxNK9snFYgL29f4~C45CQz=ldAiH^z)38E|km2wtuO`3RyS;P@-Xh#S~Dm;U< z++?lMG<=|HIvami&F%2zB6asWL;dsN-)2Rt}(mDnaU$R-K}q%kFgdsRO*5{ zd~pwmY2Js%PqlEueo=%02)em1sO96588otaUCRTkZwkRlK}GCVrHrRaxjM!4Z*%rkfn^q3}uNuP$t{^&&9PApP#Myo^alDU+rZ8F+8YG51!OtsCPt+!Ss2Y$c=(IL}B8 zB{`Noz~2o?)4rZ@Dcuz1#EKIJw97*)AJ^$2O<{_j#ig37+)y`*|`8tI9|NvB_)A8E=EvrT#L&D&n}0b>~WwfvlO4&x?*7n znjD2jrJFxs3vjM^Cwt8_z0@?b*U?q_9c>#r??6u4r~_bd!k1F%)UJ{( zSa^LN&w1bfk=3_XU)PP<(&85L?<2zP?fQqH@ahwdZjcgQw|g$SafG-m)2Hu&s8rr@ zYX-kzioSuLvA`8a*)89E@2*cb3$@&UUEoF@tQI!i0tWC|0)LGN2)s7mIv-w8-Jq>9 zX|>p`O&3V&bd(YOTF|kdR-l==UTSsT^;$pAZn9o9wh9^n?EM~!zo!1y^4SpeF;_lS zpH;n&Zii1;P>;W@_t^OOJO^LJu0IS;5Ns9Lh`+{ViS|v5R$H`u>p?dof&bcpyD%E( zixfHwW-i#@9gvDGv;~W}k!I#9`Z{u*YxF%}%D>Po1IGey1;)TlZQG{F3EEnRdtL?B3{;B9}_D-1vo=|EH!aajfMhTZ^l)Brk{fm|Zr zk07X|;08F8BQ>A|ngiVI0Fe~Tj_|K%1ZD1Nq%x3Y_!u@o87K;r1QPa|Ed%FJIm99G z14|4*j3~tqw_ANSg4ywp3!&T9u>L#%PEchuTEBya_W?}f(GeC6` z;FpCU{6jAK3@t!}93X-R5TOMEPqTfYq_9{aone#@5ny6$)PE#nOKBNChXmjO+|9{sRPu3eW)qbU-8~%vhyph9M0WlllL=BKzl+Qj}O2b{_f+(-f{19PkPi zfI`S$y@lftPY1R%3dq4yB%M0k?hp}xK=}tE7cQOp5e_S!E`aq4ACMh*3h5NXGMocF zs_r9DzYK|JQywnXND}l><QdfSnbUWEQoHJ zL(-IWFs(v{%$TJ=h*HSormB1b+FVz`u!|6sE|xU81Ixhf%wFIQtr3`2VphEkp=~<` zs=D`CH;B#{F~CStwo-hj(iLVjv?YWGS+W$(a?(N7^uG+Co%!1+ypoR_$Y1p|QmCaO zzS4slGBN?ZYPlU0k3h-6FK?{*;%nHf6y7c%osMQ23NZ!4y0wp%+hF3%E`LVSP7n3T zv9>NWqCb|mKce7=%^^K5afTpRTMcQa zE5~1yCGnJuS#7u`Moq>LSh{!HO#=un=a+6WwJd^e$hN@ zEae=pmK0xHAzBACB{ifdt$^=sP**xgwh7AUOiM-w(Qe+)4ye9LDE0h$GIp-qn)rZj zi?^i6@-GCUrvYf62D$xgK-tB27cVw#&TQJ&3IT~v7&-9E+4-0t64dtD2FG|VZ&4pW zNIjp>D*O4YPaR^^AFm43O%p7}A~T{$M#CjDXHbeyNJ8HQ-aLLd(X%5sZ51S z)o$NPR$%2Qwea-#8Zy=r#a8x@{)C<_qutval6*M@n-KM(VZ=_qtiH#VN(_IfM9*1z z*9CVM(A2HXUr)rWhEy3YaEWP1->WU`B?`S2y+)qOt|j_wFu1<(jjt+^|Jqcr0o*aV zHT*F!o`AVQEbR3^fR`Bj_XBK4Ru2@eLBBB3jZC5YPzvSA4o}5Oi3n^E7h`j!yoti|zRsNqZmMl$&)90{xo7X56WPv*(J)pO z)GlU*h@Ndu{(QLTtvgnHx-ZLlbUT}|7JA`FC3LyhF?gcqc(+|2SBtNl92dtCsXp>7 z^%o`+mwIOSJCR@bdlzw6sGJus52)&oP}D$mxDQK@K)+G!6b#4F(;FP^M9jQeJ5T$*r|$z2knb1=Fg>_I7(sr^^Q9@y*8e*@p4l z3vF*qIz8e<9VK?0U@b77FU3=zQvMgYvZlmYtS_it-z`mU`PsIM>m*0lOZg2atBNX@ zmCA+|ePi#1N!32;Vd*<*m1Rk#P?L{&FdFQIz;IcgD)cmf5y?p1+i&Z)zZp)tcFyz; z(Q-cA45?VeR8jdI&w4Fl+TuNe*l)*}y578x!Yz|9c$9sa!1Zo>nqB4nF|hkzJn-Xf^YkaufzGzGG z?f#0-k6OcTLqq7{VB-eWAnM|&Yu)4S_H=yljos(%9HK`0TBj}j2WX@{wv~Oig(X3UK@C+(}offw8lMadO+7#Ted7GI%r?@4`i67kiDOfHnp@M_%^kBuC1SojQ*H+p6XY%*fgD zE)gXQ0%6z2jAr9>O==a%j91xGd6&Y+q*4dgH2z?z09Q@jkyaEUv+nUj5~aYNzk~bgTIIg?I=U*s9Z% zHw!k9LL+OSsf1FG4G4FsB2~uz!ps#gV$2oD1N+e2BUmbGVp=MeN*SPa!L1N1AgmBT zW{7*4fu!8@Ph$SR0Kbri=7UW30#)aIGPP{q_jE>|+#xS1y4oWyuvym|)$v+e=|JC) zLVjSpgf_is}}6hzigcql}hbzL%wYKl8s9>@{OnZ4QZ9}K(L>*J@u+IWrm)8 z8cIR|*-VYB9IZbrCo;m0$V{h`GAD_!wo06W-=04T04buFfE+v^s z7Z8kN&1n1`NZNy{Ex1Eg%g^z{uU6A#beXV?hnd1 z-M1qquF5u>8d`ovwRPn8&xOaSZNU30+|d6f(Dw}~&j+CO*4CaEBRdSva$lL#1l0I> zX@6_TxZ&nhG~quk9^^0(o%ek|YfzPD?IJx_^B`-!m;jdLZ~oV^b3BrxzwQTQ;G@yF z$R}gBbkm%~q>oO6J}@D%JA!#7PAl5dmHM6g$qM49LPcmD5{ z7OHTI@L3~P4xBRvel1ZqWo1(?!dzTnVj1FlJSD*aE*fp}qg8T@dG3ETeEgK)K|E$j|dB)yNf$feedZtndaWe+D250(tN;6RQR)C&l^o5&Vw@tl)-A5AybzX>RC zY5P$sN!ma3)(CoV%J#E*r0%_ekduX1{rWBr{SoeJgE4EP_}QIRfDQXK$6m+52W!SR z8{YgzoRHon;k#HQ$bOXp^~mW{^SUhd3qLhTKFpx1h-rzFKu#4Smh@*~z%P=teb$a9 zq7({>dIbT88xNZ{!chdyZDBDvFQ$1d*mo0oUr#^g)OQ!Nk!?C^o} zl#5srMlzJVrcdaac51nm6(!-^YyIx`FyU9{fQ(2c4*H?}P@`oc50l@5TF~G{%i>!@ zu7*Ba48hm#KliJeYLl`QA4012OE%&vC(12yCtSI;BCB9u-Mqiu5eYgEyK^N(ml^xZ zp1E*#oGzy>(3f|03@I0keUFijVrCcF)~PpkOUVnZz8Ti(Qet6Jme&!7*y}a~*+vRO zKR2f!?5bGjS+7`Wmh8B&pHzPt)~@{T+NEqLab0*mn=cMpV|qFQSQ`x7^|q7O@ygG0%`&_)7A(pnja^H~lKH<4 z<9rz@*=+@z!(~Z|SFjvOT$!hO?NH`4MBG32SD?-G3)DRM_P~z^3VU)gt*&L{_j8>uHnl=1 zNNr-{f<&b37wUO${INJT-A15cU`a8i{mvRSfd1yR8Uu zRw_IVvOX6L8UL}Keu&e0wsqIVR*FtetH6%!7BjHdH=mv@wsea=@irFZ7B^f3Rm|)g zuQs#nUd*rF<0}gm*}l)SNcmZ@eWW%mFd~#x33dtr+7S~nI92@%H**?$qz!)lvae}48uEXw%4 zK5NByFI2#9SU94uwA@<(uT037qH!|-8)4WbsB0Eo^q;L&TqtMEm+qPVW2N(Zw@uCAJbFj9ClJw z8?%Rgj-IxRSuQxt--d7+6IWSrL3anB-2?k2e@rCY71V~3DKY&i{1#tfeP->?YR7Wl zYJ|?KOzSC@rzqHm!xmBR`@oCH_LbsYRAV??5NPzpaEJ2&w81uJ+odt1CDiyOQA4LUxXJv{sb@dhr6BP;Z&6S>$1T~S&b}aCi%(O zm!*1aMhnbAqyusg zZ*0)dJQ{NI`D~`4wxXkj`aUpUa#XM#len~Yl$qhK&SYNe8+lM|$^rVWN~V+RKZ6YZ z>@%5a?2CS_FxzEj(JZ$5xb<7)k9)2Qz}IO($W-u2&0(;HP99HdMiuTHFxOA-ky5Fo z5Wf%UN{Js&G15&)>EA@Y5e>3EwGIYBdFD(_o8_X7=gmBj$;@1-?GN`i!{s>+k81;%eI3imyLLupyhE{S&6m&JRObIKz z0*xv3nUixWyPL(}SCm?;J`dd&O~*V2LJs%wLdon2>+YmQPFDH^Q&S|{N*VE?4Y2$u z^oVfE;BRFQYFg7u{o;}IH7kli?mL@?p{unR?j+fNRxDA)J3mZ6XmJfVUV8tLS3KIo zL)BKP)d`+V8wgrJBCR@iREf8s`t)n<+mXlbF-9K0hTSDZVp2A?4s^3Jrmtn=Qs-LG zcLPiJMAjIgZ%bkDx%_%(;usnU3kdZ)C8wg$4Q#PXO!eu*Mo9i7XGlB=j=6rPpsu;m z$U&}?Qha$O^2DIdpIrq@x-t6wZi0@yXlIIxnN~w39hDjgZR{$C)SkV}Jowy3w(u!o zI6R_jVYE41?Si-cZ6)Wk#URWtW)Ox3Pv=0Gsu^GaR0dhG4KQ56RtNorNW~Lw16Me* z!#Fj)yC{wUFxRW1qq4a5O4sZD-c(Cyd_V2z&T&+v=xmE4Fr9S4>x!dXH2tlxt&oIC z#e-$m6<6_>#w~JGq^i{)%FJ1c&p|Z&-oIOe(+xK7D90T)rLLaSOCmW}VV9OjqZt~w z7*RtXYDQ-JGZTxYx9&oAA)Q$54q-GmA%T0Y%IovE57Cp%J2036`moZbj`o~5e?NH@ ztjY{ycQfbwd6Ej=3$ZFcwISXTn~#N)zIm<-AdcSHO6DHJD&&b0Wvy@C@_jjrynTHqQcx2S5ZSQ!a(IDR z{rH|+te3azmg%g`&}xY%Z{04r=G z@4yDk#iZEJ7O$kp=4-0Y;z)=4W;z$0CoymhK5>i8e#r9bCP_iECa7u5l##yu$Xljd z%5Y;~iNLjthwjjbLyX<$3Ns)r@kbKVzkrS+C|m{2RB1mum@HQ)+R+&(O3d3a5>QOW z{(I$-W-0fA#UAbN-bX&N?j{tZR}~eA3e%?w6`iTJH0gOhK-aH2EwTLGo!gV*kEyM< zxV&A+1FK}EV7!$WjNBLF5WCB?Bhh1j<(i%qt&eJ*Hmps^{MmY9P#!9Z^>*ORkMTxI z;^?2MKgMe@=C=NOai{dGn13)lzk7dGHC;(_Fmc*`r$fP_zZe%EEy>O{_1{n*Sk1=&o0?_aXoIEM-pjA4VwHU$v6B^8w77 z5n1mCozoY9XS;i&t>!pAGFA@T#0Sq`{Ie^&w8XEwEPHMM>CtBkGnl(7%Fw8ze*7m& z33iTIi!MV`=CR>1w?D%1F0h|Kg(#=5L)ke9d}&OZp99MJLG|Dys1$#8!I++x_6t*_ zp?}Y{mI!A*`MgXF_+0sUr2(7{_5aZKD+i`M>v3Qz&jY$e{+tSM$%y{5q7S%atXjsJ zvVE2d&U2i~hQWy-x*^U5da8-H8VBF9JP+4L1;Lji9ifyW+crZp)g_!v4DuJ@{RIr) z3NyY|#S^bN=kcU~Tl#~A&;SFn((d#jTsLJcSuPQYD$?{JVat}*1utAJ>K_ukAd!nU z>VM-;m7(P?$`hs+s>fHN&xrmTER>Q_yhercI}khmg}5{ADqhn-LY((@>Oa9k*nRLi zCU*B+;S6z>u#_+{)cS_>#iM@xCqt#-$Pa+2z+L&T!8O4_jK%B={)6{ad1yBgFsm~H z|A+HZDFAuW!szfs0XK;wknC YN5E9DaLQOh19*g!hAN0xiy8+0KiLYo&Hw-a diff --git a/composite/etc/composite.ucls b/composite/etc/composite.ucls deleted file mode 100644 index 184c452f4..000000000 --- a/composite/etc/composite.ucls +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/composite/etc/composite.urm.puml b/composite/etc/composite.urm.puml deleted file mode 100644 index 82f2cab0d..000000000 --- a/composite/etc/composite.urm.puml +++ /dev/null @@ -1,43 +0,0 @@ -@startuml -package com.iluwatar.composite { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } - class Letter { - - c : char - + Letter(c : char) - # printThisAfter() - # printThisBefore() - } - abstract class LetterComposite { - - children : List - + LetterComposite() - + add(letter : LetterComposite) - + count() : int - + print() - # printThisAfter() {abstract} - # printThisBefore() {abstract} - } - class Messenger { - + Messenger() - ~ messageFromElves() : LetterComposite - ~ messageFromOrcs() : LetterComposite - } - class Sentence { - + Sentence(words : List) - # printThisAfter() - # printThisBefore() - } - class Word { - + Word(letters : List) - # printThisAfter() - # printThisBefore() - } -} -LetterComposite --> "-children" LetterComposite -Letter --|> LetterComposite -Sentence --|> LetterComposite -Word --|> LetterComposite -@enduml \ No newline at end of file diff --git a/composite/etc/composite_1.png b/composite/etc/composite_1.png deleted file mode 100644 index 5f5b010dd2fbdfbcce43be338284ab69b1443f7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33933 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%0Aj|yv(XSrL z6KG0W%^J`YY_|?a_$>Qk0zp&p?X_N2(@jllkV6f<@gS%E_vx`tp9y)I3#6D=2f!2{ zRw`x>nXboheyLa%2o1Vx{F6f7Cg;`k#|K1Bc~g`Al>4K0Rf64N+_Hh%Et zyIA)?P7b6d96+iylKKe52Ki99UkuN@AvxIz@;dokNqB4;j#-Vt3mcCgE;FO zT^?+orQn2?JqnLUb@%Dd?V{{%GT-m0c}sz5J6;y}=FNg_{T;$W@cH(js6Yvl`wt+U z*6WPC-edoja%PC|@za%w1V~iYw-k8@JsWz{{13;=MWE@mG<4dAS|InG`H)b|MGL%h zVspHdaLL zlr!XiXFX|>Y1gmyAclgtF9xln1kl(V*{uprE7FxEU-|gx6cC8tLPOIEnug>a=Ld72 z|EV&4oHv;FYh&Xh9B&eH%o43r(->$&DLynO$Bu#W0Dn0QOFgczkx_)1u}MwTHl@c0 z6zL{&WxAPYl#CsARL7uxJPPPc^eJ11QfNw}^h4t7*Q`yAxhlWszbC$~$ywc;&Vhbt z1qJD3U;iosh3G&avTMmF&wK>*GxuvJu)t__b}9?d$1~S|v;8@$0N0x&V#+&hZSI?r zKH7U|@^md?xCRa;innpwA)o!^lu2j`b}SE{NWq^e9S+4^Oq(`6TFt_ zh3d$cg|ma{5cmDI-AI+Vjp-138<>VXdm2B-ol-e}Uu>Zi&w{ANb;jD?O>Q{eS=C$= zO9i|?kXn&Ip{lnX$$t7)n|1AUBUx9H+|e}MK1+j!1^ti~iHUq@bjmwYx=0@F(JoHe z*1ra%B~>7Xi|ugH9eFXzM}207VdjDIjTpORe%CK5;(EKs&n@M4t+^^WJ98p`u+XM$ zV=~ghGg3I-CN(e%HlB-F%;9&RTW-oUq%&36jE2!sqlg;mVqgCF>LHEnCF&b^*AwyX zve867SG|I3Bz+w(f+E2022DE+pGeDf^c#3BZyrA-+RCMx2*(I|xs!Sx#k@RXTb-TI zk>Qz_wfU!;TNjQ&ot>wPJo7wGrWAfu-SFZ)T92HoRL~Qy7BP^V_xxhZFHAIRlsZa! zTdkH?ERo1Mr#hI2mslZ)a82EJd;pz~(N?H}`FB^H*feE>?f49L);faZCZ+z@q!`vX z9E_cMr;dR0MGkE@*ZKD3cufl%43yF!6*QvXP2@wKUS?4rCe^s{8M9}%`{>7#dkqSY ziwoyI)lC?V)YeX$$c^8_UsYJ(oS1FB(q|o~W7XUs98-TTm{Y}!`X!KujOietFK6_?}ovo_wA5iQhlNTJzT5cdPn> zW3N+ps#9rG2YoUco`uX`NYXqD)pJk5QUFC)=LQzI`~e)s1+Pl`unTH4x9 zQc`_`gVLv1jKxX=SElnjZ-X31irm|6C#%zpJWmPm6hDgxQynZy<|?V@uf4v7Yza#6@hp)Ct0cWRs6FqlKT;IeGk*Rwdt!Ab38LGZ@^AHK+ zWbGdN^qTrSn9%|%STOZ`jgo~@*p~^i(>23*{9m35_;?RCcUV4sVs}j(5qlXw`%+W$ zl865OQP6z1w;E2Z&+4`6vcsnbCHsVnroY&Pizln6Oc#2KWPjsMM^MGNiX%EY#3FTJ zhuYii$V|JfVx58qle%LR>2O? zc7MJ7>5zI(pU3^p%8={j#|?^NM6-1J3+O>SSMd}IOhr$c9u=2a^VOT4mr)mIFn)LQ zW%r5PsPfV~+A~{wMq<)JcKgijlZpO)c5OFOtJlx#>H=ox40U~ud830vEV}X_-wY+u zAI+85&8})P3rQ*P5|_3^({C$GWq6P&NHiS%-t?CdqRGKcl!?>Mh)l=o_(h*Gdg!4{UB&d zym#90!uMs0^K$>?#Q4J>)%$5iZ~!F?=D;hp?#DhI>#Fkt;q}`MLiW`}4f9=B<(@_t zAt`X$5E?v?dHsf1pwr_XXhX*^R;P+jG~cskYx2voo!7?;yWd5>@j38M+RByYXE}-= z?ewSJcXh@~4Z908#Num66OVpfrn$yxuQMr*Kwt)=oM(i1tm*LE{fCq zSxP6Cl9ULXbM4PKYuBh?yKNr9%8KQKjq6K3e-mHna4uZ!qnxuDW`X7-C$kWPCxRN5 z9q&rT5pB7fhto(m!oAEN9pl?rx#d)rJZIYF4iP4TQ&HX0QYGM|uhC3AJb2Z=SBtN_ zW2um4*Nm`=bSOo?d@X&hJ5s2za4foGg<*F7=}~Dis<+!cpc~5Ek1D6V(@4n>Y60gJ z%&tBXSrWV34kriJuMzvJgpt=`XrAXNzE~Mzr9r{`-NBgqPSp%Eg4F?v%ldMZu;ZO+ z6y^reoYqFe1n5AeIC*)k1ryqS@{&xGf{&oQa*Cw!p_f60R(toUQtxtU&~Y&OCoGjw zjR{%=et$o-sfcHFTjo4F%9owhU&S9$uEnl;I6r+gp}@b87^3cd{;N zGVhu9*6f>G32A8yC98`mt_D?puToMrafPhJhzo9%1RL~w&+b)Gj?Zq*#DoQp)n}y2 z(I|)wy3$e~pdDnZ{xyJAf`Zm>R%YSq>v{_*?5H%2`Bn|XqPyNd(5p4Q}^T{v*47n`m~7j|&^ zhth2N@eD&2f^M);~*tm8Go8*RnUnZ%)a?L5i>g==B*EWe#7Ih5+=@SsO1-%dlv(U1#j?uM= zN{R{Xdcnw`0iJ#D)9p_E=IYwB6P_v$FE6(0M;1??z}DSZ4|qjnyijSIG8e?-*w+Mo zfg|6BhF0(~|Bo}VtsA2fT9~NhSfq%WsQl#Zjaf>LNA1v^JlS-+;p10JD-_L2n`g^s z>6*M{k6m0axW-(`Uo`sH06DS+mqPzcGX2KfUm*@gw6ySCyuH-7oSxYJ5n-2j_SFL) zjXx(tqwGe4$3}&Oj8ntGSq51bV(n94x&cHAi_`V7`Tjn4Ewl3noMzRAl7?>|RV_7# z2CF#SyL`=W$UnTvo6xN9!);oHm}o7t%0IjCH=0{A7ZF z4+@f@UuRNhajZ3(FLvXvQKJ+cml|3E+w?IiTx^Wr^LS2uLa$(n-l+EvSviZGiR4@5 zoC)n6ShO{Iw0{=Y24XzvrZ_X*!Y^_FB0`2}54VPlLDb?`t5HPl#zDBg60b1vn?e`?B9k zY762cV9@eueS-T%?L@sVGe$;sJtR45trb4Y$H1a=d1y(J6~_6|aZx*rTmrH7=W@pZ z3HdOkl(vXptq)5pShE^OOs?s|w@tD> zaW{<=Kk+)^lmX_ld3Y+>nUq7-#vyg4};kjpPcxlq|3A7b37QTEGgcx73KqS z9V93D5^oS(3&hzTBh}8qUB%z#N-of6o-_HlT&wfTIehB+EU+85}#!Ivj@S11L_h8_13mF3HkV5*WF(U zPlW!6JM1Xp&9sKrfG&m9#DT?R&qoi+5E)bo`|Qz@zi(5@65wYCh_sk9vpheUoC1=kxGz`rx2}CaT#oA|!(7 zdCRV72yk+w=uRm)zn9xWp%x|1jb4;5H%Le@I-{+^EglB%?kpU#sIt-j;jq`KeGgfg zOv7*0A9ilW87fT_YQ1&kJPNA(Mq7UDfK zd174hHr5zPuBm&~1(#?P_!QSLH-|a=oy*w#gH$eUzwI-=>PBX-yoQBs*Sj0O z1x39u(B-*eAFM)irv?WJj#By__r6vmU~D7{Qb3@_A)#XL62VnKq*wn&j`2d(g2!~_ zn&lX`>-hq%;Ab2E!yV#?4}L)dAO9gHx8%rcN_NZs4438pMu01|&Z}bcdYpWGkF&9Y zKFP$~hbCJbss&R1*M^=XdAuf;l}*&H^?2-i{(5!D6U#Wlac%Uy&!6#1%R{;#2t<0{ zu1`BAQ*fst`YlS-@q7)lzc}^7#VTjhWf9rQA*xL_o5092(br|eV_G2Anh*LWbiXm9_7*OLaN7Q zp??U?sD>boBFzilEgxxnXs!7=)Az*uD;W6|l0oBW4z!MzgjlXBi8nI3K2;>k6nwu* z?0TpaVyUFW5hU0C-qg>#l#75XIJ8F(SBpnzkxE!4yN+rsxemT`QCqAc5yi9EL)r1+ zuHo`nrfg{5GsoBram3p|mE`NS{4^oG-$Y^wJb0xpZQI*wR_iq~!6u6MC@H-u*7+{1 z0N&ta4e3&JA6>U>oXb$LZlOYwVgVnt$|uKDJObrPXn#`%VUw4vche!;1GaT5jhOL# z_H3!zaq;Jsbje35*De)8rcnDFH+u>!nhof870Ij;aZLa5>lTx}jQ+&9TJmT~XS9T; z&vE-)T$9D!WFF~yawNH_XNj)frt6N~+&5rwZVWeTHSR9(`a)nZDw)0exBB){;ovwVu5Pgov4lvkiSk^eB@i=04^3X$DoL}cWQY;2gZ zXHW9v%PiTc8mz97doJ^hCuk+vU8G3l1xsQhn*+_mmKkhl_=RIBf^nlkR z@TN)@))64#_caf+JoWev z;X)uo=(saqy_nL2{xH*=P=5!!F11hi(ceVeAxA6w==9RkFH(+;cTZDl0D8hn-?QHCrM`Rj?JI1jUmc@Zj*F{zWvBRve&pq8 zbh>u+SS?5KKCe5IL$#}Iz>c~_$$$OiTeEuQy4L5Ct^m-qzC3M?NREq}JTLQ{&`$glE6Q zagrX|fa_o?;Fx{#*0Swjf@for&^C))GYFN7c;5k|f$l0Q(b@50l2k*N{@d`}6F{$} zto*0jVPTK&lDv4~ldoFqu%YcCCzo;J$PLH}9S7$}g*6-ju%*i(9)}#=3(Y+zvS|)n zhN$85+V|W0Bdbaa;D^B1vd|Xvzm<&pJ@%Q8Gyo%fyixO};Dd>!TG5)s4>IRx zJz)@oNO0hTA`2AR2B*BxT%k#SL+qP_WM5nR5~Q!fxAtrgV+01CZoc(-u{@y5re1Q1 zsM4%&iPC2@%dxdY6>>19%gnDt23wwWamq)>DebP9t19_QOYhpXP13bZ4zW+(Mh0Q< zvzhL`;gPK8F8+F=l=zmtKAgykW}xUs)+i)Lo`RogJwDI>L#x!_@-SY!{qNsGP#E_c zbWL#P6;^cr0K-N<79rQDclQNpKCsI+i{B@_l6bYI`To8&&9D6!mKcR6zWWF3R>I2s z0b<2^?Iawx(+l#)Zl3ghwwGtSe8~w;ZbRM;r)z#Uc%QN%LQGC7IsMuG+PC00Z#?GS z__~Yl+pLiCfS0B2u5B7YPPDQV^5SYJ3AWy|5-LMov)+1-_s<4(mHP`Uf5;p3K3`w? zm!u5@eQGGnY3XXoD9G?F;XqGpFJt90?cVB3H_VbFgJc%H4z4sGfPD!G#c-;Cn@B5p z5Iur+iH%|{b;pr=u5Dk!ITjl2Vw)J?+}7?6OW&hPgk*`dV8Y+v)nH@nP~Mx>h=05= ztybgm-Ex?%z+s^uv`j#)FK-uKY@23VKbhms96il9qz=?%VOLa&`oiv|H zSD<-=n%6iBz})=xZP9UkT*r7zU#@nHQmJ9Q9KEYWFA3$=SJ(b&1$<{l?Ux?mh{&!oQ~Hzq;DO`+VIc@cZPEO zc7A*Tj0-XpyD=f2q5u1a9n}~^R+fUrWHt54C0PuWtBFB!1tILu$Bjpx6rk6gIux2% z-Yo!0*7e#Z2`SXzgpcq^CZNYo=%ar(=yVkM{a)8T&dO_d`zx!!2M^ahOu+_b|2q*4 z9WR?NU&hd_eV^ve{6ItT{4crch zfl|(YwM$#&L2*3o>|mA0+q|6mii}(;e;b0i4U0G%T(G7s6tfQ+a}ia%`MWV!dfeyJ zo>U*-jpBI`$@lB7>s303NmFeLlQZ&}&3fGXjtqtnvFO@PQp?%-<3mNt7H~^_Qo4$Q zH%&v1a&?&gkuSS@(FuPa$FNst&uX;?vxEIU$g%Rs!*hnx)wF!qat87X{S?F(Zh`I0 z5=UgyZ886rC-cj$G&dy!VRp9N=G073P_@vXvgSDfd&=+c0T9M*`0z>KW%q8qO>F7A z&;(22?A{#aVo9C%SfeKq^f9In{uju0(E3*ltgYm_y-bBr2uT0Nw#{esAN?OkUL;b@ zJ{8+b6kog$#vj}7xW;p}T^vZ}>^BfnicN}c+FztqNOf@OZ&VCr$ z=qPyYJ{x5tSRjT#<@?)53F6b~4}28EI*Axc?)x`fN-AG^ep;G}S~XnsCnsYeCz(-j zIhjHsFfX~`*5A;oh2mmWF+i0bv&<_GW8)#3MK>WtiNvFVnxK!u0%%JepT_O9GfsYL z?ob>ebOTr5BDDN@j@~*)rK%t}7aFf2Z{*=9j zSC*y6Onw%X5)!oj6JJi0C#YR4Q6hh8b$i0r6R}<9h)N>eT;_ID98o07_GcUk4)3*N z3O+$}uKz&N>%Fl5ifvnGJ8Ozl4-O;Y(@lo?r8{pMX7wPw{G$}U5S6YVrI3(rY``vivE4d%2ob{2LVfmr9) z7V(4C5ka~PvuuU$@aeQCC)4VLci*mY;xmm^+SbJBth^`}Raa*sVqv~)&_45H4J-dq z_0=viOFY&~qvfeo=TKtCz=#|3lq1*Jh%Ha6l0`P(-wK*<;^wFH_Bv>26dQ8v*hhn& zT$^ZenYlkWgkr3XW6b}CLEfVIK9u$>B)PsDodWNprS@D5k4366S7VP7EaXMuO&Lhto69CT!X$-vU^r=#`Pfk%_;ri)Fl09l9ds+ew65Y?EcbMD>m`^vwuSK_!OFT zwP39RJk~S)8os%^ly00bGZ5Bl|HmUMC51zkPFOE>I`3IAf-er|o#N|ny#?&dvkrIL zw;%la?zs%1``p|phf1CVO5nwg3FaF9odctYq39nHbClv{|mhqd0K^j4xy7F zC8P%~+QN*{Mb|CBJe0v2de*q`*fUn`6YHf3H8?ywIJ+u$E39vQVysi0P^MY4%7#Axr2^9Gi5Rd26S8TQI^j_G9<%?;d3sH59*CNX00+mkQrSOX5@H2 z{?PYKs(@M@=itNDg8b<0RE_6kasG|$$=7(Um=LL53nfPI1WE1+?=1gh!pCF)lmq2WCpvSOhNKHRE<6zHN(@}n=ajk-bjqT}F3mpZamvI4l zrhd%yJ4N3Gb(_ZSlDu@Sc5HCU%pinCP5l@Suq4CWNGgUllx{Pe1z-?2$mw#n2Rcoc zyd@t~(J{JoH%>CVNHzJTi8JuUHD~@ez$&XFj4v;ZSN3T5nBSHXOtPQz2)|9y>_YKq zFA%*&`eZ@A{?WxjKoHO47v?Pqg2kP+1CE;%6lc1KyV!LFKwJO0m`Lr@9r zG8e=9OY-W!ES-L%wP+5xaxZ-5dCf0<^Ot0`kMJa0Lo!Q@`mjDyPjVLwWY^yy9*SSD zwwsxRbDE;(6Z!mCzpr$DCdXQFyIGQ_etUmo(q(@ocXW_H!s`*lY9r6Fv}(8-QD^D? z>}2UuT*Oh4&SIBjxt8g(>ccawg*X-v|`T^fS$K|!?%8;*&3WW0c9d`gP#@lN#4%eilfhV;z8WIWz}_bY_Qo`TCZ+5Dr( z3>q8zYxC^~U5pC-#R(_nV5~0OR5xkI#|Tu;M*Vhym-a{i+%Bt0#9>aO@a<*Lfb##} ze{}z#Ce>$`!?E5L#M@5)2cO>O^e6xIlA^n#JCS^R z_678yldgBq`EQG*ypDVX4x&G6RjPvXW5VHkujDT2O7n8VX)npO+~hshkiQjZM4VF* z^()dZe0ikw2Uo@5K*(~0K`y?Ro7o)iTV%7gxcFccZZ?joKIvxDe?F@|ACAZ2*U`cZ zam$W_hI;Yf)LY#5_38DaH9k4Shq9`f)udNP(Df4qrmD9Y#YKbuUWprprO zA42^5vfFAQ^Ny#wy87B=&8y5YR=u5>2hAExHS3Z8F;`^ZVjxK6^C)S%)nv8)_UsEL z^adtFD zS!_#vkX4zaKZIqPwpJl2s&yj+VoFT^u8$%9uDTXFKcA*f&s3vU?^7Ot={OY|UF$rC zoZ)EI`g_X%SXC%qHmRF*;;BP~a4Cl!d@DRTYi;UB6>a>BDC~SM9%mj*zGe#_Gfe-d zPfmy*|E;##WykT|cHePLQ?&9K=;q*NQ(`y&C#@sm${2X|-u+^^^pf;z-Cd!w)+_ox zmr(nQ(U2h>xXPr{uZ^GW3fFj%*97g~`3PM9cMeB4dD$G{i8_Z2)&6z=zXfamxBua; zfY5U#phkU9^G8!M`a6=niP(&;IZPLEtX!I7ctvA}wn0FzsGX zE`J1%v#?IT$;+UqS1lHzhRG`SuX#FT$K~+s-$kg)n{_#|Y~V3A{@bq?QR07YM#kgB z5p;B_gg18)7!WIprototype adapter bridge + composite From a3324a122c5b5dd746dfa000a760d795b4659196 Mon Sep 17 00:00:00 2001 From: Dan Siwiec Date: Thu, 31 Aug 2017 18:28:27 -0700 Subject: [PATCH 41/45] Make toString synchronized. Closes #621 --- .../src/main/java/com/iluwatar/object/pool/ObjectPool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java index df6e887b8..e76d00352 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java @@ -55,7 +55,7 @@ public abstract class ObjectPool { } @Override - public String toString() { + public synchronized String toString() { return String.format("Pool available=%d inUse=%d", available.size(), inUse.size()); } } From f439673de06cc6d0bc0a7e103a57a35af26e880f Mon Sep 17 00:00:00 2001 From: josejhgjghjghjghjghj <31527891+josejhgjghjghjghjghj@users.noreply.github.com> Date: Thu, 31 Aug 2017 22:58:50 -0400 Subject: [PATCH 42/45] Delete postPumlsToServer.firstrun.output --- _scripts/postPumlsToServer.firstrun.output | 190 --------------------- 1 file changed, 190 deletions(-) delete mode 100644 _scripts/postPumlsToServer.firstrun.output diff --git a/_scripts/postPumlsToServer.firstrun.output b/_scripts/postPumlsToServer.firstrun.output deleted file mode 100644 index ea77a49a5..000000000 --- a/_scripts/postPumlsToServer.firstrun.output +++ /dev/null @@ -1,190 +0,0 @@ -parent: half-sync-half-async; artifact: half-sync-half-async -Puml Server ID: RScv3SCm3030LU819FRPXg5fIm552tnYPFiyjRi3RkbAaYkdoQr5JBy369vrxz7oaSv6XmPhL3e6TCaJ0msU-CAoilTToyG8DdKOw5z0GzcAlvNAN_WZSD1brBHHPmxv0000 -parent: abstract-document; artifact: abstract-document -Puml Server ID: PSjB3eCm34NHhPG599vtDyQn85L-ifzX-p3lxEf8Twj3MXGDQvyJMFubChxpKN767gucSq07iinEjSNDOACVNvoAUZr6MWoe3QVE_WRnxZ0Mf38b-hkIGlurX_MyehS7 -parent: tolerant-reader; artifact: tolerant-reader -Puml Server ID: NSZ14SCm20NHLf829ExfXaYChGn26lZ4xSVdtFRjSrZJx9AkZnFOyI9olkenSEOxGxmjWnXgMvE6viLWfmz_kNI9SLZP38XRqEIuWx1Kd0t5XVjjGVj_DNtMdLD_ -parent: event-driven-architecture; artifact: event-driven-architecture -Puml Server ID: TOhH3SCW30LNQGS0_tSRnrZ15H1adfFromBzkfFktZQaHT7mzgh0N1yYvoUVXXf7B7Mv1dGWozN9MZmCTlhopQdeidEaoO3wMDHvRI6zzvwAssPYbsfGGRYIGlxN7DxpZDv- -parent: publish-subscribe; artifact: publish-subscribe -Puml Server ID: PSZB3SCm203GLTe1RExT1XCKKs5YyMdMR--zFRsd66aTNAwFcRdZ1U1uzrDorgXWfykIBJjT2qJhnaI7Dtwm7HnoMjkOoMu12-C7s3LKOhQe4UGo63ZfVtlvwhkMVW40 -parent: facade; artifact: facade -Puml Server ID: BSP15eCm20N0gxG7CEoz3ILKqvTW7dpq-hhehERTJ7fMJU-l7PYn4ZbVPMlOyvEXBeT13KMEGQtdnM2d7v-yL8sssJ8PKBUWmV64lYnSbHJoRqaVPUReDm00 -parent: service-locator; artifact: service-locator -Puml Server ID: NSjB3iCm203HgxG7iDdtDeIWX0fZYqzo_MRTtUX9ynOZhPtBzNLchlW0EDxza3nhgs2dQScMdUO0qRenqU6B5xQTGmvh2pFPBM1WF07FSmbnqqcOqu6J_gsNZxvgw0y0 -parent: dao; artifact: dao -Puml Server ID: 5SR14OKW30N0LhG0oVrt4o6ZE12Ov4NR_thQNQlc5aN2sd82qtz4naywAixOmyNoK8WYvT6fjdWOR7JnpLiHhuTkam4nTUhiRwZm847-J64zpUZj3m00 -parent: model-view-presenter; artifact: model-view-presenter -Puml Server ID: ROlR3SGW3C1MkGu0-RzjKeXQJWcWFChwPO3xispvQBrmL0hbp-q-xGkWkFBL_8upZBICxjGzbo7GE1OwAlpmmLJ9sjNJH7VIRY1e6q169KvFevMcakrtI_BoD-HGoJE4Nm00 -parent: observer; artifact: observer -Puml Server ID: FSkn4OGm30NHLg00hFow4KO3PcpP8tr1-pYwx6smQz5Suv2mkbp0y1-HyPlEWYlsSB7S5Q98kJSgDLu66ztyy7Q8brEtmO2OEZNs2Uhxl9u9GVv72cjfHAiV -parent: intercepting-filter; artifact: intercepting-filter -Puml Server ID: RSfB3i8m303Hgy014k-vZN5DQkIuaJ_q-fGzkz7JtCL8Q-DolUsPAnu0ZcSVadizAzZfi6JBJiS4qJenqU6D7smRXmnh2pFPBM1YN05o_KwyKcoqb-ZFEEcVz_BPLqtz0W00 -parent: factory-method; artifact: factory-method -Puml Server ID: NSZB3G8n30N0Lg20n7UwCOxPP9MVx6TMT0zdRgEvjoazYeRrMmMsFuYChtmqr7Y6gycQq8aiQr3hSJ7OwEGtfwBUZfas0shJQR3_G2yMBFkaeQYha4B-AeUDl6FqBm00 -parent: private-class-data; artifact: private-class-data -Puml Server ID: RShR3SCm243HLTe1RFwx3S4eeSB4uf6itmpGlwkZ-nOZhS7b-ZeoLtm07E--InwrLR3JQScMdSu9edLZeiCNBso3GtPh2pFPBM1YF07BvSBaHeeHRJm_SD8VxkMphvhw0m00 -parent: async-method-invocation; artifact: async-method-invocation -Puml Server ID: TSdB3SCW303GLTe1mFTkunWhk0A3_4dKxTi5UdlIUuhIoCPfuz4Zjhy03EzwIlGyqjbeQR16fJL1HjuOQF362qjZbrFBnWWsTPZeFm3wHwbCZhvQ4RqMOSXIuA1_LzDctJd75m00 -parent: execute-around; artifact: execute-around -Puml Server ID: NSZ14G8n20NGLhI0XBlT865suoGa0n_NylNixSsxTvEHJTF7xGHsF8YShtfqdFdCK9TbK4ELDQcFl1ZizE8tbwRH3okR0NKBcXm_a7vK4bhOLreZXVnLJPzrvnnV -parent: monostate; artifact: monostate -Puml Server ID: HSV14OGm20NGLjO23FVj1YEZsGaa0nzjVxrvUszfLdlkaju_9p3ZI-HybwFXp2r3l0w364eTIgtdpM2d7r-yxXBji7Ko86v1ol60TDW8C8G4zLr9rp9J-ny0 -parent: thread-pool; artifact: thread-pool -Puml Server ID: JSV14SCW30J0Lk82GFzq8uF6a1624IUx_UIPt-xHhMXK2TTN0zP-4pa_-UfeSSOMBzCWXbpceAxnCDZfmpUdAhjVbXO3uhPfyFw1q5oufZMdag3yFuUFl6Be5m00 -parent: delegation; artifact: delegation -Puml Server ID: JSV14GCX20NGLf82LkxfXbN69OFeu2VRVdBCxRsdUhLiac6F2rZxHHHybwwuyimjKQT37ANEGMfvCpZepHy-ccpjVYm697pJuFq3DJ7f39rEWlhNaZ7Aoc5V -parent: chain; artifact: chain -Puml Server ID: 9SR13SCm20NGLTe1OkxTXX0KKzd4Wa-pVYlrdTxJN4OTMZ4U7LZv8Wg-ssdejLTgoELGHvDhaesw6HpqvWzlXwQTlYq6D3nfSlv2qjcS5F9VgvXjrHnV -parent: resource-acquisition-is-initialization; artifact: resource-acquisition-is-initialization -Puml Server ID: ZShR3S8m343HLUW0YV_PnhXMQvGumOzMOdhA1lqxkhgBABLSEQqzzeZfJm33isuIUxxIsMXei4QbqK5QdXXeyCO3oyekcvQ94MpgqD4lWB6FDEA2z4bn2HbQn8leHMponNy13hgvrhHUP_Rs0m00 -parent: fluentinterface; artifact: fluentinterface -Puml Server ID: NOj93eCm302_KXv0VEzlN6F0bMCYB_3zvjpRQ3IpY97MnkNwEZD7l04SdtP8dlMfOAVBaYqRNHr4wy54Xo_Uk6uSSjWwC9FT0Zh61DYrPY_pyXs9WPF-NIllRLJN7m00 -parent: service-layer; artifact: service-layer -Puml Server ID: LOl93SCm3C1MQGUmzUysgY8aAcJ5q96WszVV_aW2V8gHriRb-ZWoPxm07E--Inxrhc2dqv8jEvq3HEl6H8SFNjWs3jcjJSnaju21iG3MSmbnK_mkuwJ_qij7dpNq1m00 -parent: visitor; artifact: visitor -Puml Server ID: DSR14OGm20NGLhG0mtsxmSWeJa8oyD7sTo_xJczLgoqFIM_B1Spu43c_vLHSkMU8rs4GGwcZaxPy6UnqyyFR8Q6dRPC1SGlg7B_Gew4OJeBwVqdlPMPlNm00 -parent: double-dispatch; artifact: double-dispatch -Puml Server ID: NSbB3iCW303HgpG70Ezx6yTOWSeOv4zp_MRTtUZDCPGa6wV9gqTiVmCOtlKQqVDCPwEbmHgLreGXUMEWmGU_M1hxkBHiZ61JXud-1BILft1fmvz37JZetshQh3kd_000 -parent: monad; artifact: monad -Puml Server ID: 9SR13SCm20NGLPe1OkxTXjWeSMMm1Pza_LRgExsjMntP97syBc35cyZvAMV7bKU6U9q6CPGwbVh8Xy5E7xvvRnBzj7qn86v1ol4BwJHk9AZ_bNGjAtLy0G00 -parent: front-controller; artifact: front-controller -Puml Server ID: PSlB3OGm303HLfO24j-t6nCC13bEvC_IFk6yjz6JPgbIE3OAvS_fFkmBe7Zde_ePQnXfwU8adajlK3bkT5Iuy8Tf8wk7f87kf6BGq6R0hlD8xwQTUG9v-SCSslA8nWy0 -parent: strategy; artifact: strategy -Puml Server ID: FSV13OCm30NGLM00udktCS4AGOaJsTz5tRwSkBstLiqj3WbhombC_n0PtwbKdB67Y-MX44NAerDjSJFOwE8lRuTuBRfD1iJKgRC_88SnfFn8aD-ai9vczFO7 -parent: command; artifact: command -Puml Server ID: DSgn4OCm30NGLM00h3xR25i7vYpXaxx2-g59zugtTgiZcwIFvGHcV8YSdt9qdBbdYDVR88PIRwK-yc6mqyLVtff4FsoR38XRa7Aye3SgMoD1_RkaQvcfumS0 -parent: abstract-factory; artifact: abstract-factory -Puml Server ID: PSZB3OD034NHLa81Czwd6sCC39gVxEUWT1_ssLmTtQLqgR5fM7sTmFGtaV6TZu8prd0r6HtQaMKqAZLk1XjT_E6qgPUZfyc0MdTgx0-8LuUn8ErFXdr98NypXxKyezKV -parent: flux; artifact: flux -Puml Server ID: 7SP14eCm20NGg-W13FlU1YFLE0GpyAazVZk-rPkRLSrDqdKwW14l8kUxx0r7hXdYzJA8eTIhKzEy6UnqyeUNJQBjjWm6n2seS_n3Ryql2UgJajxBoAu_ -parent: event-aggregator; artifact: event-aggregator -Puml Server ID: PSf13iCW30NHgxG70Ezx6uTOX0eCih-JwvTzTwEdUJSjFKu9wwyBMFuXCdvoRRZY21ShKo6ANEQWrkDXiD6NRqwdUAkQ5WDYwZJOTv3SUqzSgqbbp0qeVvZ3Hbun-Wy0 -parent: singleton; artifact: singleton -Puml Server ID: HSV14SCm20J0Lk82BFxf1ikCh0n26ZZizfDVVhjRjwfvIhg-Bc35cyZvAQtZoYD3l4w364gTWxhcms2d3z-ydnAzsRuO4BUWmV43HRUcWcaagF-Lz55M3lq2 -parent: null-object; artifact: null-object -Puml Server ID: JSV14SCm20J0Lk829Fxf1cF6bWSX3JhYzfDdVhjRSx4yDCDU5p3NcoZugMV3bNik3HaETLGPdPhbm-2WcpzS3btjz38PqF15dTSFv6bMndwhW1Jo_vhHwynkNm00 -parent: multiton; artifact: multiton -Puml Server ID: FST14i8m20NGg-W16lRUXgPCYnD81Zxs-hfozzvJlOywf68yBc3bYoZuRgVYghrIea-7E5gVHZhgPd3Gcp-y7P9w-hOOaF0au_o1h0OKqqdG_saLrbRP-080 -parent: composite; artifact: composite -Puml Server ID: HSf13eCm30NHgy01YFUzZGaM62LEP7-NwvTTT_EaMTLgoqFIst81Cpv4payv5LVk6U9r6CHGwkYaBHy6EztyvUsGqDEsoO2u1NMED-WTvmY5aA3-LT9xcTdR3m00 -parent: api-gateway; artifact: image-microservice -Puml Server ID: 3Sp13SCm2030LTe1RFxTXX3aK1biOOZLxPlVlUujHZrFJk-lAsAk3u3ZhatYoYCNEmqBjgWq5AJdna27BzvOJbxIh4oCOBS5Yki1u9JIC7ZZ3pW8HB5nKI4VJtSBSKtNEbFx7m00 -I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'api-gateway/etc/image-microservice.urm.puml' -pumlid: 3Sp13SCm2030LTe1RFxTXX3aK1biOOZLxPlVlUujHZrFJk-lAsAk3u3ZhatYoYCNEmqBjgWq5AJdna27BzvOJbxIh4oCOBS5Yki1u9JIC7ZZ3pW8HB5nKI4VJtSBSKtNEbFx7m00 -parent: api-gateway; artifact: api-gateway-service -Puml Server ID: JSox3SCm303HLP819FRUXg49cO542_nOyFPncUvUSszHwhbpMdyT4TCt0CDLcyIHdtGsEZLOez8vG7ek33JuueLbPvUcPM84cpeCz2S0fvI6mGjluA1_b-Tt2N5D6tNcw3y0 -I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'api-gateway/etc/api-gateway-service.urm.puml' -pumlid: JSox3SCm303HLP819FRUXg49cO542_nOyFPncUvUSszHwhbpMdyT4TCt0CDLcyIHdtGsEZLOez8vG7ek33JuueLbPvUcPM84cpeCz2S0fvI6mGjluA1_b-Tt2N5D6tNcw3y0 -parent: api-gateway; artifact: price-microservice -Puml Server ID: 3Sn13iGW243HgqmFeEpdDfGIoqJK8DJqzkFklyq_f56DYyFgvtOVymjWk78Hl-ECoKQzEJVFr1Mana97Wny-c2wUKbeQwCxM9YZE7O13Ka7dXI-m4mmJugH2rlVksSXXcaTe_GC0 -I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'api-gateway/etc/price-microservice.urm.puml' -pumlid: 3Sn13iGW243HgqmFeEpdDfGIoqJK8DJqzkFklyq_f56DYyFgvtOVymjWk78Hl-ECoKQzEJVFr1Mana97Wny-c2wUKbeQwCxM9YZE7O13Ka7dXI-m4mmJugH2rlVksSXXcaTe_GC0 -parent: object-pool; artifact: object-pool -Puml Server ID: JSV94SCm2030Lk829Fxf1cF6bWU1XYDkFtdcjxiD9Qc3o-LrPQvu0pW-_HnvrLx1JgR9cfrimf1wCD7XnW-sWsESsXPcicl0nFW1RB-PiYqp0KxwVo-VVTMKBm00 -parent: adapter; artifact: adapter -Puml Server ID: DSR14S8m30J0Lg20M7-wEMnDOiPMFDA9j0yyUEtUkzMHJTF7xI1NF4GSLzaxZtncgDVJgCPIpobzv0N2vOKtjgRHTziMI7KBcOXl10thfxB-Nz9dMJd71m00 -parent: hexagonal; artifact: hexagonal -Puml Server ID: HSTB4W8X30N0g-W1XkozpPD90LO8L3wEnzUTk-xxq2fvSfhSUiJs1v7XAcr4psSwMrqQh57gcZGaBmICNdZZEDb7qsCZWasT9lm7wln1MmeXZlfVIPjbvvGl -parent: value-object; artifact: value-object -Puml Server ID: LSZ13SCm20NGLTe1RExTXX2KECBOmfza_VRQszDxDnVBNJFiTG9pVOY2dteqdBdbqf3XK4ULqQbPFWmEklZcikjgXvV9W8Olwhn-e9ijjOpjKW4fv2zgHgypktq1 -parent: twin; artifact: twin -Puml Server ID: 7SR13OCm30NGLUW0n7UsCS42eyH4zdUpFbNVwNtKQij3qjjo0ICs8kTPJiMLUuPuVGnYAFNff2qdWvrk_l9wIEXfws10t88wno-4gKQ2-az9xsLaRoy0 -parent: semaphore; artifact: semaphore -Puml Server ID: HSV14SCm20J0Lk82BFxf1ikCfOn06ZZizfDVVhjRjphobFJnQi2ADv7pKwwEbaU6U9q6CPGwbVh8Xy5E7xvvFoNwPVjYGDo2bEC72b5URRgGeFvNqhMirF45 -parent: message-channel; artifact: message-channel -Puml Server ID: NSZB3SCm203GLTe1RExTXX1akm9YyMdMRy-zFRtdCf8wkLmUCtF72y3nxcFbhAE2dIvBjknqAIof6nCTtlZ1TdAiOMrZ9hi5ACOFe1o1WnjDD6C1Jlg_NgvzbyeN -parent: poison-pill; artifact: poison-pill -Puml Server ID: JSZ14SCm20NHLf82BExfXiYCJGOX3NpYzkDZRllsgTwjTgcmnmciV145N-rGdFMkbEZJ8OxMvo2rkXWSzE4lRxka7huj1YGyQN3UGMjgpdkh6Gdwlrl5QAk6_G00 -parent: aggregator-microservices; artifact: aggregator-service -Puml Server ID: JOov3SCm301NIGQGs7iRXYPa1g8ayB7NjuiKwGvtmBrbKC-Tq_hhY5Y-0HXUjKaS-Kbdepc2HrIQ2jBpma23BvvOTdPfeooCO1iEYlu0O6l63MDQKI6Rp-CKOWSE-ey_NzEqhjH-0m00 -I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'aggregator-microservices/etc/aggregator-service.urm.puml' -pumlid: JOov3SCm301NIGQGs7iRXYPa1g8ayB7NjuiKwGvtmBrbKC-Tq_hhY5Y-0HXUjKaS-Kbdepc2HrIQ2jBpma23BvvOTdPfeooCO1iEYlu0O6l63MDQKI6Rp-CKOWSE-ey_NzEqhjH-0m00 -parent: aggregator-microservices; artifact: information-microservice -Puml Server ID: LSnB3i8m303Hgy016k-vZN5DQXGxaJ_jzUcMtKXFcgSOZTgvV3oEp1Kl0CUhTScZtXNiD2tPij5Ka54N9ZfyySHjvv1ksy9CTWjGZ3i0UtVkcDCt5V9vFquX3k0a4FjCLqoPzgUjNDig7Jy0 -I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'aggregator-microservices/etc/information-microservice.urm.puml' -pumlid: LSnB3i8m303Hgy016k-vZN5DQXGxaJ_jzUcMtKXFcgSOZTgvV3oEp1Kl0CUhTScZtXNiD2tPij5Ka54N9ZfyySHjvv1ksy9CTWjGZ3i0UtVkcDCt5V9vFquX3k0a4FjCLqoPzgUjNDig7Jy0 -parent: aggregator-microservices; artifact: inventory-microservice -Puml Server ID: LSpB3G8n303HLg20ZUzqOxnMrYXn8d-oedjovJRIIEyfIYrFJckFAsBw2y3mBbNYodSw6mqDrYWqEaZB6mCDFhZmEDcbwZ4nWaqTEleEm5gDAyQmemlPsCOIOWSE0j6riM7VlrVIUfdPsmy0 -I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'aggregator-microservices/etc/inventory-microservice.urm.puml' -pumlid: LSpB3G8n303HLg20ZUzqOxnMrYXn8d-oedjovJRIIEyfIYrFJckFAsBw2y3mBbNYodSw6mqDrYWqEaZB6mCDFhZmEDcbwZ4nWaqTEleEm5gDAyQmemlPsCOIOWSE0j6riM7VlrVIUfdPsmy0 -parent: bridge; artifact: bridge -Puml Server ID: BSR14SCm20J0Lf82BFxf1akCJ4R26ZZYzkE7zxLljJgoIVfu7S2A3v7pLRhYo3r3l9u6CPHwJjAH5uETllpZhKbejsqn86v1a-CExQwj2mdgqv8-oyev_W00 -parent: servant; artifact: servant -Puml Server ID: DSkn4O0m20NGLNG0G-ys63cDbv0SV7HzRUnUy-QYkSOkONKwWU4haV6JZe8pjd2nt1MYIBatAZKU1XjTVFEoYvT3by60c3erzW_qdPiL9CY_KrXB8rfz0G00 -parent: lazy-loading; artifact: lazy-loading -Puml Server ID: LSXB3W8X303Gg-W1e7jlqu66gIc5zED4JwzRTo_lpjeaEwN9xOpO_W0mlEhWEFD89sjBWpHgMnDOyi90WoU-i7Ho7besHf2fmqJ_0GG_xo8BE-i0YlONDMtMdLE- -parent: flyweight; artifact: flyweight -Puml Server ID: HSV94S8m3030Lg20M7-w4OvYAoCh7Xtnq3ty-Eq-MQlaJcdow17JNm26gpIEdkzqidffa4Qfrm2MN1XeSEADsqxEJRU94MJgCD1_W4C-YxZr08hwNqaRPUQGBm00 -parent: mutex; artifact: mutex -Puml Server ID: 9SR13OCm30NGLSe0n7UsCS62LB69x6zWV2hrdTxKhFRS9Br_3c34GkHybxtXo3L3l9u6CPHwAhMUDuETldpnl4cqtUR1WBW5ASSlf0bvI53_A-bQHcf_0G00 -parent: mediator; artifact: mediator -Puml Server ID: FSV14SCm20J0Lk82BFxf1akCJKOW3JhizfDNVhkRUktP9AE_Bc2kDr7mKqx5bKSkYJeSuYXr66dFXy517xvvRxBqz7qo8E6BZDSFPDAKCO84zP-IOMMczIy0 -parent: page-object; artifact: page-object -Puml Server ID: JSV14OGW30NGLjO28FVj9iOCua1Wme-sxnxtzjvMJLeS6ju-9p3NbyZvoQNYZ3sMkWo36hACJhN5ms2dYszEXwvQB4q6r6rHv_K3JIwQndwfW1Jo_npUyupUNW00 -parent: factory-kit; artifact: factory-kit -Puml Server ID: JST15i8m20N0g-W14lRU1YcsQ4BooCS-RwzBTpDNSscvQKQx7C1SDwBWi-w68--vD6Gur55bTBAM9uE3dlpcikcotSjaGCCNTLu_q8C58pxbPI25_Bzcz3gpjoy0 -parent: property; artifact: property -Puml Server ID: FSV13OCm30NGLTe1YEziumOBKYMEPN-3s9wUUdlltRJst2Izlmx0OYLolihUSEGdGxnEXIXAdODQpul1Jby-UTaasgwBCI2kGOFZ1pAV9ewR1FMVaZwAvUWF -parent: dependency-injection; artifact: dependency-injection -Puml Server ID: RSdB3SCW303GLPe1mFTkunWhSGG6-PEesxS3zFQajubIpyPf_NL6B7y363xra3XpJsUZgS4QbUO0wVbWeC65DvR6BeUMXH5iwZ3GVu36YxMnqgU8NamXKu63_aPD6tNbw5y0 -parent: layers; artifact: layers -Puml Server ID: BSR13OCm30NGLSe0n7UsCS62L8w9x6yGszD3t-bDpQhc9kdwEO0H2v7pNVQ68zSCyNeQn53gsQbftWns-lB5yoRHTfi70-8Mr3b-8UL7F4XG_otflOpi-W80 -parent: producer-consumer; artifact: producer-consumer -Puml Server ID: PSjB3iCW303HgxG70Ezx6zTO2HKso9_a-c7VtUX9y-vA8nkdZTSPiVm3O7ZNeyUPttGscXgiKMaAz94t1XhyyCBIsFkXPM44cpe8-WvODbiIMzcdfspXe7-jQL9NodW0 -parent: builder; artifact: builder -Puml Server ID: DSR94O0m2030LhG0mzzkC64KXs26GzlNZw_TcRLADagJwOWOlW8OFcNdE79B9wkN1ccKUdLWoGS33KwySMdalEioC89C7Jhw5zYIfNrIrFybhPUHNLu0 -parent: specification; artifact: specification -Puml Server ID: LSX14i8m20NGg-W16lRU1YcsE0d9mCTUNxVkthoxkVJQjQBVJc3bWoZuQeVXh6UbXao7EfhCGTRhOd3Gcp-yxPfs-BOOqF2amVa3vLAnbmd3ffD2_gTLZBPgz2y0 -parent: state; artifact: state -Puml Server ID: 9SRH3O0m20N0LNG0ox_RO2LQqz867hg-9jxNpKLpZLt2wdG2mrSYuoST1MTiuMAvAqIHSczKQZmCDhhuvcKNBuSkWm4nTMhiNyZ141BaVocifH6jlW00 -parent: reader-writer-lock; artifact: reader-writer-lock -Puml Server ID: RSZB4S8m303HLg00MtUw4R8cCP5bZpwuVL80jttxx4gIZTFaSKOiVm4OxdhqEFETpaPJWpKgpG5TScEWmGU_M1fxFxGiZ61JXu5-1nXZOolR-gqYaoxWe3-xfeswSiWF -parent: interpreter; artifact: interpreter -Puml Server ID: JSf13eCm30NHgz034E-vZGaM62Kcih_BzQ6xxjv8yr6hBJT9RzC1Z5Y8dE-oAuvSCyJhPH13gLSdRNapsEdaBy-RXEus3mR4BQXpl21zVnykFmlgVvVqNaRszW00 -parent: template-method; artifact: template-method -Puml Server ID: NSZ13SCW30NGLPe1mFTkuu0Lg6n0vZjPlpttzlIEFef6bN1zDM3jDv7paw-E5cTiyJ87P22NQTGr7WOxVVZcL6NtQwJ5WFZOPBn_88WjPKWoGPkL1EN_ShZb5QPV -parent: feature-toggle; artifact: feature-toggle -Puml Server ID: NSZ14G8X30NGLhG0oDrk8XjPd12OvCTjNy_UthpxiAPvIBhUJc37WyZvgdtWp6U6U5i6CTIs9WtDYy5ER_vmEIH6jx8P4BUWoV43lOIHBWMhTnKIjB-gwRFkdFe5 -parent: business-delegate; artifact: business-delegate -Puml Server ID: POl13SCm3CHMQGU8zUysgYCuBcJ5a4x9-l6_Fu84tzsgvYxf-Zg06HyYvxkqZYE_6UBrD8YXr7DGrxmPxFJZYxTTeZVR9WFY5ZGu5j2wkad4wYgD8IIe_xQaZp9pw0C0 -parent: naked-objects; artifact: naked-objects-integtests -Puml Server ID: LSmn4iCW30NHgoG70FMvZGmQ6ni48tt5ru_RT3kls7VJqgDAM7yTmF8FaV6TzuOZjd2nCXMYo6KEQZrk1XkT_ELKnTkkQJ4Wfaw3_GbIlgIckPrIu2Ge_vBQyziX3izX8wyO_GS0 -I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'naked-objects/etc/naked-objects-integtests.urm.puml' -pumlid: LSmn4iCW30NHgoG70FMvZGmQ6ni48tt5ru_RT3kls7VJqgDAM7yTmF8FaV6TzuOZjd2nCXMYo6KEQZrk1XkT_ELKnTkkQJ4Wfaw3_GbIlgIckPrIu2Ge_vBQyziX3izX8wyO_GS0 -parent: naked-objects; artifact: naked-objects-dom -Puml Server ID: LSZ94SCW3030Lf82G7zt8mkDZOC4eyDkF_dcjxFlhZIoSTfudH7BDm33fnuzpjpJsMXgi4QbAT17FXXeSE6DfR7tGyl223Pr4FGVGF73hSpzOWe73lgVqgRKDAahPNm1 -I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'naked-objects/etc/naked-objects-dom.urm.puml' -pumlid: LSZ94SCW3030Lf82G7zt8mkDZOC4eyDkF_dcjxFlhZIoSTfudH7BDm33fnuzpjpJsMXgi4QbAT17FXXeSE6DfR7tGyl223Pr4FGVGF73hSpzOWe73lgVqgRKDAahPNm1 -parent: naked-objects; artifact: naked-objects-fixture -Puml Server ID: LSX15i8W30N0g-W187jlaq9igH1uoO_r-BfrDs_kJKkFAc7zTW3B7qJ6LzuRZjZ2nSfKY2ANEQZrk1XiTFARKnLlkwR5W9Ww3VOVIFabDStjb08dGVcVz6mVX4aE6td5w5y0 -I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'naked-objects/etc/naked-objects-fixture.urm.puml' -pumlid: LSX15i8W30N0g-W187jlaq9igH1uoO_r-BfrDs_kJKkFAc7zTW3B7qJ6LzuRZjZ2nSfKY2ANEQZrk1XiTFARKnLlkwR5W9Ww3VOVIFabDStjb08dGVcVz6mVX4aE6td5w5y0 -parent: model-view-controller; artifact: model-view-controller -Puml Server ID: ROl13SCm201NQGUm-NSRQgE42h258Lw_wR-_qvtkoTOaEwNBuuoOwmNWkEl1SUOx5taR5cHHsr1WoOs13X-yi7HQV5YP645k2nJN3Q2ZavIBQPVVwqFajXJjVwdfMcUgV040 -parent: proxy; artifact: proxy -Puml Server ID: 9SR13OCm30NGLM00udktCS62eCI9x6yesrEfx_Jcehd69c5rEe3X7oBZE-q5HwpXOhahH95oRrHgt0msEldYPHClkow30J5rQko_qB3-VKYG_qjXBOrezGK0 -parent: memento; artifact: memento -Puml Server ID: DSgn4OCm30NGLM00h3xR2AC3SvRiaxx2-g59zugtDgiz3qdlomNC-10vF-Lik7BF4A_388PIXrBh-J3OwUOlRuT4EssR38XRa7Ay81Lz_o11_RkaQvcf_GS0 -parent: decorator; artifact: decorator -Puml Server ID: HSV14SCm20J0Lk82BFxf1YF6LaP26ZZizfDVVhjRC-bPDRs_Bc35cyZvAMV3bKU6kao36ehCGQtdms2d3z-yLursshuOKBUWmV43LPNfZEcaaFzA-YWhH_y2 -parent: data-mapper; artifact: data-mapper -Puml Server ID: JShB3OGm303HLg20nFVjnYGM1CN6ycTfVtFSsnjfzY5jPgUqkLqHwXy0mxUU8wuyqidQ8q4IjJqCO-QBWGOtVh5qyd5AKOmW4mT6Nu2-ZiAekapH_hkcSTNa-GC0 -parent: caching; artifact: caching -Puml Server ID: DSRB4OKm2030LhG0m_rrWyWaE0bc-6ZxpujxsbMKUXwSrfSMCVq7OFYKAj5oJsUZIuCr2bq3fEU3WGOdthWTx59rcnZ1fWu3_GqGKXEjm47VIzeeCqV_0m00 -parent: reactor; artifact: reactor -Puml Server ID: DSR14OGm20NGLjO23FVj1f7Hx2Ga0nzjVxtuJc-f9YrtJM-V4vZn9NA-or5nvfQXBiEWXYAZKsrvCzZfnnUlkqOzR9qCg5jGvtX2hYmOJWfvNz9xcTdR7m00 -parent: iterator; artifact: iterator -Puml Server ID: FSV13OGm30NHLg00uljsOu85HeaJsTzB-yjfBwCtgrfjUKXwMovWneV8-IcduiezGxmEWnXA7PsqvSDWfvk_l1qIUjes6H2teCxnWlGDOpW9wdzAUYypU_i1 -parent: callback; artifact: callback -Puml Server ID: FSVB4S8m30N0Lg20M7UwUL4qYOciUFGXxSE9s-wp6sjjKgwF8tF6YyXnjxtdKMk5E5-MOjdu6jIrRYIStlXWsIJwRij4fhW53SGFn51TmIT9yZ-jVBHPGxy0 -parent: repository; artifact: repository -Puml Server ID: JSV13OCm30NGLM00udktCS42eyI9xE-YRjyUUtjlLQij3qblomNCU14vF-LKNBbdYDTX44EfevEsV1ZiTFERjqD2Jzic0-8Mr3b-89SvGZ7yGuBwrvBUoypUlW00 -parent: mute-idiom; artifact: mute-idiom -Puml Server ID: JSf13iCm20NHgxG7iDdtDjH62PKX5luarq-MtSsJvgtUHdR96AyTcEj357pLJR7dDvT4EnpYgEqmqf4NWuD-V7BfidJpCXcGy4N6wmcoX1Jj-lo2ziUQONMcZHi0 -parent: prototype; artifact: prototype -Puml Server ID: HSV13OCm30NGLM00udktCS62eCInxE-YRj_UUdjlRLfx7fBUbmkmU14vF-Lik7BF4AzJ8OfIvw3Mys6mqyrltWw9Tkfc38XhqE3uWSmd9Zuc9AZ_bVHHB4V_0W00 -parent: step-builder; artifact: step-builder -Puml Server ID: LOZ93SCm3C1MQGQmzUysYYqaAcJ5q96i7t_x8KXkh4soKvfypeZfNm33fnuSP-xfPEtI88tQhW4i-M2WmGzlB9sS3oqJ8yZKOQ0lWOLPzcJfAoZQtwXfeyuSyW80 -parent: double-checked-locking; artifact: double-checked-locking -Puml Server ID: TSdH4SCW203GLTe1bFzkGv1J6qGFeLc_MI1_x-wzkv94uJ1vDVUrFm26LwxTMnonsMYgitgcEQ1BNEXeyCKVfiAxLqqBtTbqmy1z0ygCGpXHOpgv99bqTgt0JW-LmqPUCUGF From c6354c48bb0f62c3030d63a824812173263adac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serdar=20Hamzao=C4=9Fullar=C4=B1?= Date: Sat, 2 Sep 2017 21:52:02 +0300 Subject: [PATCH 43/45] - removed optional classes and interfaces in order to simplify the example - final fields are marked as final - removed unnecessary temp variables - added private constructor for not instantiated static class AccountAggregate - path of te test file is corrected --- event-sourcing/etc/event-sourcing.png | Bin 105812 -> 60339 bytes event-sourcing/etc/event-sourcing.ucls | 252 ++++-------------- .../event/sourcing/AccountService.java | 56 ---- .../sourcing/MoneyTransactionService.java | 85 ------ .../event/sourcing/SequenceIdGenerator.java | 42 --- .../event/sourcing/api/EventProcessor.java | 48 ---- .../event/sourcing/api/ProcessorJournal.java | 48 ---- .../com/iluwatar/event/sourcing/app/App.java | 50 ++-- .../event/sourcing/domain/Account.java | 71 ++--- .../event/sourcing/domain/Transaction.java | 98 ------- .../sourcing/event/AccountCreateEvent.java | 6 +- .../sourcing/{api => event}/DomainEvent.java | 4 +- .../sourcing/event/MoneyDepositEvent.java | 10 +- .../sourcing/event/MoneyTransferEvent.java | 16 +- .../sourcing/event/MoneyWithdrawalEvent.java | 78 ------ .../gateway/AccountCreateContractSender.java | 40 --- .../event/sourcing/gateway/Gateways.java | 50 ---- .../sourcing/gateway/TransactionLogger.java | 40 --- .../processor/DomainEventProcessor.java | 34 ++- .../JsonFileJournal.java | 42 +-- .../sourcing/state/AccountAggregate.java | 8 +- .../java}/IntegrationTest.java | 60 ++--- 22 files changed, 207 insertions(+), 931 deletions(-) delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/AccountService.java delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/MoneyTransactionService.java delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/SequenceIdGenerator.java delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/EventProcessor.java delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/ProcessorJournal.java delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java rename event-sourcing/src/main/java/com/iluwatar/event/sourcing/{api => event}/DomainEvent.java (95%) delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java delete mode 100644 event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java rename event-sourcing/src/main/java/com/iluwatar/event/sourcing/{journal => processor}/JsonFileJournal.java (84%) rename event-sourcing/src/{main/test/java/com/iluwatar/event/sourcing => test/java}/IntegrationTest.java (59%) diff --git a/event-sourcing/etc/event-sourcing.png b/event-sourcing/etc/event-sourcing.png index ac7192b195fb67b1d67c1b5c0e5fcc3a5cfd6fb0..0b0098546300e34203b06fefec325f0a81e1d1f7 100644 GIT binary patch literal 60339 zcmagG1yodj*EXyo2B{K5ii&hMlA?mr(j5*BLw5@Z2t!DBNH+{IbTc3=-5`y0NY{G? z)cb$O^L?)6TEv-sezEtpuU+`PmwJndMuc|b#tlr-cW-2G+(3x}{_ozq1^mRIr$+6@ zjWs9HH$w6b@#_g10ne2j57l06Nj`t3RRgkqm?HHlrS_(XWs?~$xcmtVDS0P@XIH~* zXA6mF?kBA&rr5;VHE|pzls?lBYS~OCzhfm!=!!oM@L;)BP4SNJKtXL1L+H!nU5=o>7N91fT1kcMR;QJ0zZAvnpL5!uh%-S^h6L(-4*%VM~wHD*cLDW zbVhvSw<=%f9{&Kl;;Yjmzbk%);BP>j&{rrUzti>hcm4?7SFwNrlF+{6O{f_jG-u2` zHrBI&WrE_mp_#|)8$}ZVX5n^%hY4~@m`ITwFKOsZsImLcoBqdp6sR_9@|c|;yWD->7xV6x*8YYHJTAO+V@Vfgza;gXCD zSxO!c7NgVfIEHAb$G$ZJlDHCNOBk{_;KbH65-$%#Hq2|ZkYgzS+{G}qeT=LJzd!#8`FRmZOc1)vgYHq_!Q_{P#Ug@`LK9oRaINv?E<~4#>{O)2V1b3)Zex4c$XC7I9vX?{P(r~ z0N3Jm$Ht1qMB)&1N1&I?j>$a&+HJn^Md z^#g{H*D_lHjg^_j|_j-nsAegQB5& zmv>O<^B@tRKX2#Ks?*sYD7V#&Ek#`X$SkZomUG|EkiHPWIknhJ7j#*Rm@uz&TJDaT zPB+b}QbwpyVp-8UyiX;>+XIJXzj+R#+vwJQ7SQN0q`*_si6Gk8GVff(m82xeg9i~%>i z4_iu47J*BDNDlw-0ihgvWyYnS8jivW`CK}OhNq@Z-7V+cM<3Q7rfyvxHzIoLxs77a zw}|VHULIc9Z<)F*Y%$&E(lWf+U2bH^H8ebcYYL-L&x^$}p_iyLh0RTWk-4F$i)^$~b3ZvRD&Z_~wDQ<2JCh$9qS%4+Ph7D6YAwg|cHD~bM1EJ+_cQ}mx90n~ z3TltT%BK#F56$@Y4U*1UBi?E`#GiKx)F1ktPM<{C7tf&4`OYjX5WCXr;YyIDYTp6T zkv-EKlO-51yknV`UtY3^p!78?F9`yxb&qZnRwyTVJKV-XbL1Z7F(@HZ5}W{E)@}J= z@AigCwoqoitSJ_kT`J{FT}ty{%RvikO-}AnIJNFHf1`ua!71%#lKm2KM|HkaA$`5bBm6wKT0?bB zRwWTbzN56O!C}8_{!qQXerI%i;&SzTeMWFoKs$E*hH9c=t4}Y|6}OOEyq8ylWb}-U zb4S1=!|9)t`+!fgUYJTd?6sd$YsvjecKK@SpVBbZ+MU~)@Yb1aGtxYW>hTz4ITswpzqux!QHj^Huz%VdwvH?%8$;NrGt%z4%gI3Q$fk9xOyRX_D<{=g%regByg`Ym;NP=dbg)8+% zw#=M;P+rgHwdVjg@OS3cU5RJFTq`&deqCtTUAgK7*)1#+CC)K=@U-*!TRzOEjyWss zciMlT#9DLgH#5#zzS(PknJ$r@$MH2Da5XMIx_tgi{iSc1V@2!zxx)gKbk0hOrJjuy zB_?hrpfM^=&>EEmVt-}$upcA4xFSw{A9*lG7B83A!NOOPo|{M-iUJ-);5FUjR5;ED z&Ihi4_{3iJ&rnXhbW;vZU#N=2xwl3|U7bR4v8$-8_Lw!D__upVS*J)@x2|QC8cP~h zUdf_*Ol6v6Rgzx!Jap72r1|jk^tFcdD09U>X8b8R^9+l9PX$C93!7ytrOnARg@pyM3rwamcSg;VMa-+hh4g9!LfWqB~J9GDp~F#Rlpu7ads}}ndGYnS96cvwn=|;^C`}x( zI{m4A!f}zCeeG1@(cnRv-{Kd0;~+{;Xz|R#qH2!1)%T+ZVsi;quWIh@zdXTe^UcgG zTrtS6P@blIevu#0=6{&Sp|^AAsVUw3*W<+pz2Z#pQ~H2*Pox>XmpMjS^G9E=@|0uU zWLZiUW?Utr%4SQ*15`N*Lf(sVc=hOywpug$!kNUf>W`TVpd1serO^d^*k*G_{z^A3KZ8hi_#r-t?4E3qy`DXlbuN zIC970C1_(YTyUP|`;}%qBCzyIqF@?c2kU52qrMzuABA*CNjbzkE~AByq>K7TEVc(C zrZOX67>L*84q@aswbwl9!wTyg?3T0nM)hoRrGKVl^j7}G!%u?pdoETjx=F_41uier z_GJC}7wLb1#c!$S^&+9D)0sON$_bN8zB<{#SZG)(L*%z2^?%@B8uAhN&phj`l!Qx~ z@GT^6WO0CK7Da+lLFn{P9=qZLuI}AFatrA;eLd&69Y@G(8jMBK&m)Nw2NwXXv0aWm z>|H<1+Y1a-osUngvr&GcuYM5RAQbD1Qf0`L2|c(a_0>iC4y~Ri;2@B%mu;P2T&{2E zT3Z?sIM^|NQr}={>d>OecAU?Z#Wvqj);yxFd z<8u14;Qszd;_-#_3De~s_GrB{so?RqyL?RJGpc+%d?3J z^u4r%WU_LLZT@?vk2$8Za5mWZ6l)xJbEIrx9x*|AncFH%!5@4@>ofwT#XE@wLv>I) zV8$VwnN_i=ub!&1%G_W-WEzaFY+FwpKlK`SyT zkMZFH7&_z~gpzJ@>n)(QS$RN+f;7#i%r5uW#&#Ui!!mG%)m z(j6F$gWc^9dwi3ofb-~FnK5@=pDJI6N7wDHmh@sIYOT5bN=PWnHiZ?l1ey-ZgXomY zTUay9zTvVPsRjCfwd;8>-Ir+ty9J{wt5$ArBi6`M41gI+cO!hwE61yE?s*!@DT zZuZ~UbG}}{tqtLN8Ya6~X#V}w-mXdf&Ny4!-b~K(o-J@U6VLfQPl44Rja+)v*Mc3=z9WDA2PSpWX4knmy&fS!#QOj3P# z)kN2h(O&y(Wy9Vo(5vAdru4JFevjW zVrKe#*VX4UvKbGw$lN~Vw_acd%=jxt|Gk`%27S~U9NTStMpE? z%f&B=a>y|M%WNbr-C-O?dTy`yYA}edVwC=RSI5TP4v+T^oZ^CAf~GYVA0n@hPXpr4 zA8%~i+7dU=Off_P<^JAfppk_zgvn|(`!5qtW(J#cxx{0hX{$O$)F++O=e zn%E0bj(|0L*IeyhnY%knPSx$psO)ODrX%=h>vt;pWQMD!_7sd4u5YCD{2CpO+vWq@ z%nEDM4uaE3vu-1AmuBFy3wV_--&Z<#zd~$&v$K3|w=4`gR34kxg@e9`(fr-1c%G=- zU$cPnyh+0p)-Q8}F$ACAEHibc%ef8Yn^3T!Jj-*w^6)u{j37t8ct9Csh_vbRl}01= z0jWncj~&^Jw{Hha8mtS<`-Ekcc@gvKS$hFFkb)9lxBBX7GieuNXW8sGh5PdfE&B2* z1-69}SVUwgGeIV}>GG2*Vx2>93C|ba1t_}7#iwGbH_NNP+ zoaN^H?3o=JKw4jC2O>VJ7}?m|p9r&4-`p^+@d=BS_g++WdsWX+3cKeM3KG!}V#rUF zX;5RKS~lS|nSGOy;C!Z5N4M88{xtlxN!05Xmf52;y|;Gm^|K8jc&fmATUE39#AQCT z8tKO)FD^tho#uOI<~!90tqj5fJPniJ`Du9{*9lRF=bxo&6TYXx0eBlSGSV@FMocjL z%4qz>$Z3}HUzC*NQP>b2-q2m8*H<3t4<(}BAyA@?tWhq32D*M-Xiv##)R(ifYU=!zHfRR}%}3>A@mE%vk(iTioCeF6JiMz}4))%95G3hx8BuL>!TrqD4Zij0I5!;Sfat&d9f%rwo zJ1lW0DeP@iZovl*e|<<7!l-;~Ju%X9`6jReMb!C+3wNu)zln#{T^~OG-O&fwyH6}K zo8(E_4P28e4xD&Zo&^boVZahGR&)sYrPNX&Ch?Q9WLYXF3Z)kdh_W zP37!iO`>5IEqk8ZLUiQ8SusijLg^GI@VVH&Ctd9XRxS?9b#=?SDG%pcp6+5in`3`E zcjhKMbBG=g=oe#BJ}(y$CE+FzSTFrNa!Wq?Caro?+m9gpcr>k7QVimy{GDxqQCSn{ zbe%~p-DAsk)eKQG3>@R&ufqQN8mOO{bD<0utv*Y*SH3{f7Um-91;vvUH?dsHW`$OL zAoU$s#BqzJBn;NIh5>7eCmUAmx7a2f+owI?GEV4b*0W|uX!Vs}q=0q6o3FU+iAqhO z;-PvTGMJ!U>>ValUV^jzBlq@O&5vAr=PVt^7E(m%))q4jEd~u241%Nl^hvIPMgF zTn3Kamy(gifnKW~`%`Os-krjEG|-EVd>*_X;3>9@poGhri6%@TtjuX2Rktog&4o^?=S}mNSiu_k za$F})pf~?)6d)hRQ%TtpX)CwW+*mtlUvgZdqn%C~K?7)8q5ZgGQP4ao<(u4hMLyq{4l5 z$u035{n$ibmgFq`LP?DI(u3F~rSC+f*hlpy+k-6L$Cc38$=dE>R8`=VWYbFLyeq?j zyDn<`>Vx72(`JRn$ZZRWU77c9mD{f`p+Y$&1`exMa^TUiPK`j4g_k)Q_mPX~7`qN6 z+S#7sK<@U0=1h;U-={cJZ63lKwmNWP{P657q z=Axdbqx}q7r~GFC9_c_*zqoy%RehvZfAMqXV$=OxXZG+Bd;MQ;$e@e+hBRb|#brTi zbdp|bJx}0C#;^`AtcI;p*;?9CB`Cl%+qDpiwIPPgto@-K0DlcMuV?yIn2^Me5Wsa~ z652zCOe>zEmw7iSZ`I z@)e#8u0ufvxxAi|{=^;ak_f4W9oJlgk;yxRODX{AmL`wKEhvvuAS} zCwSJsA5{p$UVr;E$jesOy4^RLMZ#7mM&NB?{@ax=UnK(PNsOtE^Q6bAHr_^Ke&bWq zWQBckLet65^>^d0yVRv~^_vf78#AqE;KV5D1|1-t1hq98-+KADt@&mS{0feY3L2sX z3Sq8;0hI^!0p-pDpEb^BEh=CznZgn0TFpK#@}kyxl$nc3jk{_s zE|V7Gg-;lKV?{SRukGJrU?r~KQ4FQMwgln3v4f_N`b_lcZed16w;8UO6oKr1W0}kQ z^G6mzpb+61HNB`u#M{N*I?y&QKDUutX>+Z!6uE=(b|GL5J-*v&U&= zDn_pg0Id&$w^rO14yXi6FXx6jXU0E}jRvpsMBXgQlbgySD;;wpVO0D`%)3vVJzd?& zER!}|Z9)&~cR-tGudVjn9ZWmqJb84=_j2}RWePQm`Sn$}>>`W;7%?(UA~uHaY_~sN z!>DLpa!!S$ia27E-s1hIDc9pFJ!c|TM&Ad(4utS>~=i)P`5O)gJ&<4?>uirYGur}k59>Xc)_`9tj#A|4J=XiuZSw;^#uil>y!%k`ufmxs zv|9>ll#`20`(h!E@*Gt$uFpCm!Ya_J8r9TVa^p+{oktBzlS zfK&QW!b#F5p~E*(d^?a_I+LX41#6IV#xpIi#FBgK*jS>PU?s+ zGRa#VJnxg8Jng*sRW_^()4u7e|N2aEh2o!72Mih!vM4(%*H{b$_}vs@Pbj} zyK72IMDs6V3RWVDjMywcjROaH*E~|BCCoQN@eb^<30W5vHQi22hPA{zI7H^jRc_i< zF>>_XShWcTh!^{h!;C(hO~%aPOEd^rwmegD@iHfN<67O*)(MB3#;FYOm0NF;fpXv&_%*2!v|0fHZ$k87{h@27oHfKcYj-+IhmC7iDv(kw>l`s-P);OCY_kByi~IhYu@^tM7F z3@;9okGojVLFo9mXia`+S$^kh0o%5B*`Gh;o4Q!SuD3Z~G+9SEmC<+`JtPvhtUpKT z*z41hOQFNkYA3hxGz8pFDzLqv%n{|nOtk;~;J$-|+YtANJ@-7JsFhwFIXS0>yYT)AELR9p4f71_<5iZbaGd3?#h= zi(BXHM!nrmx!d_b{rS}8Nn2AP9eX`8_8Xnsu?=Qts&_c<5LbG(Us!a7=#5{pQJjJ) z+_NQx2s^nQg9q8yVr|~O=uno3EF&F166&%m!*tZ?ppG_Sdz6l7sW?xexc<<#}7`^MQi&B530KLH}#!KHcLe(LnsFiI~!?uyU>(`g8R-<=2q zQJAEhR8{JRkjeLiC9tX7ewsDRx?A}9#Z>TcpgBTHRjmz%*6`X)zG*i29p8LZdtKGns6u+CieO0MEPm zCwWT=)cujUvi}3`m!>sjU+Z-Drx|ZeMF5(RZm;x;^+u$Vp^1oxUe4oGDBceP_8Ijz z##@Z@0;bE4m;`6uY%vzyxM~_g;@0998ExY4Ea{<6@;w^XTXsEOQVgNH`gTjO=SIld zOaSj=!GlSI<`DR(uijn6;Fos2$y{(m?>n^;BzdGCLUim~?benG9=_Ixx5;~8bKSa5 zrP*tLo0n5{vhUsk2gb=+z`#@LHkjr2uJYcwDYUD@-y)kElMsM77Fj_(8Sv^i?w^Pe!Xv8#x9`mRcDwsz6P_~4LZa^MysZ5lF$CF33 zSlC2a7aiSv-Cjmpw|>23HSIK_B-xt$whWKw-ScmZ=Q${kZ@==1k5qbMTl1xL5oSXY z;^V*`6q}7fkWDYsEKMq2e1^>KAQ|m7IX^AL7Hm?~xs27wQ@+1CPaQ|s*v_L5;?=7$ zIDJRj{;^}OXc#N$$7DTh;e>mb;yNZAyG1^96h3FlkAIf6jXy0=5nLHugiF=;jrYDW zeYeHE*M~vbujNH(FL?*7TK=|6TqW`tOkqtH4o>;TdAGgxfp6d;yAu0lvZ15us%>F# zg|#s;M){q8dySLBz4F0u%Vz`C$`dyt2Q-jTByGd5r?lja2v6bPI}z%DkCx<)WK=7s zE0!sEHky}Ij%G9MEZe{c#gNfaR(Lx;fl+Iwyn5<~C+*>dr=*Mr@}xU`%*It4dY^WS zUt{W<{t(ssEVkj=(&ZHshWC#obVk*vkt1yGd*3d1$FP`1vD+O`?v@JEYCIw8U*Qi4 z2HG+M;ttari4Yh{ZQLO=8tclPOT$<>!JdS8I-#!;DN`F*-%vQ&d!+w4e0A)*>4_Y_ z8d;S*=Oq}2YnCx;tMi7cOfKP}%?L((T0N_~t>HT~bcJ#OrKpi;zYD5=(>kxTE4)>( z8(5J(``^mfw|%ZMcycy;Vl%@_=V+Of=wot=$w0~DNAij$umo!+%99S5`&-Skn4u``Ys<%7B4Af{fv?5kDmhTho9OKUOLUq-BWFF${jM{M?7(@jzGl za$;f|Ygr=S!yx|D2Hls3<6-h64rSSdsEtPp|Ht0m@<}C$n|J);^U2=t!kJB5nTl9{ zZ`fTXS&nm!T`lC%cz=VxNL&ILS5Cbj?JN1|;RR7`7*;3G%fDLjJ`gMn4a^fo;wEXZ zc!GH0D$dA5+^ftY&{>I$Vi&Li;@dJyD@8BV^5Z^l$6DPiUc~CL)=Vc-2?JmcBilb` z{P$$pKl^@u5D{hW!&>FlxN#y-44-5S;^!#tFda~dKtMnCc`7U@RbRVo{{Bg+jx$*}${ zSl4-NeI4&YJVK0J#LSeb@;R1=rn^s8A~GI-hl%3tZs=MQz7W)zd3f&SfUBo2VT8R~ zv_0uX^tN%ZZBYJzyqqPG59vRST>?|p4fOZNG$D9I8VCJjhY_Kq*9ZUGF0J)& z!z+4!y=kW#JGTC1J?7_xCT1+WN%{pXkPiYiqrOdAkgfXIt<`>3Ct@uuuz8_k-N z`^Nmco>(Bd28~o!w2ZIzQN?6CHDVn9_97DOyK+hpsUoSEQwgf+m-*D*U^>J*EZB6} zFZp&os-_q;J;iEx+{OE)1nbN9o=DeRY0}-)nn_>yACe&0zVaF{@ks+!Lu^(O`7LIK zOEGs?Os7<+sP657pPS=}X3NG~7EQ>w;hBO75v!PZ#&2Wrk>`6Qj?9b~@sr5fA{fn+ zjLy>wQb(~;yE?-Gp?%_SWLDyI#pi7rQb0 zC5O(=@l-<29)^>h(E9@%B}!-_NzH_G@s@2mJ=Q-LQwAofa=f9a4Ii(c_B)lx?4)M4 zQEX3?`Qk?9m(P_TOaw9+tL$SOK=QRe<&rQMif>KOXu39J8Q+0e<#k7` zt=7NFk6w{oog6F@rzlVDN@jk|UlZ+nQ3{WZRLQ%}nH?CYF(uk_9f2#?bx(R&`iJR}9g9dyf;&hIdAx?)u#gUJ8DKka7_)e+*Es~PQU7vbAZeDY5wi3aa`KdNF??$l6 zBcK$#mZU=e({C_5mb3lw{w)226W>#^&e8g(XYp{dRyrpUAwS9ja%!aG`cHZvlZ)cp z&l(G8>sDyZuep%`e}6Z}V?w1T7D9+M5R$e3iP$h0$o;4LW-}zN>WQ<~oRI zCH}yscd&GJ4GN+mtP|4--ZD8RrdJ+CtO!yI`=fBU`|EL_Cuu(pEN37j9HNaH{KM0qFH5PT%`L zUF6I_Py+#zql*}DH#WfC+yDj|;2k^)O6$6Abw_yVxg{Lt9*;D?5b;`2nU(`!%_k;l zlp?l-6`(mg-l4xzl~ABnvD2MjMzAnF*MC(Y+5kt<|Gw$p(oB@rTfETTCFJ9vGKoio zu+Q%!@&vo@wlNOd;(84P>W+1M|EXsj9BY9p&J;`IQ@w%~>wsKZnmRo&6Y_UaCQ1-f zYKdl^lxJF5`CB$H%j%3ZYAKM(I2vOl?w?+)tCT>~(n zO>`t3&aIk0SWEL0(tY}BC{NB@DsuamN?mV7{fN^9fDc#Y(5UaWye3J3MN z2+GiHvbvjsj`cxF!z*Oo^lki@>4I+-EBxN{zz5S^c&FOq7xmS0{_P|$>M zqPrT3sYICv^4}lI-yS?2$$eI(EC6|n528~QwFe1Xo-OEpuRwiAmgUGfroMaYYFMS= zE~9!ygPK6Jv}ub4XyT_$bhd_;)@8cZ2?a97z1q)P?aBYngxei!eYc* zO)+aCG(3`=rTYkWH`IOfh16H-!Ae}`Nk z9y<-?g7zbg!)#tuU=0JoV()%qu)s$F=Qwsk(xhH5_b*fnpE2TXpK%{NjjvE4exZ_3 z<#jA<^bLDVUBs-PJIwduDSaH!4Wa&IoPA)H(rBq-;Lr;WOc`x|EGa38h`^gLzdUrm zJUlw8=rhFdZD!d8^Is2I0Pp@EY4Mfvw7mCUJ>KG-ioyP*P1{CuP;Rn2d1em!3p6ciNg zO&TaN8~k?!2j1ZDzj76Fz+}p7Xk~Qjfs`*4(`8!Nmoy+hZTMGQA3~%}atmBm@@)a! z?ComVDyT<_oJZS^Xw)vMs>)&7+IQ;K-)jvdc4?o}$Qy-m_n78(^Cbwynso?a$1s{x z&BbpW7-ZkoIIoFPhAlB(Y1i1T`8or#+WixLrF!e1tLRaWoo64NTC82%Q8TP%2wnHA zSjM-9;E;dQ8n%9$rAzv0kEwI(*Kt9MYtE8FH}!j}hb#x1topd4>UnPXKQ-2$#}7|* zSA06jZUlx-K1Pv{krn3WpRX2P(C!t_?M_Wi1qNd3>6JsffwHzd;f^tT!83!IxYu(Y zrTAHdK`SfEn4mZ=fX3eou(uJkIt?Qmci&lEG~Xz~UT>o*&mOO)OYCJ>seOK!%`+p< zA0Mwrw?TU(OU<5eC&?=zbA5`!tr<< zs9ZGbfJZnAZaI7a^M^SNPp+xXEaOr=NDBX|Q{FE#aa2w#e>K`=@J|yRI(sIs z3YJ{$9F0-yJdrzP-*cO8H1B4#6Du^iIIvX}G=E(VImd&Y(Os0kk~9S}x08%;dMmx= zmv&c(okh?*YhhvnJytp}=U)1F&$=KkE-qg&cVunsKsz_D#10|F<9qL&MxZGpr?`Qc zk@;?i&tq0uenyg>AuWXL5zNSZ&IiuO(jyc4UTzJ@wsEM_v&UWU!H4-c;#f&v;rJs8 z8kgCmvWm(J9v-XpHboVK4gY+5OT`hEj4%4@T^rji#}&#Zf<^<=62w5V_I?EGUo^%` z9$DL27&$)F&&`vwMR4llR#Xw~u`p7t0PT*?TI+AnfEr*$TLb(akkGUt;Q_zMRTVc93=Xu*btyfS6SJ9wsvrEFgB)A z$J?7t2mdidn{jsPD0h543HQ7B3OFjzxm*2^@zC1-`MIlQjweY>Ve#;|Vs2LaiDTI5 z^}|1}!s)uE0=GV{CpT_{M{5?AS5=K0vO{p%mxM7TrRs9-fY1TI@v-JXm{vqgIX<$< z6G-X;KYEE3A0N-WT$Q|_gzQ8_yPkWswzRPsgmCsI@Q$qQkYmaJfgJI>@g?%=Vwb>C zG5;ov2SHiSgPdEu8dJMb)P%8iap6|0$;5d))Tqv=7$c~t&WQE2XSq(Sg=vZ1>vf!q#;#QnwJOKO}GL7DxXJ%fgA7H?1U>Nl3xNw^QcmRrn8X6n>PQpNZ1`7C}r}jz7iHF7OV>)eJ3Qd@&JRJRLvtjjgl$tJ=e~ zqz6h7cj^@cR-A`5&vTFO`*jAmM>y<^#;uA&e617iS+{57(EhkS!jFs0Bv|4hXR8fM z;F;|sjYEOj{RV4nRHrZJoo>45n2d^c1*#Le>$A7z2#mmYB?A-KDwOqlp>{ArsoRX4 z#JHWe0sWBoo1dRAD=TxV)$|86krU+nf0auIyTSF&nl{eHa@2=VKFp8xEz5QmbGMc) zU?+)Xhex7j1wSecda1uzJhOm}B`Z?`!jp+eNJ!N0X_NUgieqs*+1I9?hD;=#eZPPz zF}a)gx@rsNthH$7&n#_?=tU9oev7S?8`PY;3 z&CP~IqudW)W_Hpy^(O1!nQ$QT_ThF81kE3S)KEv9w zFw&^~-o`SrqpweMIeK&yFa3O)S=&F0NNdUBT3mL zCmfR;=!)v+E2qJe^tRyXgtM8YpOG%{uY4$v=?dWuz6P2q=BQQ(9a|xoIF0IaJIYBo zrka{sf|LQDX@KY5-~w;9@5R_`RTO4T&$-|u`kcSmO9G*p^RYu!J4Qz67BEN2PuJ!t z9}BR$gap#1S)gA9*bH!9#YVSB19(s8KViajGNHBexn%XrKM%OvkJ8tev~++vy2x9+ z(4&%zs_)}Og$-RvkejC)qyD06Zxt0(!Pcyo7XT19#AxM|v@4_ubI(J>=@|0wjBWYA@_cX92A#?B;&c zX4YmL<}@(_2u3sOsQUVUHhRzoLSe#CNX!a1dD5yG)Hct2JaY`OtKoM#c-Upn9aN0# z>1{c%qiRXkEg@~w@><}DlH4vB z|4^qOeyp!!j@M$c>xbqvLgFi|qUPu-S|#0XHy;jB z4D<7L&{rt~&APjp4~Xnd?*>LCnWxx;0AzYEf`yG8L#1PuH?oGOfnR0AlTcR1kw`*9 zq;dcBjT=+N3S7FD+YV*@KhM&%dU2_ z;}xI)TGC`TT^r!sOvktJ2^u9mPDRYu&<54xCV6(uLD97auyOAJ!n77H5W3~>-_0Ez zMLQNd)dnq$uonpeh{4Cr{jC)5FKq4ls=&~1s_@5@WB9&4SdM)<0(4*g28c=)qClPm zsaj1fH8oxV0mdrs^bgDg%;>xmZ>s;Ym2VyZp(-mwoY9?v+6!a2d3cQ3iP(C}fRHBW zatndpXorYnHvCN$tQ*6$coVQfwMrggC35u6FhHTCmk4n!ZN|uRVu)%Dw%5|btD9pc z@A7zhZ2Q>G-kyt-^C-EfBm@|v!GswG<@;P85hOr_T)$pXQ860j_3m01#LUdh+`PA* z>@Vh~0ms6+1+1$?i*4D`lbFklJ+Axw{9OGYavUM@^Y+)Q=Xk$HsI1F-xXGiqxgco+ zo5$*u_6*+F@_+t1Jy*z{Ho}|Hk z>}`}w5yyS|Zdj-6N8@PMf4#&4Xtq;SQX&p)1(-&k9u0r@udroO1nBA*wO>lOb&uFO zqMx#{qQ{*w>;4a#vuo@@fq4#wpq-j-;!?G;uqO1GQ>~#dMdVYmySF;O(_E82Thvu* zrPy(MliPvkJo&9>m15R88kgp5C~X0DxG!|&LqE2(x8Juec<0s~m70n?Dthp9);Or^ z6nS?ilV;s+f5f|UIsiM~Yf2hE2s}$^jG(N?i+x89vwc(XR7%x2Z0HlkYOZ@XLgdAr zkn6mAE<9rSH$RUrJGthBDx#BMKqQCwf&dr^db5;m^BPW-rjZ9233vBT!q zm)OPbV^?i&qxrPOADuTwGsU{oXU#d{ve>iz(Z+2Qa*3G6!nDqbcU8Pdyt0^mLR;cK z*IVIcgkCxEAG}=}EE64Fbk?db4tQ=ootT&af-C4meK%tIa6PqLvwnHio>9YfwqJ)y z9ZY66HKUE5J`_zJz(-dS;Snq!%NaIv2Q$g4YPE%x=kURpn5*9$c%O3G;<9^B6yGEN zxs_d>APO+}1n`&bYZsT`R9gpwSz1}i+F0h?Idy8dC<1~WbbkL-`w`wMvdZ&z?2USd z{oQiA(Ypt!#Z3$8E`w!syY5a^Ig=E0DosiQ!=hF0h~a^XmgzFOgKBVSu2Z;fx5IMx zzMTLHX}HMM<+wbTaMQbps8oJl&*%vRs>T4-n@+)Acx<$$)9cDfVgz;l?xwa-A)jKs zPmB5F?G<=zqXSRhJU}G(8PZenlXp&P_#gO_MA5PrChoU&C|wDz`A9en*whui2(uAj z0NJUc(%JSU3)uV0tH30A?l1TQCb}e`O!I!_@H9|FC&nG{aM!_0axumoFN=i{Ab}tp zAdiL%;B;*FQt0L2ACP&8`ht%S!cLT%n=8Jear+fdLJtsS@5%-KAx0lp0l-wtSFE35 zs^WeO!+Zbj>)&6|0t`9iO!eM+T=V$2YUTh<&W*ovD_;l*=riVM7Lp&^9v2BZ0Njh4 zo4N?&?*l3ymVUl^31jR~^J#v1I$vV`5P^^K2Oy~lQ~R<8egYvEz@3{I!plE-HOWT9 z?ROaM3Q2ozPiPfVbg}(Zs%iEMZ8u8I){|!9^!76-@iUFXr7w?ZpHp!}fYBda(C?7c zWN<9MV1iyDPq@!N0TtB>hy@MVKX*;8*}>yhc(h)=pLa`Yl03H)KR#^*MlnNr~b#LYWbqga`=IWxvZb-Xr*zmk_V~Er&95F6iQAhRt zUo6UJC?%t1-|Wyum)dcDuB8@Xn%)&@1kAsrg$s(u`7&D6nofRQKai3>ltM-SW=Fm8 z))4rc1vw1&fwsHXd$ASDwn||`K$gg&86aAtUb06!bmwqG?=gYby+qQ}Cd_#q_kHfF zZuy$zxMOxwd_+dU?{7vMyxOHBy~g@TLFzmd05^V2Bvr3zuf;UtzzRx$<|4{r6$Z4SMMUQ8cxux7 zO?#5J=L-nB-4;Z>hmPD@Fz&kDTP*ylb?b_qr0cU2u{4(!7dP?YglhRU6d(=`?E2E* z1Ds@pzrW^eZjp{j!*8&@2^mgB%KS2w-8K3C>L+`Gj2wmg#^$Jc`Tt|@t)rrRyZ%u` zN)QE!krYs*2PGw?QIPHyq`Ny50f8YzNaQ1_Q}l8Gls9s5uAY}OG3dm>%Fa+CPs zVMk%*=0wPGdQhrzJR|MX_zD5Lpo$-d@MYVRd~)!x=Fc3k>Q5G=@t*+{4M+^>7Hn;8 zMY@}8@TB)GH~Qm9N=k}@zJ>e`CasiMj3qs#c~7b|1XXk^zxMFKfzsM+hK=>MRiu-F z(h~+DgKNiy4=Ejsh8~o2wy7lM=CCS|>ksZiH`-SX4jL^;(4l=Vn2T1T1}fAI2?0bz z&snQ$N;fKmAGG5#H+8(pr z=fmGvgEv)y^X=PKcE(owG`h=rM0xjEZ=Znn;W-*ES?;h)mDGY zf5q7r0h=1h1rIykKq?oWe&W;bC1RDK`I?-S zlH=`4aje%6RD6y4goj7Jo2acI>X!|2lo%|UbuJvp;Pe-X|J>>RsKB@$4XI*RA=$5x zN_3Y=*+>D>mWDxnS{^3Uk^;78^GlU6=Q$h^RrT>E$CV zNpHY(XFe^Xmj}$JDOW;;Ev>)T^_(H|OlhNhF63~ijS4$zYHA8WF;TKv#bspyF*Uo5 zbwXvDEQbOa%f7GC5Nl4sk@GehGC^ALml9>D!C>@{6vRPHOiby0f#;CNLd(DjMW87f z$*p(Kyz@{x&%fAE0bx7vdL=Nix|S9hrrtAK&K2ZSB~Jj`eqdCqE4gbirXO2yC3|>} zSl40CTq!hMbt`OBm*-w%A!lxEXlU?9IZRzHdhG@bzpltOpyVk0wZ<<9jX&!c03ILj zhGQXj@+dcK{VMH%`#FmgNy1qtXaf-0FD*U1w4+O@nESOI`jEdZdGze^a(16-%58b0 zmugDuT5TfHa7#P*wHwG$QTUHb2Ue(#OQrVR1#V(%(S{@uRnmwd4CL#~Mr{Bx!`cCk zG&f81Wumwh0T`jSHji1^{-%%u0#1Bo1JVh(yxJNX`e4kwC((X78X3~6w_oYy1A#Q) zoq3qCF%j${?)WE5L00)8+OIOsxH!mc2-@=U5s(byya?9W0pJ^LEG9j2*tEZFNcz}k z=r0ufwO9GhVV8r8%g9eA!P}_xcnA` z1!73^@9rolU$p`3&6&{U@T2>{UEo2zdn1slgbg(=9^(Ffg830<6C(St3|%J!pxa%h zLAmb+Id9egy&HSN$2T!HmNT+OMn-lb^dY73O96O2ZGt!NZToeQG_Lk-6qIMuAJ5v) zm>de9c^`!KnfeLq3t$4bfe;IOL;+0LZTkekAV5MG*cHtiNG3);CJKtW{vUN3GQoIz zt@z7bUfi$18SN3ES>4UQv5$d}eDccCX=mdcCCaM`b$7(3UVrMBnMmDUP~@J zvey7Tk$V;rdlGiOy2|Ljje>DXiqIMk)2~-Ee|2%)wSWzY98usERaREk*6KJips-x+ zcRP00HgG{L1_)KzaF5VxHkNgdc);HUqV+5HLDD?(cUI!RS?XpR0(hLD_n; zqR*1+@pH0PG;L;1TLBc5#m_Ta<(hc_?5?j5AC!2HaVYTPw^u}qx_Pz0cBz69Egc>B z-2*BDgiJQx!g!m8gW8UHH43fh3vYkWwK#;0Att__|7Ps>8aa>|eISkci0s|FccBv3 zU**36`d}iZB?awYW!RTwbY{k;RI|eEEB}?u2!WP(t{lWZ{2F^PfGjI3H2@;4T#fOX z#>B*gkB<+?d%k*gU1{QNoW7pl@bEAYr~^z^LAjDxO+>n?o(%*67IGVasbiJ~7hLZ_ zS9FrU)>c3z8PEizzySpp2caorUTqvZ;18fzdk=cs@LEIt<~NL8^k2iiZbazO^t7&q z#@OWKH@qY&)?Z#BU1;-a1M(q;Som^Z%^De&RD~P%!0XLC4;3JW;!yIk9a17+K zmbik!IN7A@()g#&ei`OpsIEj;9Rsk0L*}VXxaw#?@CE3xcr250Au1Nbn<{#-s)UE(z;N4Is zSgOhL;ur%P?TSS};=;?A3Ylsa{D9xEt3MMDXgH892E;@6%GSMx{Ib;wi^6XJdDX74 z1rj@iI(Xj!1C8X;U7%DoODXgQDDkr6KxQXU(60#i{x=+YjrvQx?^j%-xmq9I-*qcM zg|V{+R!THkCWBw!`ZerVmygmfe^sygJTUO|nNk1}P+j|FG|m>+*DXy(Wr^~vPdPkt@@p9oba zq~b;^P!|BumbHQqkZnS+Twb`ba1KB>aZl;1m{BTT>J^TURyzm*cTh^^=jhNeicVylvb2qKhksm7HI*Q-L=(Kn?aOp z>~(Kl*{ExHifCnSbZ^VeIr~%<%3!b>WUDGUto@y66G~4G9kR%k+Xoa z$r^|=QSTzvW>%&i^0Y6+(#682#kh!)L}|pJp)Y{u>lVav0u>P&Qs{>ocS0&xYI;K8 zS?gnYr_d|29SxKwbAcKQULQD7*OH4hX{orp$(r5Wsdp1-+eiQ5b~x%SUy!dz16*WL zwG@{Bui{?ECn;7P^>00UNBy(M!%@-ESke4_A^z=oP*t6OO19_dGOa5vVvt`=_p+w; z?37k@f4(aAcoODAManXm72vRV^!vKCu$eYiMNFfLLj#)bsX< zYFqmu?ejNAJ$cMKazh@3PqsN+9q>Q+Luo5U2OIO`6r*#hkTsnze)rw)_C=P-@$~Kk z4SwH;2++7xojY6VR*DV{2LUIqPgKt&y~fiGV9jij(UKkl@$ zNYQ&eU&vx(o}N^6)haKL#^nOeawV=ExZ_B9JINmeI(Lw6A-e$I4Ivn4t6kEquIwJX zUCvn$xz2S<_fHex#;4xeetFQ7J3aGLsftgri{@OmHT?{!SJ>( z&ZoaL#;XZ_&%BW5=~7s6(2;MiqVtzKoL^YT7;RK$OQW_?$(L;SMCFPLY%6wm3NGuX zRo}@dJw)^?WLjs7)T2=5N~2~~iIEfrQ@L*Zwf(+=s$d!9mIKc2oJ$IaQMsBRI7VMF zN(gXF-4F&gRzEsA0!UK`2=iH}X?8HpDZM%xLL-2rSF{!y3<0}0HZ}m%+tt-IYpd>P zmrIqF${6%L{iWR>&4_?j{jN`JnsP8!Jy8-86IHpBBiWE9ye%S6U!k5oNu%gQK}pF) z8agyIq+6iosL`+3AL#v`dcA2Wy5^)biZ3X9A(tYp!2`~48l>98MxhY8`ZCQt?|QwL z&y7<;@V${y zR)WL@SW2-O+c#ZTU-N6bPh{-&*VwSY#J>DUo4``P$}1?StEB}TTgiL|&^jNvrT}nc;nO(ReH{ z*T}JqUt+A7Z6Pg@y@zyOiu;*H7AIzS0x zU3B*|CVTel=mcAbgNDPkr*z9ndKM;YM&-0E`+Hs6K>>%> z2IGFs$_*44JU1f!8y+^;RBEZbcyQTQ;>K~|`2Ch>B$2kY2pB}2qle(e6{pAOOkZ?_>vTSt z;n>Gf4|}nyo^R@z4sregLopnH?av8JVmw55`af%=OgnwpnJ-STgo=i&wzGBs=rHfBW+kCZKU1cxdG~j$!f@pDCdPAO!--`*W`v+{LV93iH%l@6izJ@@U^<5LF#&Up6S7 zI^W^ErOVphW0ZQW$q~Y*H0*~#v^ez%NCA77E8Tyf^Wl>->-gsP)#>xn8W`Ys)iQx& z8;&%*q3U8Y_N7iPM;CgNKkupj+&W)A_3^gd*<+QZM7{Ky2i;qqzTB)04L>`lef;u% z$KBDciWNto@qqB`uCbDpB2hS)Qem9mODos?TLuF+a4)|MTNXI`S;-IRR)%(i1>p*L z>UK&MWRX?kCnPMVji6_t`TQr1^FV**<661Nqv86R$a5|Yo=T_4 z5r228iBH*tS&e*Nvu#var8#3i%*E-gk^nbt=P(4Eqdr{oDn+TuR>Y311hfbU3*Z_k#hP}sQHU=@d4rKUq!r8^35)^KNpPSs0*bJ5OLJ*87Fsj8$>M>PM z1jlUYKLqh*vZw;RK|B<2$u>gBUB0BOPM+^6|BaV`B57w$@&^&Rv;m05P`T%7nakFc z#|UVvdM)U5w0@mki$-JA$TW-|PfI=Z3=O0Oj_Ah6HgYMP^ZrbNvPdtY1iRSaRUiee zskOhC$#g7apFC&#eDk9`jy0t8$gQLt9v>XhK%;iPnVh$}df*NebV4QOx3_Hrx?tB5 z1G_VTW}n_Y2d8A=d9~*S(>)jG^P5GIL1Fc~UE|Myt^;>}bFodN8bWlIJs$|jpR{hS ze1e8GSa%1{e6{F&Og4#?fOPFkpwSvLJruB zT0aAp#V(*)F9BEaOGba9evQseoX9QnvxlZ~9;s9_;Qqk&;ZD0ID=Ta=qaQH{N%3LP z8FI3>Z~O#%2Y`iV;v8sQIZ@%h=JIjh^F+e%l(T`9d5hnsclI-xyei-%F;Mxcbok+3 zn}m2g8}a!4iqQ|yeI60{RKR^u5LBF|HX6aI{+t7hi|8sw&A~>yPwHz7d@2LYE!)0Y z9jhM+K@t=H)E7VapeqvL^~p!0fpCN=fs=-e<=^<8{3#2{qT}PLJpY3Lm}=feobg_d z4qm=+e{wMua$h}>5^To1C{Av=RQ%Zi+wC7;UN}+IXG(SKgu!^XkNu>wwv4T@JFTST z`mrnapW!-SP$s=VagKY>z~r6ai^uyfI+G-n%JPrWsb?2%!40%5*Nx<=e@u9lC7X69 znL3)3iJE=qpA~9E>k3>o_Eeg0X3Pr&v~2j5++Q zJh-Ro;RYkAO4XDgt6cGiQwI46wQy8}1{`63;3OVnc@4B`*I!j^&v@`tcCPLx!QR6_dm<&2U>~OW!Z`ss&#a&C+Rq7>TVayd^1kb2zh^Ef zdCECtNL|jjVPJQ}x*?}CIklxS6wR7JqiL5JQA*mfDYb3&p-{=%H4=jB4HWr~PBxzN zfsdT2i`XM$Erbbsj_~s%?n>$2bwV#KsX|`>T59i=CYIXL40H=zu*^gszUw+C%tlO@ z^Ia$4J+q(Em+XEp7vbiGRI;y{idtQ7uqkC$q+37hAxqweIBjNj!@?cjnWVd=2gcj| zpZNIo{o8PJ!6TFutHS9CKD89Jkn$+TP;}s2`cCc;qS3XI1CHaIRF_p@WwJ=$?y7da@B(`F9GqD=4<+)o*OKKG`^S5s4P!=a?fwVz7*3lkkph53q&k>wlJODtfv z9qy2xa8&b#wL2gD0a892dRDDId0uf^JlQ}+UJFSR?12qM!D#%b%8|irZS=b~5o-mPLisT0!Y>vEnr2G@1Hb-$ zpgv8D1C+bhq8VL}JXD+(asE99b_4#|fvm9zsk}UL=%X&>H_r~Erk4l4h{0HDZd+LF z8yEn60IcIr456!{bNoO4^BE>8mDmf~_+2caQ50X-=$o;ur8mLOo}1IPPsfi*2~P1W zb!sf$P$_UGYXgmV{ZklW0cGmhK$UK_J@$7;9aaIfAjBS4@BWIqV-OMpC27~N*qySrgq zJ0bAY>@)CTn=hBy8>)iVB@?C!wiUMT7`nmZ*R`2R+z#l4c=6EuH7zBsHDYL%AdH9+ z6mmZD?w&rZ(C7Mnrh-S0eS|Hte^T%JM4W~sNN3XeD&0IJIPNe^6g4Kf-(vP8?V}=9 z{Ih9}4#7c3P)F{MZ*Nyyh{hf14x_9-eDYshPZPM?jn1fwkm2EMKSwH4eW;;UZm(?Q zHxw9!Qp?+erLd!$5fKQ!yg;<#D~70OiZs*Xw3#G9O|sUYlU}~d z$WuNYG87KGCp(t9^H#k+jpo69K&+l&wpT05Ym}OTw7zLD9LNyf*3e!b6c9B;^6gin z*p3-^S!p>(Lu0EoDdd4mnG(uP>yK(IEbLSUt==th+7+$}T2cQPb?A%5okI%UK0fd@4^npQ z{f~J&*$cG-Ks_z^wTGWPFPH97?g$rV;)I&E+-jzNw4KnXV?u8L?ftV=vJN9cF~>aBRyC& z<99^uUM#gsj^)GQRZh4jZ1ls$oN5aGo1ZR2r$))ys+c= zXP6?q@}<#P5GVhxCve;h*5?GuVYEB%E;4wAx4GEeR8m1I!QgXsJR+p@YJ<6a79;i| zdt_4-+hLNz?Gm&Z*QqJ8ciZb(hRM0itWzw(!(+U#nQt2q+rsE5#2WE{UdN&kUB1sM zlVX}MjWvbrRfHBIb}5{?>sXlorO$@yoS0)es*HnzcG0LPYzmGMP-^^aKQ2ZANGj?g zv{9rLF48;s>pi#fXPCQcm6fAr{njaVWz#w}eI@rcP5W>3%^5VkYAay$v#~!B+^DU# z^Z=g}32P(XM+M=iJO|`15S_LEO-f@42LKFkkb;ItRkQ)hpZZ;#7eFY8lmOC$Bj5u< z1OTs!%o8C0StRDjk>$vrw_mZnc1t)IpkfMdK#Dx#1kfVFD8y;!KFV@@wi8R~D~3=g zr<;GhZ0uAB*K@?`Uj#-Sdi*Pg#{%RMJ>#g;sh-i%U!;k?2P5UzH$@%?NIH_4K1a&Z zZV7y|H1fuSV|9KFpvlLrnTLn{TH>!nNljXD zmL!6X_~UGg9(KO!x7rJ$A98y!xASmg@8js9_P*84F4o^mgmlphjS4}K!vX4gd9r=q zlJl^@g7NSh+e0PZmH`EG>3-S4?h*VSTA(gKcF)Zmq$Un;M(Y8LXdlRqdQ9;w3C7jq zhWB1oSwW?WMfGDCPn@M{y`Dm3v7 z9`o(qN#xS#&+-$&P;t&~hS1T1_W)6pxhPDJse|4LwIM9PWF_qexUpPlvLHGVA&nW9 z5P@oU;5rVS9==r`w6F+hd$yLlZtynuEg-S)>4D8f%V4rSl>pB5WZ(UK&@@v->oN84 zlBhq}Q^6X{?rpEHGWoBVP9_&kK;wNSLtikn&fiVVoZJbbv@|Z#nlQSV(4@ zB2-5DB#^6m^wEolkMF2HYsB#?v%TXre&?0MHJ{4lX?VcxP|d>-)QZtngfKckme#G#k(l!0?0;UszcdO!3>8S`^NhKW7Td>kn3otkZy=f>4`W9q7b? zZ>%v}@yqui#f8~M&2a;+cRU=q+}i)C={jTZKwG(#^w3>O>7rCcEQ`|;?xw$ZsRVmf zXWZ8RW|Gz}*XAT2mc&-quBzY$bg3NuIDJxBWzr9x&@;KjaB;3Nw8X}sZsRoXmGRi~ zAIe+t(60~)PMA3Pe1}mJ$**LHKb0n+rSFRray(an^NjKmi!;O)xMTt@EEOInvmGZv zu~X7)b)n!gmT=eii%XER$J&;QNW%;~j8M3gq7@-)(3<)^@UR-o16D2_i3X-wt3k_V z{a#%grfxP}$#(Y}{aRgm<6^XW+%gFnc7?6<^luUF3LQ+0OvfW6Koj=G$?M?yFRnR5 z_fZ0gAC^Zwdh%%&(FAYKCCRxXcYw~B~v@;}PDcVTozYyn8HbQ9q?|deL8z32J5YVy=8Jz$sf>(n_h>Ts3dqadQz(0%7whTpn zB0x{1AUi)=w9X&fa|O}fx53#i8EtgV;Jzs}Q4Me!$Su5YFvAMZ9HShp8GF~$0-duw zy~}+YpQHMV!tEAfv=wLrJf0S4?Z--hwg@8ydgCf0ja|Q_H`$X&smlecj+XqqvWihzEY1a8bOF(H$=oj0y87yh{=$l5(_0%BMWLO2iHJ8YQm&gb`xc{L^`RS*wFH16kEDn`EUQdwpu` zS!=^Nds)@1p4BI6Dv_3!gqx1jt-2)Xx1Vp)COL#bN~?UKR!60mk&IF;1v zWGE}F-gXu4k`z-#qZ=%CUu(zjW6#6I^z7|>{qYqPT(g27PVCed+hn5GLMQcplu``Y zM5!w5qOGQN5`3|WGhQN14(#Ts9?3jkURj~Xo{Xs~e{LCahQVP^{RYfr@jg_aCUIA* zPHDQXb`>}WZCXBF8>bm}8Y6s9SLsVHJjSbVOQ&YRuJ9OBa1dtht(jZv3oa{k8HOqy zA7vL;s1r()ITlU_qNWcR756t~t#;q_;Z)D(P(mB3Tp1UL;GT@N3L?0F7c2;DrlWG_ znCu5@ja_R0nXfCu9f7SWPnzkO^U03(%|b2;E{SLcGPJI@C*F$%(6`m;E0$3H%^MYo zzA+Fd8f<8{GSS^$$K~zoTGa|2`>%LzuLt^E{1^?HPPt;x{q3?R@2eS3ili?(H)>6suUzvDP~n17fCG_jPpn;c%+ zH>wv1v6{(Q7*Gy~dco$kuX~WFzq1TJsEm(AUwlk`4WvccakgOkG}X18A1h?DpK|U^ zpH8Z1fp@z6ZNe5fI4q4xnalPtT)0CyDf*qnu-B*4fpch4bc6bCpT*(uM`{h@<&V*E zDOC!h@;VG_8}D7F^^BJ}umT`2vL$Br`d>*Fe5&|)vI$?S4%eF@B9mlICJd4&Th*CP zFygbXka&{zH7`%~?(0sy+xUB7B=#=*S$FBEBw@-j@>8s%>jrz9K0Crrb>Wp$&6Iqj z;IyxMy*h$vFa1SgHX%bky*45Armk5vULIZG;Z;`4N6SqX*rb##Sh!O7+Lkc-D(&e< zxm~wI_XX2RwtSPC`@Bfey@_*3?fer>-U~ae;#6IPYSh0OPPFkNMQeg*&I-H!Sg)&2 zsyx~ah5XQS6SEAAO(K0zPulkWwa~lJ7PI4k3-Y_p?02(^JD0)LEv@;fMX=_xs|uNShB9Vfk|;mc-eb$l+ zbw4R_+rqrGlZ5@Wd&Ty7JREEb215$`3hwT2*P@J#9%h4oM#>zMV|(M8Dt&&s z@O1k|K&GiT-n7p~5Szp^OLD1KB`;|l>*EEzwW6V?Yg55)W%g%7jQ-3H717fL^fVP% zAjo@VG|&WNu&h^Me%_~fGbxrI2C*chB)q{EqGTdPHE}nfI6jT*`sNj*-My)p`p29$ z=o2Fvpz8J$QK$PFJ@{N&he^3g&k{aaAHQS9a9?uF-lZu~`L%XSvL6z5R+grQ_#ZP_ zPG@g^bP}x~6)7TRBO|qy*Ey&7>QZZ^ZTTG`5;(U-qCNl$BkzXKNYntQWDZN)^MA~+ zXM!$$tT;?c>SjAI;PcXrmCvt(qA@3WDQvT!DqGg4zT{TI*Jmm|ahqmng5uXb9O3?$ z)Kbsinqz0zU_}Sd8{96#6OS$FzYWzoK}>V&?`gW=X%$i&+185#RDfj|G(|38(tYhz z0_72DP*ut*fUyqb(y0Zi=0rjz7|i5lu0?}V74M%IC=_sJOR8yS_tDehLK#waX_T=+ zkdr*&e|xe*eb5GXwT}p7&VgK0Oim5v(`uKI@TBwa;pYvkp7VS@l?UZFQY#waY2Fs{ z;rSJobrKzq-QbgMC#yuwtKT9XV2Yh!pmMS1m@|}QtctKyqlvzYwOmdINL5l$<5F{y zkm+;YKO;cLRd&HeO{n&J%Gf1RuccDy#Ys1VS8$gW^;H8&S<2X+B(6i5^Xi!Www1}} zV>j!w^I&t)bz#qIRa-IqAfZrUPV|l{b*qt$dL=AzLSXk=Z`~c?nW+-@JTBf4s1?V~ zcpbJU#C{8KU1@u$_W5I%^J;VqY`WX5(o!o-d(?m{Qu@82$q*{B`I``To(~2&_!@y) zmUT(btQ0fnb3xc`nZ&JMKo?Kw3G$2H|YpdV+Yk6!~7bHXPrjxeiT1X zdb&lQs0uFDw=+w=mIuk(Z9ND*5Kq9_V0xv~9zy>}Cc}aHGb9g{XmX(U#L>Zn(K#p9 zU3DZak9isVIP@0@EW`;dIT~A_799bL962Wj>-nPAri+18S`wBYCT`_ALDC5O&*^i% zZ^}-N%zesR3Yn>bl=k#5JMw%Ig<;AiWwVek4){K)iLs&7ltT~@Sho!ix1i7bnLjsJ zIbIKsRoq~iK(~_Dfx$Q(&dR++5MlN7sHmtwc@I*yqf*+#q8g_L^W4~97ZUc!Y!#IJ`D=ZIOc!4$8p5DdxuTIX5;x@n6P5H>$HGnaoM*ZBB0DP8_tYU^!<``w25L~k z>C3G7xM8X!Kp;8z!@OpNf=}L7^+!XClyqfi8N6Qjee0;7Era3#|Ey(N+b=@z7hB zZ1k+n&v!i8a(@^!B{ITX4kGe&a&?S5p44z5$c)s|JJ7zPn*Gr}COU9koyX3}=KP2Y zyt%J~PCPBH3#9N!k*H-tt%}ZkxB`kb8;Dw7rU`F9)5QEhp&-vakh$)SbB=l59Ej=^ zkOTfrw02-D$&8zA$>9cUUP|$O=9NAF4gXk`Q|0mna4_WS@{e|OrFtKedl~q zKI$=`B>=ka0(DLv5b|~+g3N7e*14GqAgo4gz*eS9_h$84oCoVnh3iGM9O*rrSt z@@{wtxd|N_a#III0L@2OXCoWw070{ZfbCj-zvTrPAB0pux{~$g^M|Yp?rO z6$+H$rZbmV{>rS?q_jrK;XkTk+E;Lug1#HfOZLV6(5!b$Wg1b6IW2UKYY4_J23<->g3rBf0;8i*&{peRe(}!lCy(n#QxthnhYf5F9_oEw))9 zGRQUqp<|&;DyK0;)UCF?(qifwI?sS+)|G}kC(8!F3`R(bl9yf>L^y)N;J~O?K`(8tmGWGB} z!qdpqRZ(60CT`06ujOJa!#DfeExD^;D=fnJ90*@UYR(~2I{@&1seOW%oIXY|yt(gs z%y0$Ip5-D>tSXbC#g_DGr1qRWm%xB(dHOO}3YMKKy)S~Mz`fVZ3}6Qo(3&?`$=^!O z_RFoa`=>3-)^#-V-sed^FRkxCagd_LKFE|rU0G@f8{4NYoJh%gcBm1C;Kot3ZL0Q$QD0~lQ>|4jk#vx z`#qIk*DmwIa z7w}6SBjHCq+07ccL&~N(L;jj&G)g;s>9W9w6$qI5cq9^Z2n`$B(KVyr54q-iZ((2w5?mw2@g1>0hNL>u3q09-8pCP0#q$I=9=F6ZA!A3F z%0+2Tr_`aMKq_Zu&S_#FAY@HAnC;xo&6+Q|pSa7*J3Ny6?optpIW%0CYb~UF)=eJ| z2_+Se)lxr?D`&W0{bl!Vz5QJPLl_{R??AVdn-@9_LkC1A1X2YhYC^SgdFqr@ zn^YV4hxAG*=j@xR@QR6`^^X#=6cVkX4Fhh5(v4NrWUp9i>m^o=LeUt#O@PS8I&IuE z`F2m1MsZo{=#wKnqZ^AR9IUo+?diMAbPSN)mQM71Qt_cHzv-dtzP=ny0MeVOb@e*h zS*tdfUtWx)>FZpA(BIA3RvI83$54Z3nF}z{$R&+E-;p59CLN!K$AmU#TZsvupE3DE zHfoSY(B{lG#o(1-LX_SmwoR6~UWx$*O?1_f|! z78HlZvn~1Nl^6j53K@)RRZcU@>|jlT=$g`5 zmA-S}(paO4sW=FBP6V2Gj8q6?Q1vsXYzwvkn+A2cK`Q|5W2sF4oD~{so@SniAn@|L zk3C73qLSNLfQxSd>U?EnO`z~SfRaT2rtE@ZF@y!uwZRN7(+UQhrCP%0KArKqZEUxO z=B1icTD9(FthX!qobN{WHpA~Id~rigc%aQJG6fho-zIEKXtKpF-*ggRRY#n?*r``D zg{q1iOs!U%yfgj$v-!P_s`tGww4_5ecO?j0SvTOlpe8Mv3eN}RZ1^)gQ;19iy@jbbAPvXDp!j(K z5|B+K8shXE>h@#dgX>`x-GL^ZJuA0Sg8}UcZ@>A3Ac+-E8V%=DAex;4fX3^V$A3Ae z|CB#VaB(v!T}ZEPt}3&2E4|1#EWY3`9u|sS`%%fz-Po5_@)f#vA~jftJ`-v*Y*$!| zK%ZSt!!~Rw6rSI<7g%c?^Xp-LWp`KRc=U(tjqWWYlKZ7GltXWnOCZP zH(VMIb07}ftOpE}B|mv9)YQ$2m&xa7^vhss$Ex0?Jb`mz;fn?HJ}G=T6qW*0a11?f z3DIvCve7p0q9@>VGXB=TJJ1IXL}`YQIfF!hde{f)dETSU65B$fw$jIN_$^U@6~ow= zyz(>DbnFL80r=DR@4I#CN%Plxs6Q5wm7@RH@-yc_g5k6%D9$AAq)YPjaf{w(X9L_m z8BLBsSFXg+wWpktOhfgvezL9;Dlb0*q8pSZI??~X80XfdPb~x)HE@`=NKB z&)%l_?f#JFhKJH`lk}R!s41Sejo(#}&n1)z-K_p)pJBFC>8j(=BS)nJC3eo#(4~{K zfEpE6xgCtNkCHh$^T3rJ`SXM@g5d8xTb2uaWe`>KC;BD0fI^D(rLrI~5r-#ht%LK7 zPS2#raWj0cfS-ozn>1herH9#66s*A4I@bKBhna3^Xja72%))xHjZCNgak^JttP~p| z$GYP_zwD1u)0@?IIROU)?R7_LI6k*cw~vTh$SrP9$_G!z13eDJ=B95Zd5dRtm^?z5$Lsb(JG>WwR`t4ZC;WPw|%>*Wn^>UAbew_o6r=$mp6E zT-DsYi2Ja+3d|l3xLKNTnhN!_|UZv|A2A7@4eBNnMJV#APPY?k+>zCXCmqh|r5nz_qAc9#M9dMe#$H4y7 znaGz@D5s)Vrns9~j_jp*ff)pF$^L=1(4%8f*ip8 z1q7n>Jz%t--Y5ZB9Ju6;MaX9V6tL0Kk9a49_8U$s{_65XcV?Hz{}HyAaqatab%47J98 z4!zxN(nG!{fQPshoFd0jJ<497!x-C7NX8U@y<>Dy`ejn|TDgt-YHy}!Ud*)i7a&cZ zGs~u?-sk{>ai+#JB6^tY2VsCb){ik|wYzk^kH(m6bnlSOWztP}DmrS(8W$&8=4VCa zE2uXcXt`Ioaorh1AYP}Z*^cG1!K0a;IwURQASt!@(~jp$0to0Ey;SO4=p45zw3?Zq zpR{tzRc?I8Of|{GO%>Oq$SOU6)bH2Es6ih8UTI)Yu(ipA5s+014DnG&H<>$&##{G* zGi*aEHyjl0m0)LS`?>iLievu8H`d^+H)o~XKw5zAE%R|ox8=mnu23qwFa_~1Qut}F zv;1iOVe_eeyV+lA4+jY=E0a{5zCpn+Si+~fG!~z3^YC+v6EgXYN-o?HA-yo z4|I|W7-_z+DU6Q4Y4mC<*C~*Z5d?zpU(xqHr1nQ*X} zzu+t*8oyZj4JS-EC`je?)&fpyw(dYr7jcs8|lF#>VL+gt! z$+f#nw1w2V<8Hf~ozJI<=eq7t)*;V^rs)v2MOo@KP|CoZsa>mPm!oUbai=sh`@ z%TR5Gxlr^(CMjV5wG>J8<==JkGRUM?uiBS{>7E+q_UWW2K2EO=_$~BFW@{G~a#8G7 zLAY`l+#=t534K1Za5(;&=9?yr(y|YpU%z@yI-Ar8^qRW4uzc2_jMyE}(Tu3M5c+tD!;0 zulIz}oB-tkmJ?YD(0~a)m{yxv2r6HGtqM5eo~jP$Z3g!L`V)8ddGY+t*!h#pjjrY) zp`VtNwYG$SU3;yZYJJ@iUwa*csLOPTxQwj;bHK8MeWC^Ktnk;br2So)tm5qPr^OUw z(Y!2rVJ04!yK;+V(OEHOz)i!f(|Cx}A=JZak@{2Av7sT)OKx-))_<1iOmqV?&Z99+ zjw8xGrLt!{K(@Hg&^iMPVs?<%&M(zypjoFH{e4r#E>m8rFt=B{GHKWB3*EtJ{RhtK8gcAUVL#2{Efue&3g2*%fH2@a;&i~V&s&CYu z=aqY(hRa>9#>!pv-}64pmrf?0pfOrA@#g}}&2P!!s_OPR?`W*Kc=xpOGBx(XfuZpH z&0dSx$#4&@mGVEVx75A?JK6goSao{PbG}lpd$w1fRDWE5DROo?snzr8^rZ5h&vsx- zYs^}mwZ&spyM6aD^pbqQO67=5VJrgxHqiZ4%jO)hkRv_!<0Z2%8Svrkzvc+{Tp39I=zS7CbG9|td~xvfqO0xc#ZjjBmd~e? zsRA$6W$xsQkXEHF#g849y8Ep$&g`+n;+pD;5&HTD3L^T3P2e(HSf(3GxVWCB;a?oZ zKLBWIefbucAhd?{ko96|Bl&o;{&eNtW#0SIpI77MyyCB<&; zR*Ia*cPxG|O1E}di0b7=2SP&s=3JWKZl>I2LXXdSYOElu_4?&;)}_b(jvV>%S&M(& z;h{8Z-QIy*xA#`M-buzV(4YaLTEC=K3)O8J2M*5Ms2JV&R{|f8i%NpM&jyNnytnk~ zST{Gg>(75&uJ{-0)kL^-c^~Q39Zdkg8MyD(T~=x>j?8J(`d4PKmX-fydhV}o*wh}( z-=;i1=tw?3k9EFWy>}@wwczt}`qE=JLGO5B;3%*j%7dM|sj`u247NC0k!JS#LIkqd z@P!D7{Y5gn(o>UI@1@yr&jm=m-EQUO&+TL#*Y%UgIlaPjGP#*ONVxZlGnJ)5Ne!ZY z=A1qmnD&zIH+SHZ6mvcId3=Fay^T@chP7Q2W2);|NifQak&61B|4T{yd%O>V>Cl;dxREm%MaKn~(c*Pd65 z+HNXwW`L-mHn&q&H<~+9mSjlt&CrIgB^wr{Fi^cnr3nvx}Tn1w2;VLJZbJErl1@# zy(w7j((Ld}3;?aqh*r6TK+hZCP;2Gc(4riU#D1^fZ;i%5v2z8O)@la5@L(UhM%ONr zNahYN^M@A?e1>EFpRt=~f=tqq4ZY;u0^L+Ac=dO4ixmZXo|T^(l)^?QX6jdTOBW4b zdyluGkJO76CNoyKr6}x@Lfb9#Hj5ohJk??Y|Lprlg?h&gmCbD-Qn9Xbl4jXxJm*4q z$BHFaqKVsOTHiGu(zvDm7cO%IOGWb~tqNpPQ>3IM>%~s@v6b~Ky=zlpTs5!uN;~SI zX(HUi?Pbe?r<*U9J>3D&{mWQBLj{)|$~DS{_H=gz05M_?HL&S8Z<{ z5artK4I5ij5D|${5m1nZLFq;bQIM9Q!=YPZKw3dT7(%3^hVC4i8NwQn?qO)98)@nH zo^fyV+536EbKdivm;Zp7JFaWxZ~fM~NI`H0_FfR2`ZsGQ8=5~ysiOOvdi+n^j$Q4h z7vqW7FR~Sf3Oi2}lLPnEH<2;qlnUod<)*%&`d_%W&ko45V+YfKW9U>S2@GLSILJx@ zsK(Y|`+;w8w~t<40!+&-5`0us1xyR`=vO*uWXirP&1E;J0R33nM5Y+J6m%;RC@tLQ~n0NF_TZ7|atIfPJ z{Zi`|P0tL4EpUD*rSY8q#%Okd%&R32NTs|d;LtQNTPG$PUfWeLn%4q}G! z*gpW#L@V=$^0!@}zuxTMnR2|)<0zcZv-xVC)Vlz`YV7cPqdYAo`5BB7PpS3QCCVp) z865mh?WG_61=0npal`cHP6hk^>LOLul0$5wPZiOe?*K}qtS~8C_v;xZ<&qj{oEU=? zkX-(Z*TScFps(Bx_5#`iZN|qweu=xP*J6S0s2vb;&G;yXy{M+nI`W#8l?>@(fk@E*SqsL z8?Z~Rh>z)Qzj)uy?&BxA(2ZdzBmei(Z$b<5Xrz^tyhb;kTe%#qBFGPX?G_=p4xWX} zvc5ewIW1KYq7_$HiF&{sbE+kg9O{yemD<;tb`xZ}%k$WT&#`(w!U z!a11Y@!lS8V3bN7PvSg7w99L-JPNjFV%|hCF_s~IeXSa2tM$j!JtvUpHB(ccr@?28 z{g$ayrjGa2(gleZxyXw_uYI9eBA*Uzvf}RZM?4|QXladYJBe?h-tb9wg)CiRznZdn{9t%t1DLzwoqO6` zlDVeEYSR>b4x%0R2gJTY0g%cV;o8^?5P02{HC(2MLSJ?2953llnPUorQ;pui<*}D1 zz-<>3`SoqcVNa<+a1`TTy8mFWN~<2uRcmZ#-ZHjYPQM`wUA~w|38eSC4)wKgt_uqm zWu7u8!PK_*k5}Aun)NAv)Ti{dRW%K=S)MfXwm2QNJ z-ED~O+@}8V7x6W&Yyc_x%RT@94-KLL!zk&nz0ps%Lva(Sx>)Nq_FTpF*ZMVMh>xt6 z|NhrLjNRCs8@>F;`vd{B|Ks_Jf0ed_1$d(J{kQH&ZPx=WuN0k^7iEv%BuZ~_E7$sgpU$ z^r!^+jB9wFPaRPn*;pL(v4vL%U9_S*Z6h*nA}|zQTYXOUI1w^Qf&XsI<`Jq-1WA%| zFIXRP94So+MQ!q}foL)p+Qc*FpO7YW*Q}+-q4}F*_Siwzv`C3QOGx9b8D{Y^>=TkR;xFW3#r=SIl zs5-YH>{+H?qSR7{+Xfq0%|R97g}8n4J8BmnZ?zNY*_gFID}MCGdMeBTnGKvS^k@EE z76!KksXi^;fKMP7ncA3Rr#MX!&Fa{cb3CcZA28EimF&^)2Qot7OsOYqA00m|Abj5+ zge-S286mVh#;jsIzmU8(4kx^Y|{LO8jA~$CXgX^>?HIBauh<{SX zj?PQyxxbPb9x;$;+hU>K%kkg;1nu9~rI7!d{|ZM`;{c#RRk7SV zA8Ap*TwY<@&eP)jia0omo{9ZfN00PumOub4L68b85RVlNWnTXz#K8wtJO51Gfr3n> zz0t1?Orm+O=z&fM6gGG2fa`>FVig0I&+x@rD7;$>*q3I9zdm!4+w0 zpIxWATi@)}ysXA3>l7p_995sczIeVxOIWFceDlqz5t-aVZR8zC;CyyO^;uY0-sar& z*5gGrL)owMxtGQIef>HAdcQAHpgc#SU1-~Ar=xUfSh;k8C*o=LD@HzFNQ;D$r2);O z6v5Q@0x@gJ2A~DHe(?m2WLIgjN(?4d>aU#%|Jf-(Ifk*KE>#QH8c_3xD?lew(zs-r}h8*3izms}5 z@$F32AnP3@e65H?+}+L`klka;Wl|ta{IR||Z&kV7M5`M^_v5~H&X?YK!1HQ;dZdfT z-ckCsytZ6-P%R!Xb>T<0Y6GTvoWI2o04+0S+M!bKoRk7^KFZJJz56Ce*CibFp~RL6 z{Xj0wNQ+A<{y2?Fmj==|+*^E_&v30~Q}*_TY7m6*gjb)GI>^Qgk`Rxd1KK zuRJ<0ldYcm@Q(*ndN#hPO-jJPJSn71#JM-@Rk%N7BN9)jG7wJ>ScnaYMk<20l?VW~ZNQJ(5(b&G28rKKRbTD1~vv;2b zp}k`saqU<#o#i|DcCYABkN{x43*#%~S;}P+1K7qMvWbg=PU> z^ITt}ZhJ__n2^u65R#~A5T0ypn#Z6HUn)_@8b%FA?#OJ~K}6m4ZCEkHT-okw(r9#? zS#wLFj+s~OwAWofDn*97xy~Oj^V8iisp3h!_K8z|5FeQwTMlKe^?~Yo$&r3K?{))N zQGwXY2nNJ<;py4uESZG2tNAB`z%1Sjd;Mb}?S@9sJnwa9WJqnPgI+!)#sSItmhk*} z;0od|5%pB=>KALs9&Bel+$eiEZKs2iDF|l4(5NQo4oQI)LRf+3sr5Gy4c)02T!x;_jnuoYWfsMFF^wvy#?`F! zc)qP>i^@0G>Z^V%?w*%&Yq!{fMLB~Aw6L6EfWquH7^2m$(T?Ae1LUwJy z+n~;2b)O^bHR)=1>sOlYbcy{IpwXt*s4GPjA4Hk1*jqSj-gdHeTcDSoHRF^(02*17?x!e`Y#dk#Clvs{TjJFv_Ieoq5zomoglQ-nF@t@v(c2v&N99!|Z zp+dq;aTDd1$)&i?iE82V~m)F8~P%&AnSmsoWt~CXZ9lDwly%r4(G;94!jTT zHjfiE=N9%A9YZc^z|>#EU$r4?cdy(lNK@T5E3NQ$4WC!}iVAg2=1B#=1}>$6`U?H@ zwq?hHf+Vtt1u`4I#ZfOAcA)72e$-*GE@CZi^;v!{)1rhT8NNxL;vGcz$`Z6o9c(1f%s26MV=307Co6A2ISlLH~tExpahJC3O#`6|E8765`csLP1)~y$*@M_ z1%oLR?uCa^x9F1&`?!<#GbHza=*LKKRme7Dbqhb>ul*GH=e2=Jb2IgarcVrxJ|ztw zbt)WHN8%3O?-(<9Erj&n#v31e?LGBGK$TgEm~&lcqE4KQu2Tz3^;=(iuG1?eo^{qT zpD6K9nZE#irE#$1L_cz{J9D_9%YC?G*fF+0=5zDVYq`L@-RodDO!C=hW0RIMI+dFi zNNmIKauZ+D&^5ez1KWo0-5@T58gF*QA2xMJdYhY1%r1NophM+9?`y2hJ*e9GT?d9=G^LgQ3?a_U-tih0PaSD>u+(FxWxx@VJpm~14`w-iF)UYe!QE? zyQ90%9cZ)14xDCZN<9UnLvBoKoc^w*E*aG)6Mr&vw6#wX5}_o7!NcwJA?or>94p!2 z(`2rGyE4q(C z4zm(Reow4EAI&m>81n7@I5W)=#O$H+a(-e?GfCv|V-5%)#>@u+b^11&@lV>`j+uQy z%{oOUmRfDz@;w&^Ur{FEYC?tBcFt;OoYf}L1BtH1wx1sHQaZiUr*S3mGhL;AG=<2e zYZU~G!v)$4=l0sA=utjejX%;~JnTREA;@y{V=QL3_Q+x0wSG%GWz2JzmqEE!;YoWl zI0@w{x8l#qX}RjD^F}LDMeN&00RMiOaj(}iizk0Hf^EtEs<$AId?`hUt$3Jmrg(-1 zB)L5&DZUbLJ1@v{!zvSKlIk4}Khl8M+qhrHFm!#Hc8Bzl=hcZ?x|w{*i9UL7esY9T zH9ub^R2Zvg$tr6{sb8>Gq-YB1R<4pjW=f~sgX2{S>xiTm@>$%H{P87b^vfRfXxx7E zFt+0Wo#g#vj5siaZ1J#}+n{RU3nt9VXj@a`aFAR6Y;0CPvql6r(xvchT%YwUygVcs zIEsZOjb3VLR&gWB%$ZEVXK`6;rpsN|i%8tr$)e=!-E4``e^2G5DpH$?HDjdcfx5#B zBpdGiM&(TnA=nb^68u0g=?Evy?Paid=yN!CMCY|nAt!Od#%Jb0hm?J&E$z-*@ z)(f$}cgxyOeIv28!~tm*Y3ufR+NqR#cn-b^l8q3*9k(!X(2rm>AG}NxLhpYDPr}V> zD|@AKldu-9b+{2p^ad}P&m^Paen>>eL1Vzt;z#5DB+8?prLkwb2t&^ep!UR*CDEMw zMnWTfl-Fwa<5TE?P2sM0kX_b&APcz0OQglZxc8#0dq1#!SZnaawHEq#Q7rFe6YY_y z{6Z)lD_*bjA@mvZD*YxG4103Vp5rGt6o&kf|5&ydQkbgfb~A9N&;;8`;|=XkAOdf% z0n2|@*5X5v;m#s$n9tfL!yjC$D_Le)1(=KOjEn}@*B{D(Z-p?^=l~sQ$Bsod@$&zT zD>?&;PX^rI^WE1foOo+U3>LW8Wx{d-@P=ByN4&?rkj4o)wJX9=R8m^+`hX(de*CU= zAs3}c1~yCnr!U%FJGm);y+Mi&S#C6Sssl=2m#~W}KUaPU|4uel+%B?`t`;rp&QEER zJK4A#a*w0n9K9D1oBSUS^J}3g1A-PjNf3J($S^V}Mbc({-ry`lEvLE2Ht(6|ep;OybI=5UET}zpSAPt`MPLH*gDMQfQ}d-3=)Ty;9>6yKKOt=<*ieo&D4Me7qJNednk>!pG>5 zf>k;YuI=`^OM7m)Lsj<^Gpl()RZKW27CR6`1fq2|si9dJfW9aJ?BY1FdsDAX!wD7bpYdoEfY z+>xb&@wgD}*#LvoG&(HsRU9nXq>E6+NeHNP`24lJ#kqs2$0X|k!20Pr_&R4*058$Np6j`amaS&_YOq<+Mlt^y?<_Nb z3h%1TyR+_0F^9s6KTa<{oVOQb zofPI)v~?ifS&rP2G|bz7VePsHwJeEXo`l+ato<0#R8FkhGD_hcH(XV_b#0&qjNNUY z;D2pO+C8BTM;ZF;T#u(sbrWdA_+R`cEbj;JI}C!$-XX{|z$!ASG`s=Eu0S)m`4aT{ zMuh0%m6ZIMvJDbAIo3gq?2F0a257A*2@N?ji)TTxA0%|$ZnQBrFV}r+#&hDo!MFUchIY~_Lf$zAt-jr2w3n1_@bBe^MFnXoXe7V+hVthxFjvUX(jK4k; znbQ%^zmdByGWoKoDrJT-X<)NTYx|Pf(SmQ6euE%N^}q`@dEp)j3LyP6;$IzHg_G_X zuRa5W*P!AljSwN`d)AAR9|3gjAs#?X?If7U%8o;uV1PDA^UEq;L>3jy z(>!uidn`4jU>yJqxjfR2?h|biUz5aQxJ<2c{v|)CNE-B_R#1LSQ+|`HJAra1U{~1y zq&veV@R$z9YMV#;w5fY}5}8RGGct+Yn+;NF#kZW~CvQjlQk-B+ZXj>yf?h7Z&| z1ia!;OD(Jl<{HC=TYs9it_*EN>f5Xjmiiken6-@ptP_pLc0Lm{c4OKp-h=?}XU_C| zF_!B-bU?aNCwN&+JV)c+1Sg3sWu$gcTXhB4YVVsq5NY7n$r7sKYWJ5*HAic10bF$D zirfxI01A9u8=ni}b$#LCxIZv(@UgJXEWaov%nSX zCqeOV@TTEUuXy7z{Xd(#)y3m_^7lgw)=i?;d3T{5?dB0;KBKB41$t&9J!}fRYBr~J zK)O={9H^A?R<*rmtr#9g;zty7davi8d3Voj^OZ@A3?qW{BjE)_vUU$RfMZ1YdR+;b zh!uG2tNHfwZdWP&K2q|>D|^ow?#fZAn+kxBy!3BlZIlROg0qQGy`!-N`M{PFH^-hl zf4v3G7{m8u=UNwJbB)fFbry@UiMYA7kl80aD-cl3^v^2|9Y;jfsZu2;zOPu|31T3` zNEqNe^m+T}!%YRB?F1aoo#YiK5D5H-c$tgG=RRHEf;Q$d=Nz;EIu%;3q2G>)Yt(VR z2`_4wKMxc_&x+D^RN)>IEL$F0tKiL&pxOgGrUs-w;@sjc8_j|6q7{Rhy1gHp`bdY3 zwTD3G{JJdVW44sK?pkd~=<1+#5NokszAmAYsg#j;-UzGaVwivE=WQ(WLPWa5(jx8i zaYyuU`#4mc;y4?x7!MU)z5+Y%Ac4J#5OZ70Gd#%km`;1@Rr8Nl2W0_aR(6t5pE&A? z4l838^n>l;F8%gJ&2Ef)P?YF3@k}^?-dBE+h=$!viLHpfGBOpy`mR~knnLjHl}&v{ zVDV%Eud5mbtBmF^2C|T?b}D8)$+3)U4GCmM%k2YaTo>Ffkz8Yxgt`s<0zd9g1l%i) z4`7)|28>$)gjuS9V7*l3T&Fs6-Qy5#>%+tb5RL zpAM`vw*o~zl;n9Q4voG_eo0v50=>l{dU5DOj+AzYKl)WxS2%Ug!_`L$bN*vjDKxA~ zfj$ZmA=Au9IV@q3pS1JonG!FzK4fa^dFn#8|3*H7)Z3XGjeyIZ>mzt^7w}fQ;o%Io zk7~>VhmteXw=02j@Y*MER+k=5JepGsh@Oy&^RM~g4--^G&0X)R_n6>|jkhU5Qlb-o0=bUOI(i7cjBe=(d)+ihdOY5vZalpVW`NCApnz6?%@GWC3x z47cWoX*hPc+chq;{4$m+sZB%yMc$iv_@#4Pn|yeTxdQLmHYEAO?`((H3NEY8XHlI% z0csV4{fOIeI6U7037OuAnG;fSKccW=^mci)XwPJclX9VmCKIpi2LOEf6Lr$It-~37NwjnvsAgeo)o98+ zTYRmlPwr&}GhV+R;xHFA`33@-_55R7tGMm(1F8!zHFuXK_=pkcqpxOf&cB>dYY>8fS9YAtK0 z+WK%B3n?iQbpIIdF&UoMJon*t!>qLJK=sE@ZDx+6BDPHC9jWdOm)-4i9NAjRgGa(UM^zgv^v(s z^4u4L;7gIeOg~xJM_u7~=8vDu)|n#~82^nQFv&YeGS?RMD4E3f$4=hoT?tNrC>1^- zu9=4BiPf>qw7x#oBje9f!ST59)*t=2p6Jv0ncvm33KU`8#ix?c??-)Mf3!gtc1}7V zM+hil{xp=VZm+F!bT=i5`Z5h>bjUvI&1J={Z(R+TLKy(J_-E|P1GfvynU^V}Rz@hl zTpjGF&0h?&Da}Uc=JOQQVPX#mgF2|MI_TTLW!Dx@)zY|E*&5xv>$b!b7FXZlsyjVO z^@pk;!Fq6@w7wa()J`^R4Y8%mM0h&(SkmL5$Z{FI3^`e&+o!dzZAuP}clXo2!Tz zI#Ktj&zOE!Zi6we{oO*Gko!*hgWmPWlKG$^jpST(MS|_xmYKG2gLM%bFi~k8Rc@jm zWk|zdcAxT!7jl!C8=-?P6|~c?ZgGM0uG2FUZ&5xK|{u+Fr&aaB&K#5hs){Z^$k}a0i{vuSphDenPfoFy!=pBnJkg zbCJ`hxX)?V1_Cib9NrzlTG}|8$pa-3t!Z7;n8z-WB8WZ;dn=BQYHka2Dj=M602^NE zErDYA4x8-sU;L#>QEPSH-AtolHX;d{di&^AbA+4ih9Qv`TT0Wl5G`?Ih{8nYW>~zg zct}Y5qlZ93?*&7igDK-pS_uwQ5tmf*WbyU#yzgnz$Em_AX|Bv)AdE^YH%lCx`>~++(%DgX3vLQ@%WE;G zzDLYD=sG=u)CUoX!X8i8DZRnVbK9oF2OW3Y$)kOa(ri;*p&n|f5o&zY_)FE4+ictJ zR6jkVBkm;0@&%Bx=OGZ~5>YdW3snFzY42Uayf0 z#kKb8iD?A+q&5QA&_0sVS*|jYYBuo1EbkmfcaLZp6X1M-h$+|j(&=XiFx6&#RAl8^prK5tvHQej;O1Kg6d$EYq1=-TB ztc}*D?Hf$kCE)sH0-P)eqmtX>A<;Y}_D!HPCvW-szHA%(~=3X^UC z`op)P5abI2jC^TRW|MO@ZQi_< zb%c7N3%!57_3>@-il9NuHRv@oa}h^u@c8HA{(4iS9_RcU09G&>v5z7(d|$RBZDIoF zK6-m{fP`8O*LsiK3Lk49m%IzZrghwv{E4`=$nI=}vgv8Gk@VTkCZ8)OBmn>|)pdAv zoe_6y{9=y@S&-^N`Nn4jUO(ih?z3tk!^8ce2u>g2*ga4shl>OCeBN0_$QiI+HRDI% zHU!g|!c71|f&2%MOXZ{+198KOitv z^W}FUfr@|_$0$aURmzr-T>SKac(MQ&wmYxi!zl)?&bIl6JE}e^WrMS~(#W~r>|&6L z0^#C8UfLy;lBwRe%b^ln?;0Fa77Z0lmAfm3Oyd^IEDOU5`n!j+`QQU$Jy?I> zi=y~1%Ikux+m)+dRB3hCCog42+aO>(ho7iGBmwsVW-hF9_f{_VW1@gh6YPvU2gn)_ zF`lDO>K#$!XP}H@+DWUccNZQNTu)D+QS&)<)h)k?@sqm3yriOzsCy{-Yk-p1g`mNU zZAID{pco*aSL}HL^xkw3j2qwthIZHruF}Idtlr3ps|@mzphR2UKJ>oT5XfTfV4arj z(Q*%v(oK7kf1Y!lRFBi<`f*kP=$YfXI^7l30*x@UZ~GfyH6J=O30AOt@*ynRH(R7N-NoayfnD zi#{uh5bM>TSH@mZ?F^V>w=AJJf$ujWEO%a)K71yt%w1eOEx(uhK&H)EDcS=OoX*lS2oMZ04Uhp$n`Cl~P~+;bP~@*H2Qc(8eAi-A_-dC0z!g_4-2%*d7SS=Gm6tG&!Ok*B;D zYlE*UL~AePxlu*E5;Vc=RU@}asD8m`O3y=4IJJgbZK4zI4iSl~LKSe0d-wdmMfh<` zd(81h&$gVrA0zPH`G&&jEmgdBU2epTIy82K`M<0hEvRha8?fXh?r*G=bpIR`)mYk_ zz`unwurHz;vEbI5DMV$hFli3Pw@pgj8qgMg-d#y#aEC!%G65#v_XqPl01cT7N1d+a z#a$T?j*a4of49DTReer-M#Xj2N?qMLMi`-JKCvs+T7J49N}UMFXGBj>p+DWHg(K4S za81%@2M(ln;f?xM?Pwi@=ujemo1R6VxYLK49UC<>@P#CiLSEyMF9|n4`^cNpjhVOs zzRi+Bqd!04T!%AqtE{JC%{xk=kok{%bF6xnZF?0+NA&6Kzh3t*iqIr9%=3XzKfT!g z)0|-p-Od}tlQI4DGzU{Od%bHDS>;T(19ETu;T^8B?pUe%bJI(}DFsHgO z65BY<6}sCR82w=8(@!o}r7~*Q6n~d-a*t3Y{2TfS(4varwQhT7eZGIKUZLIV-464T z-{+{14MKcafqvo`I-{T8tnFE70x@wS>2xZ=su`wyI? zIJuvoBEEY}5xjLExt%CS@3k`7w5{X~%mN+rJX*R>=b9tzv;W@r^{Jy=54wm-!ItJb z1|Ev!XAnvK1(>be{lQCjcvIic{y9GNws(CR$88CY%BH zsYr5P;V|rEQp*=ZWK2h29mxoeterPlx&};R*n69C<~W?l;8tif76OvDORtcKf&U&Ox|9)&m>4*-bVT z5r&ZfuKSk5+JX+rULnukUc;$^wkJ%R=Dy|Wvo%>x5}-fw5GHIjj1L$OXhvqU*y6i-j*Ql>Sa--~=4+|ABN*dt$13jGD+PBFq0Z0rBNVdjz`n#*h;L+kETis7|$4u02pjfw;vt74#2H5bn=(7&k zOcfeR4K%9j%WV4NZv|G*!*9dwWIjB;_&&}AOR1w6pg!`(V|f;AE}y^qNX)q4v1hKQ zCBTcrg8@^sg^yrptVQWnPJmSl00P5F-)F&YhwXhk?PK2m*j|G9fTcZs-7RLvM)epq zxEzov#A}<90gO`l*?|Ytnf)LGs`Jkv$~8G$1F|C5Y@6f@QS&EtbpJ9OvaMYFR;xpxf=*|d%phWR~v>V$Z>U~FnF zMmmRboH0qC^`MeVGVduNS`eq+qR8Y0>*Tdy~OvP$LTF50*BBV9;SlBp=exg zQpp-$Tu-;!egBmlbz)6Tv{qY&hCwIaYoMtbQnAZd);_YEj7b8f%&WtcamDe4fsge| zp~kThy})c=UKSTs7M08eno$ZTeH*H!OLbQELEDf@w~5I!*NDnSRTCOg{d89LDim3O z0WmrR)-&MI{uMwU0An3*`=9B(9vm&VQp?L3Np7U$JmE%~8n3u+0;8)=n|4k_sE%}K zri$)bCB9 z(X;uklxti-u6ha8M{2Lv`CO?K2$;hfErMB9D(!|cDL^DAxbWivfo!UwW^aF_+jQJ+2+XGSNYesiX*MjabzJA{ z8atNS%$5pV^a@b(AB>K59%$2L=>4T)ghIjpX8Y2=To7o>LoYj?_TaTXqocmwswWAV zx`VZgQePEJ3>H(->rbUc>VQ++=5!QNGOW|aTmWmZGN`k%ncKpIJ3G?4cSZRx!xauj zYuPdt3=_3YHs>`E>spO*p|r}K3mh)~8Awpqv@NYPV53Ir;34JCT!6?_oW^&L@>Sso zk^Y1Yv-ZFND`{-;yAlqyYiOIdA)anQUZkKr6w88FUWiQv%N9Frs~E>{iuXpYwZK!J zh8N9Z)utN>xqMb`{q`EKpDIONC7mj2Z>(@vVsU`MBDCFZqTqd^h=O>PXcZxwQ@_NtK$OE0{ZXv=BF1LOWKD;vJWKeh6(`N)(v8f{8r}T{A3wvr=l+*bx$jm^_R{5o8@MXx4#bG~0t``NjRhiO3!6 zPwW?FfwQ+3YRh=i@4?dI$j@ZrZAVYO*wr2k_Re`keDZ(=5{~*F?!0dGsVZbSUMs=_JVah~;*4ru`>>^ptm@{=}B$hhtSb&bi ze?5$(M?L-2=`nT+MrCH>@4~!X&E*+JT{qEi#tNjiofFeYeBF7uE^Npp4-kNqd-zP? zKg1V+GA=uMj#zT(=TFZ^ZZ=I@*{D1**LXP<2gZu``3(v*6^>aheUgfyc1BL$166C; zr|M2aK|>qVpPwSJbLGz(rNI?qLFDo;fH`JLe_76dmvg}N^XD~5+^$Uo828L**s0Nc zF7**Oau_>@<&!@35iIcRMw`^tEcR{Mu&I^)fm_yJRzg^B??MaS`vGH=SJSFt6nqg} zE~+uZU!i{XFGR4{0ML03Sb9IA$DWepu3E=t#|}U}Zu1e$Y16NAVDl-E?vG%GTh8NG z7%n=%_^nSKeM9iOM-_ zzh*1o$8_J-4cLU49Q6FxS@47epZ=@C%0AKM&}B6&mY86G=qr~XfB};B`_tT#9i`_L z(7Xc6%eqv&?UHtT7iV7XC1!((wai=i6$b<4Q3FJ>vTjL-Bj4cLq@nn>LEWV)9ax`V z-Er*nKWp&$pM9$&8qQDctbcFka#8!o;y5YmGBB4h_Q2|uFH~F8=|f+(g08ISj=v~( z5yxSO4lME1UO}Y2!)NQ2;^T0(jWC7lun(Be(dr}0CZMAgZQAz{14fouYq{@OmE*)5 z zp-F$@SA@bAEllf_$-SXtuj?@&*BbKJp=$rq`Xd(&>a&S$CjG`PF3kG*sF%5(V@z6S z6U_%vB~zC1EZjVg&DzC>zKchiHY;>0KU`uev_37E`%HWEjU`0useLTMLu1jd9y7ER z6L6e00<<`U_h!xncY^zBVpc{WfrTCIdM7%wm`6m%91+dK)2fn~>fOV=-7Rv8qa*7` z#o#cfJz^U%9pJLPM%N|65i69WxF)sc-Dqh#7(6m{)AtPOY*cMnW@-MXD`KM2+bRpO z6-vqAX0em~2XbiDK4BW7UfoQOqGpQH(Q(^71t40=Cs^r!GtjO~Ki||k-67{RU!s_M zjDc-d^F`SZv9OhZwOn3}GelJ${8xlH%94e$g0I#y;P*yDTt=HQg)sa*G?~F$CxBKkFn)B+ zWk=+H7~wyDiYDDg(a!t;jNQLFxM6~|UpTy{(8C#4(R=Fju;HZNbZaOp4&+wi7~F55 zF7smMa;snS{^q4SE3;q%=;15Y@R%146PyQlaSOxQZ%)EmY=Dr(ezoF&3GjT_7kKTJ z0z+p1!MY&CFsZ5k^uU+fwun`=y3)0f<-sD4>v%Rx zA9?Ky3hceU(B<#kRC?rMLwK|CHc#b5t-7{BKapJ|Fwa-lY}Q}^f9I)h#~r7C&B+(; ziN@hjvacDbdafGAHR{iMV&e*IjDvW4u*Js_3D8{pu$f}Hx~|!-ooe4fPJb~skM6>8 z$`XDO1&paYPIUhtV;%WZ(EdcEkG)yJU2C?o*9+Y|)88v0;_uAUKIx>(ONQ(Z7MwBe zug)eNtJDD9D<0F{38ils8TI{}-M~-pyH65Uk`IiaW6i_NPw8@WPIGs(H$?2*tV-DB zbLJIngYd?Y3i?oNbG7>dhvb}?Wx@*$uyX&H-@8$r@DQ@aCO=dLwB&gO_pmDqG~KTg z!_@i1H4Ua0+$9S|28vElt6aO1z9 zHj-*v!%5GWC{G(cH`%rK{Q}%f#)&%7O`=j0mYMthgliE|<1~(E?@@x-A?4EN>oIeK zGAvA!(DI~}CAd`;GT`Z0!Vnc_51zxYmymkAZNR+Fp@_znI`{dF^0Op~lyL^?JnL*ZW+(knim#ujxr!5ztSp#1_&p6xq%q6@lDsl!oa{bEy(7l!_g~sFD zcEOtkC`~gyCz2;bQ2&`pOX3-}cBgv5YF!;;sFx@K4=7^9BG1H-HYlx^jDC-Vh?iV~hKo=iR zyVc{1M#NQGOMDv$BXiGpE2+aYc`+3`d%)R6Ytfd#Ns-Pm?v0hUff}&)6uqWl9RD-eAX3wi^@A3fOQOQ{sUxZUTMj)$jXY# znD38DyS^!!#jx!C*|>pYS^60|5KI7EZjT)T%!JPv=PvJCE9eGTtSgNR?^0McU1|K@{B_OMa@yPE`RfOkU>LqAQP#(f)9VqUgVPysjSw#$!IA> z&KL1LG1wdBnEm9jw4Otmt`+-(@|C<1+) z9;llR#{^N+8RXxqSI@&%l@#6ZnV4BtJ6cK02_$f;5f#mhmQ5OE3Ip~ooRrHq zn7#LT-SwWggHPBadnPorZMGe3rEK+fAyuNx%zIxjbo3vBnu2h1_~gxP6#zZ zPd48&LvBmfYl+sNw{1OEO!lUlDxM)-zN2wMV^G*DPSu2kzD5Jp8{AAR+~#{h6f1e! z7>n80r46gYD-Knd2CxWO8E)EaC&bE1?@3tbXU#iD-TSKgudr}iYddV` zf&w>Q%K|eed&f6XojLe@qqWE@7Xn;IC541WhIZB-)m*Y4@jCTN5H_LY;i0I-wo$(SG>wpJzW(JY-opwkzO$R`4I@`Luta!_B2)oV$pTGrliIEfvknZ}3I z=Qg$qD8EWnTGw7|c0vdDPPvtFQj?rGiGRzt#kjG<-HGMK`IVzXvHk6WXE#UvuS3)3 zo89H*2Xj-98C@kIR+k5}4)RTrUV-f@*IUY*!$P`AXBDD};zvyw_Z$NX%jPyLDpxi} zU0Euhu}?4NyDE^Xg%r2F&sTfZB)|eIAP(v4anB7fA!Uqw0vHkgE@3|Z+LB@LP1w>9 zSQdI^?b5!$=>coWWkiG)=ZPzXeKSMq8jj`r;Py8r5`&~yAvVrj5QB@+qei_A!CVwA zTpQ7csczeBX@$)BEj91#VzHmsYJ|Nkb=7oR$#%u#mPBiHLn`;)#b8E=;^!?(m8(d& zZ??b44k>j{Td>esQIK5^2)F87>CNRY5M}}N>-K*%9JC55 zbe-c>uZJ7?SZrCK^wtHFw^U-+^G)px-OrY;&BS=`(bbZSL-bYn83JfgoM3p)!N=#1 zL5MlL)^+07OgqFB^7i}7gTD5Y3&W=?F?od=+;3+|hi?tD~S zgRc_H@aDq(1m0ZO?eyfoz0VU{l{GK#gnrq(u$*H>@1|DJ^O`&&?RV1X)r+Q&xdfNkykY&{QSbk@EwLNjH$8Pi_)@85 yAH}s3(Wd}i1b!sxfh_`l_C0}{0YBf@S0%;b^kqix#RTDhe<-UYQz&KR`+op7;)e+U literal 105812 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 M|6O9HyGJ!3|Bxmyy?LP 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 diff --git a/event-sourcing/etc/event-sourcing.ucls b/event-sourcing/etc/event-sourcing.ucls index e6944ef70..2df56a479 100644 --- a/event-sourcing/etc/event-sourcing.ucls +++ b/event-sourcing/etc/event-sourcing.ucls @@ -1,50 +1,50 @@ - - - + - - - - - - - - - - - - - - - - + - - + + + + + + + + + + + + + + + @@ -55,203 +55,63 @@ project="event-sourcing" file="/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java" binary="false" corner="BOTTOM_RIGHT"> - + - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - - - - - - - - - + - - + + + + + + - + - - - - - - - - - - + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + transactions; /** * Instantiates a new Account. @@ -52,7 +55,6 @@ public class Account { this.accountNo = accountNo; this.owner = owner; money = BigDecimal.ZERO; - transactions = new ArrayList<>(); } /** @@ -91,23 +93,6 @@ public class Account { this.money = money; } - /** - * Gets transactions. - * - * @return the transactions - */ - public List getTransactions() { - return transactions; - } - - /** - * Sets transactions. - * - * @param transactions the transactions - */ - public void setTransactions(List transactions) { - this.transactions = transactions; - } /** * Copy account. @@ -117,7 +102,6 @@ public class Account { public Account copy() { Account account = new Account(accountNo, owner); account.setMoney(money); - account.setTransactions(transactions); return account; } @@ -127,29 +111,22 @@ public class Account { + "accountNo=" + accountNo + ", owner='" + owner + '\'' + ", money=" + money - + ", transactions=" + transactions + '}'; } - private Transaction depositMoney(BigDecimal money) { + private void depositMoney(BigDecimal money) { this.money = this.money.add(money); - Transaction transaction = new Transaction(accountNo, money, BigDecimal.ZERO, this.money); - transactions.add(transaction); - return transaction; } - private Transaction withdrawMoney(BigDecimal money) { + private void withdrawMoney(BigDecimal money) { this.money = this.money.subtract(money); - Transaction transaction = new Transaction(accountNo, BigDecimal.ZERO, money, this.money); - transactions.add(transaction); - return transaction; } private void handleDeposit(BigDecimal money, boolean realTime) { - Transaction transaction = depositMoney(money); + depositMoney(money); AccountAggregate.putAccount(this); if (realTime) { - Gateways.getTransactionLogger().log(transaction); + LOGGER.info("Some external api for only realtime execution could be called here."); } } @@ -158,15 +135,15 @@ public class Account { throw new RuntimeException("Insufficient Account Balance"); } - Transaction transaction = withdrawMoney(money); + withdrawMoney(money); AccountAggregate.putAccount(this); if (realTime) { - Gateways.getTransactionLogger().log(transaction); + LOGGER.info("Some external api for only realtime execution could be called here."); } } /** - * Handle event. + * Handles the MoneyDepositEvent. * * @param moneyDepositEvent the money deposit event */ @@ -176,29 +153,19 @@ public class Account { /** - * Handle event. - * - * @param moneyWithdrawalEvent the money withdrawal event - */ - public void handleEvent(MoneyWithdrawalEvent moneyWithdrawalEvent) { - handleWithdrawal(moneyWithdrawalEvent.getMoney(), moneyWithdrawalEvent.isRealTime()); - } - - /** - * Handle event. + * Handles the AccountCreateEvent. * * @param accountCreateEvent the account create event */ public void handleEvent(AccountCreateEvent accountCreateEvent) { AccountAggregate.putAccount(this); - // check if this event is replicated from journal before calling an external gateway function if (accountCreateEvent.isRealTime()) { - Gateways.getAccountCreateContractSender().sendContractInfo(this); + LOGGER.info("Some external api for only realtime execution could be called here."); } } /** - * Handle transfer from event. + * Handles transfer from account event. * * @param moneyTransferEvent the money transfer event */ @@ -207,7 +174,7 @@ public class Account { } /** - * Handle transfer to event. + * Handles transfer to account event. * * @param moneyTransferEvent the money transfer event */ diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java deleted file mode 100644 index a0d921f5f..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.domain; - -import java.math.BigDecimal; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class Transaction { - - private final int accountNo; - private final BigDecimal moneyIn; - private final BigDecimal moneyOut; - private final BigDecimal lastBalance; - - /** - * Instantiates a new Transaction. - * - * @param accountNo the account no - * @param moneyIn the money in - * @param moneyOut the money out - * @param lastBalance the last balance - */ - public Transaction(int accountNo, BigDecimal moneyIn, BigDecimal moneyOut, - BigDecimal lastBalance) { - this.accountNo = accountNo; - this.moneyIn = moneyIn; - this.moneyOut = moneyOut; - this.lastBalance = lastBalance; - } - - /** - * Gets account no. - * - * @return the account no - */ - public int getAccountNo() { - return accountNo; - } - - /** - * Gets money in. - * - * @return the money in - */ - public BigDecimal getMoneyIn() { - return moneyIn; - } - - /** - * Gets money out. - * - * @return the money out - */ - public BigDecimal getMoneyOut() { - return moneyOut; - } - - /** - * Gets last balance. - * - * @return the last balance - */ - public BigDecimal getLastBalance() { - return lastBalance; - } - - @Override - public String toString() { - return "Transaction{" - + "accountNo=" + accountNo - + ", moneyIn=" + moneyIn - + ", moneyOut=" + moneyOut - + ", lastBalance=" + lastBalance - + '}'; - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java index 350104267..c526396f3 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java @@ -22,11 +22,15 @@ */ package com.iluwatar.event.sourcing.event; -import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; /** + * This is the class that implements account create event. + * Holds the necessary info for an account create event. + * Implements the process function that finds the event related + * domain objects and calls the related domain object's handle event functions + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public class AccountCreateEvent extends DomainEvent { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/DomainEvent.java similarity index 95% rename from event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java rename to event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/DomainEvent.java index 6eb5141a2..fa6539a4f 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/DomainEvent.java @@ -20,11 +20,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.event.sourcing.api; +package com.iluwatar.event.sourcing.event; import java.io.Serializable; /** + * This is the base class for domain events. All events must extend this class. + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public abstract class DomainEvent implements Serializable { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java index 3fb61bd08..1629263a7 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java @@ -22,18 +22,22 @@ */ package com.iluwatar.event.sourcing.event; -import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; /** + * This is the class that implements money deposit event. + * Holds the necessary info for a money deposit event. + * Implements the process function that finds the event related + * domain objects and calls the related domain object's handle event functions + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public class MoneyDepositEvent extends DomainEvent { - private BigDecimal money; - private int accountNo; + private final BigDecimal money; + private final int accountNo; /** * Instantiates a new Money deposit event. diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java index bbba89988..0307d3af7 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java @@ -22,19 +22,23 @@ */ package com.iluwatar.event.sourcing.event; -import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; /** + * This is the class that implements money transfer event. + * Holds the necessary info for a money transfer event. + * Implements the process function that finds the event related + * domain objects and calls the related domain object's handle event functions + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public class MoneyTransferEvent extends DomainEvent { - private BigDecimal money; - private int accountNoFrom; - private int accountNoTo; + private final BigDecimal money; + private final int accountNoFrom; + private final int accountNoTo; /** * Instantiates a new Money transfer event. @@ -63,7 +67,7 @@ public class MoneyTransferEvent extends DomainEvent { } /** - * Gets account no from. + * Gets account no which the money comes from. * * @return the account no from */ @@ -72,7 +76,7 @@ public class MoneyTransferEvent extends DomainEvent { } /** - * Gets account no to. + * Gets account no which the money goes to. * * @return the account no to */ diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java deleted file mode 100644 index d8c295002..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.event; - -import com.iluwatar.event.sourcing.api.DomainEvent; -import com.iluwatar.event.sourcing.domain.Account; -import com.iluwatar.event.sourcing.state.AccountAggregate; -import java.math.BigDecimal; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class MoneyWithdrawalEvent extends DomainEvent { - - private BigDecimal money; - private int accountNo; - - /** - * Instantiates a new Money withdrawal event. - * - * @param sequenceId the sequence id - * @param createdTime the created time - * @param accountNo the account no - * @param money the money - */ - public MoneyWithdrawalEvent(long sequenceId, long createdTime, int accountNo, BigDecimal money) { - super(sequenceId, createdTime, "MoneyWithdrawalEvent"); - this.money = money; - this.accountNo = accountNo; - } - - /** - * Gets money. - * - * @return the money - */ - public BigDecimal getMoney() { - return money; - } - - /** - * Gets account no. - * - * @return the account no - */ - public int getAccountNo() { - return accountNo; - } - - @Override - public void process() { - Account account = AccountAggregate.getAccount(accountNo); - if (account == null) { - throw new RuntimeException("Account not found"); - } - account.handleEvent(this); - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java deleted file mode 100644 index baaf41f56..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.gateway; - -import com.iluwatar.event.sourcing.domain.Account; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class AccountCreateContractSender { - - /** - * Send contract info. - * - * @param account the account - */ - public void sendContractInfo(Account account) { - // an example imaginary funciton which sends account info to some external end point - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java deleted file mode 100644 index 84bdff3b2..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.gateway; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class Gateways { - - private static AccountCreateContractSender accountCreateContractSender = new AccountCreateContractSender(); - private static TransactionLogger transactionLogger = new TransactionLogger(); - - /** - * Gets account create contract sender. - * - * @return the account create contract sender - */ - public static AccountCreateContractSender getAccountCreateContractSender() { - return accountCreateContractSender; - } - - /** - * Gets transaction logger. - * - * @return the transaction logger - */ - public static TransactionLogger getTransactionLogger() { - return transactionLogger; - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java deleted file mode 100644 index 42ae7a1f5..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.gateway; - -import com.iluwatar.event.sourcing.domain.Transaction; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class TransactionLogger { - - /** - * Log. - * - * @param transaction the transaction - */ - public void log(Transaction transaction) { - // example imaginary function that logs the transaction to somewhere - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java index 38e72995d..05308c7c1 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java @@ -22,33 +22,43 @@ */ package com.iluwatar.event.sourcing.processor; -import com.iluwatar.event.sourcing.api.DomainEvent; -import com.iluwatar.event.sourcing.api.EventProcessor; -import com.iluwatar.event.sourcing.api.ProcessorJournal; +import com.iluwatar.event.sourcing.event.DomainEvent; /** + * This is the implementation of event processor. + * All events are processed by this class. + * This processor uses processorJournal to persist and recover events. + * * Created by Serdar Hamzaogullari on 06.08.2017. */ -public class DomainEventProcessor implements EventProcessor { +public class DomainEventProcessor { - private ProcessorJournal precessorJournal; + private final JsonFileJournal processorJournal = new JsonFileJournal(); - @Override + /** + * Process. + * + * @param domainEvent the domain event + */ public void process(DomainEvent domainEvent) { domainEvent.process(); - precessorJournal.write(domainEvent); + processorJournal.write(domainEvent); } - @Override - public void setPrecessorJournal(ProcessorJournal precessorJournal) { - this.precessorJournal = precessorJournal; + /** + * Reset. + */ + public void reset() { + processorJournal.reset(); } - @Override + /** + * Recover. + */ public void recover() { DomainEvent domainEvent; while (true) { - domainEvent = precessorJournal.readNext(); + domainEvent = processorJournal.readNext(); if (domainEvent == null) { break; } else { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/JsonFileJournal.java similarity index 84% rename from event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java rename to event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/JsonFileJournal.java index 9379e7b5c..870d8d00f 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/JsonFileJournal.java @@ -20,17 +20,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.event.sourcing.journal; +package com.iluwatar.event.sourcing.processor; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonParser; -import com.iluwatar.event.sourcing.api.DomainEvent; -import com.iluwatar.event.sourcing.api.ProcessorJournal; import com.iluwatar.event.sourcing.event.AccountCreateEvent; +import com.iluwatar.event.sourcing.event.DomainEvent; import com.iluwatar.event.sourcing.event.MoneyDepositEvent; import com.iluwatar.event.sourcing.event.MoneyTransferEvent; -import com.iluwatar.event.sourcing.event.MoneyWithdrawalEvent; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -44,12 +42,16 @@ import java.util.ArrayList; import java.util.List; /** + * This is the implementation of event journal. + * This implementation serialize/deserialize the events with JSON + * and writes/reads them on a Journal.json file at the working directory. + * * Created by Serdar Hamzaogullari on 06.08.2017. */ -public class JsonFileJournal implements ProcessorJournal { +public class JsonFileJournal { - private File aFile; - private List events = new ArrayList<>(); + private final File aFile; + private final List events = new ArrayList<>(); private int index = 0; /** @@ -72,7 +74,12 @@ public class JsonFileJournal implements ProcessorJournal { } } - @Override + + /** + * Write. + * + * @param domainEvent the domain event + */ public void write(DomainEvent domainEvent) { Gson gson = new Gson(); JsonElement jsonElement; @@ -80,9 +87,7 @@ public class JsonFileJournal implements ProcessorJournal { jsonElement = gson.toJsonTree(domainEvent, AccountCreateEvent.class); } else if (domainEvent instanceof MoneyDepositEvent) { jsonElement = gson.toJsonTree(domainEvent, MoneyDepositEvent.class); - } else if (domainEvent instanceof MoneyWithdrawalEvent) { - jsonElement = gson.toJsonTree(domainEvent, MoneyWithdrawalEvent.class); - } else if (domainEvent instanceof MoneyTransferEvent) { + } else if (domainEvent instanceof MoneyTransferEvent) { jsonElement = gson.toJsonTree(domainEvent, MoneyTransferEvent.class); } else { throw new RuntimeException("Journal Event not recegnized"); @@ -97,13 +102,20 @@ public class JsonFileJournal implements ProcessorJournal { } } - @Override + + /** + * Reset. + */ public void reset() { aFile.delete(); } - @Override + /** + * Read next domain event. + * + * @return the domain event + */ public DomainEvent readNext() { if (index >= events.size()) { return null; @@ -122,9 +134,7 @@ public class JsonFileJournal implements ProcessorJournal { domainEvent = gson.fromJson(jsonElement, MoneyDepositEvent.class); } else if (eventClassName.equals("MoneyTransferEvent")) { domainEvent = gson.fromJson(jsonElement, MoneyTransferEvent.class); - } else if (eventClassName.equals("MoneyWithdrawalEvent")) { - domainEvent = gson.fromJson(jsonElement, MoneyWithdrawalEvent.class); - } else { + } else { throw new RuntimeException("Journal Event not recegnized"); } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java index cfe0cfbb3..2d957268e 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java @@ -27,12 +27,18 @@ import java.util.HashMap; import java.util.Map; /** + * This is the static accounts map holder class. + * This class holds the state of the accounts. + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public class AccountAggregate { private static Map accounts = new HashMap<>(); + private AccountAggregate() { + } + /** * Put account. * @@ -46,7 +52,7 @@ public class AccountAggregate { * Gets account. * * @param accountNo the account no - * @return the account + * @return the copy of the account or null if not found */ public static Account getAccount(int accountNo) { Account account = accounts.get(accountNo); diff --git a/event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java b/event-sourcing/src/test/java/IntegrationTest.java similarity index 59% rename from event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java rename to event-sourcing/src/test/java/IntegrationTest.java index 8fbed333d..5a3f5718a 100644 --- a/event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java +++ b/event-sourcing/src/test/java/IntegrationTest.java @@ -20,16 +20,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.event.sourcing; import static com.iluwatar.event.sourcing.app.App.ACCOUNT_OF_DAENERYS; import static com.iluwatar.event.sourcing.app.App.ACCOUNT_OF_JON; import com.iluwatar.event.sourcing.domain.Account; -import com.iluwatar.event.sourcing.journal.JsonFileJournal; +import com.iluwatar.event.sourcing.event.AccountCreateEvent; +import com.iluwatar.event.sourcing.event.MoneyDepositEvent; +import com.iluwatar.event.sourcing.event.MoneyTransferEvent; import com.iluwatar.event.sourcing.processor.DomainEventProcessor; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; +import java.util.Date; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -44,31 +46,14 @@ public class IntegrationTest { /** * The Domain event processor. */ - DomainEventProcessor domainEventProcessor; - /** - * The Json file journal. - */ - JsonFileJournal jsonFileJournal; - /** - * The Account service. - */ - AccountService accountService; - /** - * The Money transaction service. - */ - MoneyTransactionService moneyTransactionService; + private DomainEventProcessor eventProcessor; /** * Initialize. */ @Before public void initialize() { - domainEventProcessor = new DomainEventProcessor(); - jsonFileJournal = new JsonFileJournal(); - domainEventProcessor.setPrecessorJournal(jsonFileJournal); - accountService = new AccountService(domainEventProcessor); - moneyTransactionService = new MoneyTransactionService( - domainEventProcessor); + eventProcessor = new DomainEventProcessor(); } /** @@ -76,27 +61,31 @@ public class IntegrationTest { */ @Test public void testStateRecovery() { - jsonFileJournal.reset(); + eventProcessor.reset(); - accountService.createAccount(ACCOUNT_OF_DAENERYS, "Daenerys Targaryen"); - accountService.createAccount(ACCOUNT_OF_JON, "Jon Snow"); + eventProcessor.process(new AccountCreateEvent( + 0, new Date().getTime(), ACCOUNT_OF_DAENERYS, "Daenerys Targaryen")); - moneyTransactionService.depositMoney(ACCOUNT_OF_DAENERYS, new BigDecimal("100000")); - moneyTransactionService.depositMoney(ACCOUNT_OF_JON, new BigDecimal("100")); + eventProcessor.process(new AccountCreateEvent( + 1, new Date().getTime(), ACCOUNT_OF_JON, "Jon Snow")); - moneyTransactionService - .transferMoney(ACCOUNT_OF_DAENERYS, ACCOUNT_OF_JON, new BigDecimal("10000")); - moneyTransactionService.withdrawalMoney(ACCOUNT_OF_JON, new BigDecimal("1000")); + eventProcessor.process(new MoneyDepositEvent( + 2, new Date().getTime(), ACCOUNT_OF_DAENERYS, new BigDecimal("100000"))); + + eventProcessor.process(new MoneyDepositEvent( + 3, new Date().getTime(), ACCOUNT_OF_JON, new BigDecimal("100"))); + + eventProcessor.process(new MoneyTransferEvent( + 4, new Date().getTime(), new BigDecimal("10000"), ACCOUNT_OF_DAENERYS, + ACCOUNT_OF_JON)); Account accountOfDaenerysBeforeShotDown = AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS); Account accountOfJonBeforeShotDown = AccountAggregate.getAccount(ACCOUNT_OF_JON); AccountAggregate.resetState(); - domainEventProcessor = new DomainEventProcessor(); - jsonFileJournal = new JsonFileJournal(); - domainEventProcessor.setPrecessorJournal(jsonFileJournal); - domainEventProcessor.recover(); + eventProcessor = new DomainEventProcessor(); + eventProcessor.recover(); Account accountOfDaenerysAfterShotDown = AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS); Account accountOfJonAfterShotDown = AccountAggregate.getAccount(ACCOUNT_OF_JON); @@ -105,11 +94,6 @@ public class IntegrationTest { accountOfDaenerysAfterShotDown.getMoney()); Assert .assertEquals(accountOfJonBeforeShotDown.getMoney(), accountOfJonAfterShotDown.getMoney()); - Assert.assertEquals(accountOfDaenerysBeforeShotDown.getTransactions().size(), - accountOfDaenerysAfterShotDown.getTransactions().size()); - Assert.assertEquals(accountOfJonBeforeShotDown.getTransactions().size(), - accountOfJonAfterShotDown.getTransactions().size()); - } } \ No newline at end of file From 9d2f0c6c71c2105d8468f4d3fe4526fc611ca361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 2 Sep 2017 23:10:39 +0300 Subject: [PATCH 44/45] #590 Add explanation to Decorator pattern --- decorator/README.md | 91 +++++++++++++++++- decorator/etc/decorator.png | Bin 21795 -> 0 bytes decorator/etc/decorator.ucls | 76 --------------- decorator/etc/decorator.urm.puml | 38 -------- .../com/iluwatar/decorator/ClubbedTroll.java | 15 ++- .../iluwatar/decorator/TrollDecorator.java | 53 ---------- .../iluwatar/decorator/ClubbedTrollTest.java | 2 +- pom.xml | 1 + 8 files changed, 103 insertions(+), 173 deletions(-) delete mode 100644 decorator/etc/decorator.png delete mode 100644 decorator/etc/decorator.ucls delete mode 100644 decorator/etc/decorator.urm.puml delete mode 100644 decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java diff --git a/decorator/README.md b/decorator/README.md index d2ba55afa..5f86166fe 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -19,7 +19,96 @@ Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. -![alt text](./etc/decorator.png "Decorator") +## Explanation + +Real world example + +> There is an angry troll living in the nearby hills. Usually it goes bare handed but sometimes it has a weapon. To arm the troll it's not necessary to create a new troll but to decorate it dynamically with a suitable weapon. + +In plain words + +> Decorator pattern lets you dynamically change the behavior of an object at run time by wrapping them in an object of a decorator class. + +Wikipedia says + +> In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern. + +**Programmatic Example** + +Lets take the troll example. First of all we have a simple troll implementing the troll interface + +``` +public interface Troll { + void attack(); + int getAttackPower(); + void fleeBattle(); +} + +public class SimpleTroll implements Troll { + + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTroll.class); + + @Override + public void attack() { + LOGGER.info("The troll tries to grab you!"); + } + + @Override + public int getAttackPower() { + return 10; + } + + @Override + public void fleeBattle() { + LOGGER.info("The troll shrieks in horror and runs away!"); + } +} +``` + +Next we want to add club for the troll. We can do it dynamically by using a decorator + +``` +public class ClubbedTroll implements Troll { + + private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class); + + private Troll decorated; + + public ClubbedTroll(Troll decorated) { + this.decorated = decorated; + } + + @Override + public void attack() { + decorated.attack(); + LOGGER.info("The troll swings at you with a club!"); + } + + @Override + public int getAttackPower() { + return decorated.getAttackPower() + 10; + } + + @Override + public void fleeBattle() { + decorated.fleeBattle(); + } +} +``` + +Here's the troll in action + +``` +// simple troll +Troll troll = new SimpleTroll(); +troll.attack(); // The troll tries to grab you! +troll.fleeBattle(); // The troll shrieks in horror and runs away! + +// change the behavior of the simple troll by adding a decorator +Troll clubbed = new ClubbedTroll(troll); +clubbed.attack(); // The troll tries to grab you! The troll swings at you with a club! +clubbed.fleeBattle(); // The troll shrieks in horror and runs away! +``` ## Applicability Use Decorator diff --git a/decorator/etc/decorator.png b/decorator/etc/decorator.png deleted file mode 100644 index 35a7ef35db7e7aac6621d6d33116ad2d692a76cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21795 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 KIaN6BNcsz+?~j@Q diff --git a/decorator/etc/decorator.ucls b/decorator/etc/decorator.ucls deleted file mode 100644 index 88bea6987..000000000 --- a/decorator/etc/decorator.ucls +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/decorator/etc/decorator.urm.puml b/decorator/etc/decorator.urm.puml deleted file mode 100644 index be878bd91..000000000 --- a/decorator/etc/decorator.urm.puml +++ /dev/null @@ -1,38 +0,0 @@ -@startuml -package com.iluwatar.decorator { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } - class ClubbedTroll { - - LOGGER : Logger {static} - + ClubbedTroll(decorated : Troll) - + attack() - + getAttackPower() : int - } - class SimpleTroll { - - LOGGER : Logger {static} - + SimpleTroll() - + attack() - + fleeBattle() - + getAttackPower() : int - } - interface Troll { - + attack() {abstract} - + fleeBattle() {abstract} - + getAttackPower() : int {abstract} - } - class TrollDecorator { - - decorated : Troll - + TrollDecorator(decorated : Troll) - + attack() - + fleeBattle() - + getAttackPower() : int - } -} -TrollDecorator --> "-decorated" Troll -ClubbedTroll --|> TrollDecorator -SimpleTroll ..|> Troll -TrollDecorator ..|> Troll -@enduml \ No newline at end of file diff --git a/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java index e309f17cd..edaa334a5 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java +++ b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java @@ -28,22 +28,29 @@ import org.slf4j.LoggerFactory; /** * Decorator that adds a club for the troll */ -public class ClubbedTroll extends TrollDecorator { +public class ClubbedTroll implements Troll { private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class); + private Troll decorated; + public ClubbedTroll(Troll decorated) { - super(decorated); + this.decorated = decorated; } @Override public void attack() { - super.attack(); + decorated.attack(); LOGGER.info("The troll swings at you with a club!"); } @Override public int getAttackPower() { - return super.getAttackPower() + 10; + return decorated.getAttackPower() + 10; + } + + @Override + public void fleeBattle() { + decorated.fleeBattle(); } } diff --git a/decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java b/decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java deleted file mode 100644 index d84c3a2b3..000000000 --- a/decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.decorator; - -/** - * TrollDecorator is a decorator for {@link Troll} objects. The calls to the {@link Troll} interface - * are intercepted and decorated. Finally the calls are delegated to the decorated {@link Troll} - * object. - * - */ -public class TrollDecorator implements Troll { - - private Troll decorated; - - public TrollDecorator(Troll decorated) { - this.decorated = decorated; - } - - @Override - public void attack() { - decorated.attack(); - } - - @Override - public int getAttackPower() { - return decorated.getAttackPower(); - } - - @Override - public void fleeBattle() { - decorated.fleeBattle(); - } -} diff --git a/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java b/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java index a097752cd..fb86615c6 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java @@ -34,7 +34,7 @@ import static org.mockito.internal.verification.VerificationModeFactory.times; public class ClubbedTrollTest { @Test - public void testSmartHostile() throws Exception { + public void testClubbedTroll() throws Exception { // Create a normal troll first, but make sure we can spy on it later on. final Troll simpleTroll = spy(new SimpleTroll()); diff --git a/pom.xml b/pom.xml index 6212ddc05..5e3995976 100644 --- a/pom.xml +++ b/pom.xml @@ -469,6 +469,7 @@ adapter bridge composite + decorator From a745c5d8cea8f7371ec3abb1f7b3a09124ede100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 3 Sep 2017 12:06:50 +0300 Subject: [PATCH 45/45] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 64f833e2d..fd0bb7810 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ datanucleus.log /bin/ *.log data-mapper/src/main/resources/log4j.xml +event-sourcing/Journal.json