[Work-around] (was Re: [Zope] Will the inheritance relationship will be preserved after export/import?)

iap_y2fun.com iap@y2fun.com
Wed, 16 May 2001 02:39:03 +0800


This is a multi-part message in MIME format.

------=_NextPart_000_0009_01C0DDB1.5EFD91C0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

RE: [Zope] Will the inheritance relationship will be preserved after
export/import?By stealing some codes from AlexR's helpful how-to
"Changing Base Classes for a ZClass".
I wrote an external method to be a quick-and-dirty
work around. (see the attachment)

This external method helps a zclass to change
the old reference of its base class (an instance of ZClass)
to the new one  in "new" ZODB.
Just install this external method(with t,t,t as parameters)
and request it by a browser.
It will response a form for you to fill in your product/class
name pair.

"Source Product/Class" is for the base class.
"Destination Product/Class" is for the class which lost its
reference to the base class.
The value of class accepts nested class which means
ClassA/ClassB/ClassC.... is valid for this field. In my own
case, I have a nested class up to 5 level.

The "replace" field is for inputing the index of the old reference
of base class which is going to be replaced. (starts from 0)
Since the base classes is an array which is a mixup of serveral
products.

The "copy" checkbox is for doing a full-replacement of base classes
from source zclass to destination zclass exactly as what AlexR's script
does.

The "Test Run" button won't do the real task. It just gives the information
of what is going to happen. Use this to dump out
the array of base classes of your source zclass and destination zclass.

The "Real Run" button will do the real task to replace or to copy.
Hope that you won't be regret after hit this button.
Hitting "Test Run" is strongly recommended before hitting "Real Run".

If the path of source zclass or destination zclass is wrong
which means there is no such zclass existed,
this external method will response "None" for your attention.
Make sure the zclasses you want to operate to
are really existed in your ZODB.

Most important of all: use it in your own risk.
Remember to export your product for backing up
before any actions.
It works for me not necessary work for you.
But I do hope it helps.

kosh@aesaeion.com is right. This problem won't be happened in
a product which is implemented in pure python scripts.
That is quite trivial after dumping
the base classes of a ZClasses-based product.
Zope is great! Well, I agree with what kosh said
"Zclasses are not robust solutions they mostly seem designed for trivial
solutions by largely non programmers."

Regards,
Iap, Singuan

------=_NextPart_000_0009_01C0DDB1.5EFD91C0
Content-Type: text/plain;
	name="t.py"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="t.py"

import string=0A=
from DocumentTemplate.DT_Util import html_quote=0A=
def t(self):=0A=
   #return form(self)=0A=
   #app=3Dself.REQUEST.PARENTS[-1]=0A=
   =
#m=3Dgetattr(app.Control_Panel.Products.y2Learn.y2Learn_AnnounceFolder.pr=
opertysheets,'methods')=0A=
   #return [m['y2Learn_Announce']];#hasProperty('y2Learn_Announce')=0A=
   #.y2Learn_AnnounceFolder=0A=
=0A=
   go=3Dself.REQUEST.get('go') #set go=3D1 to really do the task=0A=
 =0A=
   response=3D[]=0A=
=0A=
   srcClass=3DNone=0A=
   spn=3Dself.REQUEST.get('spn') #source product name=0A=
   spc=3Dself.REQUEST.get('spc') #source class name=0A=
   spcs=3D[]=0A=
   if not spn: spn=3D'y2FUN'=0A=
   if not spc: spc=3D'y2FUNBaseClass'=0A=
   if spc : spcs=3Dstring.split(spc,'/')=0A=
   if spn and len(spcs) : srcClass=3DgetZClass(self,spn,spcs)=0A=
   response.append('Source Class:'+str(spn)+'/'+str(spc)+'<br> =
'+html_quote(str(srcClass)))=0A=
   if srcClass: response.append('<blockquote>Bases of =
'+spn+'/'+spc+'<br> '+html_quote(str(srcClass._zbases))+'</blockquote>')=0A=
=0A=
   destClass=3DNone=0A=
   dpcs=3D[]=0A=
   dpn=3Dself.REQUEST.get('dpn') #product name=0A=
   dpc=3Dself.REQUEST.get('dpc') #class name=0A=
   if dpc : dpcs=3Dstring.split(dpc,'/')=0A=
   #return dpcs=0A=
   if dpn and len(dpcs) : destClass=3DgetZClass(self,dpn,dpcs)=0A=
   #return dpcs;=0A=
   response.append('Destination Class:'+str(dpn)+'/'+str(dpc)+'<br> =
'+html_quote(str(destClass)))=0A=
   if destClass :response.append('<blockquote>Bases of =
'+dpn+'/'+dpc+'<br> '+html_quote(str(destClass._zbases))+'</blockquote>')=0A=
=0A=
   replace=3Dint(self.REQUEST.get('replace'))=0A=
   if srcClass and destClass and replace:=0A=
      response.append('<font color=3Dred>You just issued a replace =
operation</font><br>')=0A=
      newbases=3DdestClass._zbases[:]=0A=
      response.append('To be replaced object is =
'+html_quote(str(newbases[replace])))=0A=
      if newbases[replace] is srcClass:=0A=
         response.append('They are the same object, you probably don\'t =
need to do this')=0A=
      newbases[replace]=3DsrcClass=0A=
      if go:=0A=
         destClass._setBasesHoldOnToYourButts(newbases[1:])=0A=
         response.append('After Replace at idx=3D'+str(replace)+', Bases =
of Dest. Class:<br>'+html_quote(str(destClass._zbases)))=0A=
    =0A=
   elif destClass and srcClass and self.REQUEST.has_key('copy') :=0A=
      response.append('<font color=3Dred>You just issued a copy =
operation</font><br>')=0A=
      newbases=3DsrcClass._zbases[:]=0A=
      if go: =0A=
         destClass._setBasesHoldOnToYourButts(srcClass._zbases[1:])=0A=
         response.append('After Copy,\nBases of Dest. =
Class:<br>'+html_quote(str(destClass._zbases)))=0A=
   response_html=3Dstring.join(response,"<p>")=0A=
=0A=
   return '<html><body =
style=3D"font-size:small">'+response_html+''+form(self)+'</html>'=0A=
   =0A=
def getZClass(self,pn,pcs):   =0A=
   P=3DNone=0A=
   app=3Dself.REQUEST.PARENTS[-1]=0A=
   if hasattr(app.Control_Panel.Products,pn):=0A=
      P=3Dgetattr(app.Control_Panel.Products[pn],pn)=0A=
      if hasattr(P,pcs[0]):=0A=
         P=3Dgetattr(P,pcs[0])=0A=
         #return P=0A=
      else:=0A=
         return None=0A=
      try:=0A=
         for pc in pcs[1:]:=0A=
            P=3DP.propertysheets.methods[pc]=0A=
            if not P : return None=0A=
      except KeyError:=0A=
         return None=0A=
   return P=0A=
    =0A=
def getParam(self,keys):=0A=
   v=3D[]=0A=
   for k in keys:=0A=
     try:=0A=
       v.append(self.REQUEST[k])=0A=
     except KeyError:=0A=
       v.append('')=0A=
   return tuple(v)=0A=
=0A=
def form(self):=0A=
   html=3D"""=0A=
<form method=3Dpost action=3D"">=0A=
<b>Source</b><br>=0A=
Product: <input name=3Dspn value=3D"%s" size=3D40><br>=0A=
ZClass:  <input name=3Dspc value=3D"%s" size=3D40> ClassA/ClassB is =
acceptable<br>=0A=
<b>Destination</b><br>=0A=
Product: <input name=3Ddpn value=3D"%s" size=3D40><br>=0A=
ZClass:  <input name=3Ddpc value=3D"%s" size=3D40><br>=0A=
Replace At <input name=3D"replace" value=3D"%s" size=3D5><br>=0A=
Do Copy <input type=3Dcheckbox %s name=3D"copy"><br>=0A=
<input type=3Dsubmit value=3D"Test Run">=0A=
<input type=3Dsubmit name=3D"go" value=3D"Real Run">=0A=
</form>=0A=
   """  % =
(getParam(self,['spn','spc','dpn','dpc','replace'])+((getParam(self,['cop=
y'])[0] and 'checked') or ' ',))=0A=
   return html=0A=
#
------=_NextPart_000_0009_01C0DDB1.5EFD91C0--