configurationengine/doc/plugins/dev-plugin/plugin-interface.rst
changeset 0 2e8eeb919028
child 3 e7e0ae78773e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/dev-plugin/plugin-interface.rst	Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,200 @@
+.. _plugin-howto-plugin-interface:
+
+Plug-in interface
+=================
+
+A ConE plug-in has two points for interfacing with ConE:
+
+#. Reader classes that derive from ``cone.public.plugin.ReaderBase`` . These classes
+   define supported Implementation Markup Languages (i.e. supported XML namespaces)
+   and other attributes related to them like file extensions. As the name suggests, they are
+   also responsible for reading implementation instances from XML data.
+#. Implementation classes that derive from ``cone.public.plugin.ImplBase``. These classes
+   supply the actual run-time functionality of the plug-ins.
+
+The following UML diagram shows the most important classes and their interdependencies:
+
+.. image:: plugin_classes.jpg
+
+ConE generation can be seen to consist of two phases, implementation parsing
+and output generation:
+
+Parsing phase:
+
+- Implementation file list is filtered based on a user-given file name pattern
+  and supported file extensions
+- All remaining files are parsed into ``ElementTree`` instances
+- The ``ElementTree`` instance is scanned for supported ImplML namespaces and
+  implementation instances are created using the correct reader classes
+  (the ``read_impl()`` method)
+- All implementations are collected into an ``ImplSet`` instance
+
+Generation phase:
+
+- Implementation instances are further filtered using tags and ConfML references
+  (the ``has_tag()`` and ``has_ref()`` methods)
+- Implementations instances are divided into separate sets based on their invocation
+  phases
+- Output is generated using each implementation set. For each implementation set:
+
+    - The ``generation_context`` variable of each implementation instance is set
+      (this context contains generation-scope information implementations instances may use)
+    - The ``generate()`` method of each instance is called
+    - The ``post_generate()`` method of each instance is called
+
+From a plug-in's point of view, the sequence of method calls goes as follows:
+
+.. image:: plugin_lifecycle.jpg
+
+Explanations of the steps in the diagram:
+
+====== ========================================================================
+Step   Explanation
+====== ========================================================================
+1      ``read_impl()`` is called to create an implementation instance based on
+       XML data.
+2      ``read_impl()`` creates the instance.
+3-6    Filtering based on ConfML references and implementation tags is done.
+       The implementation instance returns True in all cases, so it is included
+       in the actual generation.
+7-8    The instance is asked for its invocation phase (here it returns "normal")
+9      The implementation instance's ``generation_context`` variable is set, so
+       then it can be used in the actual generation.
+10-11  Output generation methods are called
+====== ========================================================================
+
+Plug-in interface class source
+------------------------------
+
+The following source listings show the most important parts of the ``ImplReader``
+and ``ImplBase`` classes from a plug-in's point of view:
+
+.. code-block:: python
+
+    class ReaderBase(object):
+        """
+        Base class for implementation readers.
+        
+        Each reader class supports one XML namespace, from which it reads an implementation
+        instance.
+        
+        The method for parsing an implementation (read_impl()) is given an ElementTree
+        XML element as the root from which to parse the implementation. The plug-in
+        machinery handles each XML file so that the correct reader class is used to read
+        the implementations from XML elements based on the namespaces.
+        """
+        
+        # The XML namespace supported by the implementation reader.
+        # Should be something like "http://www.xyz.org/xml/1".
+        # Can also be None, in which case the reader will not be used
+        # (this can be useful for defining base classes for e.g. readers
+        # for different versions of an implementation).
+        NAMESPACE = None
+        
+        # Any extra XML namespaces that should be ignored by the
+        # implementation parsing machinery. This is useful for specifying
+        # namespaces that are not actual ImplML namespaces, but are used
+        # inside an implementation (e.g. XInclude)
+        IGNORED_NAMESPACES = []
+        
+        # Supported implementation file extensions.
+        # Sub-classes can override this to add new supported file extensions
+        # if necessary. The file extensions simply control whether implementations
+        # are attempted to be read from a file or not.
+        # Note that the extensions are case-insensitive.
+        FILE_EXTENSIONS = ['implml']
+        
+        @classmethod
+        def read_impl(cls, resource_ref, configuration, doc_root):
+            """
+            Read an implementation instance from the given element tree.
+            
+            @param resource_ref: Reference to the resource in the configuration in
+                which the given document root resides.
+            @param configuration: The configuration used.
+            @param doc_root: The document root from which to parse the implementation.
+            @return: The read implementation instance, or None.
+            """
+            raise exceptions.NotSupportedException()
+
+.. code-block:: python
+
+    class GenerationContext(object):
+        """
+        Context object that can be used for passing generation-scope
+        data to implementation instances.
+        """
+        
+        def __init__(self, tags={}):
+            # The tags used in this generation context
+            # (i.e. the tags passed from command line)
+            self.tags = tags
+            
+            # A dictionary that implementation instances can use to
+            # pass any data between each other
+            self.impl_data_dict = {}
+
+.. code-block:: python
+
+    class ImplBase(object):
+        """
+        Base class for any confml implementation. 
+        """
+        
+        # Identifier for the implementation type, used e.g. in .cfg files.
+        # Should be a string like e.g. 'someml'.
+        IMPL_TYPE_ID = None
+        
+        # Defines the default invocation phase for the implementation.
+        # The default is used if the phase is not explicitly set in the
+        # ImplML file or manually overridden by calling set_invocation_phase()
+        DEFAULT_INVOCATION_PHASE = None
+        
+        def __init__(self,ref, configuration):
+            """
+            Create a ImplBase object
+            @param ref : the ref to the Implml file resource.
+            @param configuration : the Configuration instance for the
+            configuration data.
+            """
+            self._settings = None
+            self.ref = ref
+            self.index = None
+            self.configuration = configuration
+            self.output_root = self.settings.get('output_root','output')
+            self.output_subdir = self.settings.get('output_subdir','')
+            self.plugin_output = self.settings.get('plugin_output','')
+            
+            self.generation_context = None
+            self._tags = None
+            self._invocation_phase = None
+            self._tempvar_defs = []
+
+        def generate(self):
+            """
+            Generate the given implementation.
+            @return: 
+            """
+            raise exceptions.NotSupportedException()
+        
+        def post_generate(self):
+            """
+            Called when all normal generation has been done.
+            
+            @attention: This is a temporary method used for implementing cenrep_rfs.txt generation.
+            """
+            pass
+        
+        def list_output_files(self):
+            """
+            Return a list of output files as an array. 
+            """
+            raise exceptions.NotSupportedException()
+        
+        def get_refs(self):
+            """
+            Return a list of all ConfML setting references that affect this
+            implementation. May also return None if references are not relevant
+            for the implementation.
+            """
+            return None