Module XMLAutomata
[hide private]
[frames] | no frames]

Source Code for Module XMLAutomata

  1  #XMLAutomata.py 
  2  #A SAX based XML parser/logger implementation to write Supremica Automata files 
  3  #Author: Matteo Cantarelli 
  4  #E-mail: matteo.cantarelli@lurpa.ens-cachan.fr 
  5  #Release: 0.1.23 
  6   
  7  import Automata 
  8  import sys 
  9  from xml.sax.saxutils import XMLGenerator 
 10  from xml.sax.xmlreader import AttributesNSImpl 
 11  from xml.sax import saxutils 
 12  from xml.sax import make_parser 
 13  from xml.sax.handler import feature_namespaces 
 14   
 15   
 16  TAB='\t'    #The indentetion in the Supremica XML format 
 17   
18 -class CXMLAutomata:
19 "This Class manages the reading and the writing of XML automata files in Supremica format."
21 "This Class has methods to write to an XML file the providen automata in the Supremica format."
22 - def __init__(self, output, encoding,name,major,minor):
23 """ 24 This constructor writes the header of the XML automata file. 25 26 Set up a logger object, which takes SAX events and outputs an XML log file. 27 28 @type output: string 29 @param output: the filename where to perform all the writing operations 30 @type encoding: string 31 @param encoding: the used encoding format 32 @type name: string 33 @param name: the name of the automata 34 @type major: string 35 @param major: used in the XML Supremica format 36 @type minor: string 37 @param minor: used in the XML Supremica format 38 @return: void 39 """ 40 41 logger = XMLGenerator(output, encoding) 42 logger.startDocument() 43 attr_vals = { 44 (None, u'name'): name, 45 (None, u'major'): major, 46 (None, u'minor'): minor, 47 } 48 attr_qnames = { 49 (None, u'name'): u'name', 50 (None, u'major'): u'major', 51 (None, u'minor'): u'minor', 52 } 53 attrs = AttributesNSImpl(attr_vals, attr_qnames) 54 logger.startElementNS((None, u'Automata'), u'Automata', attrs) 55 self._logger = logger 56 self._output = output 57 self._encoding = encoding 58 return
59
60 - def startAutomaton(self,name,type):
61 """ 62 This method writes the header of an automaton in the current file. 63 64 @type name: string 65 @param name: the name of the automaton 66 @type type: string 67 @param type: the type of the automaton. Plant, Specification and Supervisor are supported by Supremica. 68 @return: void 69 """ 70 attr_vals = { 71 (None, u'name'): name, 72 (None, u'type'): type, 73 } 74 attr_qnames = { 75 (None, u'name'): u'name', 76 (None, u'name'): u'type', 77 } 78 attrs = AttributesNSImpl(attr_vals, attr_qnames) 79 self._logger.ignorableWhitespace('\n') 80 self._logger.ignorableWhitespace('\n') 81 self._logger.startElementNS((None, u'Automaton'), u'Automaton', attrs)
82
83 - def startGroup(self,type):
84 """ 85 This method writes the beginning of a generic group in the current file. 86 87 @type type: string 88 @param type: the type of the group. Events, States and Transitions are supported by Supremica. 89 @return: void 90 """ 91 attrs=AttributesNSImpl({}, {}) 92 self._logger.ignorableWhitespace('\n') 93 self._logger.ignorableWhitespace(TAB) 94 self._logger.startElementNS((None, type), type, attrs)
95
96 - def addItem(self,type,attributes):
97 """ 98 This method writes a generic XML item in the current file. 99 100 @type type: string 101 @param type: the type of the item. Events, States and Transitions are supported by Supremica. 102 @type attributes: dictionary of attributes 103 @param attributes: this dictionary specifies the attributes of the item 104 105 >>> #Example: 106 >>> ['controllable']:'false' 107 108 @return: void 109 """ 110 attr_vals={} 111 attr_qnames={} 112 for f,v in attributes.iteritems(): 113 attr_vals[(None,f)]=v 114 attr_qnames[(None,f)]=f 115 116 attrs = AttributesNSImpl(attr_vals, attr_qnames) 117 self._logger.ignorableWhitespace('\n') 118 self._logger.ignorableWhitespace(TAB+TAB) 119 self._logger.startElementNS((None, type), type, attrs) 120 self._logger.endElementNS((None, type), type)
121
122 - def endGroup(self,type):
123 """ 124 This method writes the end of a generic group in the current file. 125 126 @type type: string 127 @param type: the type of the group. Events, States and Transitions are supported by Supremica. 128 @return: void 129 """ 130 self._logger.ignorableWhitespace('\n') 131 self._logger.ignorableWhitespace(TAB) 132 self._logger.endElementNS((None, type), type)
133
134 - def endAutomaton(self):
135 """ 136 This method writes the end of an automaton in the current file. 137 138 @type name: string 139 @param name: the name of the automaton 140 @type type: string 141 @param type: the type of the automaton. Plant, Specification and Supervisor are supported by Supremica. 142 @return: void 143 """ 144 self._logger.ignorableWhitespace('\n') 145 self._logger.endElementNS((None, u'Automaton'), u'Automaton')
146
147 - def endAutomata(self):
148 """ 149 This method writes the end tag of the current automata. 150 It closes moreover the logger document. 151 152 @return: void 153 """ 154 self._logger.ignorableWhitespace('\n') 155 self._logger.ignorableWhitespace('\n') 156 self._logger.endElementNS((None, u'Automata'), u'Automata') 157 self._logger.endDocument() 158 return
159 160 161
162 - class __CXMLAutomataParser(saxutils.DefaultHandler):
163 "This Class has methods to parse an XML file writing its content in the providen automata struct."
164 - def __init__(self, automata):
165 """ 166 The constructor set the automata struct where to write the parsed information. 167 168 @type automata: a L{__CXMLAutomataStruct} instance 169 @param automata: the automata where to write the parsed information 170 @return: void 171 """ 172 self.__automata=automata
173
174 - def startElement(self, name, attrs):
175 """ 176 This method parse a single XML element and write it in the automata class. 177 178 @type name: string 179 @param name: the type's name of the element to parse 180 @return: void 181 """ 182 if len(self.__automata.automatons)>0: 183 la=self.__automata.automatons[len(self.__automata.automatons)-1] #the last automaton inserted, it's a sequencial reading process, will belongs to him the incoming datas 184 if name == 'Automata': 185 self.__automata.name=attrs.get('name',None) 186 self.__automata.minor=attrs.get('minor',None) 187 self.__automata.major=attrs.get('major',None) 188 elif name == 'Automaton' : 189 a=self.__automata.CXMLAutomatonStruct(attrs.get('name',None),attrs.get('type',None)) 190 self.__automata.automatons.append(a) 191 elif name == 'Event': 192 e=la.CXMLEventStruct(attrs.get('id',None),attrs.get('label',None),attrs.get('controllable',None)) 193 la.events.append(e) 194 elif name == 'State': 195 s=la.CXMLStateStruct(attrs.get('id',None),attrs.get('name',None),attrs.get('initial',None),attrs.get('accepting',None)) 196 la.states.append(s) 197 elif name == 'Transition': 198 t=la.CXMLTransitionStruct(attrs.get('source',None),attrs.get('dest',None),attrs.get('event',None)) 199 la.transitions.append(t)
200 201
202 - class __CXMLAutomataStruct(object):
203 """ 204 A structure to store the information present in a XML Supremica Automata file. 205 """
206 - class CXMLAutomatonStruct(object):
207
208 - def __init__(self,name,Type):
209 self.name=name 210 self.type=Type 211 self.events=[] 212 self.states=[] 213 self.transitions=[]
214
215 - class CXMLEventStruct(object):
216
217 - def __init__(self,ID,label,controllable):
218 self.id=ID 219 self.label=label 220 self.controllable=controllable
221
222 - class CXMLStateStruct(object):
223
224 - def __init__(self,ID,name,initial,accepting):
225 self.id=ID 226 self.name=name 227 self.initial=initial 228 self.accepting=accepting
229
230 - class CXMLTransitionStruct(object):
231
232 - def __init__(self,source,dest,event):
233 self.source=source 234 self.dest=dest 235 self.event=event
236
237 - def __init__(self,name, minor, major):
238 self.name=name 239 self.minor=minor 240 self.major=major 241 self.automatons=[]
242
243 - def __file2Struct(self,file):
244 """ 245 This method permits to read a given XML file and to write it in the form of a L{CXMLAutomata.__CXMLAutomataStruct} class. 246 247 @type file: string 248 @param file: the XML file to read 249 @return: a L{CXMLAutomata.__CXMLAutomataStruct} instance 250 """ 251 parser = make_parser() 252 parser.setFeature(feature_namespaces, 0) 253 a=self.__CXMLAutomataStruct("",0,0) #create a CXMLAutomataStruct to store the file 254 dh=self.__CXMLAutomataParser(a) #the parser will fill the created structure 255 parser.setContentHandler(dh) #states the parser will use our overloaded function to handle the file 256 parser.parse(file) #parse it! 257 return a
258
259 - def __struct2File(self,xmlstruct,filename):
260 """ 261 This method permits to read a given automata struct and to write it on a given XML file. 262 263 @type xmlstruct: a L{CXMLAutomata.__CXMLAutomataStruct} instance 264 @param xmlstruct: the automata struct to read 265 @type filename: string 266 @param filename: the XML file where to write the automata struct 267 @return: void 268 """ 269 270 f=open(filename,'w') 271 log=self.__CXMLAutomataLogger(f, 'ISO-8859-1',xmlstruct.name,xmlstruct.major,xmlstruct.minor) 272 for a in xmlstruct.automatons: 273 log.startAutomaton(a.name, a.type) 274 log.startGroup('Events') 275 for e in a.events: 276 log.addItem('Event',{'id':e.id,'label':e.label,'controllable':e.controllable}) 277 log.endGroup('Events') 278 log.startGroup('States') 279 for s in a.states: 280 log.addItem('State',{'id':s.id,'name':s.name,'initial':s.initial,'accepting':s.accepting}) 281 log.endGroup('States') 282 log.startGroup('Transitions') 283 for t in a.transitions: 284 log.addItem('Transition',{'source':t.source,'dest':t.dest,'event':t.event}) 285 log.endGroup('Transitions') 286 log.endAutomaton() 287 log.endAutomata()
288
289 - def __struct2Automata(self,xmlstruct):
290 """ 291 This method permits to read a given automata struct and to write it on a automata class. 292 293 @type xmlstruct: a L{CXMLAutomata.__CXMLAutomataStruct} instance 294 @param xmlstruct: the automata struct to read 295 @return: a L{Automata.CAutomata} instance 296 """ 297 automata=Automata.CAutomata(xmlstruct.name,xmlstruct.minor,xmlstruct.major) 298 299 for a in xmlstruct.automatons: 300 automaton=Automata.CAutomaton(a.name,'',a.type) 301 for s in a.states: 302 automaton.addState(s.id,s.name,'',s.initial=="true",s.accepting=="true") 303 for e in a.events: 304 automaton.addEvent(e.id,e.label,'',e.controllable!="false") 305 for t in a.transitions: 306 automaton.getStateFromId(t.source).addTransition(automaton.getEventFromId(t.event),automaton.getStateFromId(t.dest)) 307 automata.addAutomaton(automaton) 308 309 return automata
310
311 - def __automata2Struct(self,automata):
312 """ 313 This method permits to read a given automata class and to write it on a automata struct. 314 315 @type xmlstruct: a L{Automata.CAutomata} instance 316 @param xmlstruct: the automata class to read 317 @return: a L{CXMLAutomata.__CXMLAutomataStruct} instance 318 """ 319 #TODO: Minor and Major ? 320 xmlstruct=self.__CXMLAutomataStruct(automata.name,'0','0') 321 322 for a in automata.getAutomata(): 323 324 automaton=self.__CXMLAutomataStruct.CXMLAutomatonStruct(a.name,a.Type) 325 xmlstruct.automatons.append(automaton) 326 327 for e in a.getEvents(): 328 ea=self.__CXMLAutomataStruct.CXMLAutomatonStruct.CXMLEventStruct(e.id,e.name,str(e.controllable==1).lower()) 329 automaton.events.append(ea) 330 331 for s in a.getStates(): 332 sa=self.__CXMLAutomataStruct.CXMLAutomatonStruct.CXMLStateStruct(s.id,s.name,str(s.initial==1).lower(),str(s.marked==1).lower()) 333 automaton.states.append(sa) 334 for t in s.getTransitions(): 335 #a triplet source id - dest id - event id 336 ta=self.__CXMLAutomataStruct.CXMLAutomatonStruct.CXMLTransitionStruct(s.id,s.getTransitions()[t].id,a.getEvent(t).id) 337 automaton.transitions.append(ta) 338 339 return xmlstruct
340
341 - def file2Automata(self,file):
342 """ 343 This method permits to parse a given XML automata file and to write its content on a automata class. 344 345 @type file: string 346 @param file: the XML file to parse the automata 347 @return: a L{Automata.CAutomata} instance 348 """ 349 return self.__struct2Automata(self.__file2Struct(file))
350
351 - def automata2File(self,automata,filename):
352 """ 353 This method permits to read a given automata class and to write its content on a XML Supremica automata file. 354 355 @type filename: string 356 @param filename: the XML file where to write the automata class 357 @type xmlstruct: a L{Automata.CAutomata} instance 358 @param xmlstruct: the automata class to read 359 @return: void 360 """ 361 return self.__struct2File(self.__automata2Struct(automata),filename)
362