configurationengine/doc/plugins/dev-plugin/plugin-interface.rst
changeset 0 2e8eeb919028
child 3 e7e0ae78773e
equal deleted inserted replaced
-1:000000000000 0:2e8eeb919028
       
     1 .. _plugin-howto-plugin-interface:
       
     2 
       
     3 Plug-in interface
       
     4 =================
       
     5 
       
     6 A ConE plug-in has two points for interfacing with ConE:
       
     7 
       
     8 #. Reader classes that derive from ``cone.public.plugin.ReaderBase`` . These classes
       
     9    define supported Implementation Markup Languages (i.e. supported XML namespaces)
       
    10    and other attributes related to them like file extensions. As the name suggests, they are
       
    11    also responsible for reading implementation instances from XML data.
       
    12 #. Implementation classes that derive from ``cone.public.plugin.ImplBase``. These classes
       
    13    supply the actual run-time functionality of the plug-ins.
       
    14 
       
    15 The following UML diagram shows the most important classes and their interdependencies:
       
    16 
       
    17 .. image:: plugin_classes.jpg
       
    18 
       
    19 ConE generation can be seen to consist of two phases, implementation parsing
       
    20 and output generation:
       
    21 
       
    22 Parsing phase:
       
    23 
       
    24 - Implementation file list is filtered based on a user-given file name pattern
       
    25   and supported file extensions
       
    26 - All remaining files are parsed into ``ElementTree`` instances
       
    27 - The ``ElementTree`` instance is scanned for supported ImplML namespaces and
       
    28   implementation instances are created using the correct reader classes
       
    29   (the ``read_impl()`` method)
       
    30 - All implementations are collected into an ``ImplSet`` instance
       
    31 
       
    32 Generation phase:
       
    33 
       
    34 - Implementation instances are further filtered using tags and ConfML references
       
    35   (the ``has_tag()`` and ``has_ref()`` methods)
       
    36 - Implementations instances are divided into separate sets based on their invocation
       
    37   phases
       
    38 - Output is generated using each implementation set. For each implementation set:
       
    39 
       
    40     - The ``generation_context`` variable of each implementation instance is set
       
    41       (this context contains generation-scope information implementations instances may use)
       
    42     - The ``generate()`` method of each instance is called
       
    43     - The ``post_generate()`` method of each instance is called
       
    44 
       
    45 From a plug-in's point of view, the sequence of method calls goes as follows:
       
    46 
       
    47 .. image:: plugin_lifecycle.jpg
       
    48 
       
    49 Explanations of the steps in the diagram:
       
    50 
       
    51 ====== ========================================================================
       
    52 Step   Explanation
       
    53 ====== ========================================================================
       
    54 1      ``read_impl()`` is called to create an implementation instance based on
       
    55        XML data.
       
    56 2      ``read_impl()`` creates the instance.
       
    57 3-6    Filtering based on ConfML references and implementation tags is done.
       
    58        The implementation instance returns True in all cases, so it is included
       
    59        in the actual generation.
       
    60 7-8    The instance is asked for its invocation phase (here it returns "normal")
       
    61 9      The implementation instance's ``generation_context`` variable is set, so
       
    62        then it can be used in the actual generation.
       
    63 10-11  Output generation methods are called
       
    64 ====== ========================================================================
       
    65 
       
    66 Plug-in interface class source
       
    67 ------------------------------
       
    68 
       
    69 The following source listings show the most important parts of the ``ImplReader``
       
    70 and ``ImplBase`` classes from a plug-in's point of view:
       
    71 
       
    72 .. code-block:: python
       
    73 
       
    74     class ReaderBase(object):
       
    75         """
       
    76         Base class for implementation readers.
       
    77         
       
    78         Each reader class supports one XML namespace, from which it reads an implementation
       
    79         instance.
       
    80         
       
    81         The method for parsing an implementation (read_impl()) is given an ElementTree
       
    82         XML element as the root from which to parse the implementation. The plug-in
       
    83         machinery handles each XML file so that the correct reader class is used to read
       
    84         the implementations from XML elements based on the namespaces.
       
    85         """
       
    86         
       
    87         # The XML namespace supported by the implementation reader.
       
    88         # Should be something like "http://www.xyz.org/xml/1".
       
    89         # Can also be None, in which case the reader will not be used
       
    90         # (this can be useful for defining base classes for e.g. readers
       
    91         # for different versions of an implementation).
       
    92         NAMESPACE = None
       
    93         
       
    94         # Any extra XML namespaces that should be ignored by the
       
    95         # implementation parsing machinery. This is useful for specifying
       
    96         # namespaces that are not actual ImplML namespaces, but are used
       
    97         # inside an implementation (e.g. XInclude)
       
    98         IGNORED_NAMESPACES = []
       
    99         
       
   100         # Supported implementation file extensions.
       
   101         # Sub-classes can override this to add new supported file extensions
       
   102         # if necessary. The file extensions simply control whether implementations
       
   103         # are attempted to be read from a file or not.
       
   104         # Note that the extensions are case-insensitive.
       
   105         FILE_EXTENSIONS = ['implml']
       
   106         
       
   107         @classmethod
       
   108         def read_impl(cls, resource_ref, configuration, doc_root):
       
   109             """
       
   110             Read an implementation instance from the given element tree.
       
   111             
       
   112             @param resource_ref: Reference to the resource in the configuration in
       
   113                 which the given document root resides.
       
   114             @param configuration: The configuration used.
       
   115             @param doc_root: The document root from which to parse the implementation.
       
   116             @return: The read implementation instance, or None.
       
   117             """
       
   118             raise exceptions.NotSupportedException()
       
   119 
       
   120 .. code-block:: python
       
   121 
       
   122     class GenerationContext(object):
       
   123         """
       
   124         Context object that can be used for passing generation-scope
       
   125         data to implementation instances.
       
   126         """
       
   127         
       
   128         def __init__(self, tags={}):
       
   129             # The tags used in this generation context
       
   130             # (i.e. the tags passed from command line)
       
   131             self.tags = tags
       
   132             
       
   133             # A dictionary that implementation instances can use to
       
   134             # pass any data between each other
       
   135             self.impl_data_dict = {}
       
   136 
       
   137 .. code-block:: python
       
   138 
       
   139     class ImplBase(object):
       
   140         """
       
   141         Base class for any confml implementation. 
       
   142         """
       
   143         
       
   144         # Identifier for the implementation type, used e.g. in .cfg files.
       
   145         # Should be a string like e.g. 'someml'.
       
   146         IMPL_TYPE_ID = None
       
   147         
       
   148         # Defines the default invocation phase for the implementation.
       
   149         # The default is used if the phase is not explicitly set in the
       
   150         # ImplML file or manually overridden by calling set_invocation_phase()
       
   151         DEFAULT_INVOCATION_PHASE = None
       
   152         
       
   153         def __init__(self,ref, configuration):
       
   154             """
       
   155             Create a ImplBase object
       
   156             @param ref : the ref to the Implml file resource.
       
   157             @param configuration : the Configuration instance for the
       
   158             configuration data.
       
   159             """
       
   160             self._settings = None
       
   161             self.ref = ref
       
   162             self.index = None
       
   163             self.configuration = configuration
       
   164             self.output_root = self.settings.get('output_root','output')
       
   165             self.output_subdir = self.settings.get('output_subdir','')
       
   166             self.plugin_output = self.settings.get('plugin_output','')
       
   167             
       
   168             self.generation_context = None
       
   169             self._tags = None
       
   170             self._invocation_phase = None
       
   171             self._tempvar_defs = []
       
   172 
       
   173         def generate(self):
       
   174             """
       
   175             Generate the given implementation.
       
   176             @return: 
       
   177             """
       
   178             raise exceptions.NotSupportedException()
       
   179         
       
   180         def post_generate(self):
       
   181             """
       
   182             Called when all normal generation has been done.
       
   183             
       
   184             @attention: This is a temporary method used for implementing cenrep_rfs.txt generation.
       
   185             """
       
   186             pass
       
   187         
       
   188         def list_output_files(self):
       
   189             """
       
   190             Return a list of output files as an array. 
       
   191             """
       
   192             raise exceptions.NotSupportedException()
       
   193         
       
   194         def get_refs(self):
       
   195             """
       
   196             Return a list of all ConfML setting references that affect this
       
   197             implementation. May also return None if references are not relevant
       
   198             for the implementation.
       
   199             """
       
   200             return None