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