Method support

Add support for a method callback.  The method callback enables
arbitrary DBus method calls.  A sample use case could be
starting a systemd unit via the sytemd DBus API.

Change-Id: If25131d11497c82f862ae1f47da066c5fd8b2e2e
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/src/pdmgen.py b/src/pdmgen.py
index 6dc6861..5d4bf29 100755
--- a/src/pdmgen.py
+++ b/src/pdmgen.py
@@ -635,6 +635,85 @@
             indent=indent)
 
 
+class Method(ConfigEntry, Renderer):
+    '''Handle the method callback config file directive.'''
+
+    def __init__(self, *a, **kw):
+        self.service = kw.pop('service')
+        self.path = kw.pop('path')
+        self.interface = kw.pop('interface')
+        self.method = kw.pop('method')
+        self.args = [TrivialArgument(**x) for x in kw.pop('args', {})]
+        super(Method, self).__init__(**kw)
+
+    def factory(self, objs):
+        args = {
+            'class': 'interface',
+            'interface': 'element',
+            'name': self.service
+        }
+        add_unique(ConfigEntry(
+            configfile=self.configfile, **args), objs)
+
+        args = {
+            'class': 'pathname',
+            'pathname': 'element',
+            'name': self.path
+        }
+        add_unique(ConfigEntry(
+            configfile=self.configfile, **args), objs)
+
+        args = {
+            'class': 'interface',
+            'interface': 'element',
+            'name': self.interface
+        }
+        add_unique(ConfigEntry(
+            configfile=self.configfile, **args), objs)
+
+        args = {
+            'class': 'propertyname',
+            'propertyname': 'element',
+            'name': self.method
+        }
+        add_unique(ConfigEntry(
+            configfile=self.configfile, **args), objs)
+
+        super(Method, self).factory(objs)
+
+    def setup(self, objs):
+        '''Resolve elements.'''
+
+        self.service = get_index(
+            objs,
+            'interface',
+            self.service)
+
+        self.path = get_index(
+            objs,
+            'pathname',
+            self.path)
+
+        self.interface = get_index(
+            objs,
+            'interface',
+            self.interface)
+
+        self.method = get_index(
+            objs,
+            'propertyname',
+            self.method)
+
+        super(Method, self).setup(objs)
+
+    def construct(self, loader, indent):
+        return self.render(
+            loader,
+            'method.mako.cpp',
+            c=self,
+            indent=indent)
+
+
 class CallbackGraphEntry(Group):
     '''An entry in a traversal list for groups of callbacks.'''
 
@@ -724,6 +803,7 @@
             'callback': {
                 'journal': Journal,
                 'group': GroupOfCallbacks,
+                'method': Method,
             },
             'condition': {
                 'count': CountCondition,