вторник, 30 декабря 2008 г.

PowerBall

Отличная штука. Кручу верчу - остановиться не могу.

среда, 24 декабря 2008 г.

Нравица!

Little Boots нравица!





Хотет полноценный альбом этой исполнительницы.

среда, 18 июня 2008 г.

оле!!!

Сборная - молодцы. Ещё бы моменты так не растрачивали, были бы совсем красавцы.

суббота, 7 июня 2008 г.

grails 1.0.3

Вышел grails 1.0.3. При попытке заапгрейдтить проект с 1.0.2 до 1.0.3 наткнулся на то, что предыдущий конфиг не совместим с новыми скриптом Package и некоторыми другими.

Заборол конечно. Но осадок остался.

среда, 4 июня 2008 г.

speedy racer

Посмотрел Спиди гоншика. Шёл на этот фильм с опаской, но мои опасения были развеяны за первые 15 минут фильма.

Очень хорошее кино.

grails: работа с шаблонами

Вот здесь описан способ отправки почтовых сообщений с html форматированием. Всё бы хорошо, но использование groovy шаблонов вместо обычных gsp для задания отображения почтового сообщени я считаю неверным.

Поэтому я чуть-чуть покапался во внутренностях grails и вот результат:

import org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngine
import org.codehaus.groovy.grails.web.pages.GroovyPageTemplate
import grails.util.GrailsWebUtil
import org.springframework.web.context.request.RequestContextHolder

class TemplateService {
GroovyPagesTemplateEngine groovyPagesTemplateEngine

def createHtml(String templateName, Map model) {
if(!RequestContextHolder.getRequestAttributes())
GrailsWebUtil.bindMockWebRequest()

GroovyPageTemplate tpl = groovyPagesTemplateEngine.createTemplate(templateName)
StringWriter out = new StringWriter()
tpl.make(model).writeTo(out)

return out.toString()
}
}


Хочу отметить, что очень большой недостаток доступной документации по grails заключается в отсутствии описания контекстных бинов, которые grails инициализирует и использует. В данном случае такой бин - groovyPagesTemplateEngine.

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

физики шутят

АНГЕЛ: Господи, они синтезировали еще один трансурановый элемент. Как будем реагировать?
БОГ: Добавим еще один нелинейный член в Истинное Уравнение Единого Поля.

четверг, 15 мая 2008 г.

немного магии

потс радости

ЗЕНИТ - ЧЕМПИОН!!!111

p.s. ох и накидался я вчера, ОЯЕБУ.

воскресенье, 4 мая 2008 г.

зайцы. зайцы - мозгоразрывайцы.




Картинке кликабле.

grails: gorm & query by criteria

Есть такая симпатичная штука в hibernate, а как следствие, и в grails. Штука очень хорошая для составления динмаических запросов, в зависимости от того, допустим, по какому набору полей надо искать. И есть в hibernate criteria api такая штука как alias'ы - метод формулировать условия для ассоциаций.

Я очень удивился, когда не нашёл в документации grails ничего об алиасах, ну и полез в гугл - куда ж ещё. Всё оказалось, как обычно, просто. Допустим есть сущность Foo с ассоциацей bar, у которой условие необходимо наложить на поле baz. Пишется это так:

def c = Foo.createCriteria()
def someList = c{
bar {
eq("baz", "some value")
}
}

Вот примерно так. bar {...} и является той самой ассоциацией. Вложенность таких вызовов с клозуром может быть какая угодно.

Кстате, пока писал, подумал, как команда grails собирается реализовать gorm на базе JPA текущей (а это планируется в grails 1.1)? В JPA ведь нет никакого criteria api, это чисто hibernate заморочка. Интересно будет посмотреть.

суббота, 3 мая 2008 г.

А пока были праздники

произошла пара интересных событий:
1. groovy 1.6 beta - заявлено о нехилом росте производительности.
2. SpringSource Application Platform beta - очень интересная штука должна быть, кроме того, grails приложения на неё деплоятся без проблем.

Всех с прошедшими праздниками.

вторник, 29 апреля 2008 г.

