from PyXML import * from graph import Graph from Tkinter import Tk class schema: def __init__(self): self.archetypeTable={} self.archetypes=[] self.roots=[] self.forwardRefs=[] self.leaves=[] def fromFile(self): tk=Tk() filename=tk.tk.call('tk_getOpenFile','-defaultextension','.xsd', '-filetypes',(('Schema Files',('*.xsd',)), ('All files',('*.*','*')))) tk.destroy() if not filename: return if filename[1]==':': filename='file:///'+filename file=Open(filename,NSL_read) root=ItemParse(file,GetNextBit(file).item) self.processRoot(root) for elt in root.data: self.processDecl(elt) Close(file) maxh=0 map(archetype.addDescendants,self.archetypes) for a in self.archetypes: maxh=max(maxh,a.height()) if not a.descendantNames: self.leaves.append(a) self.maxHeight=maxh map(archetype.rootNames,self.leaves) for (name,arn) in self.forwardRefs: self.archetypeTable[arn].elements.append(name) self.leaves.sort(archetype.rootCompare) print map(lambda a:a.name,self.leaves) return self.showGraph() def processRoot(self,root): pass def processDecl(self,elt): if type(elt)==ItemType: eval("%s(self,elt)"%elt.label) def showGraph(self): column=0 g=Graph(self,font='-adobe-helvetica-medium-r-normal-*-14-*-*-*-*-*-*-*') nextColumn=self.leaves while nextColumn: g.showColumn(column,nextColumn) column=column+1 nextColumn=filter(lambda a,c=column:a.hgt==c,self.archetypes) return g def clear(self): # cut all circularities self.archetypes=self.leaves=self.roots=None self.archetypeTable=None def mapArchetypes(self,fn,keys,*args): if keys: if args: allArgs=[0] allArgs[1:1]=list(args) for key in keys: allArgs[0]=self.archetypeTable[key] apply(fn,tuple(allArgs)) else: for key in keys: fn(self.archetypeTable[key]) class archetype: def __init__(self,schema,elt,isElt=0): name=GetAttrVal(elt,"name") self.name=name self.schema=schema schema.archetypeTable[name]=self schema.archetypes.append(self) self.ancestorNames=None self.descendantNames=[] self.vertex=None self.hgt=None self.rtNames=None if isElt: self.namesAsElement=[name] else: self.namesAsElement=[] for d in elt.data: if d.label=='refines': self.ancestorNames=[] for ar in d.data: # should check for schemaName aname=GetAttrVal(ar,"name") if aname in self.ancestorNames: print "%s refines %s twice\n"%(name,aname ) else: self.ancestorNames.append(aname) if not self.ancestorNames: schema.roots.append(self) def addDescendants(self): self.schema.mapArchetypes(archetype.newDescendant, self.ancestorNames,self.name) def newDescendant(self,dName): self.descendantNames.append(dName) def rootNames(self): if not self.rtNames: rts=[] if self.ancestorNames: for an in self.ancestorNames: arns=self.schema.archetypeTable[an].rootNames() if arns: for rt in arns: if not rt in rts: rts[0:0]=[rt] rts.sort() else: # it's a REAL root, so it's my only root rts=[an] self.rtNames=rts return self.rtNames def height(self): if self.hgt==None: if self.descendantNames: mh=0 for dn in self.descendantNames: d=self.schema.archetypeTable[dn] mh=max(mh,d.height()) self.hgt=mh+1 else: self.hgt=0 return self.hgt def rootCompare(self,other): l1=len(self.rtNames) l2=len(other.rtNames) if l1l2: return 1 elif self.rtNamesother.rtNames: return 1 elif self.nameother.highestHeight: return 1 else: return 0 class elementType: def __init__(self,schema,elt): name=GetAttrVal(elt,"name") if elt.data and elt.data[0].label=='archetypeRef': # should check for schemaName arn=GetAttrVal(elt.data[0],"name") if schema.archetypeTable.has_key(arn): schema.archetypeTable[arn].namesAsElement.append(name) else: schema.forwardRefs.append((name,arn)) else: archetype(schema,elt,1) class datatype: def __init__(self,schema,elt): pass class include: def __init__(self,schema,elt): pass class attrGroup: def __init__(self,schema,elt): pass class modelGroup: def __init__(self,schema,elt): pass class notation: def __init__(self,schema,elt): pass # simple types # give textonly complex types a coreType to carry their datatype part # # Revision 1.52 1999/11/25 13:13:46 ht # merge in branch which switched to separate classes for ab initio types # # Revision 1.48.1.2 1999/11/25 10:21:24 aqw # convert to classes for primitive types, use them as effectiveType for # all simpleTypes # # Revision 1.48.1.1 1999/11/22 16:03:10 aqw # classes for ab initio types #