79 lines
3.2 KiB
Groovy
79 lines
3.2 KiB
Groovy
/**
|
|
* # Item
|
|
* @author Jonathan Bernard (jdb@jdb-labs.com)
|
|
* @copyright 2013 [JDB Labs LLC](http://jdb-labs.com)
|
|
*/
|
|
package com.jdblabs.gtd
|
|
|
|
/**
|
|
* One Getting Things Done item (a page in David Allen's system). An item is
|
|
* represented by a file on the filesystem, organized into one of the GTD
|
|
* folders. The Item can have arbitrarily many properties, which are stored in
|
|
* the Item file as standard Java properties. By convention the `action`
|
|
* property is used as the item description (assuming this item is a next
|
|
* action item). Other important properties include:
|
|
*
|
|
* * `outcome`: describes the desired outcome.
|
|
* * `title`: the item title (optionally used if no `action` is defined).
|
|
* * `date`: the due date for this item. Remember that we should not use the
|
|
* calendar to "schedule" items, but only to represent items which must be
|
|
* done by or on that day.
|
|
* * `details`: more information related to this item.
|
|
* @org gtd.jdb-labs.com/Item
|
|
*/
|
|
public class Item {
|
|
|
|
public File file
|
|
public Map gtdProperties = [:]
|
|
|
|
/**
|
|
* #### constructor
|
|
* Load an item from a file. The typical pattern for creating new Items is
|
|
* to create the file first then pass that file to an Item constructor.
|
|
* Files with no contents are valid GTD items (the file name is used as a
|
|
* description in lieu of an `action` or `title` property). */
|
|
public Item(File f) {
|
|
this.file = f
|
|
|
|
/// Read and parse the item's properties from the file.
|
|
def javaProps = new Properties()
|
|
f.withReader { reader -> javaProps.load(reader) }
|
|
|
|
/// Properties are stored as plain text in the file. We use the
|
|
/// [PropertyHelp](jlp://gtd.jdb-labs.com/PropertyHelp) Enum to
|
|
/// serialize and deserialize the property objects.
|
|
javaProps.each { k, v -> gtdProperties[k] = PropertyHelp.parse(v) } }
|
|
|
|
/** #### `save`
|
|
* Persist the Item to it's file. */
|
|
public void save() {
|
|
def javaProps = new Properties()
|
|
gtdProperties.each { k, v -> javaProps[k] = PropertyHelp.format(v) }
|
|
file.withOutputStream { os -> javaProps.store(os, "") } }
|
|
|
|
/** #### `propertyMissing`
|
|
* Provide an implementation of the Groovy dynamic [propertyMissing][1]
|
|
* method to expose the gtdProperties map as properties on the item
|
|
* itself.
|
|
*
|
|
* [1]: http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing
|
|
*/
|
|
public def propertyMissing(String name, def value) {
|
|
gtdProperties[name] = value }
|
|
|
|
public def propertyMissing(String name) { return gtdProperties[name] }
|
|
|
|
/** #### `toString`
|
|
* Provide a standard description of the item. This is used by the CLI
|
|
* interface, for example, to directly display GTD items.
|
|
*
|
|
* Look first for the `action` property, then `outcome`, then `title`.
|
|
* Failing to find any of these properties, pretty-print the filename
|
|
* as a description. */
|
|
public String toString() {
|
|
if (gtdProperties.action) return gtdProperties.action
|
|
if (gtdProperties.outcome) return gtdProperties.outcome
|
|
if (gtdProperties.title) return gtdProperties.title
|
|
return file.name.replaceAll(/[-_]/, " ").capitalize() }
|
|
}
|