> 
> On May 12, 2021, at 1:50 PM, D Tim Cummings <t...@triptera.com.au.INVALID> 
> 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));
    }
}




Reply via email to