Refactored to remove Entry and use Event everywhere.

This commit is contained in:
Jonathan Bernard 2011-01-18 07:20:56 -06:00
parent ab1c7f2393
commit e4a3b967de
13 changed files with 127 additions and 121 deletions

3
project.properties Normal file
View File

@ -0,0 +1,3 @@
#Fri, 14 Jan 2011 22:05:22 -0600
build.number=1

View File

@ -4,7 +4,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public interface CategorizationPlan { public interface CategorizationPlan {
boolean deservesNewCategory(Event event, List<Entry> existingEntries); boolean deservesNewCategory(Event event, List<Event> existingEvents);
Category newCategory(Event event, List<Entry> existingEntries); Category newCategory(Event event, List<Event> existingEvents);
List<Entry> findEntriesToRecategorize(Event event, List<Entry> existingEntries); List<Event> findEventsToRecategorize(Event event, List<Event> existingEvents);
} }

View File

@ -7,20 +7,20 @@ import org.joda.time.Duration
*/ */
public abstract class Category implements Comparable<Category> { public abstract class Category implements Comparable<Category> {
public List<Entry> entries public List<Event> events
public List<Category> categories public List<Category> categories
public List<CategorizationPlan> categorizationPlans public List<CategorizationPlan> categorizationPlans
public String description public String description
public Category() { public Category() {
entries = [] events = []
categories = [] categories = []
categorizationPlans = [] categorizationPlans = []
description = "Unnamed Category" description = "Unnamed Category"
} }
public Category(String description) { public Category(String description) {
entries = [] events = []
categories = [] categories = []
categorizationPlans = [] categorizationPlans = []
this.description = description this.description = description
@ -28,60 +28,74 @@ public abstract class Category implements Comparable<Category> {
public abstract boolean matchesEvent(Event e) public abstract boolean matchesEvent(Event e)
public Entry addEvent(Event e) { public void addEvent(Event event) {
Entry entry
// see if we have or can create a subcategory that will hold this event // see if we have or can create a subcategory that will hold this event
entry = addToSubcategory(e) Event addedEvent = addToSubcategory(event)
// no, let's create a generic entry and add it // no, let's just add it on ourself
if (!entry) { if (!addedEvent) {
entry = new Entry(this, e) events << event
entries << entry addedEvent = event
} }
return entry return addedEvent
} }
public Entry addToSubcategory(Event e) { public boolean addToSubcategory(Event e) {
// find all matching subcategories // find all matching subcategories
def matchingCategories = categories.findAll { it.matchesEvent(e) } def matchingCategories = categories.findAll { it.matchesEvent(e) }
if (matchingCategories) if (matchingCategories)
return matchingCategories[0].addEvent(e) return matchingCategories[0].addEvent(e)
// no matching subcategories, can we create a new one based on one // no matching subcategories, can we create a new one based on one
// of our plans? // of our plans?
def matchingPlans = categorizationPlans.findAll def matchingPlans = categorizationPlans.findAll
{ it.deservesNewCategory(e, entries) } { it.deservesNewCategory(e, events) }
if (matchingPlans) { if (matchingPlans) {
// create the new category // create the new category
def newCategory = matchingPlans[0].newCategory(e, entries) def newCategory = matchingPlans[0].newCategory(e, events)
// add it to our list of cateogries // add it to our list of cateogries
categories << newCategory categories << newCategory
// add the new event to the category // add the new event to the category
def entry = newCategory.addEvent(e) def addedEvent = newCategory.addEvent(e)
// move all the entries that match the new category over // move all the events that match the new category over
def existingEntries = matchingPlans[0].findEntriesToRecategorize(e, entries) def existingEvents = matchingPlans[0].findEventsToRecategorize(e, events)
entries -= existingEntries events -= existingEvents
newCategory.entries.addAll(existingEntries) existingEvents.each { newCategory.addEvent(it) }
existingEntries.each { it.category = newCategory }
// return the new entry // return the new entry
return entry return addedEvent
} }
return null 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() { public Duration getDuration() {
return categories.sum(new Duration(0)) { it.duration } + return categories.sum(new Duration(0)) { it.duration } +
entries.sum(new Duration(0)) { it.duration } events.sum(new Duration(0)) { it.duration }
} }
public int compareTo(Category other) { public int compareTo(Category other) {

View File

@ -2,19 +2,18 @@ package com.jdbernard.timeanalyzer
public class DescriptionBasedCategorizationPlan implements CategorizationPlan { public class DescriptionBasedCategorizationPlan implements CategorizationPlan {
public boolean deservesNewCategory(Event event, List<Entry> existingEntries) { public boolean deservesNewCategory(Event event, List<Event> existingEvents) {
return existingEntries.findAll { return existingEvents.any { it.description == event.description }
it.description == event.description }.size() > 0
} }
public Category newCategory(Event event, public Category newCategory(Event event,
List<Entry> existingEntries) { List<Event> existingEvents) {
return new DescriptionBasedCategory(event.description) return new DescriptionBasedCategory(event.description)
} }
public List<Entry> findEntriesToRecategorize(Event event, public List<Event> findEventsToRecategorize(Event event,
List<Entry> existingEntries) { List<Event> existingEvents) {
return existingEntries.findAll { it.description == event.description } return existingEvents.findAll { it.description == event.description }
} }
} }

View File

@ -1,35 +0,0 @@
package com.jdbernard.timeanalyzer;
import org.joda.time.DateTime;
import org.joda.time.Duration;
public class Entry {
public String description;
public String notes;
public DateTime start;
public Duration duration;
public Category category;
public Entry(Category c, String description, DateTime start,
Duration duration) {
this(c, description, "", start, duration);
}
public Entry(Category c, Event e) {
this(c, e.description, e.notes, e.start, e.duration);
}
public Entry(Category c, String description, String notes, DateTime start,
Duration duration) {
this.description = description;
this.notes = notes;
this.start = start;
this.duration = duration;
this.category = c;
}
public String toString() {
return category.description + ": " + description;
}
}

View File

@ -0,0 +1,40 @@
package com.jdbernard.timeanalyzer
import org.joda.time.DateTime
import org.joda.time.Duration
import org.joda.time.format.PeriodFormat
import org.joda.time.format.PeriodFormatter
public class Event implements Cloneable {
public final String description
public final String notes
public final DateTime start
public final Duration duration
public static PeriodFormatter periodFormatter = PeriodFormat.getDefault()
public Event(String desc, String notes, DateTime start, Duration duration) {
this.description = desc
this.notes = notes
this.start = start
this.duration = duration
}
public Event(Map params) {
this.description = params.description ?: ""
this.notes = params.notes ?: ""
this.start = params.start
this.duration = params.duration
}
public Event(Map params, Event e) {
this.description = params.description ?: e.description
this.notes = params.notes ?: e.notes
this.start = params.start ?: e.start
this.duration = params.duration ?: e.duration
}
public String toString() { return description }
}

View File

@ -1,25 +0,0 @@
package com.jdbernard.timeanalyzer;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.format.PeriodFormat;
import org.joda.time.format.PeriodFormatter;
public class Event implements Cloneable {
public String description;
public String notes;
public DateTime start;
public Duration duration;
public static PeriodFormatter periodFormatter = PeriodFormat.getDefault();
public String toString() {
return description;
}
public Object clone() throws CloneNotSupportedException
{ return super.clone(); }
}

View File

@ -12,7 +12,8 @@ public class TimeIntervalCategoryFilter implements CategoryFilter {
this.interval = interval this.interval = interval
} }
public TimeIntervalCategoryFilter(ReadableInstant start, ReadableInstant end) { public TimeIntervalCategoryFilter(ReadableInstant start,
ReadableInstant end) {
this.interval = new Interval(start, end) this.interval = new Interval(start, end)
} }

View File

@ -4,18 +4,18 @@ public class TwoLevelCategorizationPlan implements CategorizationPlan {
private static final def TWO_LEVEL_PATTERN = ~/(.+?):(.*)/ private static final def TWO_LEVEL_PATTERN = ~/(.+?):(.*)/
public boolean deservesNewCategory(Event event, List<Entry> el) { public boolean deservesNewCategory(Event event, List<Event> el) {
return event ==~ TWO_LEVEL_PATTERN return event ==~ TWO_LEVEL_PATTERN
} }
public Category newCategory(Event event, List<Entry> el) { public Category newCategory(Event event, List<Event> el) {
def m = event.description =~ TWO_LEVEL_PATTERN def m = event.description =~ TWO_LEVEL_PATTERN
return new TwoLevelCategory(m[0][1]) return new TwoLevelCategory(m[0][1])
} }
public List<Entry> findEntriesToRecategorize(Event event, public List<Event> findEventsToRecategorize(Event event,
List<Entry> existingEntries) { List<Event> existingEvents) {
def m = event.description =~ TWO_LEVEL_PATTERN def m = event.description =~ TWO_LEVEL_PATTERN
return existingEntries.findAll { it.description ==~ /${m[0][1]}:.*/ } return existingEvents.findAll { it.description ==~ /${m[0][1]}:.*/ }
} }
} }

View File

@ -15,14 +15,10 @@ public class TwoLevelCategory extends Category {
} }
public Entry addEvent(Event e) { public Entry addEvent(Event e) {
def event = e.clone() def m = e.description =~ descriptionPattern
def m = event.description =~ descriptionPattern e = new Event(e, description: m[0][1])
event.description = m[0][1] return super.addEvent(e)
def entry = super.addEvent(event)
return entry
} }
} }

View File

@ -3,28 +3,27 @@ package com.quantumdigital.ithelp.timeanalyzer
import com.jdbernard.timeanalyzer.Category import com.jdbernard.timeanalyzer.Category
import com.jdbernard.timeanalyzer.CategorizationPlan import com.jdbernard.timeanalyzer.CategorizationPlan
import com.jdbernard.timeanalyzer.Event import com.jdbernard.timeanalyzer.Event
import com.jdbernard.timeanalyzer.Entry
public class TicketCategorizationPlan implements CategorizationPlan { public class TicketCategorizationPlan implements CategorizationPlan {
private static def TICKET_PATTERN = ~/.*#(\d+).*/ private static def TICKET_PATTERN = ~/.*#(\d+).*/
public boolean deservesNewCategory(Event e, List<Entry> el) { public boolean deservesNewCategory(Event e, List<Event> el) {
return e.description ==~ TICKET_PATTERN return e.description ==~ TICKET_PATTERN
} }
public Category newCategory(Event e, List<Entry> el) { public Category newCategory(Event e, List<Event> el) {
def m = e.description =~ TICKET_PATTERN def m = e.description =~ TICKET_PATTERN
return new TicketCategory(m[0][1] as int) return new TicketCategory(m[0][1] as int)
} }
public List<Entry> findEntriesToRecategorize(Event e, public List<Event> findEventsToRecategorize(Event e,
List<Entry> existingEntries) { List<Event> existingEvents) {
def m = e.description =~ TICKET_PATTERN def m = e.description =~ TICKET_PATTERN
int ticketId = m[0][1] as int int ticketId = m[0][1] as int
return existingEntries.findAll { return existingEvents.findAll {
it.description ==~ /.*#${ticketId}.*/ } it.description ==~ /.*#${ticketId}.*/ }
} }
} }

View File

@ -17,9 +17,9 @@ public class TicketCategory extends Category {
return (e.description ==~ /.*#${ticketId}.*/) return (e.description ==~ /.*#${ticketId}.*/)
} }
public TicketEntry addEvent(Event e) { public TicketEvent addEvent(Event e) {
TicketEntry te = new TicketEntry(this, e) TicketEvent te = new TicketEvent(this, e)
entries << te events << te
return te return te
} }
} }

View File

@ -1,16 +1,30 @@
package com.quantumdigital.ithelp.timeanalyzer package com.quantumdigital.ithelp.timeanalyzer
import com.jdbernard.timeanalyzer.Entry
import com.jdbernard.timeanalyzer.Event import com.jdbernard.timeanalyzer.Event
public class TicketEntry extends Entry { public class TicketEvent extends Event {
public int id public final int id
public TicketEntry(TicketCategory category, Event e) { public TicketEvent(String desc, String notes, String start, String duration) {
super(category, e)
def m = e.description =~ /.*#(\d+).*/ super(desc, note, start, duration)
def m = desc =~ /.*#(\d+).*/
this.id = m[0][1] as int
}
public TicketEvent(Map params) {
super(params)
def m = description =~ /.*#(\d+).*/
this.id = m[0][1] as int
}
public TicketEvent(Map params, Event e) {
super(params, e)
def m = description =~ /.*#(\d+).*/
this.id = m[0][1] as int this.id = m[0][1] as int
} }
} }