Access to the "application" Variable inside a Model

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Access to the "application" Variable inside a Model

mecorusfc
Trying to upgrade from 0.9 to 2.6.  However, I'm still having a lot of problems with not having access to the application variable inside any of my models.  For a few of them, I've been able to move the functionality out to a controller or somewhere else but it is really crippling the capabilities of my application to do that.  Here is an example of a simple model that uses this but gets the following error:

@ArtifactProviderFor(GriffonModel)
class ReportModel {
   // @Bindable String propName
  EventList<VarianceModel> variances = new BasicEventList<VarianceModel>()
 ...
  @Bindable URL goodUrl = new File("${application.configuration.get('trade.good.icon.file')}").toURI().toURL()
  @Bindable URL uglyUrl = new File("${application.configuration.get('trade.ugly.icon.file')}").toURI().toURL()
}

If I run a report that displays a view that uses this model, I get the following error:

Caused by: java.lang.NullPointerException: Cannot get property 'configuration' on null object
        at trader.ReportModel.<init>(ReportModel.groovy:15)

Is there any way to get access to the "application" variable inside a model in v2.6?
Reply | Threaded
Open this post in threaded view
|

Re: Access to the "application" Variable inside a Model

aalmiray
Administrator
The `application` instance is injected into artifacts using Dependency Injection, thus it's not yet initialized when the field values are assigned. You can either initialize field values inside `mvcGroupInit` or provide a method annotated with `@PostConstruct`.

In other words any of these two

@ArtifactProviderFor(GriffonModel)
class ReportModel {
   // @Bindable String propName
  EventList<VarianceModel> variances = new BasicEventList<VarianceModel>()
 ...
  @Bindable URL goodUrl
  @Bindable URL uglyUrl

  void mvcGroupInit(@Nonnull Map args) {
      setGoodUrl(new File("${application.configuration.get('trade.good.icon.file')}").toURI().toURL())
      setUglyUrl(new File("${application.configuration.get('trade.ugly.icon.file')}").toURI().toURL())
  }
}


@ArtifactProviderFor(GriffonModel)
class ReportModel {
   // @Bindable String propName
  EventList<VarianceModel> variances = new BasicEventList<VarianceModel>()
 ...
  @Bindable URL goodUrl
  @Bindable URL uglyUrl

  @PostConstruct
  private void initialize() {
      setGoodUrl(new File("${application.configuration.get('trade.good.icon.file')}").toURI().toURL())
      setUglyUrl(new File("${application.configuration.get('trade.ugly.icon.file')}").toURI().toURL())
  }
}

Note the usage of explicit setters instead of property access; this is done in order to trigger property change events. Relying on property access mutator results in the value being written directly to the field and no events are triggered. This is a known Groovy behavior, shortcircuiting method calls inside the property's owner.

Cheers,
Andres

Reply | Threaded
Open this post in threaded view
|

Re: Access to the "application" Variable inside a Model

mecorusfc
Ah, I see now.  I was trying the @PostConstruct and it wasn't working for me because I was doing the direct access instead of the setters.  Thanks again, Mike