blob: e855d0240449fafc209c04c8928689874e98e82c [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License
#
"""
AMQP Managment Entity
"""
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function
import itertools
import re
import sys
if sys.version_info[0] > 2:
# Python 3 does not have a unicode() builtin method,
# luckily all strings are unicode to start with
def unicode(s):
return s
def dict_iteritems(d):
return iter(d.items())
else:
def dict_iteritems(d):
return d.iteritems()
def clean_dict(items, **kwargs):
"""
@param items: A mapping or iterable of pairs.
@return: dict containing items + kwargs without any None values. All keys are unicode.
"""
if isinstance(items, dict):
items = dict_iteritems(items)
return dict((unicode(k), v) for k, v in itertools.chain(items,
dict_iteritems(kwargs))
if v is not None)
class EntityBase(object):
"""
A collection of named attributes.
Attribute access:
- via index operator: entity['foo']
- as python attributes: entity.foo (only if attribute name is a legal python identifier
after replacing '-' with '_')
@ivar attributes: Map of attribute values for this entity.
NOTE: EntityBase does not itself implement the python map protocol because map
methods (in particular 'update') can clash with AMQP methods and attributes.
"""
def __init__(self, attributes=None, **kwargs):
self.__dict__['attributes'] = {}
if attributes:
for k, v in dict_iteritems(attributes):
self.attributes[k] = v
self.__dict__[self._pyname(k)] = v
for k, v in dict_iteritems(kwargs):
self._set(k, v)
def __getitem__(self, name):
return self.attributes[name]
def __getattr__(self, name):
if name in self.attributes:
return self.attributes[name]
raise AttributeError
def __contains__(self, name):
return name in self.attributes
@staticmethod
def _pyname(name): return name.replace('-', '_')
def _set(self, name, value):
"""Subclasses can override _set to do validation on each change"""
self.attributes[name] = value
self.__dict__[self._pyname(name)] = value
# Access using []
def __setitem__(self, name, value): self._set(name, value)
def __delitem__(self, name):
del self.attributes[name]
del self.__dict__[self._pyname(name)]
# Access as python attribute.
def __setattr__(self, name, value): self._set(name, value)
def __delattr__(self, name):
self.__delitem__(name)
def __repr__(self): return "EntityBase(%r)" % self.attributes
# attributes name, identity and type are special snowflake
# attributes that we print before all the not so special
# attributes. Assign each a priority for the sort
_SPECIAL = {u"name": 0, u"identity": 1, u"type": 2}
def __str__(self):
# Sort so the _SPECIAL attributes are printed first, 3 ==
# lower priority than special
keys = sorted(self.attributes.keys(),
key=lambda k: self._SPECIAL.get(k, 3))
return "Entity(%s)" % ", ".join("%s=%s" % (k, self.attributes[k]) for k in keys)
def update(entity, values):
"""Update entity from values
@param entity: an Entity
@param values: a map of values
"""
for k, v in dict_iteritems(values):
entity[k] = v
SEPARATOR_RE = re.compile(r' |_|-|\.')
def camelcase(str, capital=False):
"""Convert string str with ' ', '_', '.' or '-' separators to camelCase."""
if not str:
return ''
words = SEPARATOR_RE.split(str)
first = words[0]
if capital:
first = first[0].upper() + first[1:]
return first + ''.join([w.capitalize() for w in words[1:]])
CAPS_RE = re.compile('[A-Z]')
def uncamelcase(str, separator='_'):
"""Convert camelCase string str to string with separator, e.g. camel_case"""
if len(str) == 0:
return str
return str[0] + CAPS_RE.sub(lambda m: separator + m.group(0).lower(), str[1:])