/[papo]/gnue/common/src/GParser.py
ViewVC logotype

Diff of /gnue/common/src/GParser.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.6 by charlie, Tue Aug 27 18:15:51 2002 UTC revision 1.7 by styxman, Fri Nov 15 15:32:54 2002 UTC
# Line 27  Line 27 
27  # NOTES:  # NOTES:
28  #  #
29    
30  import sys  import sys, copy, types
31    from gnue.common.GObjects import GObj
32    from gnue.common.GTrigger import GTrigger
33    from gnue.common.FileUtils import openResource
34    
35  try:  try:
36    from xml.sax import saxutils    from xml.sax import saxutils
# Line 80  class MarkupError(StandardError): Line 83  class MarkupError(StandardError):
83    
84  def loadXMLObject(stream, handler, rootType, xmlFileType,  def loadXMLObject(stream, handler, rootType, xmlFileType,
85    initialize=1, attributes={}, initParameters={}):    initialize=1, attributes={}, initParameters={}):
86    
87    
88    # Create a parser    # Create a parser
89    parser = xml.sax.make_parser()    parser = xml.sax.make_parser()
90    
91    # Set up some namespace-related stuff for the parsers    # Set up some namespace-related stuff for the parsers
92    parser.setFeature(xml.sax.handler.feature_namespaces, 1)    parser.setFeature(xml.sax.handler.feature_namespaces, 1)
93      
94      # Allow for parameter external entities
95      ## Does not work with expat!!! ##
96      ##parser.setFeature(xml.sax.handler.feature_external_pes, 1)
97    
98    # Create a stack for the parsing routine    # Create a stack for the parsing routine
99    object = None    object = None
100    
101    # Create the handler    # Create the handler
102    dh = handler()    dh = handler()
103      dh.initValidation()
104    
105    # Tell the parser to use our handler    # Tell the parser to use our handler
106    parser.setContentHandler(dh)    parser.setContentHandler(dh)
# Line 104  def loadXMLObject(stream, handler, rootT Line 114  def loadXMLObject(stream, handler, rootT
114      raise MarkupError, _("Error loading %s: not a valid %s definition (expected: %s, got: %s)") % (xmlFileType,      raise MarkupError, _("Error loading %s: not a valid %s definition (expected: %s, got: %s)") % (xmlFileType,
115           xmlFileType, rootType, object._type)           xmlFileType, rootType, object._type)
116    
117      dh.finalValidation()
118    
119    # Set the object's attributes    # Set the object's attributes
120    object.__dict__.update(attributes)    object.__dict__.update(attributes)
121    
122      
123    if initialize:    if initialize:
124      GDebug.printMesg(10,"Initializing the object tree starting at %s" %(object))      GDebug.printMesg(10,"Initializing the object tree starting at %s" %(object))
125      object.phaseInit(dh._phaseInitCount)      object.phaseInit(dh._phaseInitCount)
126    
   return object  
   
127    
128    
129  #######################################################    return object
 #  
 # char  
 #  
 # This is for typecasting strings  
 #  
 # NOTE: This is a redefinition of GTypecast.text.  
 #   This redefinition will be removed as soon as all  
 #   references to it are changes.  You should be using  
 #   GTypecast from now on.  
 #  
 #######################################################  
 char  = GTypecast.text  
   
   
 #######################################################  
 #  
 # bool  
 #  
 # This is for typecasting booleans  
 #  
 # NOTE: This is a redefinition of GTypecast.boolean.  
 #   This redefinition will be removed as soon as all  
 #   references to it are changes.  You should be using  
 #   GTypecast from now on.  
 #  
 #######################################################  
 bool = GTypecast.boolean  
