Author: tross
Date: Tue Nov 11 08:52:44 2008
New Revision: 713079

URL: http://svn.apache.org/viewvc?rev=713079&view=rev
Log:
QPID-1448 - Management APIs and CLI tools are not unicode safe
The management APIs (old and new) now use unicode strings as the default.
The CLI utilities now use the preferred shell encoding to support multibyte
characters in the command line and in managed objects.

Modified:
    incubator/qpid/trunk/qpid/python/commands/qpid-config
    incubator/qpid/trunk/qpid/python/commands/qpid-route
    incubator/qpid/trunk/qpid/python/qpid/disp.py
    incubator/qpid/trunk/qpid/python/qpid/management.py
    incubator/qpid/trunk/qpid/python/qpid/managementdata.py
    incubator/qpid/trunk/qpid/python/qpid/qmfconsole.py

Modified: incubator/qpid/trunk/qpid/python/commands/qpid-config
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/commands/qpid-config?rev=713079&r1=713078&r2=713079&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/python/commands/qpid-config (original)
+++ incubator/qpid/trunk/qpid/python/commands/qpid-config Tue Nov 11 08:52:44 
2008
@@ -22,6 +22,7 @@
 import os
 import getopt
 import sys
+import locale
 from qpid import qmfconsole
 
 _recursive         = False
@@ -305,10 +306,16 @@
     longOpts = ("durable", "cluster-durable", "bindings", "broker-addr=", 
"file-count=",
                 "file-size=", "max-queue-size=", "max-queue-count=", 
"policy-type=",
                 "last-value-queue", "optimistic-consume", "sequence", "ive")
-    (optlist, cargs) = getopt.gnu_getopt (sys.argv[1:], "a:b", longOpts)
+    (optlist, encArgs) = getopt.gnu_getopt (sys.argv[1:], "a:b", longOpts)
 except:
     Usage ()
 
+try:
+    encoding = locale.getpreferredencoding()
+    cargs = [a.decode(encoding) for a in encArgs]
+except:
+    cargs = encArgs
+
 for opt in optlist:
     if opt[0] == "-b" or opt[0] == "--bindings":
         _recursive = True
@@ -381,6 +388,7 @@
             Usage ()
 except Exception,e:
     print "Failed:", e.message
+    raise
     sys.exit(1)
 
 bm.Disconnect()

Modified: incubator/qpid/trunk/qpid/python/commands/qpid-route
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/commands/qpid-route?rev=713079&r1=713078&r2=713079&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/python/commands/qpid-route (original)
+++ incubator/qpid/trunk/qpid/python/commands/qpid-route Tue Nov 11 08:52:44 
2008
@@ -23,6 +23,7 @@
 import sys
 import socket
 import os
+import locale
 from qpid import qmfconsole
 
 def Usage():
@@ -116,11 +117,11 @@
             print "No Links Found"
         else:
             print
-            print "Host            Port    Durable  State             Last 
Error"
-            print 
"==================================================================="
+            print "Host            Port    Transport Durable  State            
 Last Error"
+            print 
"============================================================================="
             for link in links:
-                print "%-16s%-8d   %c     %-18s%s" % \
-                (link.host, link.port, YN(link.durable), link.state, 
link.lastError)
+                print "%-16s%-8d%-13s%c     %-18s%s" % \
+                (link.host, link.port, link.transport, YN(link.durable), 
link.state, link.lastError)
 
     def mapRoutes(self):
         qmf = self.qmf
@@ -401,10 +402,16 @@
 
 try:
     longOpts = ("verbose", "quiet", "durable", "del-empty-link", "src-local", 
"transport=")
-    (optlist, cargs) = getopt.gnu_getopt(sys.argv[1:], "vqdest:", longOpts)
+    (optlist, encArgs) = getopt.gnu_getopt(sys.argv[1:], "vqdest:", longOpts)
 except:
     Usage()
 
+try:
+    encoding = locale.getpreferredencoding()
+    cargs = [a.decode(encoding) for a in encArgs]
+except:
+    cargs = encArgs
+
 for opt in optlist:
     if opt[0] == "-v" or opt[0] == "--verbose":
         _verbose = True

Modified: incubator/qpid/trunk/qpid/python/qpid/disp.py
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/disp.py?rev=713079&r1=713078&r2=713079&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/disp.py (original)
+++ incubator/qpid/trunk/qpid/python/qpid/disp.py Tue Nov 11 08:52:44 2008
@@ -40,7 +40,7 @@
     for head in heads:
       width = len (head)
       for row in rows:
-        cellWidth = len (str (row[col]))
+        cellWidth = len (unicode (row[col]))
         if cellWidth > width:
           width = cellWidth
       colWidth.append (width + self.tableSpacing)
@@ -60,9 +60,9 @@
       line = self.tablePrefix
       col  = 0
       for width in colWidth:
-        line = line + str (row[col])
+        line = line + unicode (row[col])
         if col < len (heads) - 1:
-          for i in range (width - len (str (row[col]))):
+          for i in range (width - len (unicode (row[col]))):
             line = line + " "
         col = col + 1
       print line

Modified: incubator/qpid/trunk/qpid/python/qpid/management.py
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/management.py?rev=713079&r1=713078&r2=713079&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/management.py (original)
+++ incubator/qpid/trunk/qpid/python/qpid/management.py Tue Nov 11 08:52:44 2008
@@ -479,7 +479,7 @@
     elif typecode == 5:
       data = codec.read_uint8 ()
     elif typecode == 6:
-      data = str (codec.read_str8 ())
+      data = codec.read_str8 ()
     elif typecode == 7:
       data = codec.read_str16 ()
     elif typecode == 8:  # ABSTIME
@@ -534,7 +534,7 @@
 
   def handleMethodReply (self, ch, codec, sequence):
     status = codec.read_uint32 ()
-    sText  = str (codec.read_str16 ())
+    sText  = codec.read_str16 ()
 
     data = self.seqMgr.release (sequence)
     if data == None:
@@ -570,7 +570,7 @@
 
   def handleCommandComplete (self, ch, codec, seq):
     code = codec.read_uint32 ()
-    text = str (codec.read_str8 ())
+    text = codec.read_str8 ()
     data = (seq, code, text)
     context = self.seqMgr.release (seq)
     if context == "outstanding":
@@ -597,7 +597,7 @@
     ch.send ("qpid.management", smsg)
 
   def handlePackageInd (self, ch, codec):
-    pname = str (codec.read_str8 ())
+    pname = codec.read_str8 ()
     if pname not in self.packages:
       self.packages[pname] = {}
 
@@ -614,8 +614,8 @@
     kind  = codec.read_uint8()
     if kind != 1:  # This API doesn't handle new-style events
       return
-    pname = str (codec.read_str8())
-    cname = str (codec.read_str8())
+    pname = codec.read_str8()
+    cname = codec.read_str8()
     hash  = codec.read_bin128()
     if pname not in self.packages:
       return
@@ -642,10 +642,10 @@
       return
     timestamp = codec.read_uint64()
     objId = objectId(codec)
-    packageName = str(codec.read_str8())
-    className   = str(codec.read_str8())
+    packageName = codec.read_str8()
+    className   = codec.read_str8()
     hash        = codec.read_bin128()
-    name        = str(codec.read_str8())
+    name        = codec.read_str8()
     classKey    = (packageName, className, hash)
     if classKey not in self.schema:
       return;
@@ -669,8 +669,8 @@
     kind  = codec.read_uint8()
     if kind != 1:  # This API doesn't handle new-style events
       return
-    packageName = str (codec.read_str8 ())
-    className   = str (codec.read_str8 ())
+    packageName = codec.read_str8 ()
+    className   = codec.read_str8 ()
     hash        = codec.read_bin128 ()
     configCount = codec.read_uint16 ()
     instCount   = codec.read_uint16 ()
@@ -808,8 +808,8 @@
     if cls == 'I' and self.instCb == None:
       return
 
-    packageName = str (codec.read_str8 ())
-    className   = str (codec.read_str8 ())
+    packageName = codec.read_str8 ()
+    className   = codec.read_str8 ()
     hash        = codec.read_bin128 ()
     classKey    = (packageName, className, hash)
 

Modified: incubator/qpid/trunk/qpid/python/qpid/managementdata.py
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/managementdata.py?rev=713079&r1=713078&r2=713079&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/managementdata.py (original)
+++ incubator/qpid/trunk/qpid/python/qpid/managementdata.py Tue Nov 11 08:52:44 
2008
@@ -29,6 +29,7 @@
 import socket
 import struct
 import os
+import locale
 from qpid.management import managementChannel, managementClient
 from threading       import Lock
 from disp            import Display
@@ -727,7 +728,11 @@
       self.schemaTable (data)
 
   def do_call (self, data):
-    tokens = data.split ()
+    encTokens = data.split ()
+    try:
+      tokens = [a.decode(locale.getpreferredencoding()) for a in encArgs]
+    except:
+      tokens = encTokens
     if len (tokens) < 2:
       print "Not enough arguments supplied"
       return

Modified: incubator/qpid/trunk/qpid/python/qpid/qmfconsole.py
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/qmfconsole.py?rev=713079&r1=713078&r2=713079&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/qmfconsole.py (original)
+++ incubator/qpid/trunk/qpid/python/qpid/qmfconsole.py Tue Nov 11 08:52:44 2008
@@ -26,7 +26,7 @@
 import re
 from qpid.peer       import Closed
 from qpid.connection import Connection, ConnectionFailed
-from qpid.datatypes  import uuid4, Message, RangedSet
+from qpid.datatypes  import UUID, uuid4, Message, RangedSet
 from qpid.util       import connect, ssl, URL
 from qpid.codec010   import StringCodec as Codec
 from threading       import Lock, Condition
@@ -384,7 +384,7 @@
     pass
 
   def _handleBrokerResp(self, broker, codec, seq):
-    broker.brokerId = codec.read_uuid()
+    broker.brokerId = UUID(codec.read_uuid())
     if self.console != None:
       self.console.brokerInfo(broker)
 
@@ -397,7 +397,7 @@
     broker._send(smsg)
 
   def _handlePackageInd(self, broker, codec, seq):
-    pname = str(codec.read_str8())
+    pname = codec.read_str8()
     notify = False
     try:
       self.cv.acquire()
@@ -420,7 +420,7 @@
 
   def _handleCommandComplete(self, broker, codec, seq):
     code = codec.read_uint32()
-    text = str(codec.read_str8())
+    text = codec.read_str8()
     context = self.seqMgr._release(seq)
     if context == self._CONTEXT_STARTUP:
       broker._decOutstanding()
@@ -442,8 +442,8 @@
 
   def _handleClassInd(self, broker, codec, seq):
     kind  = codec.read_uint8()
-    pname = str(codec.read_str8())
-    cname = str(codec.read_str8())
+    pname = codec.read_str8()
+    cname = codec.read_str8()
     hash  = codec.read_bin128()
     unknown = False
 
@@ -469,7 +469,7 @@
 
   def _handleMethodResp(self, broker, codec, seq):
     code = codec.read_uint32()
-    text = str(codec.read_str16())
+    text = codec.read_str16()
     outArgs = {}
     method, synchronous = self.seqMgr._release(seq)
     if code == 0:
@@ -512,8 +512,8 @@
 
   def _handleSchemaResp(self, broker, codec, seq):
     kind  = codec.read_uint8()
-    pname = str(codec.read_str8())
-    cname = str(codec.read_str8())
+    pname = codec.read_str8()
+    cname = codec.read_str8()
     hash  = codec.read_bin128()
     classKey = (pname, cname, hash)
     _class = SchemaClass(kind, classKey, codec)
@@ -529,8 +529,8 @@
       self.console.newClass(kind, classKey)
 
   def _handleContentInd(self, broker, codec, seq, prop=False, stat=False):
-    pname = str(codec.read_str8())
-    cname = str(codec.read_str8())
+    pname = codec.read_str8()
+    cname = codec.read_str8()
     hash  = codec.read_bin128()
     classKey = (pname, cname, hash)
     try:
@@ -585,7 +585,7 @@
     elif typecode == 2:  data = codec.read_uint16()     # U16
     elif typecode == 3:  data = codec.read_uint32()     # U32
     elif typecode == 4:  data = codec.read_uint64()     # U64
-    elif typecode == 6:  data = str(codec.read_str8())  # SSTR
+    elif typecode == 6:  data = codec.read_str8()       # SSTR
     elif typecode == 7:  data = codec.read_str16()      # LSTR
     elif typecode == 8:  data = codec.read_int64()      # ABSTIME
     elif typecode == 9:  data = codec.read_uint64()     # DELTATIME
@@ -593,7 +593,7 @@
     elif typecode == 11: data = codec.read_uint8() != 0 # BOOL
     elif typecode == 12: data = codec.read_float()      # FLOAT
     elif typecode == 13: data = codec.read_double()     # DOUBLE
-    elif typecode == 14: data = codec.read_uuid()       # UUID
+    elif typecode == 14: data = UUID(codec.read_uuid()) # UUID
     elif typecode == 15: data = codec.read_map()        # FTABLE
     elif typecode == 16: data = codec.read_int8()       # S8
     elif typecode == 17: data = codec.read_int16()      # S16
@@ -617,7 +617,7 @@
     elif typecode == 11: codec.write_uint8  (int(value))    # BOOL
     elif typecode == 12: codec.write_float  (float(value))  # FLOAT
     elif typecode == 13: codec.write_double (double(value)) # DOUBLE
-    elif typecode == 14: codec.write_uuid   (value)         # UUID
+    elif typecode == 14: codec.write_uuid   (value.bytes)   # UUID
     elif typecode == 15: codec.write_map    (value)         # FTABLE
     elif typecode == 16: codec.write_int8   (int(value))    # S8
     elif typecode == 17: codec.write_int16  (int(value))    # S16
@@ -628,26 +628,26 @@
 
   def _displayValue(self, value, typecode):
     """ """
-    if   typecode == 1:  return str(value)
-    elif typecode == 2:  return str(value)
-    elif typecode == 3:  return str(value)
-    elif typecode == 4:  return str(value)
-    elif typecode == 6:  return str(value)
-    elif typecode == 7:  return str(value)
-    elif typecode == 8:  return strftime("%c", gmtime(value / 1000000000))
-    elif typecode == 9:  return str(value)
-    elif typecode == 10: return value.__repr__()
+    if   typecode == 1:  return unicode(value)
+    elif typecode == 2:  return unicode(value)
+    elif typecode == 3:  return unicode(value)
+    elif typecode == 4:  return unicode(value)
+    elif typecode == 6:  return value
+    elif typecode == 7:  return value
+    elif typecode == 8:  return unicode(strftime("%c", gmtime(value / 
1000000000)))
+    elif typecode == 9:  return unicode(value)
+    elif typecode == 10: return unicode(value.__repr__())
     elif typecode == 11:
-      if value: return 'T'
-      else:     return 'F'
-    elif typecode == 12: return str(value)
-    elif typecode == 13: return str(value)
-    elif typecode == 14: return "%08x-%04x-%04x-%04x-%04x%08x" % 
struct.unpack("!LHHHHL", value)
-    elif typecode == 15: return value.__repr__()
-    elif typecode == 16: return str(value)
-    elif typecode == 17: return str(value)
-    elif typecode == 18: return str(value)
-    elif typecode == 19: return str(value)
+      if value: return u"T"
+      else:     return u"F"
+    elif typecode == 12: return unicode(value)
+    elif typecode == 13: return unicode(value)
+    elif typecode == 14: return unicode(value.__repr__())
+    elif typecode == 15: return unicode(value.__repr__())
+    elif typecode == 16: return unicode(value)
+    elif typecode == 17: return unicode(value)
+    elif typecode == 18: return unicode(value)
+    elif typecode == 19: return unicode(value)
     else:
       raise ValueError ("Invalid type code: %d" % typecode)
     
@@ -764,7 +764,7 @@
   """ """
   def __init__(self, codec):
     map = codec.read_map()
-    self.name     = str(map["name"])
+    self.name     = map["name"]
     self.type     = map["type"]
     self.access   = map["access"]
     self.index    = map["index"] != 0
@@ -776,11 +776,11 @@
     self.desc     = None
 
     for key, value in map.items():
-      if   key == "unit"   : self.unit   = str(value)
+      if   key == "unit"   : self.unit   = value
       elif key == "min"    : self.min    = value
       elif key == "max"    : self.max    = value
       elif key == "maxlen" : self.maxlen = value
-      elif key == "desc"   : self.desc   = str(value)
+      elif key == "desc"   : self.desc   = value
 
   def __repr__(self):
     return self.name
@@ -789,14 +789,14 @@
   """ """
   def __init__(self, codec):
     map = codec.read_map()
-    self.name     = str(map["name"])
+    self.name     = map["name"]
     self.type     = map["type"]
     self.unit     = None
     self.desc     = None
 
     for key, value in map.items():
-      if   key == "unit" : self.unit = str(value)
-      elif key == "desc" : self.desc = str(value)
+      if   key == "unit" : self.unit = value
+      elif key == "desc" : self.desc = value
 
   def __repr__(self):
     return self.name
@@ -805,10 +805,10 @@
   """ """
   def __init__(self, codec):
     map = codec.read_map()
-    self.name = str(map["name"])
+    self.name = map["name"]
     argCount  = map["argCount"]
     if "desc" in map:
-      self.desc = str(map["desc"])
+      self.desc = map["desc"]
     else:
       self.desc = None
     self.arguments = []
@@ -833,10 +833,10 @@
   """ """
   def __init__(self, codec, methodArg):
     map = codec.read_map()
-    self.name    = str(map["name"])
+    self.name    = map["name"]
     self.type    = map["type"]
     if methodArg:
-      self.dir   = str(map["dir"].upper())
+      self.dir   = map["dir"].upper()
     self.unit    = None
     self.min     = None
     self.max     = None
@@ -845,12 +845,12 @@
     self.default = None
 
     for key, value in map.items():
-      if   key == "unit"    : self.unit    = str(value)
+      if   key == "unit"    : self.unit    = value
       elif key == "min"     : self.min     = value
       elif key == "max"     : self.max     = value
       elif key == "maxlen"  : self.maxlen  = value
-      elif key == "desc"    : self.desc    = str(value)
-      elif key == "default" : self.default = str(value)
+      elif key == "desc"    : self.desc    = value
+      elif key == "default" : self.default = value
 
 class ObjectId:
   """ Object that represents QMF object identifiers """
@@ -904,7 +904,6 @@
     codec.write_uint64(self.first)
     codec.write_uint64(self.second)
 
-
 class Object(object):
   """ """
   def __init__(self, session, broker, schema, codec, prop, stat):
@@ -955,12 +954,16 @@
 
   def getIndex(self):
     """ Return a string describing this object's primary key. """
-    result = ""
+    result = u""
     for property, value in self._properties:
       if property.index:
-        if result != "":
-          result += ":"
-        result += str(value)
+        if result != u"":
+          result += u":"
+        try:
+          valstr = unicode(value)
+        except:
+          valstr = u"<undecodable>"
+        result += valstr
     return result
 
   def getProperties(self):
@@ -979,7 +982,7 @@
       self.statistics = newer.getStatistics()
 
   def __repr__(self):
-    return self.getIndex()
+    return self.getIndex().encode("utf8")
 
   def __getattr__(self, name):
     for method in self._schema.getMethods():
@@ -1365,7 +1368,8 @@
     out += " " + self._sevName() + " " + self.classKey[0] + ":" + 
self.classKey[1]
     out += " broker=" + self.broker.getUrl()
     for arg in self.schema.arguments:
-      out += " " + arg.name + "=" + 
self.session._displayValue(self.arguments[arg.name], arg.type)
+      out += " " + arg.name + "=" + \
+          self.session._displayValue(self.arguments[arg.name], 
arg.type).encode("utf8")
     return out
 
   def _sevName(self):


Reply via email to