четверг, 27 марта 2008 г.

язычники.

По поводу вот этого почему то вспомнилось:
Я его в химках видел. Он там деревянными членами торгует. (с)

среда, 26 марта 2008 г.

grails: mein kampf 1 / опять TagLib

Во время разбирательств с Web Flow я обнаружил, что входящий в поставку тег sortableColumn не поддерживает этот самый Web Flow. Ну что-ж, пора сделать свой тег - сказал я себе. Сказано, сделано. Вот тегова либа.


class ExtTagLib {
static namespace = "ext"

def sortableColumn = {attrs ->
['sort', 'order'].each { name ->
if(attrs[name] && attrs[name] != '') {
params[name] = attrs[name]
}
}
if(attrs.event) {
if(!attrs.params) attrs.params = [:]
attrs.params['_eventId'] = attrs.event
}

out << g.sortableColumn(attrs)
['sort', 'order'].each { name ->
params.remove(name)
}
}
}


Несколько кривовато, конечно, но работает. А это, в конце концов самое важное.

groovy: маленькие фкусняшечки 1 / работа с датами

Сейчас я решаю задачу: необходимо составить возможное расписание некоторого события, протяжённого во времени, причём, естественно, необходимо знать дату начала и конца данного события.


import groovy.time.*
// groovy time!
import org.codehaus.groovy.runtime.TimeCategory

approxStartDate = new Date()
// возможная дата начала
approxEndDate = new Date() + 2
// возможная дата конца (импользуем +!)
startHour = 10
//начальный час. число произвольное
endHour = 20
//конечный час. число произвольное
stepsPerHour = 4
//разбивка часа, т.е. событие длится 15 минут. число произвольное
int duration = 7 * 15
//длительность. число произвольное

for(day in approxStartDate..approxEndDate) {
println " $day"
for(hour in startHour..<endHour) {
println " $hour"
for(step in 0..<stepsPerHour) {
use(TimeCategory) {
def dateTimeStart = new Date(
year: day.year,
month: day.month,
hours: hour,
minutes: step * 15,
seconds: 0)

def dateTimeEnd = dateTimeStart + duration.minutes
//прибавляем длительность чтобы получить конечную дату. просто и разумно.
println " $step : $dateTimeStart, $dateTimeEnd"
}
}
}
}


Простой, понятный и короткий код. И это хорошо.
Магия groovy работы с датами проявляется в 2-х местах.
Первое:

approxEndDate = new Date() + 2

В груви для даты опеределна функция plus(), поэтому к дате можно спокойно добавить дни. Самое смешно, что функция minus() для даты не определена, так что вычитать из даты таким образом нельзя.

Второе:

