Re: [Zope-dev] Success! Was: Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists? Specialists?

2000-10-05 Thread Phillip J. Eby

At 09:15 PM 10/4/00 -0500, Steve Spicklemire wrote:

This was also nice since in my Specialist I could do things
like:

dtml-call "RESPONSE.redirect(this().theRealThing.absolute_url())"

After the user is finished working in my 'app area' they could
get redirected back to the actual object that my Specialist
was 'posing' for...

I don't really recommend the above, unless it's being done by SkinScript.
Otherwise, you're unnecessarily exposing an implementation attribute
(theRealThing).  Instead, require that your object implement a redirect()
method, and define it in the class as "class_default_for_redirect".  Then
you can override the method in SkinScript or with a class extender (a new
0.4.3 feature).  Doing it this way means your framework code will not
incorporate an assumption that your whitebox specialist is always going to
be wrapping someone else's objects.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] Success! Was: Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists? Specialists?

2000-10-05 Thread Steve Spicklemire


Yes.. I see what you mean... this is a 'whitebox customization' 
that I used as part of the integration of my framework into
the 'online catalog' system. This is not 'blackbox' code that
is integral to my system 

In fact, I mis-spoke earlier, it's not in my specialist at all... it
only appears in a method of a ZClass that I use as the 'storage class'
for objects controlled by one of my specialists this is clearly
whitebox territory, since this wrapper is chosen by the
integrator... The first thing my docs (will) say to do.. is go through all
my specialists and choose 'storage' classes for each specialist.

This brings up another point If I choose 'DataSkin' as a storage
class, then my code hits the security system every time a refer
to any data (simple types) stored directly in the DataSkin. I can either
set __allow_access_to_unprotected_subobjects=1 on each instance,
or I can write accessor methods for each attribute, (yuk!, but
maybe good in some ways...) or I can ask the integrator to create
'dummy' ZClass(es) even for those racks that they don't want/need
to customize (which seems to 'get around' the security system.)
I'm curious to know what you folks do here.. do you write accessor
methods for every type stored in your DataSkins?

Anyway.. thanks for the great tools! I'm having fun now. ;-)

-steve

 "Phillip" == Phillip J Eby [EMAIL PROTECTED] writes:

Phillip At 09:15 PM 10/4/00 -0500, Steve Spicklemire wrote:
  This was also nice since in my Specialist I could do things
 like:
 
 dtml-call
 "RESPONSE.redirect(this().theRealThing.absolute_url())"
 
 After the user is finished working in my 'app area' they could
 get redirected back to the actual object that my Specialist was
 'posing' for...

Phillip I don't really recommend the above, unless it's being
Phillip done by SkinScript.  Otherwise, you're unnecessarily
Phillip exposing an implementation attribute (theRealThing).
Phillip Instead, require that your object implement a redirect()
Phillip method, and define it in the class as
Phillip "class_default_for_redirect".  Then you can override the
Phillip method in SkinScript or with a class extender (a new
Phillip 0.4.3 feature).  Doing it this way means your framework
Phillip code will not incorporate an assumption that your
Phillip whitebox specialist is always going to be wrapping
Phillip someone else's objects.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




[Zope-dev] Accessors for DataSkin attributes (was Re: [Zope-dev] Success!Was: Re: [Zope-dev] How is 'retrieveItem intended to work with TTWSpecialists? Was: Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?

2000-10-05 Thread Phillip J. Eby

At 06:57 AM 10/5/00 -0500, Steve Spicklemire wrote:

This brings up another point If I choose 'DataSkin' as a storage
class, then my code hits the security system every time a refer
to any data (simple types) stored directly in the DataSkin. I can either
set __allow_access_to_unprotected_subobjects=1 on each instance,
or I can write accessor methods for each attribute, (yuk!, but
maybe good in some ways...) or I can ask the integrator to create
'dummy' ZClass(es) even for those racks that they don't want/need
to customize (which seems to 'get around' the security system.)
I'm curious to know what you folks do here.. do you write accessor
methods for every type stored in your DataSkins?

We never use raw DataSkins, first off.  We always create a domain-specific
ZClass subclassed from DataSkin.  In your case, I would suggest simply
including such ZClasses with your product to provide the default
implementation of your domain and presentation logic.

As for set/get methods, we usually just define DataSkin property sheets in
the ZClass, and use permission mappings to define the read/write
permissions for each sheet.  We group properties in sheets according to the
domain model permissions for access.  Then the domain logic methods in the
ZClass call propertysheets.sheetname.manage_changeProperties() with keyword
parameters to set things.  Usually, we have domain specific methods that
alter the values of multiple attributes at the same time, using the
property sheets.  We rarely have code outside of the ZClass directly
manipulate attributes.  In instances where we've needed to set attributes
which are of types not supported by Zope propertysheets, we've had to use
ExternalMethods or something similar.  In the long run we expect to be able
to use PropertyHandlers to do this without dropping down to Python.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?

2000-09-30 Thread Steve Spicklemire


Thanks again... it's great that you're willing to entertain
my apparantly twisted use of ZPatterns. ;-)

 "PJE" == Phillip J Eby [EMAIL PROTECTED] writes:

PJE To put it another way: design your whitebox specialist how
PJE you want it.  Make it complete, but of course some parts will
PJE have to be changed if someone wants to use other than your
PJE default implementation.  If they want its data to come from
PJE somewhere else, they can plug in the SkinScript or do
PJE whatever else it takes.

PJE So, to sum up...  Stop worrying about delegated retrieval!
PJE :) You're stepping into app integrator territory here.
PJE ZPatterns was designed to make it easy to make reusable
PJE frameworks without hardly trying.  And it was *especially*
PJE designed for retrofitting object frameworks over legacy
PJE applications and databases.

Hmm... OK I see what you mean. I guess I somehow got the idea that ZPatterns 
worked best when you had two ZPatterns based frameworks that you wanted
to work together *after* they had both been designed. I was looking for a
way to 'hook up' two 'finished' applications. I was trying to avoid creating
a framework that couldn't be easily integrated, by attemting a 'fake' integration
myself. How can I be sure I've got all the TTW stuff organized in a way that
an integrator can change unless I actually set it up and test it that way?
I'd hate to find out later that someone needs to go in and edit my Python
code to make my framework useable But.. I think what I'm hearing is that
working out the integration at the Rack level is much better than trying
to delgate retrieval at the Specialist level. I'm not sure where I got the
idea that delegating retrieval at the Specialist level was the 'right' way,
maybe in the Drop Zone example? Anyway... thanks again for your reply. I'll
march happily along now and see what I run into next! ;-) (I'm especially
grateful for your explaination of using a virtual object (non-persistent)
in a Rack. I've not seen that explained so clearly anywhere else.. and I'm
going to use it!

thanks!
-steve



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?

2000-09-29 Thread Steve Spicklemire


Thanks so much for the response... 

It turns out, I tried the Python Method and it had the 
same basic problem as the DTML Method... however I've now
moved on, using deletageRetrieve to a new thorny issue. ;-)

When I get an object from of another specialist it appears
that it doies not inherit from my specialist, but from 
*its* specialist. (e.g., my framework specialist has methods
that I want the dataskins to acquire). I've currently got it
wrapped like so:

def retrieveItem(self, key):
""" get an item"""
return self.delegateRetrieve(self, None, key=key).__of__(self)

I've tried several different combinations of __of__ etc, but
none of them seems to allow the dataskin to acquire, for example,
standard_html_header from my specialist. Is there any way to 
enforce acquisition at this level?

thanks!
-steve


 "pje" == Phillip J Eby [EMAIL PROTECTED] writes:

pje At 08:00 AM 9/25/00 -0500, Steve Spicklemire wrote:
  So my retrieve item gets called. *unfortunately* it gets
 called without any namespace parameter... so my retrieveItem
 DTML method has no way to acquire a namespace so that it can
 delagate to something else!
 
 So... here is what I did... I defined a method in my Python
 subclass of Specialist..
 
 class MarketItemManager(ZPatterns.Specialists.Specialist): """A
 Market Item Manager"""
 
 # Specify a name for the item type:
 meta_type='MarketItemManager'
 
 def retrieveItem(self, key): """ get an item"""  return
 self.__of__(self).delegateRetrieve(self, None, key=key)
 
 Then I made a DTML method called 'delegateRetrieve' like so:
 
 dtml-return "myGreatSite.ThingManager.getItem(key)"
 
 this way, my integrator can edit 'delegateRetrieve' to point to
 whatever Specialist he wants to... and I have a Python
 implementation of retrieveItem.
 
 Does this sound OK? Am I working way too hard here?  (I feel
 like I am! ;- )
 

pje Remember in the code where I have "# XXX DTML check?"  That's
pje because I was anticipating your problem, but since I didn't
pje personally need to do what you're doing yet, I didn't
pje implement it.  For one thing, I was waiting to see if Zope
pje core method binding would get fixed.  Unfortunately, I'm not
pje sure that Zope method binding is going to be available for
pje anything but PythonMethods in 2.3.  As of right now, however,
pje you should be able to use a PythonMethod for retrieveItem,
pje rather than a DTML Method, and it should work.

