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 <t...@triptera.com.au >> <mailto:t...@triptera.com.au>> 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 t...@triptera.com.au
OpenPGP_signature
Description: OpenPGP digital signature