Hi Nikita,

That looks great and pretty much exactly what I was hoping for. Thanks!

F

> 
> On May 6, 2020, at 2:46 AM, Nikita Timofeev <ntimof...@objectstyle.com> wrote:
> 
> 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 <list...@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 <johnth...@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 <list...@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 <johnth...@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 <list...@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 <johnth...@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 <list...@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
>>>>>>>> list...@dakri.com
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>> 
>>>>>> 
>>>> 
>> 
> 
> 
> -- 
> Best regards,
> Nikita Timofeev

Reply via email to