After about a year of doing nothing but Adobe Action Script projects, I'm finally back to a java/groovy/grails project. So, I downloaded the latest grails and fired up my version of NetBeans (6.8) and generated some code. Here's what I discovered...
First, NetBeans is very groovy/grails friendly. I was able to generate the project inside the IDE. I then dropped to the command line to generate domain classes and tests. I was able to run the full test suite inside the IDE, but I still prefer the command line.
I noticed that the generated code doesn't include an ant script, but just as well. I'm so sick of the XML crap, and the grails command line does everything you need, so...
Next step is to generate controllers, and maybe a few views, but I usually use grails as a JSON or XML server with a Flex/Action Script UI. I'm also creating all the unit tests as I go and running them from inside the IDE and from the command line.
Next post will discuss the controllers and any problems related to getting the application into production. So far everything works as advertised--better than previous versions, and very productive. My new best friend...
Showing posts with label groovy. Show all posts
Showing posts with label groovy. Show all posts
Wednesday, September 22, 2010
Friday, July 17, 2009
Simple Digest to Test File Uniqueness
Here is a simple way to use the groovy Digest class from org.raincity.glib.crypto package. It's limited to reasonably small files, but could be used with chunked sections of files. In any case, here is the test script:
s1 = the byte stream from the first file, s2 is the byte stream from the second file. If the hashes match, then the files are identical, i.e., not unique.
Digest's default algorithm is SHA-256, but SHA-512 is available in java > 1.4 and is much stronger. The 256 default was designed to match the SHA-256 limit for Adobe/Flex.
Thanks to Brad Rhoads for inspiring this post...
void testStringDigest() {
def algorithm = 'SHA-512'
def s1 = 'this is test 1'
def s2 = 'this is test 2'
def hash1 = new Digest().createHashString( s1, algorithm )
def hash2 = new Digest().createHashString( s2, algorithm )
println "h1 = ${hash1}"
println "h2 = ${hash2}"
assert hash1 != hash2
}
s1 = the byte stream from the first file, s2 is the byte stream from the second file. If the hashes match, then the files are identical, i.e., not unique.
Digest's default algorithm is SHA-256, but SHA-512 is available in java > 1.4 and is much stronger. The 256 default was designed to match the SHA-256 limit for Adobe/Flex.
Thanks to Brad Rhoads for inspiring this post...
Saturday, February 28, 2009
JSR-310 javax.time Periods
The proposed JSR-310 date/time API comes with many representations of date and time including Instant, Duration, LocalDate, LocalTime, LocalDateTime, OffsetDate, OffsetTime, OffsetDateTime, ZonedDateTime, MonthDay, YearMonth and others. One of the more interesting classes is Period. It represents a quantity of time, not fixed to any time in space--just a quantity. This entry will discuss periods, how they are parsed, and examples of use.
Parsing: Periods are parsed from string using formats that conform to the ISO-8601 duration format PnYnMnDTnHnMn.nS. Variations of this format are parsed to create Period objects. Parsing is done in PeriodParser, a standalone helper class that is easily accessed through the static method Period.parse(). Here are a few examples:
As you can see, the parsing scheme is robust and flexible. The main thing to keep in mind is that the Period object is more of a value container as opposed to a process unit. So, 60 minutes won't directly translate to 1 hour, and 24 months does not directly equal 2 years. But this aside, there are many uses for the Period class.
For example, lets say I want to periodically archive old temp files from a system. I could set the period to minutes, hours, days, whatever, then based on an arbitrary start time, begin the archive sweep. In the same moment, I could compute the next archive sweep by adding my pre-defined period object to the current time.
A more elaborate implementation would be to self-adjust the scheduled periods based on some criteria. Sticking with the archive sweep, lets say I set the initial period to 2 hours, or better yet, 120 minutes to give a finer resolution. Then, at the end of the sweep, I tally archived files. The smaller the number, the longer the period, on a sliding scale, up to 240 minutes. A large number would decrease the period to zero minutes, or a continual sweep, so I want to make sure that this is the very worst case scenario.
The Period class makes this easy to implement and maintain. To keep it simple, lets just use a linear equation. The formula for calculating the number of minutes between sweeps is reduced to period in minutes = mx + b, where b = 240 minutes (our maximum amount), x = the number of files, and m = the slope. Lets say that the maximum number anticipated required archives were 2 per minute, so after 240 minutes we would have 480 files that needed to be archived. If that is our worst case then m = -0.5 (delta y divide delta x, or -240 / 480). So the curve looks like this:

Now each time I do an archive sweep, I tally the files and calculate the next sweep interval using:
You might think there is a danger in allowing the returned period to be a negative number of minutes. But in all practicality this is acceptable because the objective is to determine the next instant when a sweep should occur. If this time is in the past, simply do it now. Of coarse you would design the slope to target the worst case, so a negative time should seldom if ever occur. And the good part is that the parameters are easy to modify to fit changing environments.
Testing with a Fixed Time Source: My previous entries have demonstrated using TimeSource and Clock tied to the System clock. But, for these tests, I think a fixed time source would be more appropriate. The syntax is like this:
So now when I create a date, time or date/time object from the clock, the time is always the same. Not very meaningful for real life, but great for testing.
If I create a class that uses clock, I can inject the TimeSource based on the system clock. And for testing, I can inject a fixed TimeSource, run tests, and not have to worry about the specific time, but simply base my tests on a static source. Here is the class:
And here is the test script:
When I run the script, here is what I get:
The main advantage is that I can run this independent of the current date, but still use the clock object without changing anything inside the class.
Conclusion: This quick look at Period and PeriodParser to see how it fits into the JSR-310 from the groovy coder's perspective. Next time well look closer at Date, Time and DateTime math capabilities and how they work with groovy plus/minus operator overloading.
Parsing: Periods are parsed from string using formats that conform to the ISO-8601 duration format PnYnMnDTnHnMn.nS. Variations of this format are parsed to create Period objects. Parsing is done in PeriodParser, a standalone helper class that is easily accessed through the static method Period.parse(). Here are a few examples:
assert Period.parse("PT0S") == Period.ZERO
assert Period.parse("P1Y") == Period.years(1)
assert Period.parse("P10Y8M22DT3M") == Period.period(10, 8, 22, 3)
assert Period.parse("PT1M") == Period.minutes(1)
assert Period.parse("P-4Y") == Period.years(-4)
As you can see, the parsing scheme is robust and flexible. The main thing to keep in mind is that the Period object is more of a value container as opposed to a process unit. So, 60 minutes won't directly translate to 1 hour, and 24 months does not directly equal 2 years. But this aside, there are many uses for the Period class.
For example, lets say I want to periodically archive old temp files from a system. I could set the period to minutes, hours, days, whatever, then based on an arbitrary start time, begin the archive sweep. In the same moment, I could compute the next archive sweep by adding my pre-defined period object to the current time.
A more elaborate implementation would be to self-adjust the scheduled periods based on some criteria. Sticking with the archive sweep, lets say I set the initial period to 2 hours, or better yet, 120 minutes to give a finer resolution. Then, at the end of the sweep, I tally archived files. The smaller the number, the longer the period, on a sliding scale, up to 240 minutes. A large number would decrease the period to zero minutes, or a continual sweep, so I want to make sure that this is the very worst case scenario.
The Period class makes this easy to implement and maintain. To keep it simple, lets just use a linear equation. The formula for calculating the number of minutes between sweeps is reduced to period in minutes = mx + b, where b = 240 minutes (our maximum amount), x = the number of files, and m = the slope. Lets say that the maximum number anticipated required archives were 2 per minute, so after 240 minutes we would have 480 files that needed to be archived. If that is our worst case then m = -0.5 (delta y divide delta x, or -240 / 480). So the curve looks like this:

