108 lines
2.9 KiB
Groovy
108 lines
2.9 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<Event> events
|
|
public List<Category> categories
|
|
public List<CategorizationPlan> categorizationPlans
|
|
public String description
|
|
|
|
public Category() {
|
|
events = []
|
|
categories = []
|
|
categorizationPlans = []
|
|
description = "Unnamed Category"
|
|
}
|
|
|
|
public Category(String description) {
|
|
events = []
|
|
categories = []
|
|
categorizationPlans = []
|
|
this.description = description
|
|
}
|
|
|
|
public abstract boolean matchesEvent(Event e)
|
|
|
|
public void addEvent(Event event) {
|
|
|
|
// see if we have or can create a subcategory that will hold this event
|
|
Event addedEvent = addToSubcategory(event)
|
|
|
|
// no, let's just add it on ourself
|
|
if (!addedEvent) {
|
|
events << event
|
|
addedEvent = event
|
|
}
|
|
|
|
return addedEvent
|
|
}
|
|
|
|
public boolean 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, events) }
|
|
|
|
if (matchingPlans) {
|
|
// create the new category
|
|
def newCategory = matchingPlans[0].newCategory(e, events)
|
|
|
|
// add it to our list of cateogries
|
|
categories << newCategory
|
|
|
|
// add the new event to the category
|
|
def addedEvent = newCategory.addEvent(e)
|
|
|
|
// move all the events that match the new category over
|
|
def existingEvents = matchingPlans[0].findEventsToRecategorize(e, events)
|
|
events -= existingEvents
|
|
existingEvents.each { newCategory.addEvent(it) }
|
|
|
|
// return the new entry
|
|
return addedEvent
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
public Category filter(List<CategoryFilters> filters) {
|
|
|
|
// create new filtered category
|
|
FilteredCategory fc = new FilteredCategory(description)
|
|
fc.filters = filters
|
|
|
|
// filter all events and add them to the category
|
|
fc.events
|
|
|
|
// TODO
|
|
}
|
|
|
|
public Category filter(CategoryFilter filter) { return filter([filter]) }
|
|
|
|
public Category filter(Closure c) { return filter(c as CategoryFilter) }
|
|
|
|
public Duration getDuration() {
|
|
return categories.sum(new Duration(0)) { it.duration } +
|
|
events.sum(new Duration(0)) { it.duration }
|
|
}
|
|
|
|
public int compareTo(Category other) {
|
|
return this.getDuration().compareTo(other.getDuration())
|
|
}
|
|
|
|
public String toString() { return description }
|
|
|
|
}
|