Re: [Zope-dev] Accessors for DataSkin attributes (was Re: [Zope-dev] Success!

2000-10-08 Thread Phillip J. Eby

At 09:14 PM 10/6/00 -0500, Steve Spicklemire wrote:
>
>OK.. allow me to summarize my very latest thought. Subclassing
>is OK withing my own framework.

Yep.

>It's OK to require users of my
>framework to create ZClasses that subclass from my core logic
>Python classes, and from DataSkin.

Sort of.  To be more precise, as a framework provider you may require that
participating objects provide a particular interface.  The framework user
may 1) create a subclass of one of your classes, 2) add an implementation
of your interface to an existing class of theirs, or 3) use your class as
is, using SkinScript or other means to form an "adapter" between your
desired interface and their existing 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] Accessors for DataSkin attributes (was Re: [Zope-dev] Success!

2000-10-06 Thread Steve Spicklemire


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

pje> It is *not* undesirable to have ZClasses be subclasses of
pje> your core logic base class.  Just make sure they *also*
pje> subclass DataSkin, or that you use the metaclass definition
pje> stuff above.  You've actually got a pretty decent approach
pje> going there.

Hmmm.. again, maybe I'm reading too much into the DropZone example,
but I seem to recall there that subclassing was pretty much
explicitly discouraged.  Did I misinterpret that?

'''
 Notice that we do not subclass SkyDiver from a Customer class and a
 ResourceUser class. What we are doing is saying is that Customer is a
 role that a Party (person or organization) plays in an accounting
 system, and ResourceUser is a role that a Party plays in a resource
 scheduling system. SkyDiver, then should implement a Party interface,
 allowing it to be used as a Customer or ResourceUser. Thus, SkyDiver
 can be used by any framework that needs to collaborate with a Party
 object, although it may have a new role in which the party will be
 used. For example, if I later add a curriculum management system to
 cover my skydiver training courses, I will want SkyDiver to fill the
 Student role.
'''

OK.. allow me to summarize my very latest thought. Subclassing
is OK withing my own framework. It's OK to require users of my
framework to create ZClasses that subclass from my core logic
Python classes, and from DataSkin. If we need integration between
frameworks, we can handle that in SkinScript to share attributes 
between Specialist, or anthing else that might be helpful in 
providing the needed information.

Does that sound right?

pje> One question, though.  Why the derivation from Folder?

Oh... this was a case where my object, in addition to 'simple'
properties also needed to 'contain' other stuff (files, images and the
like...) making it a subclass of folder just got me that ability for
'free'. I could also have used ObjectManager, but making it folder
just reduces the amount of 'UI' effort needed for the management
interface of the contained stuff. I could have just created a 
plain folder with the same 'id' as my DataSkin, and 'associated' they
two, but it made some sort of sense to keep them all together.

-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] Accessors for DataSkin attributes (was Re: [Zope-dev] Success!

2000-10-06 Thread Phillip J. Eby

At 02:24 PM 10/5/00 -0500, Steve Spicklemire wrote:
>
>You're not using propertysheet providers, but DataSkin propertysheets
>'installed' in a ZClass that directly inherits from DataSkin. Your use
>of the "Data Skin Attribute Property Sheets" is primarily to associate
>permissions with groupings of attributes, and to simplify
>establishment and management of those properties through the ZClass
>administrative interface. As a bonus, you get 'free' methods needed to
>adjust these attributes from DTML (i.e., manage_changeProperties) without
>requiring custom PropertyHandlers.

Yes.


>I did notice that when I create a ZClass (in a completely different
>project) that inherits from a Python Product (registered with
>registerBaseClass) that inherits from DataSkin, I don't get the option
>of a DataSkin propertysheet, in the 'common' container of the ZClass,
>so there's probably some manual fiddling I need to do when I register
>my ZClass base class that I'm not doing...

A simple way to avoid this is to simply create the ZClass subclassed from
DataSkin *and* your Python class.


>I'm guessing that the code that defines the SkinZISS, SZHolder, and
>_ZClass_for_DataSkin culminating in registerZClass perform the
>necessary magic to make that happen

Yes.  If you want to make this work on a Python class, you need to do
something like:

class _ZClass_for_MyClass(_ZClass_for_DataSkin):
_zclass_ = MyClass

And then in your registration, call:

context.registerZClass(_ZClass_for_MyClass)

That should be it.


>This is deep magic!

Aye.  Here there be dragons.  :)  Wait'll you see the magic I had to do in
0.4.3 to get ZClass PlugIns and PlugInContainers to work...



>Sooo... if I want my DataSkin subclass to have the same ability
>I'll need to do something similar? (just replace _zclass_ = DataSkin
>with _zclass_ = MyDataSkinSubclass?) 

See above for the shortest way to do this.


