julian.lylly.model.Task.java Source code

Java tutorial

Introduction

Here is the source code for julian.lylly.model.Task.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package julian.lylly.model;

import org.joda.time.Duration;
import org.joda.time.Instant;
import org.joda.time.Interval;
import org.joda.time.LocalDate;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Task implements Serializable {

    //TODO: test! especially getTimeSpentInInterval & evalDurationSum

    /*
    context condition: fragment <==>      descr == null ||   tag == null
                      || importance == -1 || urgency == -1
    */

    //status:
    private boolean fragment = true;
    private Instant done = null;

    // essential:
    private String descr;
    private Tag tag;
    private int importance = -1, urgency = -1;

    //optional:
    private LocalDate startDate;
    private LocalDate expiryDate;

    //variable
    private List<Interval> intervals = new ArrayList<>();
    private Instant starttime;

    /*
    status operators:
    */

    public void start() {
        if (isActive()) {
            throw new IllegalStateException("already active");
        }
        starttime = Instant.now();
    }

    public void pause() {
        if (!isActive()) {
            throw new IllegalStateException("already non-active");
        }
        intervals.add(new Interval(starttime, Instant.now()));
        starttime = null;
    }

    public void playPause() {
        if (isActive()) {
            pause();
        } else {
            start();
        }
    }

    public void finish() {
        if (isActive()) {
            pause();
        }
        done = Instant.now();
    }

    /*
    status getter:
    */

    public boolean isFragment() {
        return fragment;

    }

    public boolean isActive() {
        return starttime != null;
    }

    public Instant getDone() {
        return done;
    }

    public boolean isDone() {
        return done != null;
    }

    public void setDone(Instant done) {
        this.done = done;
    }

    public void setDonity(boolean done) {
        if (!isDone() && done) {
            this.done = Instant.now();
        }
        if (isDone() && !done) {
            this.done = null;
        }
    }

    /*
    get & set properties:
    */

    void checkCompleteness() {
        fragment = descr == null || tag == null || importance == -1 || urgency == -1;
    }

    public String getDescr() {
        return descr;
    }

    public void setDescr(String descr) {
        this.descr = descr;
        checkCompleteness();
    }

    public Tag getTag() {
        return tag;
    }

    public void setTag(Tag tag) {
        this.tag = tag;
        checkCompleteness();
    }

    public int getImportance() {
        return importance;
    }

    public void setImportance(int importance) {
        this.importance = importance;
        checkCompleteness();
    }

    public void setStartTime(Instant starttime) {
        this.starttime = starttime;
    }

    public int getUrgency() {
        return urgency;
    }

    public void setUrgency(int urgency) {
        this.urgency = urgency;
        checkCompleteness();
    }

    public LocalDate getExpiryDate() {
        return expiryDate;
    }

    public void setExpiryDate(LocalDate expiryDate) {
        this.expiryDate = expiryDate;
    }

    public LocalDate getStartDate() {
        return startDate;
    }

    public void setStartDate(LocalDate startDate) {
        this.startDate = startDate;
    }

    /*
    getter for timetracking:
    */

    public Duration evalDurationSum() {
        return getTimeSpentInInterval(null, null);
    }

    public void setIntervals(List<Interval> intervals) {
        checkDistinctness(intervals);
        Collections.sort(intervals, new Comparator<Interval>() {
            @Override
            public int compare(Interval lhs, Interval rhs) {
                return lhs.getStart().compareTo(rhs.getStart());
            }
        });
        this.intervals = intervals;
    }

    static void checkDistinctness(List<Interval> intervals) {
        for (int i = 0; i < intervals.size(); i++) {
            Interval x = intervals.get(i);
            for (int j = i + 1; j < intervals.size(); j++) {
                Interval y = intervals.get(j);
                if (x.overlaps(y)) {
                    throw new IllegalArgumentException(x.toString() + " overlaps " + y.toString());
                }
            }
        }
    }

    public List<Interval> getIntervals() {
        return intervals;
    }

    /**
     * behaviour undefined if interval list is unsorted
     * any {@code null} input is interpreted as a non-bound in that direction
     * @param focusStart
     * @param focusEnd
     * @return
     */
    public Duration getTimeSpentInInterval(LocalDate focusStart, LocalDate focusEnd) {
        Instant startInst, endInst;
        if (intervals.size() == 0 && !isActive()) { // #
            return Duration.ZERO;
        }
        if (focusStart == null) {
            startInst = intervals.size() == 0 ? starttime // != null because #
                    : intervals.get(0).getStart().toInstant();
        } else {
            startInst = focusStart.toDateTimeAtStartOfDay().toInstant();
        }
        if (focusEnd == null) {
            endInst = isActive() ? Instant.now()
                    //v intervals.size() != 0 because #
                    : intervals.get(intervals.size() - 1).getEnd().toInstant();//TODO
        } else {
            endInst = focusEnd.toDateTimeAtStartOfDay().toInstant();
        }
        Interval focus = new Interval(startInst, endInst);

        return getTimeSpentInInterval(focus);
    }

    public Duration getTimeSpentInInterval(Interval focus) {
        if (focus == null) {
            throw new IllegalArgumentException("focus == nul");
        }

        Duration timespent = Duration.ZERO;

        for (Interval i : intervals) {
            Duration ov = computeOverlap(i, focus);
            timespent = timespent.plus(ov);
        }
        if (isActive()) {
            Interval activeInterval = new Interval(starttime, Instant.now());
            Duration overlapDuration = computeOverlap(activeInterval, focus);
            timespent = timespent.plus(overlapDuration);
        }

        return timespent;
    }

    private Duration computeOverlap(Interval x, Interval y) {
        if (x.overlaps(y)) {
            return x.overlap(y).toDuration();
        } else {
            return Duration.ZERO;
        }
    }

    public boolean isRecent() {
        return done == null || !new LocalDate(done).isBefore(LocalDate.now());
    }//DANGER
}