Java tutorial
/* * Copyright (c) 2012, Robert von Burg * * All rights reserved. * * This file is part of the XXX. * * XXX 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 3 of the License, * or (at your option) any later version. * * XXX 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 XXX. If not, see * <http://www.gnu.org/licenses/>. */ package ch.eitchnet.android.mabea.model; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.joda.time.Duration; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; import org.joda.time.Period; import ch.eitchnet.android.mabea.model.MabeaState.State; /** * @author Robert von Burg <eitch@eitchnet.ch> * */ public class Today { private final LocalDate dateCreated; private List<Booking> bookings; private Duration startBalance; private Duration requiredWorkPerDay; private Duration workToday; /** * Default constructor * * @param requiredWorkPerDay * @param initialBooking */ public Today(Duration requiredWorkPerDay, Booking initialBooking) { if (requiredWorkPerDay == null) throw new IllegalArgumentException("requiredWorkPerDay must not be null"); if (initialBooking == null) throw new IllegalArgumentException("Initial booking must not be null!"); if (initialBooking.getState() != State.LOGGED_OUT) throw new IllegalArgumentException( "Initial booking must be " + MabeaState.State.LOGGED_OUT + " not " + initialBooking.getState()); if (initialBooking.getTimestamp().compareTo(LocalDate.now().toLocalDateTime(LocalTime.MIDNIGHT)) > 0) throw new IllegalArgumentException("The initial booking must be at midnight of today!"); this.dateCreated = LocalDate.now(); this.requiredWorkPerDay = requiredWorkPerDay; this.startBalance = initialBooking.getBalance(); this.workToday = new Duration(0L); this.bookings = new ArrayList<Booking>(); this.bookings.add(initialBooking); } /** * @return the dateCreated */ public LocalDate getDateCreated() { return dateCreated; } public void addBooking(Booking booking) { // only logged in our logged out bookings State newState = booking.getState(); if (newState == State.UNKNOWN) throw new IllegalArgumentException("The booking may not have the state " + State.UNKNOWN); // must toggle current state Booking lastBooking = this.bookings.get(this.bookings.size() - 1); if (lastBooking.getState() == newState) throw new IllegalArgumentException("The latest booking already has state " + newState); // and be later than previous state if (booking.getTimestamp().isBefore(lastBooking.getTimestamp())) throw new IllegalArgumentException("New booking time stamp " + booking.getTimestamp() + " is not later than current time stamp " + lastBooking.getTimestamp()); // and it should be earlier than now if (LocalDateTime.now().isBefore(booking.getTimestamp())) throw new IllegalArgumentException("The new booking has a time stamp later than now!"); // then we can update the model this.bookings.add(booking); updateWorkToday(); } public void removeBooking(Booking booking) { this.bookings.remove(booking); updateWorkToday(); } private void updateWorkToday() { Iterator<Booking> iter = bookings.iterator(); while (iter.hasNext()) { Booking booking = iter.next(); if (booking.getState() != State.LOGGED_IN || !iter.hasNext()) continue; Booking next = iter.next(); if (next.getState() != State.LOGGED_OUT) throw new IllegalArgumentException( "logging mismatch, expected LOGGED_OUT, but was " + next.getState()); LocalDateTime lastStateChange = booking.getTimestamp(); LocalDateTime newStateChange = next.getTimestamp(); Period period = new Period(lastStateChange, newStateChange); this.workToday = period.toStandardDuration().plus(workToday); } } public Booking getLatestBooking() { return this.bookings.get(this.bookings.size() - 1); } public Duration getActualBalance() { return getLatestBooking().getBalance(); } public Duration getEstimatedBalance() { return this.startBalance.minus(getRemainingWork()); } public Duration getRemainingWork() { return this.requiredWorkPerDay.minus(getWorkToday()); } public Duration getWorkToday() { Booking latestBooking = getLatestBooking(); if (latestBooking.getState() == State.LOGGED_OUT) return workToday; Period period = new Period(latestBooking.getTimestamp(), LocalDateTime.now()); return workToday.plus(period.toStandardDuration()); } }