pje In short, even now, delegateRetrieve should not be necessary.
pje You should be able to implement retrieveItem using a
pje PythonMethod or a DTML Document rather than a DTML Method.
pje (I say *should* because I have not tried it personally.)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?

2000-09-29 Thread Phillip J. Eby

At 03:14 PM 9/29/00 -0500, Steve Spicklemire wrote:

Thanks so much for the response... 

It turns out, I tried the Python Method and it had the 
same basic problem as the DTML Method... however I've now
moved on, using deletageRetrieve to a new thorny issue. ;-)

When I get an object from of another specialist it appears
that it doies not inherit from my specialist, but from 
*its* specialist. (e.g., my framework specialist has methods
that I want the dataskins to acquire). I've currently got it
wrapped like so:

def retrieveItem(self, key):
""" get an item"""
return self.delegateRetrieve(self, None, key=key).__of__(self)

I've tried several different combinations of __of__ etc, but
none of them seems to allow the dataskin to acquire, for example,
standard_html_header from my specialist. Is there any way to 
enforce acquisition at this level?

You can use aq_base before the __of__, but I wouldn't recommend it, because
you'll be forcibly ripping off security-related data.  Probably aq_explicit
would work better, since it would prevent default acquisition but leave
security acquisitions relatively intact.

I still suspect, though, that your design is not optimal.  If you actually
need a "bridge" specialist that lets you change the behaviors of the thing
you're accessing, then you should really just build a bridge specialist and
not simply do directly delegated retrieval.  What you want is to set up a
rack in the specialist that creates a virtual object which gets all its
attributes (the ones you care about, anyway) from an object retrieved from
the other specialist.  SkinScript example:

WITH otherSpecialist.getItem(self.id)
COMPUTE theRealThing = (RESULT is None) and NOT_FOUND or RESULT

WITH self.theRealThing COMPUTE
myAttr1 = RESULT.theirAttr1, 
myAttr2 = theirAttr2, # equivalent to myAttr2 = RESULT.theirAttr2
SomeAttr, # equivalent to SomeAttr = RESULT.SomeAttr
myAttr5 = theirAttr1 * theirAttr6

# Shorthand way of copying attributes with the same names
WITH self.theRealThing COMPUTE foo,bar,baz

You would put this in a script inside a rack in your "bridge" specialist.
You would set up the rack to be "non-persistent" and use "theRealThing" as
the existence attribute.  Now, when you access the rack, it will create a
dummy object and try to look at its "theRealThing" attribute.  This will
cause the SkinScript to call the other Specialist and attempt retrieval.
If it succeeds, theRealThing will equal the object and the Rack will
consider the object to exist in the bridge specialist.  If it fails,
theRealThing will be a non-existent attribute and the Rack's getItem will
return None.

Let's say it has succeeded.  You now have an object with no attributes
loaded other than 'id' and 'theRealThing'.  You attempt to access attribute
SomeAttr.  The second SkinScript declaration fires, and computes the values
of myAttr1, myAttr2, SomeAttr, and myAttr5, caching them in the DataSkin.
Voila.  You now have a completely transformed object, in the context of
*your* specialist, with *your* attribute names.  It has no leftover
acquisition context, but of course you had to have permission to access all
those attributes on the object and to the specialist you retrieved it from.
 But here's the real kicker...  You determine in *your* rack the precise
ZClass it will be implemented as.  In effect, you have rewrapped an
object's data into another class.

Okay, so that works for reads.  What about writes?  That's a little more
complex, as you'll need to write something like:

STORE foo,bar
USING self.theRealThing.manage_changeProperties(foo=self.foo,bar=self.bar)

For whatever combinations of properties are applicable.  If the properties
are on a sheet, the USING expression gets more complicated.  Note, too,
that we could have done transformations on the 'id' to look something up,
and that we could also have multiple racks, each doing transformations from
different Specialists.

Now, you may be asking yourself, "This all looks incredibly flexible, but
is it efficient?"  Hell no, of course not.  You are much better off, if you
have the option, of specifying to your framework's user the requirements
you have for objects in that part of your system.  Then, when they are
designing their system, they can get the names and features right, and you
call *their* specialist for what you need.  If they didn't do it the easy
way, then it's again *their* responsibility to re-cast your whitebox as a
bridge.

