pit/libpit/src/main/com/jdbernard/pit/ExtendedPropertyHelp.groovy
Jonathan Bernard 6f58a83ad4 Multiple sort criteria to filters, bugfix, and cleanup.
* Fixed a bug in the common build. This bug is fixed in version 1.9, but I am
  patching this bug locally in 1.6 until I have evaluated 1.9 with this project.
* Moved `ExtendedPropertyHelp` to `com.jdbernard.pit` from
  `com.jdbernard.pit.file`.
* Added a number of property types to `ExtendedPropertyHelp`. New additions are:

    * `java.util.Calendar` *object -> string value only*
    * `java.util.Date` *object -> string value only*
    * `java.lang.Long` *this replaces `java.util.Integer`*
    * `java.lang.Float` *object -> string value only*
    * `java.lang.Double`
* Cleaned up the `matches(String)` and `matches(Class)` functions of
  `ExtendedPropertyHelp`
* Modified `Filter` sorter behaviours. The `issueSorter` and `projectSorter`
  fields are now allowed to be either a closure or a list of closures. A single
  closure works as it did before. The list of closures allows the caller to
  specify multiple sort criteria. The individual criteria closures are applied
  in reverse order, so that the first item in the sorter list is the most
  significant criteria. For example, if the caller set the sorter to
  `[{it.category},{it.priority}]` then the issues would be sorted first by
  priority and then sorted again by category, meaning that the resulting data
  would be ordered first by the category of the issue and then by the priority
  for issues that share the same category.
* Modified the methods in `Project` that use `Filter` objects to conform to the
  above behavior regarding sorting. It may be a better idea though to move the
  sort code all into `Filter` so that it is in one place.
* Cleaned up the code in `Status` for matching status based on given symbols or
  partial status names.
2011-12-07 18:01:18 -06:00

82 lines
2.8 KiB
Groovy

package com.jdbernard.pit
import org.joda.time.DateMidnight
import org.joda.time.DateTime
import java.text.SimpleDateFormat
public enum ExtendedPropertyHelp {
// Property types should be ordered here in order of decreasing specificity.
// That is, subclasses should come before the more general class so that
// objects are converted using the most specific class that
// ExtendedPropertyHelp knows how to work with.
DATE_MIDNIGHT(/^\d{4}-\d{2}-\d{2}$/, DateMidnight,
{ v -> DateMidnight.parse(v) },
{ d -> d.toString("YYYY-MM-dd") }),
DATETIME(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/, DateTime,
{ v -> DateTime.parse(v) },
{ d -> d.toString("YYYY-MM-dd'T'HH:mm:ss") }),
// We never want to parse a value into a java.util.Date or
// java.util.Calendar object (we are using Joda Time instead of the
// standard Java Date and Calendar objects) but we do want to be able to
// handle if someone gives us a Date or Calendar object.
DATE(NEVER_MATCH, Date,
{ v -> v }, // never called
{ d -> dateFormat.format(d) }),
CALENDAR(NEVER_MATCH, Calendar,
{ v -> v }, // never called
{ c ->
def df = dateFormat.clone()
df.calendar = c
df.format(c.time) }),
INTEGER(NEVER_MATCH, Integer,
{ v -> v as Integer }, // never called
{ i -> i as String }),
LONG(/^\d+$/, Long,
{ v -> v as Long },
{ l -> l as String }),
FLOAT(NEVER_MATCH, Float,
{ v -> v as Float}, // never called
{ f -> f as String}),
DOUBLE(/^\d+\.\d+$/, Double,
{ v -> v as Double },
{ d -> d as String });
String pattern;
Class klass;
def parseFun, formatFun;
private static SimpleDateFormat dateFormat =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
// This pattern for can never match (is uses negative lookahead to
// contradict itself).
private static String NEVER_MATCH = /(?!x)x/;
public ExtendedPropertyHelp(String pattern, Class klass, def parseFun,
def formatFun) {
this.pattern = pattern
this.klass = klass
this.parseFun = parseFun
this.formatFun = formatFun }
public boolean matches(String prop) { return prop ==~ pattern }
public boolean matches(Class klass) { return this.klass == klass }
public static Object parse(String value) {
def propertyType = ExtendedPropertyHelp.values().find {
it.matches(value) }
return propertyType ? propertyType.parseFun(value) : value }
public static String format(def object) {
def propertyType = ExtendedPropertyHelp.values().find {
it.klass.isInstance(object) }
return propertyType ? propertyType.formatFun(object) : object.toString() }
}