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 String description public Category() { entries = [] categories = [] 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 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) 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 } }