(Note, by the way, that if the end-user's raw data is coming from something
like an SQL database in the first place, then all they have to do is map
from SkinScript to SQL, and this is *much* more efficient than mapping
Specialist-Rack-Specialist-Rack-SQL, which involves many more layers of
object creation, method calls, and security checks.)

To put it another way: design your whitebox specialist how you want it.
Make it complete, but of course some parts will have to be changed if
someone wants to 

[Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?

2000-09-25 Thread Steve Spicklemire


Hello ZPatterns Folk.

I'm trying to implement 'delagation' with a custom Specialist. The idea,
(I think this is one of the goals of ZPatterns... to allow delegation
of responsibility after the Framework is built...) 

I have:

a) MarketItemManager (Python subclass of Specialist) Some of methods, both DTML 
Methods,
   and plain old Python Methods, are *meant* to be acquire by the objects (DataSkins)
   he manages.


b) ThingManager (ZClass subclass of Specialist). This is really just a test
   class that is supposed to represent some later developer integrating
   my ZPattern based EMarket into their application, (e.g., inventory or
   whatever...)

in MarketItemManager I've defined a 'retrieveItem' (this would really be
done by the integrator...) that does something like this:

dtml-return "myGreatSite.ThingSpecialist.getItem(key)"

with the hope that when the Specialist class gets traversed 
it will execute:

def __bobo_traverse__(self, REQUEST, name):
ob = getattr(self, name, _marker)
if ob is _marker:
ob = self.getItem(name)  --- traversal invokes getItem
if ob is not None:
return ob
raise 'NotFound'
return ob

def getItem(self, key):
"""Get an item"""
if hasattr(self.aq_base,'retrieveItem'):   --- getItem invokes 
retrieveItem
return self.retrieveItem(key=key) # XXX need DTML check?

for rack in self.rackList:
item = rack.__of__(self).getItem(key)
if item is not None: return item


So my retrieve item gets called. *unfortunately* it gets
called without any namespace parameter... so my retrieveItem
DTML method has no way to acquire a namespace so that it can
delagate to something else! 

So... here is what I did... I defined a method in my Python
subclass of Specialist..

class MarketItemManager(ZPatterns.Specialists.Specialist):
"""A Market Item Manager"""

# Specify a name for the item type:
meta_type='MarketItemManager'

def retrieveItem(self, key):
""" get an item"""
return self.__of__(self).delegateRetrieve(self, None, key=key)

Then I made a DTML method called 'delegateRetrieve' like so:

dtml-return "myGreatSite.ThingManager.getItem(key)"

this way, my integrator can edit 'delegateRetrieve' to point
to whatever Specialist he wants to... and I have a Python
implementation of retrieveItem.

Does this sound OK? Am I working way too hard here? 
(I feel like I am! ;- )

thanks,
-steve


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?

2000-09-25 Thread Phillip J. Eby

At 08:00 AM 9/25/00 -0500, Steve Spicklemire wrote:

So my retrieve item gets called. *unfortunately* it gets
called without any namespace parameter... so my retrieveItem
DTML method has no way to acquire a namespace so that it can
delagate to something else! 

So... here is what I did... I defined a method in my Python
subclass of Specialist..

class MarketItemManager(ZPatterns.Specialists.Specialist):
"""A Market Item Manager"""

# Specify a name for the item type:
meta_type='MarketItemManager'

def retrieveItem(self, key):
""" get an item"""
return self.__of__(self).delegateRetrieve(self, None, key=key)

Then I made a DTML method called 'delegateRetrieve' like so:

dtml-return "myGreatSite.ThingManager.getItem(key)"

this way, my integrator can edit 'delegateRetrieve' to point
to whatever Specialist he wants to... and I have a Python
implementation of retrieveItem.

Does this sound OK? Am I working way too hard here? 
(I feel like I am! ;- )


Remember in the code where I have "# XXX DTML check?"  That's because I was
anticipating your problem, but since I didn't personally need to do what
you're doing yet, I didn't implement it.  For one thing, I was waiting to
see if Zope core method binding would get fixed.  Unfortunately, I'm not
sure that Zope method binding is going to be available for anything but
PythonMethods in 2.3.  As of right now, however, you should be able to use
a PythonMethod for retrieveItem, rather than a DTML Method, and it should
work.  

In short, even now, delegateRetrieve should not be necessary.  You should
be able to implement retrieveItem using a PythonMethod or a DTML Document
rather than a DTML Method.  (I say *should* because I have not tried it
personally.)


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )