Merge pull request #3 from bradbishop/enumerate

Support for org.openbmc.Object.Enumerate
diff --git a/phosphor-rest b/phosphor-rest
index 600b3d5..026eb74 100644
--- a/phosphor-rest
+++ b/phosphor-rest
@@ -20,14 +20,14 @@
 import SocketServer
 import json
 import dbus
-from OpenBMCMapper import Path
+from OpenBMCMapper import Path, Mapper, PathTree
 import OpenBMCMapper
 
 class RestException(Exception):
 	def __init__(self, msg, http_status=403):
 		self.status = http_status
 		super(RestException, self).__init__(msg)
-        
+
 class Response(object):
 	def render(self, handler):
 		raise NotImplemented()
@@ -55,7 +55,7 @@
 
 class RequestHandler(object):
 	def __init__(self, req, path, data):
-		self.req = req 
+		self.req = req
 		self.path = path
 		self.bus = req.server.bus
 		self.mapper = req.server.mapper
@@ -101,8 +101,8 @@
 		return m
 
 	def find_method(self):
-		busses = self.mapper.GetTree(
-				self.path, 0, 'exact')[self.path]
+		busses = self.mapper.get_object(
+				self.path)
 		for items in busses.iteritems():
 			m = self.find_method_on_bus(*items)
 			if not m:
@@ -166,7 +166,7 @@
 				obj, dbus_interface=dbus.PROPERTIES_IFACE)
 
 		for iface in interfaces:
-			if self.try_set_one_interface(prop, value, 
+			if self.try_set_one_interface(prop, value,
 					properties_iface, iface):
 				return True
 
@@ -209,7 +209,7 @@
 		super(AttrHandler, self).__init__(req, path, data)
 		try:
 			self.inst = InstanceHandler(req, path, data,
-					self.mapper.GetTree(path, 0, 'exact')[path])
+					self.mapper.get_object(path))
 		except KeyError:
 			raise RestException("Not Found", 404)
 		self.attr = Path(self.req.path).rel(first = -1)
@@ -229,7 +229,7 @@
 		super(TypesHandler, self).__init__(req, path, data)
 
 	def do_GET(self):
-		types = self.mapper.GetTreePaths(self.path, 1, 'exact')
+		types = self.mapper.get_subtree_paths(self.path, 1)
 		if not types:
 			raise RestException("Not Found", 404)
 
@@ -240,25 +240,57 @@
 		super(ListHandler, self).__init__(req, path, data)
 
 	def do_GET(self):
-		objs = self.mapper.GetTree(self.path, -1, 'fuzzy')
-		if self.path in objs:
-			del objs[self.path]
+		objs = self.mapper.get_subtree(self.path)
 		if not objs:
 			raise RestException("Not Found", 404)
 
-		return objs.keys() 
+		return objs.keys()
 
 class EnumerateHandler(RequestHandler):
 	def __init__(self, req, path, data):
 		super(EnumerateHandler, self).__init__(req, path, data)
 
+	def get_enumerate(self, path, data):
+		busses = []
+		for s, i in data.iteritems():
+			if OpenBMCMapper.ENUMERATE_IFACE in i:
+				busses.append(s)
+		return busses
+
+	def call_enumerate(self, path, busses):
+		objs = {}
+		for b in busses:
+			obj = self.bus.get_object(b, path)
+			iface = dbus.Interface(obj, OpenBMCMapper.ENUMERATE_IFACE)
+			objs.update(iface.enumerate())
+		return objs
+
 	def do_GET(self):
 		objs = {}
-		mapper_data = self.mapper.GetTree(self.path, -1, 'fuzzy')
-		if self.path in mapper_data:
-			del mapper_data[self.path]
-
+		mapper_data = self.mapper.get_subtree(self.path)
+		tree = PathTree()
 		for x,y in mapper_data.iteritems():
+			tree[x] = y
+
+		try:
+			# Check to see if the root path implements
+			# enumerate in addition to any sub tree
+			# objects.
+			root = self.mapper.get_object(self.path)
+			mapper_data[self.path] = root
+		except:
+			pass
+
+		have_enumerate = [ (x[0], self.get_enumerate(*x)) for x in mapper_data.iteritems() \
+				if self.get_enumerate(*x) ]
+
+		for x,y in have_enumerate:
+			objs.update(self.call_enumerate(x, y))
+			tmp = tree[x]
+			del tree[x]
+			tree[x] = tmp
+
+		for x,y in tree.dataitems():
 			objs[x] = InstanceHandler(self.req, x, self.data, y).do_GET()
 
 		if not objs:
@@ -279,18 +311,17 @@
 		if path.parts[-1] == 'enumerate':
 			return EnumerateHandler(self, path.fq(last = -1), data)
 
-		if path.parts[-2] == 'attr':
+		if path.depth() > 1 and path.parts[-2] == 'attr':
 			return AttrHandler(self, path.fq(last = -2), data)
 
-		if path.parts[-2] == 'action':
+		if path.depth() > 1 and path.parts[-2] == 'action':
 			return MethodHandler(self, path.fq(last = -2), data)
 
 		# have to do an objectmapper query at this point
-		mapper_entry = self.server.mapper.GetTree(
-				path.fq(), 0, 'exact')
+		mapper_entry = self.server.mapper.get_object(path.fq())
 		if mapper_entry:
-			return InstanceHandler(self, path.fq(), data, 
-					mapper_entry[path.fq()])
+			return InstanceHandler(self, path.fq(), data,
+					mapper_entry)
 
 		raise RestException("Not Found", 404)
 
@@ -328,15 +359,12 @@
 		return self.do_command()
 
 class HTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
-	def __init__(self, bind, handler):
+	def __init__(self, bind, handler, bus):
 		BaseHTTPServer.HTTPServer.__init__(self, bind, handler)
-		self.bus = dbus.SystemBus()
-		mapper = self.bus.get_object(OpenBMCMapper.MAPPER_NAME,
-				OpenBMCMapper.MAPPER_PATH)
-		self.mapper = dbus.Interface(mapper,
-				dbus_interface = OpenBMCMapper.MAPPER_IFACE)
+		self.bus = bus
+		self.mapper = Mapper(self.bus)
 
 if __name__ == '__main__':
 	bus = dbus.SystemBus()
-	server = HTTPServer(('', 80), DBusRestHandler)
+	server = HTTPServer(('', 80), DBusRestHandler, bus)
 	server.serve_forever()