Forwarding to list.
On 13/5/21 17:03, Andrus Adamchik wrote:
> Ah sorry, missed this piece. I have the services declared in the
> Bootique module via provider methods, and there's also a "shared
> context supplier" service, that is a wrapper against ObjectContext
> singleton (appropriate for read-only work of course; writable contexts
> should not be shared). See below.
>
> Andrus
> ------
> @Provides @Singleton SharedContextSupplier
> provideCayenneContextSupplier(ServerRuntime runtime) {
> return new DefaultSharedContextSupplier(runtime.newContext());
> }
> @Singleton @Provides private ObjectIdCoder provideIdCoder(IdCoder idCoder) {
> return new ObjectIdCoder(idCoder);
> }
>
> @Singleton @Provides private PersistentCoder providePersistentCoder(IdCoder
> idCoder, SharedContextSupplier contextSupplier) {
> return new PersistentCoder(idCoder, contextSupplier);
> }
>
> @Singleton @Provides private IdCoder provideIdCoder(ServerRuntime
> serverRuntime) {
> return new IdCoder(serverRuntime.getDataDomain().getEntityResolver());
> }
> public interface SharedContextSupplier extends Supplier<ObjectContext> {
> ObjectContext get();
> }
> public class DefaultSharedContextSupplier implements
> SharedContextSupplier {
>
> private ObjectContext sharedContext;
>
> public DefaultSharedContextSupplier(ObjectContext sharedContext) {
> this.sharedContext = sharedContext;
> }
>
> @Override public ObjectContext get() {
> return sharedContext;
> }
> }
>
>
>
>> On May 13, 2021, at 9:56 AM, D Tim Cummings <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> Thanks Andrus. I am trying to use encoders like you have done. I put
>> the method contributeValueEncoderSource in my AppModule.java.
>>
>> 1. Is Supplier from java.util.function.Supplier (re: your class
>> PersistentCoder)?
>>
>> 2. Do I need to add the following to bind in AppModule.java? (If not
>> I got 'No service implements the interface').
>>
>> public static void bind(ServiceBinder binder) {
>> // ...
>> binder.bind(PersistentCoder.class, PersistentCoder.class);
>> binder.bind(ObjectIdCoder.class, ObjectIdCoder.class);
>> binder.bind(IdCoder.class, IdCoder.class);
>> binder.bind(EntityResolver.class, EntityResolver.class);
>> }
>>
>> 3. I am now getting an error
>>
>> No service implements the interface java.util.function.Supplier
>>
>> Thanks
>> Tim
>>
>> On 12/5/21 21:57, Andrus Adamchik wrote:
>>>> On May 12, 2021, at 1:50 PM, D Tim Cummings wrote:
>>>>
>>>> Does anyone know of any good open-source Cayenne Tapestry apps that show
>>>> best practice and latest features for using these two frameworks
>>>> together? Most of the Tapestry examples use Hibernate.
>>>>
>>>> Tim
>>> Hi Tim,
>>>
>>> Not aware of any other than this ancient one [1] (I see your commits in
>>> there :)) . Also you probably know that Bootique supports Tapestry [2], and
>>> that's what we are on. As for the Tapestry part, we are using vanilla
>>> Tapestry functionality for the most part. Looking at my own (non-open
>>> source) Tapestry modules [3,4], the only Cayenne extension is encoders for
>>> Persistent and ObjectId [5], so that objects can be encoded/decoded to/from
>>> page URL parameters. So our entire integration can fit in an email message,
>>> and that's the beauty of it :)
>>>
>>> Andrus
>>>
>>> -----
>>>
>>> [1] https://github.com/andrus/wowodc13
>>> [2] https://github.com/bootique/bootique-tapestry
>>> [3] Bootique config:
>>>
>>> TapestryModule.extend(binder).addTapestryModule(TapestryModule.class)
>>> // this ensures that T5 JS/CSS only includes when the page or
>>> components explicitly import parts of
>>> // the stack
>>> .setSymbol(SymbolConstants.INCLUDE_CORE_STACK, "false")
>>> // turn off Tapestry Bootstrap .. we don't have much choice in the
>>> matter of the root selection
>>> // it has to be one of the standard T5 locations. "META-INF/asset" is
>>> the most neutral one..
>>> .setSymbol(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/META-INF/assets")
>>> .setSymbol(SymbolConstants.OMIT_GENERATOR_META, "true");
>>>
>>> [4] Tapestry module loaded via Bootique:
>>>
>>> public class TapestryModule {
>>>
>>> public void contributeValueEncoderSource(
>>> MappedConfiguration<Class, ValueEncoderFactory> configuration,
>>> PersistentCoder persistentCoder,
>>> ObjectIdCoder objectIdCoder) {
>>>
>>> configuration.add(Persistent.class, c -> persistentCoder);
>>> configuration.add(ObjectId.class, c -> objectIdCoder);
>>> }
>>> }
>>>
>>> [5] ID coders
>>>
>>> import org.apache.cayenne.ObjectId;
>>> import org.apache.cayenne.lifecycle.id.IdCoder;
>>> import org.apache.tapestry5.ValueEncoder;
>>>
>>> public class ObjectIdCoder implements ValueEncoder<ObjectId> {
>>>
>>> private IdCoder idCoder;
>>>
>>> public ObjectIdCoder(IdCoder idCoder) {
>>> this.idCoder = idCoder;
>>> }
>>>
>>> @Override
>>> public String toClient(ObjectId value) {
>>> return idCoder.getStringId(value);
>>> }
>>>
>>> @Override
>>> public ObjectId toValue(String clientValue) {
>>> return idCoder.getObjectId(clientValue);
>>> }
>>> }
>>>
>>> import org.apache.cayenne.Cayenne;
>>> import org.apache.cayenne.ObjectContext;
>>> import org.apache.cayenne.Persistent;
>>> import org.apache.cayenne.lifecycle.id.IdCoder;
>>> import org.apache.tapestry5.ValueEncoder;
>>>
>>> public class PersistentCoder implements ValueEncoder<Persistent> {
>>>
>>> private IdCoder idCoder;
>>> private Supplier<ObjectContext> contextSupplier;
>>>
>>> public PersistentCoder(IdCoder idCoder, Supplier<ObjectContext>
>>> contextSupplier) {
>>> this.idCoder = idCoder;
>>> this.contextSupplier = contextSupplier;
>>> }
>>>
>>> @Override
>>> public String toClient(Persistent value) {
>>> return idCoder.getStringId(value);
>>> }
>>>
>>> @Override
>>> public Persistent toValue(String clientValue) {
>>>
>>> // TODO: should we be using ObjectIdQuery with caching?
>>>
>>> return (Persistent) Cayenne.objectForPK(
>>> contextSupplier.get(),
>>> idCoder.getObjectId(clientValue));
>>> }
>>> }
>>>
>>>
>>>
>>>
>>
>
--
Triptera Pty Ltd
D Tim Cummings
0418778422
[email protected]
OpenPGP_signature
Description: OpenPGP digital signature
