Sure, I will put it up tonight ;-) Bryan: I never thought of the bookmark thing, definitely something worth mentioning. Can I post your comments along with my step-by-step explanation (with your name ofcourse) or do you want to post it yourself?
Filip On 7/12/05, Jamie Orchard-Hays <[EMAIL PROTECTED]> wrote: > If you haven't, would you mind putting this up on the WIKI? > > Jamie > > > On Jul 12, 2005, at 1:13 PM, Filip Balas wrote: > > > It seems to me that no where on the internet is this whole > > process explained in enough detail to make it easy to > > understand in under 15min. So here is my best attempt. > > > > I assume: > > a) You know what a Squeezer is and how to use it. > > If you do not, visit: > > http://wiki.apache.org/jakarta-tapestry/DataSqueezer > > b) You are familiar enough with Cayenne to understand > > that each user/session must have it's own, unique > > DataContext (whether you share the 'DataRowStore' > > or not) > > > > Now typically we store the Datacontext in the Visit class. > > That way each session has one unique data context for > > all pages. Peace of cake right? Wrong... > > > > When using direct links, the cleanest way to serialize and > > de-serialize objects is using your own SqueezerAdaptor. > > This is where the problem begins, the ISqueezeAdaptor > > interface does not provide a mechanism for accessing the > > Visit class, hence no access to your Datacontext which > > results in having no way to de-serialize your objects. > > > > This is where the Threadlocal solution mentioned above by > > my savvy colleagues comes in. This solution essentially > > makes the current visit class globaly available through access > > to the current running thread. I am not sure how the specifics > > work <someone can jump in with links to the deatails here> > > but this essentially gives us what we need to make this > > machine purrrrrr. > > > > Okay, code is worth a thousand words so I'm going to paste > > some code and explain as I go. > > > > First we create the class that gives us access to the current > > thread and will henceforth be used to provide global access > > to whatever the current visit class is: > > > > public class UserContext { > > > > static ThreadLocal _visitLocal = new ThreadLocal(); > > > > public static Object getVisit() { > > return (Visit) _visitLocal.get(); > > } > > > > public static void setVisit(Object visit) { > > _visitLocal.set(visit); > > } > > } > > > > You should take note that everything here is static and > > so can be accessed from anywhere. > > > > Next we need to Create a Custom Engine to initialize > > the UserContext with the Visit and to register our custom > > Squeeze adapter. > > > > NOTE: > > To register a custom engine, go to your foo.application > > file and change the engine in the line: > > <application name="foo" engine-class="com.acme.superApp.CustomEngine"> > > > > If you already knew how to do this, this may seem like a > > silly step to mention but I couldn't find a single place in the > > TIA book where it tells you this, nor could I find it on the net. > > > > public class CustomEngine extends BaseEngine { > > > > protected void setupForRequest(RequestContext context) > > { > > if (getVisit() != null) > > UserContext.setVisit(getVisit()); > > > > super.setupForRequest(context); > > } > > > > public DataSqueezer createDataSqueezer() > > { > > DataSqueezer defaultDataSqueezer = super.createDataSqueezer(); > > DataSqueezeAdaptor customAdaptor = new DataSqueezeAdaptor(); > > customAdaptor.register(defaultDataSqueezer); > > return defaultDataSqueezer; > > } > > } > > > > The main magic in the above is initializing the UserContext > > with the visit class currently registered with the Engine. > > > > Now because of this magic, we can access the Visit class in our > > adaptor > > unsqueeze method: > > > > public class DataSqueezeAdaptor implements ISqueezeAdaptor { > > > > private static final String prefix = "D"; > > > > public DataSqueezeAdaptor() > > { > > super(); > > } > > > > public String squeeze(DataSqueezer squeezer, Object data) throws > > IOException > > { > > if (data instanceof IDataObject) > > return prefix + getDataStore().put((IDataObject) data); > > > > return null; > > > > } > > > > public Object unsqueeze(DataSqueezer squeezer, String string) > > throws IOException > > { > > String id = string.substring(prefix.length()); > > > > try > > { > > return getDataStore().get(id, getDataContext()); > > } catch (Exception e) > > { > > return null; > > } > > } > > > > private Visit getVisit() > > { > > return (Visit) UserContext.getVisit(); > > } > > > > public void register(DataSqueezer squeezer) > > { > > squeezer.register(prefix, IDataObject.class, this); > > } > > > > private DataContext getDataContext() > > { > > return getVisit().getDataContext(); > > } > > > > private IDataStore getDataStore() > > { > > return getVisit().getDataStore(); > > } > > } > > > > And there you have it folks! If you're wondering > > what the IDataStore is, it's simply a Map that > > serves 2 purposes. First it generates unique > > IDs for each object and second is stores the objects > > while they are off on their trip to the client. Why > > don't I just use the DataContext for this you ask? > > Because I have chosen to make all of my objects > > follow a state pattern, so internally they can be either > > connected (Registered with the DataContext) or > > Disconnected (Just Pojo's masquerading as DataObjects). > > This allows my app to always work with objects as whole > > entities, whithout worrying about how to create and remove > > them from cayenne (each state does that). > > > > Thanks to everyone who helped me figure this one out. > > > > Filip > > > > > > On 7/11/05, Robert Zeigler <[EMAIL PROTECTED]> wrote: > > > >> Incidentally, I made the data squeezer implementation I sent to Todd > >> available awhile ago on Tassel. > >> > >> Robert > >> > >> Todd O'Bryan wrote: > >> > >>> Robert Ziegler sent me a CayenneDataObjectSqueezeAdaptor.jar awhile > >>> ago. Check the list to see if he sent it through the list. > >>> Otherwise, > >>> I'd be happy to send it along if I get his permission. > >>> > >>> Todd > >>> > >>> On Jul 7, 2005, at 9:49 PM, Filip Balas wrote: > >>> > >>> > >>>> Has anybody been able to get the squeezer interface > >>>> to work with Cayenne? > >>>> > >>>> It seems like it is impossible to make the Datacontext > >>>> available to the datasqueezer. I can't get the visit class > >>>> from the squeezer and that is where the context resides?!?!? > >>>> > >>>> I tried to use the global map to solve this problem except > >>>> the map is not initialized until AFTER the squeezer is > >>>> created. I am at my wits end. > >>>> > >>>> HELP! > >>>> Filip > >>>> > >>>> ------------------------------------------------------------------- > >>>> -- > >>>> To unsubscribe, e-mail: tapestry-user- > >>>> [EMAIL PROTECTED] > >>>> For additional commands, e-mail: tapestry-user- > >>>> [EMAIL PROTECTED] > >>>> > >>>> > >>>> > >>> > >>> > >>> -------------------------------------------------------------------- > >>> - > >>> To unsubscribe, e-mail: [EMAIL PROTECTED] > >>> For additional commands, e-mail: tapestry-user- > >>> [EMAIL PROTECTED] > >>> > >> > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: [EMAIL PROTECTED] > >> For additional commands, e-mail: tapestry-user- > >> [EMAIL PROTECTED] > >> > >> > >> > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [EMAIL PROTECTED] > > For additional commands, e-mail: [EMAIL PROTECTED] > > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
