#! /usr/bin/env python # Copyright (c) 2005 by Mark T. Holder, Florida State University. (see end of file) '''Classes and functions for reading an instance document of a CIPRES UI XML. Uses xml_to_obj to make the sax code easier. ''' from xml_to_obj import * from PIPRes.wrap.idl import CipresIDL_api1 import os, sys, time, re from cStringIO import StringIO from PIPRes.util.io import logException, cipresGetLogger from PIPRes.wrap.idl import CipresInterfaceEnum, CipresIDL_api1, stringifyEntry import PIPRes.util.ui_tools as ui_tools import copy _LOG = cipresGetLogger('pipres.util.cmd_obj_xml') TextOnlyElement.automaticallyConvertToString = True SAXConstructible.purgeParsingVars = True class CommandObjectXMLError(ValueError): pass def getTopLevelObjectReference(cmdObject, narrowToClass=None, honorHostField=False): """Returns an object reference to the service that is the top-level target of `cmdObject`. - `narrowToClass` can be inferred from the registryEntry (if there is one). - `honorHostField` is False to ignore the registryInstanceID in the target's registryEntry. If it is True then the specified registry must be available. """ if not isinstance(cmdObject, CipresIDL_api1.CommandObject): cmdObject = cmdObject.toCmdObj() targetRef = cmdObject.commandTarget.reference from PIPRes.util.cipres import getCipresRegistry registry = getCipresRegistry() try: ior = targetRef.ior except: if not honorHostField: globHost(cmdObject) regEntryStr = targetRef.registryInfo regEntry = _parseRegistryEntryInfoStr(regEntryStr) regEntry.description = "*" return registry.getServiceOrThrow(narrowToClass=narrowToClass, registryEntry=regEntry) else: if narrowToClass is None: return registry.orb.string_to_object(ior) return registry.getObjectFromIOR(narrowToClass) def globHost(cmdObject): """Replaces the host name in the targets of a command object with a *. Recursively called on all children elements. """ globHostFromTargetReference(cmdObject.commandTarget.reference) for c in cmdObject.children: globHost(c) def globHostFromTargetReference(targetRef): "Replaces the host names in the a registryInfo string with *" try: regEntryStr = targetRef.registryInfo except: return # targetRef is a union, if the ior is used then we get an exception regFields = regEntryStr.split(",") targetRef.registryInfo = "*," + ",".join(regFields[1:]) _LOG.debug(targetRef.registryInfo) def _parseRegistryEntryInfoStr(res): regFields = res.split(",") nFields = len(regFields) if nFields < 4: toAdd = [""] * (4 - nFields) regFields.extend(toAdd) if nFields > 4: description = ",".join(regFields[3:]) else: description = regFields[3] registryInstanceID = regFields[0] repositoryID = regFields[1] applicationName = regFields[2] return CipresIDL_api1.RegistryEntryInfo(registryInstanceID, repositoryID, applicationName, description) def deserialize(s): "Converts the string `s` to a CommandObject. `s` must be valid XML." sio = StringIO(s) return readCmdObjFromXML(sio) def readCmdObjFromXMLFile(fn): if not os.path.exists(fn): raise ValueError("The file %s does not exist" % fn) return readCmdObjFromXML(open(fn, "rU")) def readCmdObjFromXML(uiStreamObject): '''Reads the uiStreamObject and returns a PIPRes.util.ui_tools.UI_Group object''' cmdObj = CipresCommandObject('command-object',{}) if cmdObj.parseFileObj(uiStreamObject): return cmdObj.toCmdObj() raise CommandObjectXMLError, 'Could not parse Command Object XML' class CipresCommandTargetReference(SAXConstructible): def toCmdObj(self): if self.ior: ior = str(self.ior) print "ior is ", ior return CipresIDL_api1.TargetReference(CipresIDL_api1.IOR_TARGET_TYPE, ior) assert self.registryInfo regInf = str(self.registryInfo) return CipresIDL_api1.TargetReference(CipresIDL_api1.REGISTRY_TARGET_TYPE, regInf) class CipresCommandTarget(SAXConstructible): def toCmdObj(self): reference = self.reference.toCmdObj() uiId = self.uiId and str(self.uiId) or "" return CipresIDL_api1.Target(reference, uiId) class CipresCommandObject(SAXConstructible): def toCmdObj(self): target = self.commandTarget.toCmdObj() commands = [str(i) for i in self.commands] children = [i.toCmdObj() for i in self.children] return CipresIDL_api1.CommandObject(target, commands, children) CipresCommandTargetReference._CTH = ChildrenToHandle( singleEl = { "ior" : TextOnlyElement, "registry-info": TextOnlyElement, }) CipresCommandTarget._CTH = ChildrenToHandle( singleEl = { "reference": CipresCommandTargetReference, "ui-id" : TextOnlyElement, }) CipresCommandObject._CTH = ChildrenToHandle( singleEl = { "command-target" : CipresCommandTarget, }, multiEl = { "commands" : TextOnlyElement, "children" : CipresCommandObject }) if __name__ == "__main__": for a in sys.argv[1:]: o = readCmdObjFromXMLFile(a) for k, v in o.__dict__.iteritems(): print k, v.__class__ print v # This file is part of the PIPRes library # The PIPRes library is free software; you can redistribute it # and/or modify it under the terms of the GNU Lesser General # Public License as published by the Free Software Foundation; # either version 2.1 of the License, or (at your option) any later # version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, # MA 02111-1307, USA