uk.co.onehp.trickle.ui.BetView.java Source code

Java tutorial

Introduction

Here is the source code for uk.co.onehp.trickle.ui.BetView.java

Source

/*
 * Betfair Trickle. Automatic bet placement application. Copyright (C) 2011
 * Thomas Inman. This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version. This program is distributed in the hope that it
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details. You should have received a copy of the GNU
 * General Public License along with this program; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
package uk.co.onehp.trickle.ui;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

import uk.co.onehp.trickle.controller.domain.DomainController;
import uk.co.onehp.trickle.domain.Bet;
import uk.co.onehp.trickle.domain.BetLog;
import uk.co.onehp.trickle.domain.BetType;
import uk.co.onehp.trickle.domain.BettingAspect;
import uk.co.onehp.trickle.domain.Horse;
import uk.co.onehp.trickle.domain.Meeting;
import uk.co.onehp.trickle.domain.Race;
import uk.co.onehp.trickle.domain.Strategy;
import uk.co.onehp.trickle.util.BettingUtil;
import uk.co.onehp.trickle.util.DateUtil;

import com.google.common.collect.Lists;
import com.vaadin.data.Container;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.Notification;
import com.vaadin.ui.themes.BaseTheme;

@Configurable(preConstruction = true)
public class BetView extends CustomComponent {
    private static final long serialVersionUID = 37912938374833758L;
    private static final String[] INCOMPLETE_BETS_COLUMNS = { "Meeting", "Time", "Race", "Horse", "Strategy" };

    @Autowired
    private DomainController domainController;

    private HorizontalLayout mainLayout;
    private List<Meeting> meetings;
    private List<Strategy> strategies;
    private List<Bet> incompleteBets;
    private List<Bet> completeBets;
    private Table incompleteBetsTable;
    private Button deleteBetButton;
    private Button clearAllBetsButton;
    private Tree meetingsTree;
    private Tree completeBetsTree;
    private VerticalLayout incompleteBetsSection;
    private VerticalLayout formSection;
    private VerticalLayout completeBetsSection;
    private Panel meetingsTreePanel;
    private Panel completeBetsTreePanel;
    private ComboBox strategy;
    private final Label formTitle = new Label("New Bet");
    private Button saveBetButton;

    private final ClickListener saveBetListener = new ClickListener() {
        private static final long serialVersionUID = 3652412596841159881L;

        @Override
        public void buttonClick(ClickEvent event) {
            if (validateForm()) {
                final Bet bet = new Bet(
                        (Horse) BetView.this.meetingsTree
                                .getContainerProperty(BetView.this.meetingsTree.getValue(), "Horse").getValue(),
                        (Strategy) BetView.this.strategy
                                .getContainerProperty(BetView.this.strategy.getValue(), "Strategy").getValue());
                BetView.this.domainController.saveBet(bet);
                addBetToTableContainer(BetView.this.incompleteBetsTable.getContainerDataSource(), bet);
                getWindow().showNotification("Bet Saved", Notification.TYPE_HUMANIZED_MESSAGE);
            }
        }
    };

    private final ClickListener deleteBetListener = new ClickListener() {
        private static final long serialVersionUID = 3652412596841159881L;

        @Override
        public void buttonClick(ClickEvent event) {
            if (null != BetView.this.incompleteBetsTable.getValue()) {
                Bet bet = (Bet) BetView.this.incompleteBetsTable
                        .getContainerProperty(BetView.this.incompleteBetsTable.getValue(), "Bet").getValue();
                BetView.this.domainController.deleteBet(bet);
                BetView.this.incompleteBetsTable.setValue(null);
                populateIncompleteBetsTable();
                getWindow().showNotification("Bet Deleted", Notification.TYPE_HUMANIZED_MESSAGE);
            }
        }
    };

    private final ClickListener clearAllBetsListener = new ClickListener() {
        private static final long serialVersionUID = 3652412596841159881L;

        @Override
        public void buttonClick(ClickEvent event) {
            BetView.this.domainController.deleteIncompleteBets();
            BetView.this.incompleteBetsTable.setValue(null);
            populateIncompleteBetsTable();
            getWindow().showNotification("All Bets Cleared", Notification.TYPE_HUMANIZED_MESSAGE);
        }
    };

    public BetView() {
        this.meetings = this.domainController.getAllMeetings();
        this.strategies = this.domainController.getAllStrategies();
        this.incompleteBets = this.domainController.getIncompleteBets();
        this.completeBets = this.domainController.getCompleteBets();
        buildView();
        setCompositionRoot(this.mainLayout);
    }

    private void buildView() {
        this.mainLayout = new HorizontalLayout();
        this.mainLayout.setSpacing(true);
        this.mainLayout.setMargin(true);

        this.formSection = new VerticalLayout();
        this.formSection.setSpacing(true);

        this.incompleteBetsSection = new VerticalLayout();
        this.incompleteBetsSection.setSpacing(true);

        this.completeBetsSection = new VerticalLayout();
        this.completeBetsSection.setSpacing(true);

        this.meetingsTreePanel = new Panel();
        this.meetingsTreePanel.setHeight("350px");

        this.completeBetsTreePanel = new Panel();
        this.completeBetsTreePanel.setHeight("350px");

        this.meetingsTree = new Tree("Races", createTreeContainerFromMeetings());

        this.completeBetsTree = new Tree("Complete Bets", createTreeContainerFromCompleteBets());

        this.strategy = new ComboBox("Strategy", createDropdownContainerFromStrategies());

        this.incompleteBetsTable = new Table("Bets", createTableContainerFromIncompleteBets());
        this.incompleteBetsTable.setSelectable(true);
        this.incompleteBetsTable.setVisibleColumns(INCOMPLETE_BETS_COLUMNS);
        this.incompleteBetsTable.setWidth("100%");
        this.incompleteBetsTable.setHeight("350px");

        this.saveBetButton = new Button("Save Bet", this.saveBetListener);
        this.saveBetButton.setStyleName(BaseTheme.BUTTON_LINK);

        this.deleteBetButton = new Button("Delete Bet", this.deleteBetListener);
        this.deleteBetButton.setStyleName(BaseTheme.BUTTON_LINK);

        this.clearAllBetsButton = new Button("Clear All Bets", this.clearAllBetsListener);
        this.clearAllBetsButton.setStyleName(BaseTheme.BUTTON_LINK);

        this.meetingsTreePanel.addComponent(this.meetingsTree);

        this.completeBetsTreePanel.addComponent(this.completeBetsTree);

        setupFormFields();

        this.formSection.addComponent(this.formTitle);
        this.formSection.addComponent(this.meetingsTreePanel);
        this.formSection.addComponent(this.strategy);
        this.formSection.addComponent(this.saveBetButton);

        this.incompleteBetsSection.addComponent(this.incompleteBetsTable);
        this.incompleteBetsSection.addComponent(this.deleteBetButton);
        this.incompleteBetsSection.addComponent(this.clearAllBetsButton);

        this.completeBetsSection.addComponent(this.completeBetsTreePanel);

        this.mainLayout.addComponent(this.incompleteBetsSection);
        this.mainLayout.addComponent(this.formSection);
        this.mainLayout.addComponent(this.completeBetsSection);

    }

    public void populateMeetingsTree() {
        this.meetings = this.domainController.getAllMeetings();
        this.meetingsTree.setContainerDataSource(createTreeContainerFromMeetings());
    }

    public void populateIncompleteBetsTable() {
        this.incompleteBets = this.domainController.getIncompleteBets();
        this.incompleteBetsTable.setContainerDataSource(createTableContainerFromIncompleteBets());
        this.incompleteBetsTable.setVisibleColumns(INCOMPLETE_BETS_COLUMNS);
    }

    public void populateCompleteBetsTree() {
        this.completeBets = this.domainController.getCompleteBets();
        this.completeBetsTree.setContainerDataSource(createTreeContainerFromCompleteBets());
    }

    public void populateStrategyDropDown() {
        this.strategies = this.domainController.getAllStrategies();
        Collections.sort(this.strategies, new Comparator<Strategy>() {
            @Override
            public int compare(Strategy o1, Strategy o2) {
                return o1.getDescription().compareTo(o2.getDescription());
            }
        });
        this.strategy.setContainerDataSource(createDropdownContainerFromStrategies());
    }

    private void setupFormFields() {
        this.meetingsTree.setItemCaptionPropertyId("Name");
        this.meetingsTree.setWidth("100%");
        this.meetingsTree.setHeight("100%");
        this.meetingsTree.setNullSelectionAllowed(false);
        this.meetingsTree.setRequired(true);
        this.meetingsTree.setMultiSelect(false);

        this.completeBetsTree.setItemCaptionPropertyId("Detail");
        this.completeBetsTree.setWidth("100%");
        this.completeBetsTree.setHeight("100%");
        this.completeBetsTree.setSelectable(false);

        this.strategy.setItemCaptionPropertyId("Description");
        this.strategy.setNullSelectionAllowed(false);
        this.strategy.setRequired(true);
    }

    private boolean validateForm() {
        return this.strategy.isValid() && this.meetingsTree.isValid()
                && null != this.meetingsTree.getContainerProperty(this.meetingsTree.getValue(), "Horse").getValue();
    }

    private Container createTreeContainerFromCompleteBets() {
        HierarchicalContainer container = new HierarchicalContainer();
        container.addContainerProperty("Detail", String.class, "");
        for (Bet bet : this.completeBets) {
            Object betId = addBetToTreeContainer(container, bet);
            for (BetLog betLog : bet.getBetLogs()) {
                addBetLogToTreeContainer(container, betLog, betId);
            }
        }
        return container;
    }

    private Object addBetToTreeContainer(HierarchicalContainer container, Bet addition) {
        Object id = container.addItem();
        container.getContainerProperty(id, "Detail").setValue(addition.getHorse().getRace().getName() + " - "
                + addition.getHorse().getName() + " - " + addition.getStrategy().getDescription());
        return id;
    }

    private Object addBetLogToTreeContainer(HierarchicalContainer container, BetLog addition, Object parent) {
        Object id = container.addItem();
        container.getContainerProperty(id, "Detail")
                .setValue(DateUtil.toShortString(addition.getPlacedDateTime()) + " - \\U+00A3"
                        + addition.getLiability() + " - " + addition.getPrice() + " - "
                        + (addition.getBetType() == BetType.MOC_EXCHANGE ? "Exchange" : "SP"));
        container.setParent(id, parent);
        container.setChildrenAllowed(parent, true);
        container.setChildrenAllowed(id, false);
        return id;
    }

    private Container createTreeContainerFromMeetings() {
        HierarchicalContainer container = new HierarchicalContainer();
        container.addContainerProperty("Name", String.class, "");
        container.addContainerProperty("Horse", Horse.class, null);
        for (Meeting meeting : this.meetings) {
            Object meetingId = addMeetingToTreeContainer(container, meeting);
            for (Race race : meeting.getRaces()) {
                Object raceId = addRaceToTreeContainer(container, race, meetingId);
                for (Horse horse : race.getRunners()) {
                    addHorseToTreeContainer(container, horse, raceId);
                }
            }
        }
        return container;
    }

    private Object addMeetingToTreeContainer(HierarchicalContainer container, Meeting addition) {
        Object id = container.addItem();
        container.getContainerProperty(id, "Name").setValue(addition.getName());
        return id;
    }

    private Object addRaceToTreeContainer(HierarchicalContainer container, Race addition, Object parent) {
        Object id = container.addItem();
        container.getContainerProperty(id, "Name")
                .setValue(addition.getName() + " - " + DateUtil.toShortString(addition.getStartTime()));
        container.setParent(id, parent);
        container.setChildrenAllowed(parent, true);
        return id;
    }

    private Object addHorseToTreeContainer(HierarchicalContainer container, Horse addition, Object parent) {
        Object id = container.addItem();
        container.getContainerProperty(id, "Name")
                .setValue(addition.getName() + " - B"
                        + BettingUtil.bestPrice(addition.getPrices(), BettingAspect.BACK).getPrice() + " - L"
                        + BettingUtil.bestPrice(addition.getPrices(), BettingAspect.LAY).getPrice());
        container.getContainerProperty(id, "Horse").setValue(addition);
        container.setParent(id, parent);
        container.setChildrenAllowed(parent, true);
        container.setChildrenAllowed(id, false);
        return id;
    }

    private Container createDropdownContainerFromStrategies() {
        Container container = new IndexedContainer();
        container.addContainerProperty("Description", String.class, "");
        container.addContainerProperty("Strategy", Strategy.class, null);
        for (Strategy strategy : this.strategies) {
            addStrategyToDropdownContainer(container, strategy);
        }
        return container;
    }

    private void addStrategyToDropdownContainer(Container container, Strategy addition) {
        Object id = container.addItem();
        container.getContainerProperty(id, "Description").setValue(addition.getDescription());
        container.getContainerProperty(id, "Strategy").setValue(addition);
    }

    private Container createTableContainerFromIncompleteBets() {
        Container container = new IndexedContainer();
        List<String> headers = Lists.newArrayList(INCOMPLETE_BETS_COLUMNS);
        for (String header : headers) {
            container.addContainerProperty(header, String.class, "");
        }
        container.addContainerProperty("Bet", Bet.class, null);

        for (Bet bet : this.incompleteBets) {
            addBetToTableContainer(container, bet);
        }

        return container;
    }

    private void addBetToTableContainer(Container container, Bet addition) {
        Object id = container.addItem();

        container.getContainerProperty(id, "Meeting").setValue(addition.getHorse().getRace().getMeetingName());
        container.getContainerProperty(id, "Race").setValue(addition.getHorse().getRace().getName());
        container.getContainerProperty(id, "Time")
                .setValue(DateUtil.toShortString(addition.getHorse().getRace().getStartTime()));
        container.getContainerProperty(id, "Horse").setValue(addition.getHorse().getName());
        container.getContainerProperty(id, "Strategy").setValue(addition.getStrategy().getDescription());
        container.getContainerProperty(id, "Bet").setValue(addition);
    }
}