class Senml():
    
    def __init__(self, items=None, baseName=None):
        self._senml = {}
        self._items = SenmlItems(items)
        self._senml[v._e] = self._items._items
        if None != baseName :
            self._baseName = baseName
            self._senml[v._bn] = baseName
        
    def configure(self, items=None):
        self.__init__(items, self._baseName)
        
    def addItems(self, items):
        if [] != items:
            self._items.add(items)
        
    def serialize(self):
        return json.dumps(self._senml, sort_keys=False, indent=2, separators=(',', ': '))
    
    def load(self, jsonString):
        self._loadObject = json.loads(jsonString)
        self.addItems(self._loadObject[v._e])
        
    def items(self):
        return self._items._items
    def __init__(self, rootResource=None, uriPath=["/"], resourceLink=None, resourceItem=None ):
        HypermediaResource.__init__(self)
        self._uriPath = uriPath
        self._pathString = "/"
        for pathElement in uriPath[1:]:
            self._pathString += (pathElement + "/")
        self._pathLen = len(self._uriPath)
        if ["/"] == uriPath :
            self._rootResource = self
        else:
            self._rootResource = rootResource
        self._unrouted = 0
            
        self._itemArray = SenmlItems()
        self._subresources = {}
        
        """ merge the constructor rt link attribute values into the self link """
        if None != resourceLink:
            if v._rt in resourceLink:
                self._linkArray.selectMerge({v._rel:v._self}, {v._rt: resourceLink[v._rt]})
            
        """ if there is an item in the constructor, null the resource name and add it to items """
        if None != resourceItem :
            resourceItem[v._n] = v._null
            self._itemArray.add(resourceItem)
            self._linkArray.selectMerge({v._href:v._null},{ v._rel: v._item})

        PlainTextHandler(self)
        SenmlHandler(self)
        SenmlCollectionHandler(self)
 def __init__(self, items=None, baseName=None):
     self._senml = {}
     self._items = SenmlItems(items)
     self._senml[v._e] = self._items._items
     if None != baseName :
         self._baseName = baseName
         self._senml[v._bn] = baseName
class HypermediaCollection(HypermediaResource):

    def __init__(self, rootResource=None, uriPath=["/"], resourceLink=None, resourceItem=None ):
        HypermediaResource.__init__(self)
        self._uriPath = uriPath
        self._pathString = "/"
        for pathElement in uriPath[1:]:
            self._pathString += (pathElement + "/")
        self._pathLen = len(self._uriPath)
        if ["/"] == uriPath :
            self._rootResource = self
        else:
            self._rootResource = rootResource
        self._unrouted = 0
            
        self._itemArray = SenmlItems()
        self._subresources = {}
        
        """ merge the constructor rt link attribute values into the self link """
        if None != resourceLink:
            if v._rt in resourceLink:
                self._linkArray.selectMerge({v._rel:v._self}, {v._rt: resourceLink[v._rt]})
            
        """ if there is an item in the constructor, null the resource name and add it to items """
        if None != resourceItem :
            resourceItem[v._n] = v._null
            self._itemArray.add(resourceItem)
            self._linkArray.selectMerge({v._href:v._null},{ v._rel: v._item})

        PlainTextHandler(self)
        SenmlHandler(self)
        SenmlCollectionHandler(self)

    """ Route requests using hyperlinks. Link relations "item" and "sub" are used to identify 
        local items in the collection and sub resources, respectively."""        
    def routeRequest(self, request):  
        self._request = request
        self._unrouted = len(request[v.uriPath]) - self._pathLen
            
        if 0 == self._unrouted:
            """ this resource is selected, process content-format """
            self._processGroup(self._request)
            self.handleRequest(self._request)
        else:
            self._resourceName = self._request[v.uriPath][self._pathLen]
            # if there is both sub and item, route sub and ignore item
            if [] != self._linkArray.get({v._href:self._resourceName, v._rel:v._sub}):
                """ route request to subresource item"""
                self._subresources[self._resourceName].routeRequest(self._request)
            elif 1 == self._unrouted and [] != self._linkArray.get({v._href:self._resourceName, v._rel:v._item}) :
                """ item in the local collection is selected, handle content-format in this context"""
                self.handleRequest(self._request)
            else:
                """ nothing to route or process """
                self._request[v.response][v.status] = v.NotFound

    def _processGroup(self, request):
        """invoke a proxy or promise to forward the request to each resource marked with rel=grp """
        self._groupLinks = self._linkArray.get({v._rel:v._grp})
        if [] != self._groupLinks:
            request[v.response][v.payload] = []
            request[v.response][v.code] = []
            """ make request instances """
            self._requests = []
            for self._link in self._groupLinks:
                print "group link: ", self._link
                self._requests.append( deepcopy(request) )
            for self._request in self._requests:
                """ overwrite uriPath """                
                self._request[v.uriPath] = ["/"]
                for self._pathElement in self._groupLinks.popleft()[v._href].split("/"):
                    if len(self._pathElement) > 0:
                        self._request[v.uriPath].append(self._pathElement)
                """ route request to root resource if path starts with /  """        
                if "/" == self._request[v.uriPath][0]:
                    self._rootResource.routeRequest(self._request)
                else:
                    self.routeRequest(self._request)
            """ collect the results """
            for self._request in self._requests:
                request[v.response][v.payload].append(self._request[v.response][v.payload])
                if v.Success != self._request[v.response][v.status] and \
                        v.Created != self._request[v.response][v.status]:
                    request[v.response][v.status] = v.BadRequest
                request[v.response][v.code].append(self._request[v.response][v.code]) 
            return self._requests
        else:
            return None

    def _createSubresource(self, resourceLink, resourceItem=None):
        resourceName = resourceLink[v._href]
        self._subresources[resourceName] = \
            HypermediaCollection( self._rootResource, self._uriPath + [resourceName], resourceLink, resourceItem) 
        return self._subresources[resourceName]