package com.jdbernard.timeanalyzer import org.joda.time.Duration /** * A category represents a collection of like events. */ public abstract class Category implements Comparable { public List entries public List categories public List 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 } }