Перехват свойств классов домена Grails - PullRequest
2 голосов
/ 11 февраля 2010

Я хотел бы перехватить вызовы свойств классов домена для реализации контроля доступа.

Моей первой попыткой было переопределить setProperty и getProperty. Делая это, я отключил все приятные функциональные возможности классов домена Grails, таких как

domainClass.properties = params

и автоматическое преобразование типов данных.

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

Наконец, groovy.lang.Interceptor, кажется, хороший выбор, так как я могу получить доступ к реальному объекту. Но так ли это? Как я могу заставить все классы домена быть перехваченным?

Заранее большое спасибо.

С уважением, Даниэль

1 Ответ

4 голосов
/ 11 февраля 2010

Вы можете переопределить getProperty и setProperty, если вы ссылаетесь на реальные версии. Добавьте такой код в BootStrap для добавления перехватчиков для всех классов домена:

class BootStrap {

   def grailsApplication

   def init = { servletContext ->

      for (dc in grailsApplication.domainClasses) {
         dc.class.metaClass.getProperty = { String name ->
            // do stuff before access
            def result
            def metaProperty = delegate.class.metaClass.getMetaProperty(name)
            if (metaProperty) {
               result = metaProperty.getProperty(delegate)
            }
            else {
               throw new MissingPropertyException(name, delegate.class)
            }
            // do stuff after access
            result
         }

         dc.class.metaClass.setProperty = { String name, value ->
            // do stuff before update
            def metaProperty = delegate.class.metaClass.getMetaProperty(name)
            if (metaProperty) {
               metaProperty.setProperty(delegate, value)
            }
            else {
               throw new MissingPropertyException(name, delegate.class)
            }
            // do stuff after update
         }
      }
   }

   def destroy = {}
}
...