Continued implementation of extended attributes.
* Changed the `Issue` constructor to use an attribute map instead of an increasingly long parameter list. Of course we lose some control over required parameters. * Added the Joda Time and SLF4J logging libraries. * Implemented the `FileIssue` constructor for the new `Issue` refactor.
This commit is contained in:
parent
5ff4665a07
commit
f86316c68f
BIN
libpit/lib/joda-time-2.0.jar
Normal file
BIN
libpit/lib/joda-time-2.0.jar
Normal file
Binary file not shown.
BIN
libpit/lib/logback-classic-0.9.26.jar
Normal file
BIN
libpit/lib/logback-classic-0.9.26.jar
Normal file
Binary file not shown.
BIN
libpit/lib/logback-core-0.9.26.jar
Normal file
BIN
libpit/lib/logback-core-0.9.26.jar
Normal file
Binary file not shown.
BIN
libpit/lib/slf4j-api-1.6.1.jar
Normal file
BIN
libpit/lib/slf4j-api-1.6.1.jar
Normal file
Binary file not shown.
@ -1,10 +1,10 @@
|
|||||||
#Wed, 26 Oct 2011 14:20:47 -0500
|
#Thu, 03 Nov 2011 13:47:05 -0500
|
||||||
#Sat Apr 24 17:08:00 CDT 2010
|
#Sat Apr 24 17:08:00 CDT 2010
|
||||||
build.dir=build
|
build.dir=build
|
||||||
src.dir=src
|
src.dir=src
|
||||||
lib.shared.dir=../shared-libs
|
lib.shared.dir=../shared-libs
|
||||||
test.dir=test
|
test.dir=test
|
||||||
build.number=0
|
build.number=11
|
||||||
expected.application.version=3.0.0
|
expected.application.version=3.0.0
|
||||||
lib.dir=lib
|
lib.dir=lib
|
||||||
release.dir=release
|
release.dir=release
|
||||||
|
@ -13,13 +13,20 @@ public abstract class Issue {
|
|||||||
|
|
||||||
protected Map extendedPropeties = [:]
|
protected Map extendedPropeties = [:]
|
||||||
|
|
||||||
Issue(String id, Category c = Category.TASK, Status s = Status.NEW,
|
Issue(Map props) {
|
||||||
int p = 9) {
|
this.id = props.id
|
||||||
this.id = id
|
this.category = props.category ?: Category.TASK
|
||||||
this.category = c
|
this.status = props.status ?: Status.NEW
|
||||||
this.status = s
|
this.priority = props.priority ?: 9
|
||||||
this.priority = p
|
this.title = props.title ?: ''
|
||||||
}
|
this.text = props.text ?: ''
|
||||||
|
|
||||||
|
def nativeProps =
|
||||||
|
["id", "category", "status", "priority", "title", "text"]
|
||||||
|
|
||||||
|
props.each { key, val ->
|
||||||
|
if (nativeProps.contains(key)) { return }
|
||||||
|
this.extendedProperties[key] = val }}
|
||||||
|
|
||||||
public String getId() { return id; }
|
public String getId() { return id; }
|
||||||
|
|
||||||
@ -49,7 +56,7 @@ public abstract class Issue {
|
|||||||
|
|
||||||
public String getTitle() { return title }
|
public String getTitle() { return title }
|
||||||
|
|
||||||
public String setTitle(String t) throws IOException { title = t }
|
public void setTitle(String t) throws IOException { title = t }
|
||||||
|
|
||||||
public String getText() { return text }
|
public String getText() { return text }
|
||||||
|
|
||||||
|
@ -1,31 +1,75 @@
|
|||||||
package com.jdbernard.pit.file
|
package com.jdbernard.pit.file
|
||||||
|
|
||||||
import com.jdbernard.pit.*
|
import com.jdbernard.pit.*
|
||||||
|
|
||||||
import java.lang.IllegalArgumentException as IAE
|
import java.lang.IllegalArgumentException as IAE
|
||||||
|
|
||||||
|
import org.joda.time.DateMidnight
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
public class FileIssue extends Issue {
|
public class FileIssue extends Issue {
|
||||||
|
|
||||||
protected File source
|
protected File source
|
||||||
|
private Logger log = LoggerFactory.getLogger(getClass())
|
||||||
|
|
||||||
public static final String fileExp = /(\d+)([bft])([ajnsv])(\d).*/
|
public static final String fileExp = /(\d+)([bft])([ajnsv])(\d).*/
|
||||||
|
|
||||||
public FileIssue(File file) {
|
public FileIssue(File file) {
|
||||||
|
|
||||||
super('REPLACE_ME')
|
super(id: -1, title: 'REPLACE_ME')
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Loading a FileIssue from '{}'", file.canonicalPath) }
|
||||||
|
|
||||||
def matcher = file.name =~ fileExp
|
def matcher = file.name =~ fileExp
|
||||||
if (!matcher)
|
if (!matcher)
|
||||||
throw new IllegalArgumentException("${file} " +
|
throw new IllegalArgumentException("${file} " +
|
||||||
"is not a valid Issue file.")
|
"is not a valid Issue file.")
|
||||||
|
|
||||||
|
// Read issue attributes from the filename.
|
||||||
super.@id = matcher[0][1]
|
super.@id = matcher[0][1]
|
||||||
super.@category = Category.toCategory(matcher[0][2])
|
super.@category = Category.toCategory(matcher[0][2])
|
||||||
super.@status = Status.toStatus(matcher[0][3])
|
super.@status = Status.toStatus(matcher[0][3])
|
||||||
super.@priority = matcher[0][4].toInteger()
|
super.@priority = matcher[0][4].toInteger()
|
||||||
|
|
||||||
|
log.debug("id: {}\tcategory: {}\tstatus: {}\tpriority: {}",
|
||||||
|
[super.@id, super.@category, super.@status, super.@priority])
|
||||||
|
|
||||||
this.source = file
|
this.source = file
|
||||||
|
|
||||||
super.@text = file.text
|
String text = ""
|
||||||
super.@title = super.@text.readLines()[0]
|
boolean parsingText = true
|
||||||
|
|
||||||
|
// Now parse the actual file contents.
|
||||||
|
file.text.eachLine { line, lineNumber ->
|
||||||
|
|
||||||
|
log.trace("lineNumber: {}, line: {}", lineNumber, line)
|
||||||
|
|
||||||
|
if (lineNumber == 0) {
|
||||||
|
super.@title = line
|
||||||
|
log.debug("Found title: {}", super.@title) }
|
||||||
|
|
||||||
|
else if (lineNumber > 2) {
|
||||||
|
// We see the horizontal rule
|
||||||
|
if (line ==~ /\s*^\-{4}\-*\s*$/) { parsingText = false }
|
||||||
|
|
||||||
|
if (parsingText) { text += "$line\n" }
|
||||||
|
|
||||||
|
else {
|
||||||
|
def match = (line =~ /^([^:]+):(.+)$/)
|
||||||
|
if (match) {
|
||||||
|
def key = match[0][1].trim()
|
||||||
|
def value = parseValue(match[0][2].trim())
|
||||||
|
super.@extendedProperties[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.@text = text
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCategory(Category c) throws IOException {
|
public void setCategory(Category c) throws IOException {
|
||||||
@ -109,22 +153,22 @@ public class FileIssue extends Issue {
|
|||||||
|
|
||||||
public static String formatIssue(Issue issue) {
|
public static String formatIssue(Issue issue) {
|
||||||
def result = new StringBuilder()
|
def result = new StringBuilder()
|
||||||
result.append(title)
|
result.append(issue.@title)
|
||||||
result.append("\n")
|
result.append("\n")
|
||||||
result.append("=".multiply(title.length()))
|
result.append("=".multiply(issue.@title.length()))
|
||||||
result.append("\n")
|
result.append("\n")
|
||||||
result.append(text)
|
result.append(issue.@text)
|
||||||
result.append("\n----\n")
|
result.append("\n----\n")
|
||||||
|
|
||||||
// If there are any extended properties, let's write those.
|
// If there are any extended properties, let's write those.
|
||||||
if (super.@extendedProperties.size() > 0) {
|
if (issue.@extendedProperties.size() > 0) {
|
||||||
def extOutput = [:]
|
def extOutput = [:]
|
||||||
def maxKeyLen = 0
|
def maxKeyLen = 0
|
||||||
def maxValLen = 0
|
def maxValLen = 0
|
||||||
|
|
||||||
// Find the longest key and value, convert all to strings.
|
// Find the longest key and value, convert all to strings.
|
||||||
super.@extendedProperties.each { key, val ->
|
issue.@extendedProperties.each { key, val ->
|
||||||
def ks = key.toString(), vs = val.toString()
|
def ks = key.toString(), vs = formatProperty(val)
|
||||||
extOutput[ks] = vs
|
extOutput[ks] = vs
|
||||||
if (ks.length() > maxKeyLen) { maxKeyLen = ks.length() }
|
if (ks.length() > maxKeyLen) { maxKeyLen = ks.length() }
|
||||||
if (vs.length() > maxKeyLen) { maxValLen = vs.length() } }
|
if (vs.length() > maxKeyLen) { maxValLen = vs.length() } }
|
||||||
@ -146,7 +190,7 @@ public class FileIssue extends Issue {
|
|||||||
result.append("\n") }}
|
result.append("\n") }}
|
||||||
|
|
||||||
protected void writeFile() {
|
protected void writeFile() {
|
||||||
try { source.write(formatIssue(this) }
|
try { source.write(formatIssue(this)) }
|
||||||
catch (IOException ioe) {
|
catch (IOException ioe) {
|
||||||
throw new IOException("I could not save the new text for this "
|
throw new IOException("I could not save the new text for this "
|
||||||
+ "issue. I can not write to the file for this issue. I do not"
|
+ "issue. I can not write to the file for this issue. I do not"
|
||||||
@ -154,4 +198,16 @@ public class FileIssue extends Issue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public def parseValue(String value) {
|
||||||
|
switch (value) {
|
||||||
|
case ~/\d{4}-\d{2}-\d{2}/: return DateMidnight.parse(value)
|
||||||
|
default: return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String formatProperty(DateTime prop) {
|
||||||
|
return prop.format("YYYY-MM-dd'T'HH:mm:ss") }
|
||||||
|
|
||||||
|
public String formatProperty(DateMidnight prop) {
|
||||||
|
return prop.format("YYYY-MM-dd") }
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package com.jdbernard.pit
|
|||||||
|
|
||||||
public class MockIssue extends Issue {
|
public class MockIssue extends Issue {
|
||||||
public MockIssue(String id, Category c, Status s, int p) {
|
public MockIssue(String id, Category c, Status s, int p) {
|
||||||
super (id, c, s, p)
|
super ([id: id, category: c, status: s, priority: p])
|
||||||
}
|
}
|
||||||
public boolean delete() { return true }
|
public boolean delete() { return true }
|
||||||
}
|
}
|
||||||
|
@ -171,9 +171,7 @@ class FileIssueTest {
|
|||||||
assertEquals issue.status , Status.NEW
|
assertEquals issue.status , Status.NEW
|
||||||
assertEquals issue.priority , 1
|
assertEquals issue.priority , 1
|
||||||
assertEquals issue.title , "Add the killer feature to the killer app."
|
assertEquals issue.title , "Add the killer feature to the killer app."
|
||||||
assertEquals issue.text , "Add the killer feature to the killer app.\n" +
|
assertEquals issue.text , "Make our killer app shine!."
|
||||||
"=========================================\n\n" +
|
|
||||||
"Make our killer app shine!."
|
|
||||||
assertEquals issue.source , issueFile
|
assertEquals issue.source , issueFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user