use(TimeCategory) {
def dateTimeStart = new Date(
year: day.year,
month: day.month,
hours: hour,
minutes: step * 15,
seconds: 0)

def dateTimeEnd = dateTimeStart + duration.minutes
//прибавляем длительность чтобы получить конечную дату. просто и разумно.
println " $step : $dateTimeStart, $dateTimeEnd"

Здесь используются классы TimeCategory и Duration. Первый позволяет записать Duration в виду duration.minutes, а Duration ползволяет прибавлять и вычитать из даты произвольные периоды времени.

Кстати вместо duration.minutes можно было бы записать 15.minutes или 2.hours, таким образом в этом небольшом куске кода используется DSL для работы с единицами измерения времени.

Такие дела.

вторник, 25 марта 2008 г.

Биопринтер.

Помнится в 5 элементе Лилу восстанавливали такой хитрой машинкой, у неё ещё ручки так быстро тык-мык тык мык. Так вот, похоже сделали прообраз такой технологии. Охуени!

среда, 19 марта 2008 г.

Умер Артур Кларк.

понедельник, 17 марта 2008 г.

Доброе утро.

Котег сегодня таки заинтересовался движущимися картинками в телеящике. Забавно было то, как он трогал лапой эти самые картинки, и его задумчивый загривок, который как бы говорил мне "OMG! WTF?".

среда, 12 марта 2008 г.

вторник, 11 марта 2008 г.

groovy: маленькие фкусняшечки 0

Допустим, у меня есть некоторый объект (foo), набор полей которого необходимо обработать единообразно.

Java:

public void process(String field) {
System.out.println(field)
}

process(foo.getBar());
process(foo.getBaz());
process(foo.getMaz());

groovy:

class Foo {
def bar
def baz
def maz
}

def foo = new Foo(bar : "barrr", baz : "bazzz", maz : "mazzz")
['bar','baz','maz'].each { name ->
println foo[name]
}

Вариант на Java не полный - было лень приводить весь код. И не смотря на это, вариант на groovy на мой взгляд несомненно изящнее.

grails: mein kampf 1 / TagLib

Приступил к разборками с TagLib в grails. В документации обещают, что они будут перегружаться автоматом, как и почти все остальные артефакты проекта.
Однако, как обычно, есть нюанс: если обращаться непосредственно к gsp странице минуя контроллер, то автоматическая перезагрузка не происходит.

rocket day.

Ракетные дни. Французы запустили, японцы запустили. Молодцы.

понедельник, 10 марта 2008 г.

Хомяк.

JavaService

JavaService - продукт позволяющий использовать java приложения в качестве нативных сервисов (демонов под Unix). Сочетание же java 1.6 и JavaService под Windows даёт замечательный баг: сервис не стартует а в логах виндоуз появляются сообщения о том, что jvm.dll загрузить не было никакой возможности ("can't load jvm.dll").

В результате гуглежа я выяснил, что этот баг не уникален для JavaService, но характерен для jdk 1.6, и что происходит он от того, что приложение пытается запустить java машину через jni, но чего то для этого не хватает. Подробно описано здесь.

Написал я это всё к тому, что я натыкась на эту пердь уже раз в 10-ый, каждый раз как разворачиваю приложение, и каждый раз уходит минут 10-15 поисков.
Решил оставить себе заметку.

пятница, 7 марта 2008 г.

ПОра бухать.

Фсем чмоке. Особенно бабцам.

До встречи в адеквате.

grails: mein kampf 0 / Web Flow

В Grails есть чудесная штука - называется Web Flow. Хотя, я неверно выразился, Web Flow есть в Spring, а в Grails его "воткнули", как и многое другое. У Web Flow Grails есть чудесная особенность - внутри кода описывающего Web FLow в контроллере нельзя применять Hibernate Criteria, потому как они работают в этом случае очень странно.

Например вот такой код:


def mainFlow = {
...
search {
action {
...
def listCriteria = Client.createCriteria()
def clientList = listCriteria {
like("fname", fname)
like("pname", pname)
like("sname", sname)
firstResult(params.offset)
maxResults(params.max)
}
...
}
}
}


даст на выходе запрос в котором отсутствуют всякие упоминания о firstResult и maxResults.

Решение данной проблемы - перенос работы с Criteria в сервис и последующий инжект оного в контроллер.

Такие дела.

grails: маленькие фкусняшечки 0

А вот код, перетаскивающий параметры POST или GET запроса с именем формата flow.<имя> в контекст Web Flow. Ну напрмер из адресной строки формата http://some.domain/controller/flow?oppa=1&flow.q=obana в Web Flow пробрасывается q (flow.q == "obana").


params.flow?.each { entry ->
flow.'${entry.key}' = entry.value
}


Нравицца!

четверг, 6 марта 2008 г.

groovy & grails

Два очень интересных и перспективных Java продукта, которые я буду использовать в 2008 году. Постараюсь делать некоторые заметки как о Groovy - в основном в контексте сравнения Java подхода и Groovy, так и о Grails.

тук тук

Ридер принёс мне вот такую новость. Хорошая новость, я считаю - ещё один шаг к децентрализации, чистой энергии, отказу от сжигания нефти.