cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nikita Timofeev <ntimof...@objectstyle.com>
Subject Re: Can I access metadata (InfoExtension) from my velocity templates
Date Wed, 06 May 2020 07:45:50 GMT
Hi Faizel,

Accessing metadata from cgen is a long-standing task [1]. And I
finally made an approach to it and unshelved some code I've been
working on [2]. It does exactly as you think it should, exporting
"metadataUtils" to the Velocity context, see [3] as an example.

[1] https://issues.apache.org/jira/browse/CAY-2338
[2] https://github.com/apache/cayenne/pull/422
[3] https://github.com/apache/cayenne/pull/422/files#diff-f4dfa761f5ec173dacb042c857cd7708R53

On Tue, May 5, 2020 at 8:43 PM Faizel Dakri <listfez@dakri.com> wrote:
>
> Accessing metadata from my Cayenne app is not an issue at the moment—I am doing the
same thing you suggest and providing the default metadata class. That works well, and I’m
able to store/retrieve metadata other than comments. However, it appears that metadata, specifically
DataChannelMetaData, is not accessible when running cgen, and by extension my entity templates.
And I cannot find a way to get access to it from my own tool.
>
> Cayenne is fairly new to me, so I may not know what I’m talking about, however, it
seems to me like the metadata cannot be accessed from cgen or any velocity tool. Unless I’m
missing something, there’s no way to access the runtime instance (or injector) in cgen,
either of which is sufficient to get access to the metadata instance. I would think the easiest
way to make metadata available to templates is by making the DataChannelMetaData instance
available to the velocity context (e.g. channelMetaData) as a root object (perhaps in EntityArtifact’s
postInitContext), that way it can be passed to any tool that needs it.
>
> F
>
>
> > On May 5, 2020, at 10:05 AM, John Huss <johnthuss@gmail.com> wrote:
> >
> > For accessing the metadata, I looked into this a bit. At runtime in an app
> > this information isn't accessible by default, so if you wanted to use it at
> > runtime you would have to configure the runtime to access it with a DI
> > module like this:
> >
> > *public* *class* MyModule *implements* Module {
> >
> > *public* *void* configure(Binder binder) {
> >
> >        binder.bind(HandlerFactory.*class*).to(ExtensionAwareHandlerFactory.
> > *class*);
> >
> >        binder.bind(DataChannelMetaData.*class*
> > ).to(DefaultDataChannelMetaData.*class*);
> >
> >        ProjectModule.*contributeExtensions*(binder)
> >
> >        .add(InfoExtension.*class*);
> >
> > }
> >
> > }
> >
> >
> > Then you can get the metadata like so:
> >
> >
> > DataChannelMetaData metadata = localRuntime
> > .getInjector().getInstance(DataChannelMetaData.*class*);
> >
> > String comment = ObjectInfo.*getFromMetaData*(metadata, attribute,
> > ObjectInfo.*COMMENT*);
> >
> >
> > In an entity template for cgen that part is all you need. Coding these two
> > lines directly in a template is difficult and ugly, so this would be a good
> > place to use a custom velocity tool to simplify this API.
> >
> >
> > COMMENT is the only metadata type defined currently, but I would bet you
> > could add your own, although I don't know if Modeler would preserve them if
> > you use it for editing.
> >
> >
> >
> >
> >> On Tue, May 5, 2020 at 1:13 AM Faizel Dakri <listfez@dakri.com> wrote:
> >>
> >> No worries. I never did find a way to pass properties to the cgen goal in
> >> the plugin, so I ended up experimenting with the plugin source and modified
> >> it to allow specifying system properties from the pom.xml file (in the
> >> goal’s configuration section).
> >>
> >> Once the plugin was able to set system properties, it was relatively
> >> painless to get cgen to pick up my new tool using maven (I just had to
> >> specify it as a dependency in the cayenne plugin declaration in my
> >> application’s POM)—no need to muck with classpaths explicitly, thankfully.
> >>
> >> After all this, I still can’t find a way to access the metadata from
> >> within my own tool. I am starting to think that it can only be done by
> >> supplying the metadata (e.g. metaDataUtils) from the ClassGenerationAction
> >> class.
> >>
> >> Thanks again for the pointers.
> >>
> >> F
> >>
> >>
> >>>> On May 4, 2020, at 9:56 AM, John Huss <johnthuss@gmail.com> wrote:
> >>>
> >>> Unfortunately I'm not a maven user, so I can't really help here. But
> >>> hopefully someone else could chime in.
> >>>
> >>>> On Sun, May 3, 2020 at 11:39 AM Faizel Dakri <listfez@dakri.com>
wrote:
> >>>>
> >>>> Hi John,
> >>>>
> >>>> Thank you for the pointers. I didn’t see any way to easily get the
> >>>> metadata into my templates via a custom tool, however I thought it
> >> would be
> >>>> a good exercise to figure out how to do it anyway. I’ve tried to follow
> >>>> your advice (as well as looking at the cayenne source),   but I’m
having
> >>>> difficulty getting my properties file loaded via the
> >>>> org.apache.velocity.tools property.
> >>>>
> >>>> I’m running cgen via my maven build and I can confirm the cgen goal
is
> >>>> running (I can see that it is picking up my custom templates), however
> >> I’ve
> >>>> been unsuccessful in getting it to pick up my custom properties file
> >> where
> >>>> my tool is specified.  Is there a sanctioned way of telling the cgen
> >> goal
> >>>> about this property?  I’ve tried using both the maven properties plugin
> >> and
> >>>> passing on the command line, but I have yet to succeed in loading my
> >> file.
> >>>> At least it appears unsuccessful. When I debug my maven build, I see
> >> that
> >>>> there is an unresolved reference for my tool when velocity is
> >> processing my
> >>>> templates.
> >>>>
> >>>> Assuming I’m eventually successful in loading my properties, I have
one
> >>>> more question. You mention that any custom velocity tool (and properties
> >>>> files) must be on the class path. I’m assuming that this is the class
> >> path
> >>>> in effect while the cgen goal is running. How does one go about altering
> >>>> the class path for a maven plugin? Or does the plugin pickup the project
> >>>> dependencies? (Apologies if this is a basic question, I’m not yet
a
> >> Maven
> >>>> expert).
> >>>>
> >>>> Thanks again for your help,
> >>>>
> >>>> F
> >>>>
> >>>>
> >>>>>> On Apr 29, 2020, at 02:14 PM, John Huss <johnthuss@gmail.com>
wrote:
> >>>>>
> >>>>> I haven't used the metadata / comments yet, so I can't help with
that
> >>>>> specifically.
> >>>>>
> >>>>> For the using a custom tool with cgen you need to define a
> >>>>> "tools.properties" file in your class path (I would just put it
at the
> >>>>> root) with contents like this:
> >>>>>
> >>>>>
> >>>>> tools.toolbox = application
> >>>>>
> >>>>> tools.application.*myUtils* = com.something.tools.MyCgenUtils
> >>>>>
> >>>>>
> >>>>> The referenced class (and the properties file) needs to be on the
class
> >>>>> path when you invoke cgen. The class should contain public instance
> >> (not
> >>>>> static) methods in bean-style that work on parts of the DataMap,
like
> >> an
> >>>>> ObjEntity or a ObjAttribute (or their properties). For example:
> >>>>>
> >>>>>
> >>>>> *public* *boolean* hasReverse(ObjRelationship rel) {}
> >>>>>
> >>>>> Then when you invoke cgen you need to set a system property to point
to
> >>>> the
> >>>>> location of your tools.properties file, like this if it is in the
class
> >>>>> path root:
> >>>>>
> >>>>> -Dorg.apache.velocity.tools=/tools.properties
> >>>>>
> >>>>>
> >>>>> Your template can reference an instance of your util class using
the
> >>>> short
> >>>>> name defined for it in the tools.properties file:
> >>>>>
> >>>>>
> >>>>> ${*myUtils*.getGwtType($attr.Type)}
> >>>>>
> >>>>>
> >>>>> This process has multiple points of failure, so it can be hard to
> >>>>> setup correctly, but hopefully you can get it working.
> >>>>>
> >>>>>> On Wed, Apr 29, 2020 at 11:29 AM Faizel Dakri <listfez@dakri.com>
> >> wrote:
> >>>>>
> >>>>>> Hello all,
> >>>>>>
> >>>>>> Being fairly new to Cayenne, this may be an obvious question.
I would
> >>>> like
> >>>>>> to know how I can access the metadata stored on an
> >>>>>> attribute/relationship/entity in the datamap from within my
velocity
> >>>>>> templates (I think in CayenneModeler, this is how the comment
field is
> >>>>>> stored for a datamap item). I think this is the metadata stored
via
> >> the
> >>>>>> newish InfoExtension facility.
> >>>>>>
> >>>>>> I see that the DataChannelMetaData can be injected into a DataDomain
> >>>> (and
> >>>>>> I’m doing that at runtime in my server app), however I cannot
see how
> >> to
> >>>>>> get to this metadata from an attribute or relationship or entity
in
> >> the
> >>>>>> context of a velocity template. Is this possible? I would think
it is
> >>>> since
> >>>>>> Modeler is able to read/write those comments, but I am having
a hard
> >>>> time
> >>>>>> doing so in a template.
> >>>>>>
> >>>>>> I did see that there is a hook to provide my own tool into the
cgen
> >>>> tool.
> >>>>>> Would this be a potential path to look into if the metadata
is not
> >>>>>> accessible directly in the templates as is? If so, any pointers
on
> >>>> where to
> >>>>>> start?
> >>>>>>
> >>>>>> Thanks for any advice.
> >>>>>>
> >>>>>> F
> >>>>>>
> >>>>>> --
> >>>>>> Faizel Dakri
> >>>>>> listfez@dakri.com
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>
> >>>>
> >>
>


-- 
Best regards,
Nikita Timofeev

Mime
View raw message