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 Category(String description) { entries = [] categories = [] categorizationPlans = [] this.description = description } public abstract boolean matchesEvent(Event e) public Entry addEvent(Event e) { Entry entry // see if we have or can create a subcategory that will hold this event entry = addToSubcategory(e) // no, let's create a generic entry and add it if (!entry) { 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 newCategory = matchingPlans[0].newCategory(e, entries) // add it to our list of cateogries categories << newCategory // add the new event to the category def entry = newCategory.addEvent(e) // move all the entries that match the new category over def existingEntries = matchingPlans[0].findEntriesToRecategorize(e, entries) entries -= existingEntries newCategory.entries.addAll(existingEntries) existingEntries.each { it.category = newCategory } // return the new entry return entry } return null } 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 } }