>Well.. my *new* strategy (I'm using this on EMarket) is to put all the
>core logic in a Specialist subclass... and let my DataSkins be
>ZClasses that are directly subclassed from __ZClass_for_DataSkin. This
>has its own problems (I still have a hard time working in a
>'specialist' on a method that is supposed to be acquired by a
>DataSkin, and keeping track of who 'self' is and what properties I can
>really get to etc...). 

Personally, I don't recommend this approach, even if you end up with a
ZClass that doesn't do much besides have a propertysheet or two.


>Why did I do all that? I am used to a development routine where I work
>a while... in emacs.. then hit ctrl-c ctrl-c which 'runs' the current
>module. With this setup, everything in Thing.py can work without
>Zope. All my core logic can be tested and I can verify that it works
>correctly *before* I layer all the ZClass stuff on top. (I know..  now
>I guess I need to learn to use ZPublisher/Client.py ;->) Of course
>this requires that my ZClasses are subclasses of my core logic base
>class.. and I now understand why that is generally undesirable. (It
>makes integrating frameworks later more difficult ) But there is a
>clear advantage... I think that with the flexibility of Racks and
>SkinScript you could probably even have the best of all possible
>worlds...

It is *not* undesirable to have ZClasses be subclasses of your core logic
base class.  Just make sure they *also* subclass DataSkin, or that you use
the metaclass definition stuff above.  You've actually got a pretty decent
approach going there.

One question, though.  Why the derivation from Folder?


___
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] Accessors for DataSkin attributes (was Re: [Zope-dev] Success!

2000-10-05 Thread Steve Spicklemire


Hi Phillip

First of all... please forgive the long message. When I started
it was going to be a quick note... now it's turned into a bit
of a novel... but you don't have to read it all. ;-> I'm spewing all
this out in part to illustrate some of the things I've done 'wrong'
so that others might not go down that road... and also... your
reaction (if any) to some of the random thoughts popping up here
and there would be most welcome... anyway.. here goes

OK.. I think this makes sense.. (hmm.. how's *that* for a statement of
supreme confidence!)

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

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

OK.. let me just make sure I'm understanding you correctly. 

You're not using propertysheet providers, but DataSkin propertysheets
'installed' in a ZClass that directly inherits from DataSkin. Your use
of the "Data Skin Attribute Property Sheets" is primarily to associate
permissions with groupings of attributes, and to simplify
establishment and management of those properties through the ZClass
administrative interface. As a bonus, you get 'free' methods needed to
adjust these attributes from DTML (i.e., manage_changeProperties) without
requiring custom PropertyHandlers.

I did notice that when I create a ZClass (in a completely different
project) that inherits from a Python Product (registered with
registerBaseClass) that inherits from DataSkin, I don't get the option
of a DataSkin propertysheet, in the 'common' container of the ZClass,
so there's probably some manual fiddling I need to do when I register
my ZClass base class that I'm not doing...

I'm guessing that the code that defines the SkinZISS, SZHolder, and
_ZClass_for_DataSkin culminating in registerZClass perform the
necessary magic to make that happen

Aha!  I just found part of the magic in "ProductContext.py"

lib/python/App/ProductContext.py

This is deep magic! But I think I see that you are up to:

>From DataSkins.py:

class SZHolder:
""" """
def __init__(self):
ZClassSheets.__init__.im_func(self)
self.common=SkinZISS('common')

class _ZClass_for_DataSkin:
propertysheets = SZHolder()
_zclass_   = DataSkin
manage_options = ()

def initialize(context):
context.registerZClass(_ZClass_for_DataSkin)

So you set up SZHolder to pose as a 'propertysheets' attribute of the
ZClass (I'm guessing that im_func(self) is to get around the 'unbound
method' ExtensionClass problem.).  Then your 'hand creating' the
_ZClass_for_DataSkin rather than using 'registerBaseClass' You're also
overriding the ZClass 'common' collection of propertysheets with one
that will allow both 'regular' ZClass propertysheets, and also
Dataskin propertysheets.

Sooo... if I want my DataSkin subclass to have the same ability
I'll need to do something similar? (just replace _zclass_ = DataSkin
with _zclass_ = MyDataSkinSubclass?) 

This of course begs the question... why do I want to subclass
from anything other than DataSkin in the first place?

Well.. my *new* strategy (I'm using this on EMarket) is to put all the
core logic in a Specialist subclass... and let my DataSkins be
ZClasses that are directly subclassed from __ZClass_for_DataSkin. This
has its own problems (I still have a hard time working in a
'specialist' on a method that is supposed to be acquired by a
DataSkin, and keeping track of who 'self' is and what properties I can
really get to etc...). But in my last project I hadn't figured all that out, 
so I originally made a layered system something like this:

Thing.py 
--

try:
#
# if we're running in Zope.. this will work and we can inherit
# from OFS.Folder
#

from OFS.Folder import Folder
from Products.ZPatterns.DataSkins import DataSkin

class FlexBase( DataSkin, Folder ):
pass

except: 

#
# if we're testing stand-alone... we can just subclass from an empty class
#

class FlexBase:

def

[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 )