130    
131    
132  #######################################################  #######################################################
# Line 183  class xmlHandler(xml.sax.ContentHandler) Line 167  class xmlHandler(xml.sax.ContentHandler)
167      self.uniqueIDs = {}      self.uniqueIDs = {}
168      self.root = None      self.root = None
169      self._phaseInitCount = 0      self._phaseInitCount = 0
170        
171        self._requiredTags = []
172        self._singleInstanceTags = []
173        self._tagCounts = {}
174    
175        
176    #    #
177    # Called by client code to get the "root" node    # Called by client code to get the "root" node
178    #    #
# Line 191  class xmlHandler(xml.sax.ContentHandler) Line 180  class xmlHandler(xml.sax.ContentHandler)
180      return self.root      return self.root
181    
182    #    #
183      # Builds structures need to verify requirements in the file
184      #
185      def initValidation(self):
186        #
187        # Build list of tags along with a list of
188        # require tags
189        #
190        for element in self.xmlElements.keys():
191          self._tagCounts[element] = 0
192          try:
193            if self.xmlElements[element]['Required'] == 1:
194              self._requiredTags.append(element)
195          except KeyError:
196            pass
197    
198          try:
199            if self.xmlElements[element]['SingleInstance'] == 1:
200              self._singleInstanceTags.append(element)
201          except KeyError:
202            pass
203          
204      def finalValidation(self):
205        for element in self._singleInstanceTags:
206          if self._tagCounts[element] > 1:
207            raise MarkupError, _("File has multiple instances of <%s> when only one allowed") % (element)
208          
209        for element in self._requiredTags:
210          if self._tagCounts[element] < 1:
211            raise MarkupError, _("File is missing required tag <%s>") % (element)
212      
213    
214      #
215    # Called by the internal SAX parser whenever    # Called by the internal SAX parser whenever
216    # a starting XML element/tag is encountered.    # a starting XML element/tag is encountered.
217    #    #
# Line 203  class xmlHandler(xml.sax.ContentHandler) Line 224  class xmlHandler(xml.sax.ContentHandler)
224        #        #
225        # No namespace qualifier        # No namespace qualifier
226        #        #
227          self._tagCounts[name] += 1
228        GDebug.printMesg(50, "<%s>" % name)        GDebug.printMesg(50, "<%s>" % name)
229    
230        try:        try:
231          baseAttrs = self.xmlElements[name].get('Attributes',{}) # default(self.xmlElements[name],'Attributes',{})          baseAttrs = self.xmlElements[name].get('Attributes',{})
232        except KeyError:        except KeyError:
233          raise MarkupError, _('Error processing <%s> tag [I do not know what a <%s> tag does]') % (name, name)          raise MarkupError, _('Error processing <%s> tag [I do not know what a <%s> tag does]') % (name, name)
234    
235    
236        for qattr in saxattrs.keys():        for qattr in saxattrs.keys():
237          attrns, attr = qattr          attrns, attr = qattr
238            encoding= sys.getdefaultencoding()
239            if encoding == 'ascii':
240              encoding = 'iso8859-1'  # TODO: fix this when we have [common] section
241            try:                    #       in gnue.conf
242              encoding = gConfig('formFontEncoding')
243            except:
244              pass
245    
246          # Typecasting, anyone?  If attribute should be int, make it an int          # Typecasting, anyone?  If attribute should be int, make it an int
247          try:          try:
248            attrs[attr] = baseAttrs[attr].get('Typecast',char)(saxattrs[qattr]) # default(baseAttrs[attr],'Typecast',char)(saxattrs[qattr])            attrs[attr] = baseAttrs[attr].get('Typecast',GTypecast.text)(saxattrs[qattr].encode(encoding)) # default(baseAttrs[attr],'Typecast',GTypecast.text)(saxattrs[qattr])
249            loadedxmlattrs[attr] = attrs[attr]            loadedxmlattrs[attr] = attrs[attr]
250          except KeyError:          except KeyError:
251            raise MarkupError, _('Error processing <%s> tag [I do not recognize the "%s" attribute') % (name, attr)            raise MarkupError, _('Error processing <%s> tag [I do not recognize the "%s" attribute') % (name, attr)
# Line 234  class xmlHandler(xml.sax.ContentHandler) Line 262  class xmlHandler(xml.sax.ContentHandler)
262    
263            # Pull default values for missing attributes            # Pull default values for missing attributes
264            if baseAttrs[attr].has_key ('Default'):            if baseAttrs[attr].has_key ('Default'):
265              attrs[attr] = baseAttrs[attr].get('Typecast', char) (baseAttrs[attr]['Default'])# default(baseAttrs[attr],'Typecast', char) (baseAttrs[attr]['Default'])              attrs[attr] = baseAttrs[attr].get('Typecast', GTypecast.text) (baseAttrs[attr]['Default'])# default(baseAttrs[attr],'Typecast', GTypecast.text) (baseAttrs[attr]['Default'])
266    
267            # Check for missing required attributes            # Check for missing required attributes
268            elif baseAttrs[attr].get('Required', 0): #default(baseAttrs[attr], 'Required', 0):            elif baseAttrs[attr].get('Required', 0): #default(baseAttrs[attr], 'Required', 0):
# Line 329  class xmlHandler(xml.sax.ContentHandler) Line 357  class xmlHandler(xml.sax.ContentHandler)
357      GDebug.printMesg(50, "</%s>" % name)      GDebug.printMesg(50, "</%s>" % name)
358    
359    
360    class GImportItem(GObj):
361      def __init__(self, parent=None, type="GCImport-Item"):
362        GObj.__init__(self, parent, type=type)
363        self._loadedxmlattrs = {} # Set by parser
364        self._inits = [self.primaryInit]
365        self._xmlParser = self.findParentOfType(None)._xmlParser
366    
367      def _buildObject(self):
368        if hasattr(self,'_xmltag'):
369          self._type = 'GC%s' % self._xmltag
370        if not hasattr(self,'_importclass'):
371          self._importclass = self._xmlParser\
372             .getXMLelements()[string.lower(self._type[9:])]['BaseClass']
373        return GObj._buildObject(self)
374    
375      def primaryInit(self):
376         #
377         # Open the library and convert it into objects
378         #
379         handle = openResource(self.library)
380         form = self._xmlParser.loadFile(handle, self.findParentOfType(None)._app, initialize=0)
381         handle.close()
382         id = 'id'
383         if hasattr(self,'name'):
384             id = 'name'
385         #
386         # Configure the imported object, assign as a child of self
387         #
388         rv = self.__findImportItem(self, form, id)
389         if rv != None:
390           rv._parent = self
391           rv._IMPORTED = 1
392           self._children.append(rv)
393           #
394           # transfer attributes reassigned during the import
395           #
396           for key in self._loadedxmlattrs.keys():
397             if key[0] != '_':
398               rv.__dict__[key] = self._loadedxmlattrs[key]
399               GDebug.printMesg (5, ">>> Moving %s" % key)
400           rv._buildObject()
401    
402      #
403      # __findImportItem
404      #
405      # finds the item in the object tree with the
406      # same name and instance type
407      #
408      def __findImportItem(self, find, object, id):
409         if isinstance(object, find._importclass) and \
410            hasattr(object, id) and \
411            object.__dict__[id] == find.__dict__[id]:
412           return object
413         elif hasattr(object,'_children'):
414           rv = None
415           for child in object._children:
416             rv = self.__findImportItem(find, child, id)
417             if rv:
418               break
419           return rv
420         else:
421           return None
422                                                      
423    
424    class GImport(GObj):
425      def __init__(self, parent=None):
426        GObj.__init__(self, parent, type="GCImport")
427        self.library = ""
428        self._form = None
429        self._inits = [self.primaryInit]
430        self._xmlParser = self.findParentOfType(None)._xmlParser
431                      
432      def primaryInit(self):
433        handle = openResource(self.library)
434        form = self._xmlParser.loadFile(handle, self.findParentOfType(None)._app, initialize=0)
435        handle.close()
436    
437        for attribute in self._loadedxmlattrs.keys():
438          if attribute != 'library':
439            importAll =  self._loadedxmlattrs[attribute] == "*"
440            importNames = string.split(string.replace(self._loadedxmlattrs[attribute],' ',''),',')
441    
442            instanceType = self._xmlParser.getXMLelements()[string.lower(attribute)]['BaseClass']
443                  
444            if importAll or len(importNames):
445              for child in form._children:
446                if isinstance(child,instanceType) and \
447                   (importAll or child.name in importNames):
448                  child._parent = self
449                  child._IMPORTED = 1
450                  self._children.append(child)
451                  child._buildObject()
452    
453    def buildImportableTags(rootTag, elements):
454        #
455        # Scans xml elements and looks for Importable = 1
456        # Items with this set can be imported
457        # If an object needs to be importable,
458        # simply add its tag name to the tuple below
459        # and make sure it has a "name" attribute
460        # (otherwise we don't know how to reference
461        # it in the imported file).
462        #
463        importElement = {'BaseClass': GImport,
464                         'Attributes': {'library': {
465                                          'Required': 1,
466                                          'Typecast': GTypecast.name },
467                                       },
468                         'ParentTags': rootTag,
469                         }
470        
471        for key in elements.keys():
472         if elements[key].has_key('Importable') and elements[key]['Importable']:
473           name = "import-%s" % key
474           copy._deepcopy_dispatch[types.FunctionType] = copy._deepcopy_atomic
475           copy._deepcopy_dispatch[types.ClassType] = copy._deepcopy_atomic
476           copy._deepcopy_dispatch[type(int)] = copy._deepcopy_atomic
477    
478           p = copy.deepcopy(elements[key])
479           p['BaseClass'] = GImportItem
480          
481           if not p.has_key('Attributes'):
482             p['Attributes'] = {}
483    
484           p['Attributes']['library'] = {
485              'Required': 1,
486              'Typecast': GTypecast.name }
487           p['MixedContent'] = 0
488           p['Required'] = 0
489           elements[name] = p
490    
491           importElement['Attributes'][key] =  {
492             'Typecast': GTypecast.name,
493             'Default': ""  }
494    
495        if len(importElement['Attributes'].keys()):
496          elements['import'] = importElement
497        return elements

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26