libraryDependencies +=
"org.scala-tools.sbinary" %% "sbinary" % "0.4.2"
-/* There is also manual dependencies in ./lib:
- *
- * - JCalendar <http://toedter.com/jcalendar/>
- */
+// There is also manual dependencies in ./lib:
+//
+// - JCalendar <http://toedter.com/jcalendar/>
+//
-scalacOptions ++= Seq("-deprecation", "-unchecked", "-encoding", "UTF-8")
+scalacOptions ++= Seq("-deprecation", "-unchecked", "-encoding", "UTF-8", "-feature")
assemblySettings
column match {
case 0 => "チケットID"
case 1 => "作業名"
- case 2 => "ä»®æ\9c\9fé\99\90"
- case 3 => "期限"
+ case 2 => "ä½\9cæ¥å®\8cäº\86äº\88å®\9aå¹´æ\9c\88æ\97¥"
+ case 3 => "タスク期限"
case 4 => "状態"
- case 5 => "è£\9c足"
+ case 5 => "説æ\98\8e"
}
}
def getValueAt(row: Int, column: Int) : Object = {
val task = _tasks(row)
column match {
- case 0 => task.ticketID : Integer
+ case 0 => task.ticketID.map(_.toString).getOrElse("")
case 1 => task.title
- case 2 => task.tentativeDeadline.map(dateString).getOrElse("")
- case 3 => task.deadline .map(dateString).getOrElse("")
+ case 2 => dateString(task.expectedCompletionDate)
+ case 3 => task.deadline.map(dateString).getOrElse("")
case 4 => task.status
- case 5 => task.supplement
+ case 5 => task.description.getOrElse("")
}
}
}
_file.foreach { file => load(file) }
def load(file: File) {
+ import Task._
+
var reports = _reports.empty
val src = Source.fromFile(file, "UTF-8")
+ TSV.decode(src.mkString).foreach { task =>
+ if (reports.isDefinedAt(task.date)) {
+ reports(task.date) += task
+ }
+ else {
+ val report = new Report(task.date)
+ report += task
+ reports += (report.date -> report)
+ }
+ }
+
+/*
for (line <- src.getLines) {
if (!line.isEmpty) {
val task = new Task(line)
}
}
}
+ */
_file = Some(file)
_reports = reports
--- /dev/null
+package jp.ymir.taskReporter.core
+import scala.collection._
+import scala.collection.immutable.StringLike
+
+object TSV {
+ type Header = Seq[Symbol]
+ type Field = String
+ type Record = Map[Symbol, Field]
+
+ def decode[A: FromRecord](tsv: StringLike[_]): Seq[A] = {
+ val lines = tsv.split('\n').filter(!_.isEmpty)
+ val header = lines.head.split('\t').map(Symbol(_))
+ val body = lines.tail.map(line => (header zip line.split('\t')).toMap)
+ return body.map(implicitly[FromRecord[A]].parseRecord)
+ }
+
+ trait FromRecord[A] {
+ def parseRecord(r: Record): A
+ }
+
+ trait FromField[A] {
+ def parseField(f: Field): A
+ }
+ def parseField[A: FromField](f: Field): A
+ = implicitly[FromField[A]].parseField(f)
+
+ trait ToRecord[A] {
+ def toRecord(a: A): Record
+ }
+
+ trait ToField[A] {
+ def toField(a: A): Field
+ }
+
+ // Option[A]
+ implicit def OptionFromField[A: FromField] = new FromField[Option[A]] {
+ def parseField(f: Field): Option[A] = {
+ if (f.isEmpty) {
+ return None
+ }
+ else {
+ return Some(implicitly[FromField[A]].parseField(f))
+ }
+ }
+ }
+
+ // String
+ implicit def StringFromField = new FromField[String] {
+ def parseField(f: Field): String = f
+ }
+
+ // Int
+ implicit def IntFromField = new FromField[Int] {
+ def parseField(f: Field): Int = f.toInt
+ }
+}
import java.util.GregorianCalendar
import scala.util.matching.Regex
+case class Task(
+ date: Calendar,
+ ticketID: Option[Int],
+ title: String,
+ expectedCompletionDate: Calendar,
+ deadline: Option[Calendar],
+ status: Task.Status,
+ description: Option[String]
+)
+
+object Task {
+ import TSV._
+
+ sealed abstract class Status
+ object Status {
+ case object DoingFine extends Status
+ case object Lagging extends Status
+ case object DeadlineChanged extends Status
+ case object Completed extends Status
+ }
+
+ implicit def CalendarFromField = new FromField[Calendar] {
+ val pattern = """^(\d{4})/(\d{2})/(\d{2})$""".r
+
+ def parseField(f: Field): Calendar = {
+ f match {
+ case pattern(year, month, day) =>
+ new GregorianCalendar(year.toInt, month.toInt, day.toInt)
+ }
+ }
+ }
+
+ implicit def StatusFromField = new FromField[Status] {
+ def parseField(f: Field): Status = f match {
+ case "順調" => Status.DoingFine
+ case "遅延" => Status.Lagging
+ case "期限変更" => Status.DeadlineChanged
+ case "完了" => Status.Completed
+ }
+ }
+
+ implicit def TaskFromRecord = new FromRecord[Task] {
+ def parseRecord(r: Record): Task = {
+ return Task(
+ date = parseField[Calendar](r('報告日)),
+ ticketID = parseField[Option[Int]](r('チケットID)),
+ title = parseField[String](r('作業名)),
+ expectedCompletionDate = parseField[Calendar](r('作業完了予定年月日)),
+ deadline = parseField[Option[Calendar]](r('タスク期限)),
+ status = parseField[Status](r('状態)),
+ description = parseField[Option[String]](r('説明))
+ )
+ }
+ }
+}
+
+/*
class Task(tsvLine: String) {
sealed abstract class Status
object Status {
}
}
}
+ */