Now each time I do an archive sweep, I tally the files and calculate the next sweep interval using:
maxMinutes = 240
slope = -0.5
periodInMinutes = slope * fileCount + maxMinutes
Or, as a single groovy closure:
def periodToNextSweep = { fileCount, slope = -0.5, maxMinutes = 240 ->
Period.minutes( slope * fileCount + maxMinutes )
}
You might think there is a danger in allowing the returned period to be a negative number of minutes. But in all practicality this is acceptable because the objective is to determine the next instant when a sweep should occur. If this time is in the past, simply do it now. Of coarse you would design the slope to target the worst case, so a negative time should seldom if ever occur. And the good part is that the parameters are easy to modify to fit changing environments.
Testing with a Fixed Time Source: My previous entries have demonstrated using TimeSource and Clock tied to the System clock. But, for these tests, I think a fixed time source would be more appropriate. The syntax is like this:
millis = 1234920035991L // 2009-02-17T17:20:35.991-08:00 Tuesday...
timeSource = TimeSource.fixed( Instant.millisInstant( millis ) )
clock = Clock.clockDefaultZone( timeSource )
So now when I create a date, time or date/time object from the clock, the time is always the same. Not very meaningful for real life, but great for testing.
If I create a class that uses clock, I can inject the TimeSource based on the system clock. And for testing, I can inject a fixed TimeSource, run tests, and not have to worry about the specific time, but simply base my tests on a static source. Here is the class:
class SweepController {
def clock = Clock.systemDefaultZone()
def slope = -0.5
def maxMinutes = 240
def periodToNextSweep = { fileCount ->
int x = (int)(slope * fileCount + maxMinutes)
x < 0 ? Period.ZERO : Period.minutes( x )
}
def nextSweepTime = { fileCount ->
def period = periodToNextSweep( fileCount )
clock.offsetDateTime() + period
}
}
And here is the test script:
millis = 1235721600000L // 2009-02-27T00:00-08:00
fixed = TimeSource.fixed( Instant.millisInstant( millis ) )
clock = Clock.clockDefaultZone( fixed )
sweep = new SweepController( clock:clock )
println "now -> ${clock.offsetDateTime()}"
source = [
[ 480, '2009-02-27T00:00-08:00' ],
[ 0, '2009-02-27T04:00-08:00' ],
[ 240, '2009-02-27T02:00-08:00' ],
[ 120, '2009-02-27T03:00-08:00' ],
]
source.each { count, value ->
println "count: ${count} -> ${sweep.periodToNextSweep( count )}, ${sweep.nextSweepTime( count )}"
assert value == sweep.nextSweepTime( count ).toString()
}
When I run the script, here is what I get:
now -> 2009-02-27T00:00-08:00
count: 480 -> PT0S, 2009-02-27T00:00-08:00
count: 0 -> PT240M, 2009-02-27T04:00-08:00
count: 240 -> PT120M, 2009-02-27T02:00-08:00
count: 120 -> PT180M, 2009-02-27T03:00-08:00
The main advantage is that I can run this independent of the current date, but still use the clock object without changing anything inside the class.
Conclusion: This quick look at Period and PeriodParser to see how it fits into the JSR-310 from the groovy coder's perspective. Next time well look closer at Date, Time and DateTime math capabilities and how they work with groovy plus/minus operator overloading.
Sunday, February 22, 2009
Adjusting Date and Time with javax.time
Java's JSR-310 date and time API, co-lead by Michael Nascimento Santos and Stephen Colebourne is a natural spinoff from the venerable joda time. The implementation has many advantages over java util's Date and Calendar. Compared to java.util.Date the API has many types of Date and Time including LocalDate, LocalTime, LocalDateTime, OffsetDate, OffsetTime, OffsetDateTime, and ZonedDateTime.
The new JSR-310 date, time, and date/time classes are immutable and thread safe, unlike java.util.Calendar, but at the same time they offer many basic math, adjusters, and matchers that enable date and time calculations missing in java.util.Date. They are created from a TimeSource that can be tied to the System clock, fixed, or offset in time. This makes the classes extremely test friendly.
This entry discusses how the basic date/time math work and how the date and time adjusters can be used to solve common problems. Lets look first at the basic math.
Look Ma, no Setters: The JSR-310 date/time classes are immutable and thread safe. To accomplish this, the API doesn't include any setXX methods. Days, Hours, Years, etc are manipulated through "plus", "minus", and "with" methods that return new objects of the same type. Here are a few examples, first with date then time:
The Adjusters: Here is a tricky problem: how do you compute the specific date of a week numbered day of the month, for example the 3rd friday or 4th tuesday. Bay area residents know that not being able to calculate these simple problems can cost real money (street sweep adys). So here is how JSR-310 handles this:
These examples just scratch the surface of the many date/time manipluation methods for JSR-310's javax.time package. The next entry will discuss how JSR-310 matchers help determine if a date lands on a leap year, leap day, last day of the month, etc. and how to use this in groovy.
The new JSR-310 date, time, and date/time classes are immutable and thread safe, unlike java.util.Calendar, but at the same time they offer many basic math, adjusters, and matchers that enable date and time calculations missing in java.util.Date. They are created from a TimeSource that can be tied to the System clock, fixed, or offset in time. This makes the classes extremely test friendly.
This entry discusses how the basic date/time math work and how the date and time adjusters can be used to solve common problems. Lets look first at the basic math.
Look Ma, no Setters: The JSR-310 date/time classes are immutable and thread safe. To accomplish this, the API doesn't include any setXX methods. Days, Hours, Years, etc are manipulated through "plus", "minus", and "with" methods that return new objects of the same type. Here are a few examples, first with date then time:
// tomorrow and 5 years from now
clock = Clock.systemDefaultZone()
today = clock.today()
assert clock.tomorrow() == today.plusDays(1)
fiveYearsFromNow = today.plusYears( 5 )
assert today.plusMonths( 60 ).year == fiveYearsFromNow.year
// two hours ago
now = clock.timeToSecond()
twoHoursAgo = now.minusHours( 2 )
assert now.minusMinutes( 120 ) == twoHoursAgo
// use offset datetime to get today at noon
noon = clock.offsetDateTime().withTime( 12, 0, 0 )
assert noon.hourOfDay == 12
assert noon.minuteOfHour == 0
assert noon.secondOfMinute == 0
The Adjusters: Here is a tricky problem: how do you compute the specific date of a week numbered day of the month, for example the 3rd friday or 4th tuesday. Bay area residents know that not being able to calculate these simple problems can cost real money (street sweep adys). So here is how JSR-310 handles this:
dt = clock.offsetDate()
thirdFridayAdjuster = DateAdjusters.dayOfWeekInMonth( 3, DayOfWeek.FRIDAY )
fourthTuesdayAdjuster = DateAdjusters.dayOfWeekInMonth( 4, DayOfWeek.TUESDAY )
thirdFriday = dt.with( thirdFridayAdjuster )
println "third friday -> ${thirdFriday}, ${thirdFriday.toDayOfWeek()}, ${thirdFridayAdjuster}"
assert DayOfWeek.FRIDAY == thirdFriday.toDayOfWeek()
fourthTuesday = dt.with( fourthTuesdayAdjuster )
println "fourth tuesday -> ${fourthTuesday}, ${fourthTuesday.toDayOfWeek()}, ${fourthTuesdayAdjuster}"
assert DayOfWeek.TUESDAY == fourthTuesday.toDayOfWeek()
These examples just scratch the surface of the many date/time manipluation methods for JSR-310's javax.time package. The next entry will discuss how JSR-310 matchers help determine if a date lands on a leap year, leap day, last day of the month, etc. and how to use this in groovy.
Saturday, February 21, 2009
JSR-310 javax.time and Groovy Tests
The development and implementation of JSR-310 is continuing to move ahead at a good pace. Once delivered, (hopefully by JDK 7) the java community will have a solid replacement for the outdated and comparatively buggy Date and Calendar classes. At the same time, I have created a series of groovy tests that exercise the JSR-310 capabilities.
Formal unit tests for JSR-310 are written in testng and cover all the low level details including TimeZone resolving, serialization, etc. My tests simply verify a subset of the current API and demonstrate use with groovy. The tests cover the basic API, adjusters, matchers, peroids, formatters and parsers. This post demonstrates the basic tests.
Basic API Tests: These tests take advantage of groovy's invokeMethod() to test methods that take zero or more parameters. They demonstrate typical use of TimeSource, Clock, LocalDate, and LocalTime classes. With these basics it's easy to extend to LocalDateTime, OffsetDate, OffsetTime, or ZonedDateTime. Here is the output trace generated from running BasicTests.groovy:
Here is a simple way to access some of the missing methods:
Future posts will demonstrate the Adjusters, Matchers, Periods, Formatters and Parsers. Once the tests are cleaned up a bit, I'll post them on line.
Formal unit tests for JSR-310 are written in testng and cover all the low level details including TimeZone resolving, serialization, etc. My tests simply verify a subset of the current API and demonstrate use with groovy. The tests cover the basic API, adjusters, matchers, peroids, formatters and parsers. This post demonstrates the basic tests.
Basic API Tests: These tests take advantage of groovy's invokeMethod() to test methods that take zero or more parameters. They demonstrate typical use of TimeSource, Clock, LocalDate, and LocalTime classes. With these basics it's easy to extend to LocalDateTime, OffsetDate, OffsetTime, or ZonedDateTime. Here is the output trace generated from running BasicTests.groovy:
Close inspection reveals that some methods in LocalDate are missing in OffsetDate. This isn't a huge problem, because OffsetDate can easily create a LocalDate object. But, it would be nice to have isLeapYear(), toEpochDays(), toModifiedJulianDays() and other methods in both classes. (This may already be in the works)...
TimeSource to Date/Calendar conversion tests ---------------------------------------
Timesource.system().instant() -> {ts.instant()}
Clock Method Tests ----------------------------------------------------------------
clock = Clock.systemDefaultZone() -> TimeSourceClock[SystemTimeSource, America/Los_Angeles]
Clock methods...
method: clock.getSource() -> SystemTimeSource
method: clock.getZone() -> America/Los_Angeles
method: clock.today() -> 2009-02-21
method: clock.tomorrow() -> 2009-02-22
method: clock.yesterday() -> 2009-02-20
method: clock.dateTime() -> 2009-02-21T08:56:35.512
method: clock.dateTimeToMinute() -> 2009-02-21T08:56
method: clock.dateTimeToSecond() -> 2009-02-21T08:56:35
method: clock.time() -> 08:56:35.515
method: clock.timeToMinute() -> 08:56
method: clock.timeToSecond() -> 08:56:35
method: clock.offsetDate() -> 2009-02-21-08:00
method: clock.offsetTime() -> 08:56:35.517-08:00
method: clock.offsetTimeToMinute() -> 08:56-08:00
method: clock.offsetTimeToSecond() -> 08:56:35-08:00
method: clock.offsetDateTime() -> 2009-02-21T08:56:35.518-08:00
method: clock.zonedDateTime() -> 2009-02-21T08:56:35.521-08:00 America/Los_Angeles
method: clock.zonedDateTimeToMinute() -> 2009-02-21T08:56-08:00 America/Los_Angeles
method: clock.zonedDateTimeToSecond() -> 2009-02-21T08:56:35-08:00 America/Los_Angeles
method: clock.year() -> Year=2009
method: clock.yearMonth() -> 2009-02
OffsetDate methods from offsetDate = clock.offsetDate() -> 2009-02-21-08:00
method: offsetDate.atMidnight() -> 2009-02-21T00:00-08:00
method: offsetDate.getDayOfMonth() -> 21
method: offsetDate.getDayOfWeek() -> DayOfWeek=SATURDAY
method: offsetDate.getDayOfYear() -> 52
method: offsetDate.getMonthOfYear() -> MonthOfYear=FEBRUARY
method: offsetDate.getYear() -> 2009
method: offsetDate.toDayOfMonth() -> DayOfMonth=21
method: offsetDate.toDayOfWeek() -> DayOfWeek=SATURDAY
method: offsetDate.toDayOfYear() -> DayOfYear=52
method: offsetDate.toLocalDate() -> 2009-02-21
method: offsetDate.toMonthOfYear() -> MonthOfYear=FEBRUARY
method: offsetDate.toYear() -> Year=2009
method: offsetDate.getDate() -> 2009-02-21
LocalDate methods from localDate = LocalDate.date(2019, 03, 01) -> 2019-03-01
method: localDate.atMidnight() -> 2019-03-01T00:00
method: localDate.getDayOfMonth() -> 1
method: localDate.getDayOfWeek() -> DayOfWeek=FRIDAY
method: localDate.getDayOfYear() -> 60
method: localDate.getMonthOfYear() -> MonthOfYear=MARCH
method: localDate.getYear() -> 2019
method: localDate.toDayOfMonth() -> DayOfMonth=1
method: localDate.toDayOfWeek() -> DayOfWeek=FRIDAY
method: localDate.toDayOfYear() -> DayOfYear=60
method: localDate.toLocalDate() -> 2019-03-01
method: localDate.toMonthOfYear() -> MonthOfYear=MARCH
method: localDate.toYear() -> Year=2019
method: localDate.getMonthDay() -> --03-01
method: localDate.getYearMonth() -> 2019-03
method: localDate.isLeapYear() -> false
method: localDate.toEpochDays() -> 17956
method: localDate.toModifiedJulianDays() -> 58543
method: localDate.toDateTimeFields() -> {ISO.Year=2019, ISO.MonthOfYear=3, ISO.DayOfMonth=1}
LocalTime methods, from localTime = clock.time() -> 08:56:35.549
method: localTime.getHourOfDay() -> 8
method: localTime.getMinuteOfHour() -> 56
method: localTime.getSecondOfMinute() -> 35
method: localTime.toDateTimeFields() -> {ISO.HourOfDay=8, ISO.MinuteOfHour=56, ISO.SecondOfMinute=35, ISO.NanoOfSecond=549000000}
method: localTime.toHourOfDay() -> HourOfDay=8
method: localTime.toLocalTime() -> 08:56:35.549
method: localTime.toMinuteOfHour() -> MinuteOfHour=56
method: localTime.toSecondOfMinute() -> SecondOfMinute=35
method: localTime.getNanoOfSecond() -> 549000000
method: localTime.toNanoOfSecond() -> NanoOfSecond=549000000
method: localTime.toNanoOfDay() -> 32195549000000
End basic tests...
Here is a simple way to access some of the missing methods:
Conclusion: What these tests really do is to demonstrate the basic functionality of the new javax.time classes. It's obvious that JSR-310 offers the horsepower missing from the current java implementations. And, it will be a very useful addition to the groovy toolkit as well.
offsetDate = clock.offsetDate()
offsetDate.toLocalDate().toEpochDays()
offsetDate.toLocalDate().toModifiedJulianDays()
offsetDate.toLocalDate().isLeapYear()
// or, even groovyer
offsetDate.toLocalDate().leapYear
Future posts will demonstrate the Adjusters, Matchers, Periods, Formatters and Parsers. Once the tests are cleaned up a bit, I'll post them on line.
Saturday, February 14, 2009
Java Date/Time Objects with JSR-310
I spent the day experimenting with the proposed javax.time API's from JSR-310. Modeled after the popular joda-time the new javax.time objects offer a rich set of date and time manipulation, basic math, durations, matching and time zone awareness.
At the top level, the concept of a TimeSource is introduced. This is a replacement for using System.currentTimeMillis() or System.timeNanos() or the standard java.util.Date and Calendar contructors. It can be spring loaded, so getting a source that has an offset is possible, which makes testing very easy.
The abstract Clock class is similar to TimeSource, but it is time zone aware. It's easy to get the local time (Clock.systemDefaultZone()) or to create a clock from a different time zone (Clock.system(TimeZone.UTC)).
Once the Clock object is created you can access today(), tomorrow(), yesterday(), the current DateTime and other methods for creating complex DateTime objects. You can also get the current instant which represents the current date/time as an instant since the epoch in nanoseconds.
The first step to using javax.time is to checkout the latest version from subversion. (I'm at build version 702).
Converting Date and Calendar to javax.time
A common way to construct both Date and Calendar from the java.util package is to use milliseconds. The Instant class from javax.time includes a method called toEpochMillis() that makes this easy: (groovy syntax)
Converting javax.time to Date/Calendar
To convert a javax.time object back to either Date or Calendar is just as simple:
Date Math
Here is a quick example of what you can do with a DateTime object. In this case, I'll use an OffsetDateTime to express the full ISO8601 date. (again, groovy syntax)
So you get the point. Many useful methods currently missing from the java JDK. So, hopefully this will be complete in time to make it into java 7. In the mean time, though not ready for production, it's available for bleeding-edge use.
At the top level, the concept of a TimeSource is introduced. This is a replacement for using System.currentTimeMillis() or System.timeNanos() or the standard java.util.Date and Calendar contructors. It can be spring loaded, so getting a source that has an offset is possible, which makes testing very easy.
The abstract Clock class is similar to TimeSource, but it is time zone aware. It's easy to get the local time (Clock.systemDefaultZone()) or to create a clock from a different time zone (Clock.system(TimeZone.UTC)).
Once the Clock object is created you can access today(), tomorrow(), yesterday(), the current DateTime and other methods for creating complex DateTime objects. You can also get the current instant which represents the current date/time as an instant since the epoch in nanoseconds.
The first step to using javax.time is to checkout the latest version from subversion. (I'm at build version 702).
Converting Date and Calendar to javax.time
A common way to construct both Date and Calendar from the java.util package is to use milliseconds. The Instant class from javax.time includes a method called toEpochMillis() that makes this easy: (groovy syntax)
utilDate = new java.util.Date()
instant = Instant.millisInstant( utilDate.time )
zone = ZoneOffset.zoneOffset( -8 )
dateTime = OffsetDateTime.dateTime( instant, zone )
Converting javax.time to Date/Calendar
To convert a javax.time object back to either Date or Calendar is just as simple:
ts = TimeSource.system()
dt = new Date( ts.instant().toEpochMillis() )
cal = Calendar.instance
cal.timeInMillis = ts.instant().toEpochMillis()
Date Math
Here is a quick example of what you can do with a DateTime object. In this case, I'll use an OffsetDateTime to express the full ISO8601 date. (again, groovy syntax)
clock = Clock.systemDefaultZone()
assert clock.today().toString() == "2009-02-14"
assert clock.tomorrow().toString() == "2009-02-14"
dt = clock.offsetDateTime()
assert dt.toString() == "2009-02-14T20:31:50.896-08:00"
dt.plusYears(3).toString() == "2012-02-14T20:31:50.896-08:00
assert dt.year == 2009
year = dt.toYear() // get the object, not the int
assert year.lengthInDays() == 365
assert year.next().value == 2010
assert year.nextLeap().value == 2012
assert year.nextLeap().lengthInDays() == 366
yearMonth = YearMonth.yearMonth( dt )
assert yearMonth.toString() == "2009-02"
assert yearMonth.plusMonths(5).toString() == "2009-07"
assert yearMonth.minusMonths(5).toString() == "2008-09"
So you get the point. Many useful methods currently missing from the java JDK. So, hopefully this will be complete in time to make it into java 7. In the mean time, though not ready for production, it's available for bleeding-edge use.
Friday, August 1, 2008
Groovy Excel Report Library
I just finished a series of reports for one of my customers using grails as the backend and Flex for the user interface. As with many of my reports for this customer, they requested the output be delivered as CSV files. Easy, and very boring.
So, with the help of JExcel and the jxl APIs from Andy Khan, I created an alternate output of an excel spreadsheet rather than CSV flat file. This has the additional benefit of sending multi-dimensional results, e.g., summary and details on two separate sheets, output statistics and charting on a third. This is much more useful for the end-user.
To make life easy, I created a wrapper around the jxl libraries to make it possible to use an alternate excel API such as Apache POI. At the same time, I created a set of conventions that use a template spreadsheet to easily create all the output without having to program any of the "view" components (i.e., classic MVC). The controller class is Workbook and the Model data is configured in Worksheet objects. All the formatting for dates, numbers, layout, etc. is in configured in templates (xsl files) easily configured and modified by non-programmers.
Since the target for this is inside war-deployed web applications I had to configure an external templates folder to enable report format changes without having to re-war/deploy or bounce the server. The templates folder is part of a more extensive Exchange class that coordinates remote data exchanges to a known area outside the web-space.
Conventions: Below is a list of convetions used to build reports...
Working Example: To demonstrate the report library I created a "Customer Invoice" report. The template has three sheets, includes graphic images, and shows two of the three "ReportData" sets in green bar (and blue bar) with automatic item numbering.
The Code: The full report can be built and run with just a few lines of code. Here is a typical example that prints the invoice, details, and expenses for a single period.

The three sheets are defined as details, expenses and invoice. Invoice details and expense rows are fetched for a specific period with GORM in the typical way. Report fields are extracted to match the template report data layout. The main invoice sheet has a few extra named values (line 28-31) and constructs two lines of data (lines 33 & 34).
Report Output: Here are the three sheets created by the code above.


So, with the help of JExcel and the jxl APIs from Andy Khan, I created an alternate output of an excel spreadsheet rather than CSV flat file. This has the additional benefit of sending multi-dimensional results, e.g., summary and details on two separate sheets, output statistics and charting on a third. This is much more useful for the end-user.
To make life easy, I created a wrapper around the jxl libraries to make it possible to use an alternate excel API such as Apache POI. At the same time, I created a set of conventions that use a template spreadsheet to easily create all the output without having to program any of the "view" components (i.e., classic MVC). The controller class is Workbook and the Model data is configured in Worksheet objects. All the formatting for dates, numbers, layout, etc. is in configured in templates (xsl files) easily configured and modified by non-programmers.
Since the target for this is inside war-deployed web applications I had to configure an external templates folder to enable report format changes without having to re-war/deploy or bounce the server. The templates folder is part of a more extensive Exchange class that coordinates remote data exchanges to a known area outside the web-space.
Conventions: Below is a list of convetions used to build reports...
- xls template contains all formatting and sheets for the report
- key words embedded into the template provides cell locations where data is to be written. values stored in the Worksheet object are used by the Workbook controller to update the spreadsheet output.
- a special type of keyword called "ReportData" is used to insert multilple rows into the spreadsheet, based on query result sets (or any list of data).
Working Example: To demonstrate the report library I created a "Customer Invoice" report. The template has three sheets, includes graphic images, and shows two of the three "ReportData" sets in green bar (and blue bar) with automatic item numbering.
The Code: The full report can be built and run with just a few lines of code. Here is a typical example that prints the invoice, details, and expenses for a single period.

The three sheets are defined as details, expenses and invoice. Invoice details and expense rows are fetched for a specific period with GORM in the typical way. Report fields are extracted to match the template report data layout. The main invoice sheet has a few extra named values (line 28-31) and constructs two lines of data (lines 33 & 34).
Report Output: Here are the three sheets created by the code above.


Thursday, July 10, 2008
Replacing GORM with Groovy Sql for Lightwieght Jobs
GORM, the Grails Object-Relational Mapping persistence framework provides a rational way to use Hibernate based on pojo (or groovy pogo) domain classes and basic conventions. Create a domain class, define some constraints, start up grails and viola! tables, columns, indexes are created without coding a line of SQL/DDL or creating annoying XML mappings.
But, what if you have a simple standalone process that requires single or multiple database access? Currently GORM has trouble working outside of grails, and creating a new grails project just to support a simple, no-client script is overkill. For that, I use groovy's database access classes in groovy.sql and a small custom library to easily access multiple data sources and provide simple query tools optimized for batch operations.
Here's an example: Tracking multiple UPS shipments. The application must access existing shipment requests from a local database, then query the UPS tracking remote service to discover shipment status. When a shipment is picked up or delivered, another local database is updated and a third system is updated via XML feed.
To summarize, the requirements are:
Design Implementation:
As always, I start with the tests. Using groovy test case, the database queries, inserts, and updates tests were created, then the target classes and methods. Queries are always the easiest, and updates are straight forward as well. Inserts with auto generated IDs are a bit tricker, but here is where groovy sql comes to the rescue.
Creating new tables presented a new problem: should I create SQL/DDL scripts? No! For this, it was easy enough to access the current grails application and create the new domain classes, run grails to have Hibernate create the new tables.
The groovy Sql class provides a method called executeInsert(). The magic in this method is that it returns an array of all auto-generated keys. So, if I'm working in MySql or Oracle or whatever, inserts all look the same--no database specific code required.
Database access defaults to the production environment but database tests must operate on the test database (similar to grails). This is easy to accomplish by simply overriding the default behavior in the test scripts.
Conclusions:
But, what if you have a simple standalone process that requires single or multiple database access? Currently GORM has trouble working outside of grails, and creating a new grails project just to support a simple, no-client script is overkill. For that, I use groovy's database access classes in groovy.sql and a small custom library to easily access multiple data sources and provide simple query tools optimized for batch operations.
Here's an example: Tracking multiple UPS shipments. The application must access existing shipment requests from a local database, then query the UPS tracking remote service to discover shipment status. When a shipment is picked up or delivered, another local database is updated and a third system is updated via XML feed.
To summarize, the requirements are:
- provide simultaneous access to multiple databases
- query UPS tracking via HTTP requests
- create XML responses and write to a messaging system
Design Implementation:
As always, I start with the tests. Using groovy test case, the database queries, inserts, and updates tests were created, then the target classes and methods. Queries are always the easiest, and updates are straight forward as well. Inserts with auto generated IDs are a bit tricker, but here is where groovy sql comes to the rescue.
Creating new tables presented a new problem: should I create SQL/DDL scripts? No! For this, it was easy enough to access the current grails application and create the new domain classes, run grails to have Hibernate create the new tables.
The groovy Sql class provides a method called executeInsert(). The magic in this method is that it returns an array of all auto-generated keys. So, if I'm working in MySql or Oracle or whatever, inserts all look the same--no database specific code required.
Database access defaults to the production environment but database tests must operate on the test database (similar to grails). This is easy to accomplish by simply overriding the default behavior in the test scripts.
Conclusions:
- Use groovy Sql for small, non-web applications that require single or multiple database access.
- Use Grails/GORM for all database/table creation and maintenance (no DDL scripts). This also has the additional benefit of enabling access to new tables through grails if required.
- Use executeInsert() to return auto-generated keys when inserting new rows.
Tuesday, March 4, 2008
Groovy DateTime Comparisons
Those of you following my posts know that I'm working on enhanced date/time support for groovy. In a previous post, I discussed a new DateTime class that leverages the power of java's Calendar and updates the interface in a groovy way. Which brings me to after(), before(), and compareTo() methods.
Calendar implements compareTo() that accepts only a calendar object. If you pass it a Date and exception is thrown. How restrictively lame.
DateTime's compareTo() accepts multiple types that can be evaluated to the millisecond level. So, DateTime, Date, Calendar, even long types are accepted. This approach enables this to work:
Calendar implements compareTo() that accepts only a calendar object. If you pass it a Date and exception is thrown. How restrictively lame.
DateTime's compareTo() accepts multiple types that can be evaluated to the millisecond level. So, DateTime, Date, Calendar, even long types are accepted. This approach enables this to work:
DateTime. How groovy is that!
now = [ new Date(), Calendar.getInstance(), System.currentTimeMillis, new DateTime() ]
yesterday = new DateTime() - 1
tomorrow = new DateTime() + 1
later = new DateTime(hours:23, minutes:59)
now.each {
assert yesterday.before( it )
assert tomorrow.after( it )
assert laster.after( it )
}
Groovy Temporal Support Continued
One area where ruby outshines groovy is in date and date time support. Ruby's date time support isn't more capable, just easier to use. Java, and groovy have Calendar--very complete, and very clunky. There is also joda time. Very complete, but a bit of an overkill for my tastes.
So here are the objectives:
DateTime, the Groovy Calendar: The first step is to create an easy (easier) to use, full featured DateTime class. One approach is to simply extend GregorianCalanedar and add the new methods, mostly getters and setters. That's were I started but soon discovered a better solution was to contain the calendar object, and use invokeMethod() to pass methods and arguments. Then, rather than define properties of the DateTime object, define getters and setters in bean style making the variables appear as if they were members. For example, I define these two methods:
Constructors: This was also very groovy. After I added the getter/setters, constructing with the virtual member vars was easy. So the DateTime class can be constructed like this:
Date/Time Formatting: The Rails group enhanced ruby's DateTime.to_s() method by adding formatting like this: to_s(format). This makes a lot of sense. To implement this I use a format hash that stores formatting strings by name. The map is static to enable use application wide (I may regret this later) and there is a default format member variable that controls how toString() is formatted. I also added toString(format) to display a date in multiple formats like this:
A Groovy Date Parser: I've seen many approaches to this, usually making use of java's SimpleDateFormat class with a boat load of formats. I think there may be a better way. First, extracting the date parts, usually the numbers and constructing date time objects based on the numeric values. I'll discuss this implementation later...
So here are the objectives:
- ability to add/subtract dates with integers representing days, months, etc.
- ability to subtract two dates to yield intervals representing days, hours, etc.
- ability to compare two dates
- ability to parse any type of date input, and most easily parse the standards
- ability to format dates in a wide variety of ways
- ability to create dates with integers and words like 10.days.ago or nextweek
DateTime, the Groovy Calendar: The first step is to create an easy (easier) to use, full featured DateTime class. One approach is to simply extend GregorianCalanedar and add the new methods, mostly getters and setters. That's were I started but soon discovered a better solution was to contain the calendar object, and use invokeMethod() to pass methods and arguments. Then, rather than define properties of the DateTime object, define getters and setters in bean style making the variables appear as if they were members. For example, I define these two methods:
int getYear() { return calendar.get(Calendar.YEAR) }
void setYear(int yr) { calendar.set(Calendar.YEAR, yr) }
Now, I can use short hand to access "year" like this:def dateTime = new DateTime(year:2008)Groovy, right? And adding other methods like setSeconds(), clearTime(), isWednesday() were easy one-liners to implement. I also took the liberty of shifting the month to 1..12 rather than 0..11, the calendar default.
assert dateTime.year == 2008
dateTime.year = 2020
assert dateTime.year == 2020
dateTime.year++
assert dateTime.year == 2021
Constructors: This was also very groovy. After I added the getter/setters, constructing with the virtual member vars was easy. So the DateTime class can be constructed like this:
dt = new DateTime(year:2020, month:4, day:1)
dt = new DateTime(hours:0, minutes:0, seconds:0)
dt = new DateTime().clearTime()
dt = new DateTime() + 5
Date/Time Formatting: The Rails group enhanced ruby's DateTime.to_s() method by adding formatting like this: to_s(format). This makes a lot of sense. To implement this I use a format hash that stores formatting strings by name. The map is static to enable use application wide (I may regret this later) and there is a default format member variable that controls how toString() is formatted. I also added toString(format) to display a date in multiple formats like this:
// default format is a modified ISO-8601 called 'db'Other formats are available in the formats hash. The actual formatting is done using SimpleDateFormat that supplies a wide range of date formats and is compatible with Java 1.4, important in the groovy community.
dt = new DateTime(year:2010, day:25, month:4, hours:15, minutes:35, seconds:29)
assert dt.toString() == '2010-04-25 15:35:29'
assert dt.toString(8601) == '2010-04-25T15:35:29-0800'
assert dt.toString('mdy') == '04/25/2010'
assert dt.toString('dmy') == '25.04.2010'
assert dt.toString('dMony') == '25-Apr-2010'
A Groovy Date Parser: I've seen many approaches to this, usually making use of java's SimpleDateFormat class with a boat load of formats. I think there may be a better way. First, extracting the date parts, usually the numbers and constructing date time objects based on the numeric values. I'll discuss this implementation later...
Sunday, March 2, 2008
Groovy Temporal Support Classes
Groovy adds a rich set of features to java including closures, ranges, dynamic metaClass, access to existing java code base, etc. What is missing is full featured date processing. One approach to fixing this is to use existing libraries of java date extensions, such as joda time. Today I decided to implement some basic date/time features without a third party dependency. I may end up using joda as the project unfolds, but for now I'm trying to resist the temptation.
HourMinuteSecond: This class acts as a container and formatter of hours, minutes and seconds similar to groovy's TimeDuration class. In native form it's completely mutable, so not thread safe. But it can be made immutable by invoking asImmutable(). I'll explain how groovy makes this easy to implement later on.
The class API is as follows:
The methods are actually closures, so creating the immutable clone was as simple as pointing all the mutators to a single closure that throws an UnsupportedOperationException when a mutating method is called. This mimics how groovy's List.asImmutable() method works.
I will post more as the temporal project unfolds, and supply a link once the library is ready for distribution.
HourMinuteSecond: This class acts as a container and formatter of hours, minutes and seconds similar to groovy's TimeDuration class. In native form it's completely mutable, so not thread safe. But it can be made immutable by invoking asImmutable(). I'll explain how groovy makes this easy to implement later on.
The class API is as follows:
static HourMinuteSecond now()The object can be used as a simple up/down timer measured in seconds. When attached to a one second ticker thread, only the next() method needs to be invoked to tally up the seconds. Used as a count down timer, an event is triggered when zero is reached.
static HourMinuteSecond fromDate(date)
def parse('hh:mm:ss')
def set(hours, minutes, seconds)
def set(Date dt)
def next() // enables ++
def previous() // enables --
def add(hours, minutes, seconds)
def sub(hours, minutes, seconds)
boolean isZero()
String toString() // formatted as hh:mm:ss
void addZeroEventListener(closure)
def asImmutable()
The methods are actually closures, so creating the immutable clone was as simple as pointing all the mutators to a single closure that throws an UnsupportedOperationException when a mutating method is called. This mimics how groovy's List.asImmutable() method works.
I will post more as the temporal project unfolds, and supply a link once the library is ready for distribution.
Wednesday, February 6, 2008
UPS Web Services Interface
One of my customers has a requirement to use United Parcel Service to ship large and small packages. UPS has a great set of documentation, but they handle large and small packages with different technologies. Small packages are simple XML request/response transactions that provide methods for requesting a shipment, accepting shipments, and voiding shipments. Large packages allow you to request a shipment, but the request/response is all in SOAP, something of an overkill in my opinion.
UPS requires lots of data concerning who, what and where to establish their pricing. Data is sent to a URL/end point and a response is returned. The response includes pricing and tracking numbers, as well as image data for printing barcoded shipping labels. So, it is mainly a data transfer operation-- a single service.
SOAP is great if you have lots of defined services, like weather in Seattle or Paris or zip code 94705. Or conversion of units from/to. But for simple data transfer, REST, or just plain old XML request/response is much more efficient.
Here is a diagram of the complete data transfer...
...
As you can see, there are lots of communications. The first question is, why is there a server in the middle? Well, here's the deal--the SunReturns client is just that, a client. The data really resides at the DataServer--the client simply persists it's own private session. The UPS server is at their site. All communications are via SOA/services--some simple request/response (ala REST) and others use SOAP.
The technology used in the middle is grails/groovy. The SunReturns server is currently a mixture of JSP (legacy) and groovy/GSP. The groovy components are XML only and include controllers, services, domain objects, etc--similar to grails but without the Hibernate layer. It talks to legacy databases, both Oracle and MySQL--not impossible with grails, but definitely outside the conventions.
Conclusions: The natural loose coupling of SOA provides a new vehicle to solve business problems. At the same time, distributing business processes across diverse servers provides a workable migration path to newer technologies. Groovy, grails, and simple XML transport provide a way to implement SOA with a minimum of effort.
UPS requires lots of data concerning who, what and where to establish their pricing. Data is sent to a URL/end point and a response is returned. The response includes pricing and tracking numbers, as well as image data for printing barcoded shipping labels. So, it is mainly a data transfer operation-- a single service.
SOAP is great if you have lots of defined services, like weather in Seattle or Paris or zip code 94705. Or conversion of units from/to. But for simple data transfer, REST, or just plain old XML request/response is much more efficient.
Here is a diagram of the complete data transfer...
...
As you can see, there are lots of communications. The first question is, why is there a server in the middle? Well, here's the deal--the SunReturns client is just that, a client. The data really resides at the DataServer--the client simply persists it's own private session. The UPS server is at their site. All communications are via SOA/services--some simple request/response (ala REST) and others use SOAP.
The technology used in the middle is grails/groovy. The SunReturns server is currently a mixture of JSP (legacy) and groovy/GSP. The groovy components are XML only and include controllers, services, domain objects, etc--similar to grails but without the Hibernate layer. It talks to legacy databases, both Oracle and MySQL--not impossible with grails, but definitely outside the conventions.
Conclusions: The natural loose coupling of SOA provides a new vehicle to solve business problems. At the same time, distributing business processes across diverse servers provides a workable migration path to newer technologies. Groovy, grails, and simple XML transport provide a way to implement SOA with a minimum of effort.
Sunday, December 30, 2007
10 Reasons to Switch from Rails to Grails
After spending a few years really enjoying Rails it was difficult to bring myself to even try groovy and grails. But my latest contract forced me to look for alternatives, and I'm glad I did. Here are some reasons that you may want to switch...
One thing I thought I might be giving up was the endless list of valuable gems that make developing in Rails a real pleasure. But after re-reviewing the list of open source products from apache, java source, spring, hibernate, and even Sun (glassfish), I can't think of any gems that I will miss.
- GORM with hibernate/spring and jpa is much better than ActiveRecord
- No distribution problems; runs in many production ready containers
- Internationalization out of the box (not specifically ignored as DHH does)
- Transactions actually work, and they include save-points.
- Not only dynamic finders and counters, but dynamic listOrderBy
- No green threads (although this may be fixed in Ruby 2.0, around 2010?)
- Ability to use pessimistic locking out of the box
- Real-live prepared statements and .withCriteria method
- Production level test reporting with built in Mocking and Stubbing
- Search operations are based on Lucene (with a plugin)
One thing I thought I might be giving up was the endless list of valuable gems that make developing in Rails a real pleasure. But after re-reviewing the list of open source products from apache, java source, spring, hibernate, and even Sun (glassfish), I can't think of any gems that I will miss.
Subscribe to:
Posts (Atom)