2011-01-12 06:54:03 -06:00

107 lines
3.0 KiB
Groovy

package com.jdbernard.timeanalyzer
import org.joda.time.Duration
/**
* A category represents a collection of like events.
*/
public abstract class Category implements Comparable<Category> {
public List<Entry> entries
public List<Category> categories
public List<CategorizationPlan> categorizationPlans
public String description
public Category() {
entries = []
categories = []
categorizationPlans = []
description = "Unnamed Category"
}
public abstract boolean matchesEvent(Event e)
public Entry addEvent(Event e) {
Entry entry
// see if we have a subcategory that will hold this event
entry = addToSubcategory(e)
if (!entry) {
// if not, do we have a plan for categorizing this event?
// if not, do we have another entry that could be grouped with
// this one to create a new category, based on the description?
def existingEntry = entries.find
{ it.description == e.description }
// yes
if (existingEntry) {
// create the new category
def category = new DescriptionBasedCategory(e.description)
// add the new event to the category
entry = category.addEvent(e)
// remove the existing entry from this category and
// add it to the subcategory
this.entries -= existingEntry
category.entries << existingEntry
existingEntry.category = category
// add the category to our list of subcategories
categories << category
}
// no, let's create a generic entry and add it
else {
entry = new Entry(this, e)
entries << entry
}
}
return entry
}
public Entry addToSubcategory(Event e) {
// find all matching subcategories
def matchingCategories = categories.findAll { it.matchesEvent(e) }
if (matchingCategories)
return matchingCategories[0].addEvent(e)
// no matching subcategories, can we create a new one based on one
// of our plans?
def matchingPlans = categorizationPlans.findAll
{ it.deservesNewCategory(e, entries) }
if (matchingPlans) {
// create the new category
def result = matchingPlans.createNewCategory(e, entries)
// add it to our list of cateogries
categories << result.category
// return new entry
return result.entry
}
return null
}
public Entry
public Duration getDuration() {
return categories.sum(new Duration(0)) { it.duration } +
entries.sum(new Duration(0)) { it.duration }
}
public int compareTo(Category other) {
return this.getDuration().compareTo(other.getDuration())
}
public String toString() { return description }
}