Использование asType с аннотацией Mixin - PullRequest
0 голосов
/ 21 августа 2011

Я хотел бы написать пользовательское преобразование типов Категория в Groovy.Цель состоит в том, чтобы присвоить значения Map полям компонента Groovy.В будущем будут разные типы ответов.Значения Map всегда имеют тип String, но их необходимо преобразовать в другой тип данных.Чтобы сделать эту работу, я создал класс Category, который реализует метод с именем asType.Это упрощенный пример моего кода:

class MapCategory {
    static Object asType(Map self, Class clazz) {
        if(clazz == Response) {
            Response response = new Response()

            self.each { key, value ->
                response.setProperty(key, value)
            }

            return response
        }

        DefaultGroovyMethods.asType(self, clazz)
    }
}

class Response {
    String result
    String message
}

Это прекрасно работает, когда я применяю категорию, используя ключевое слово use.

use(MapCategory) {
    println [result: 'OK', message: 'Success'] as Response
}

Однако, когда я пытаюсьвместо этого используйте аннотацию @Mixin, которая работает неправильно.Я получил правильный тип ответа, но все поля null.

@Mixin(MapCategory)
class MyClass {
    def printResponse() {
        println [result: 'OK', message: 'Success'] as Response    
    }
}

Кто-нибудь знает, почему он не работает правильно, используя аннотацию?

1 Ответ

0 голосов
/ 21 августа 2011

Mixins не работают таким образом.Вы пытаетесь смешать метод для Map с вашим MyClass объектом.Миксин будет работать только в том случае, если MyClass extended Map.

Вместо этого вы хотите использовать ключевое слово use, как обычно, и просто использовать свою категорию в качестве категории.Вам это может не понадобиться.Знаете ли вы, что по умолчанию вы можете конвертировать любую карту в любой GroovyBean без дополнительного кода?Просто используйте конструктор на основе карты, например:

@groovy.transform.Canonical // Groovy 1.8, just added for automatic toString method
class Response {
    String result
    String message
}

println new Response([result: 'OK', message: 'Success'])
println([result: 'bad', message: 'blah'] as Response)

Обратите внимание, что автоматическое преобразование карты работает в обоих направлениях.Это встроенная функция Groovy.

Конечно, если вам нужно что-то более сложное, чем просто присвоение свойств бина, это не поможет.

Примечание: я бы хотелдать вам ссылку, но сайт Groovy, кажется, не работает, и я не могу найти примеры кода.: - (

РЕДАКТИРОВАТЬ: Другое предложение

Вместо того, чтобы вообще использовать Категорию, почему бы вам не позволить самому компоненту обработать его:

@groovy.transform.Canonical
class Response {
    String result
    String message
    int num

    public void setNum(String num) {
       this.num = Integer.parseInt(num) 
    }
}

def map = [result: 'OK', message: 'Success', num: '35' ]

println map as Response
...