grails: testing & dbunit

DBUnit plugin для Grails оказался не без изъяна. Две вещи раздражают :
1. Только plain данные можно описать в датасетах. Это очень плохо. Возможно я просто не нашёл как по другому.
2. Почему-то каждый раз при запуске теста происходит полная перекомпиляция, а это очень долго.

Возможно, не стоит использовать DBUnit, потому что, учитывая синатксис Groovy, создание данных для тестиварония простая задача.

среда, 23 апреля 2008 г.

Чудное

http://community.livejournal.com/ru_java/638585.html

пятница, 11 апреля 2008 г.

grails: unit testing

Пришлов время пописать юнит тесты. Юнит тестировал я один из методов сервиса, который проверяет может ли пользователь видеть урл или нет.
Метод вот такой:

class SecurityService {
static digestAlgo = "MD5"


boolean checkAccess(def acc, def controller, def action) {
def attachedAcc = Account.get(acc.id)
def checkingUrl = controller + "/" + action
def realRes = false

log.debug "let's check it"
log.debug "attachedAcc : ${attachedAcc}"
log.debug "checkingUrl : ${checkingUrl}"

if(attachedAcc) {
attachedAcc.roles.urls*.find { requestmap ->
if(checkingUrl =~ requestmap.url) {
realRes = true
return true
}
}
}

return realRes
}
...
}


Так как я захотел создать именно юнит тест, то все инжекты из grails необходимо было проэмулировать. А это следующее:
Account.get
объект log
attachedAcc.roles.urls - т.е. свойства roles и urls.
И здесь на выручку приходит динамеческая природа groovy, которая позволяет всё необходимое добавить к классам прямо в run-time.
И так:
1. создаём список аккаунтов, назначем аккаунтам роли, ролям паттерны доступных урлов

def adminRole = new Role()
adminRole['urls'] = [
[url: ".*"],
]
def adminAccount = new Account(username : 'admin')
adminAccount['roles'] = [adminRole]

def oneControllerAllRole = new Role()
oneControllerAllRole['urls'] = [
[url: "one/.*"],
]

def restrictedRole = new Role()
restrictedRole['urls'] = [
[url: "two/three"],
[url: "four/five"]
]

def account1 = new Account(username : 'oneAll')
account1['roles'] = [oneControllerAllRole]
def account2 = new Account(username : 'restricted')
account2['roles'] = [restrictedRole]
def account3 = new Account(username : 'oneAllAndRestricted')
account3['roles'] = [oneControllerAllRole, restrictedRole]

def accounts = [
(new Long(1)) : adminAccount,
(new Long(2)) : account1,
(new Long(3)) : account2,
(new Long(4)) : account3
]

2. Добавляем к Account метод get()

Account.metaClass.static.get = { Long id ->
return accounts[(id)]
}

3. Добавляем к сервису объект log. Ну и конечно же надо создать сам сервис.

def sol = new SOL()
SecurityService.metaClass.getLog = { ->
return sol
}
securityService = new SecurityService()

здесь SOL - простейщий класс реализующий метод debug()

Собственно всё, среда готова, можно тестировать.

пятница, 4 апреля 2008 г.

среда, 2 апреля 2008 г.

Бу-ра-ти-но!!!

Отсюда:

Петр Кузнецов, лидер пензенских сектантов, пытался в среду совершить самоубийство. Об этом по телефону из села Никольское Бековского района сообщил вице-губернатор области Олег Мельниченко.

В ходе следствия выяснилось, что открытую черепно-мозговую травму Кузнецов получил не в результате нападения со стороны сектантов, как сообщалось ранее, а «это была попытка суицида».

«Кузнецов положил голову на деревянный чурбан и наносил себе удары другим деревянным чурбаном. В результате он получил открытую черепно-мозговую травму. Кузнецов был доставлен в Бековскую ЦРБ и экстренно прооперирован. В настоящее время он отправлен в больницу в Пензу для дальнейшего хирургического обследования специалистами», - рассказал Мельниченко.

четверг, 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.

тук тук

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