configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/relations.py
author terytkon
Thu, 11 Mar 2010 17:04:37 +0200
changeset 0 2e8eeb919028
child 3 e7e0ae78773e
permissions -rw-r--r--
Adding EPL version of configurationengine.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     1
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     2
# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     3
# All rights reserved.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     4
# This component and the accompanying materials are made available
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     5
# under the terms of "Eclipse Public License v1.0"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     6
# which accompanies this distribution, and is available
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     7
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     8
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     9
# Initial Contributors:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    10
# Nokia Corporation - initial contribution.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    11
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    12
# Contributors:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    13
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    14
# Description: 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    15
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    16
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    17
'''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    18
implementation for ruleml relations.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    19
'''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    20
import os
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    21
import StringIO
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    22
import logging
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    23
import operator as ops
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    24
import re
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    25
import sys, traceback
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    26
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    27
log = logging.getLogger('cone.ruleplugin.relations')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    28
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    29
from cone.public import api, rules, utils, exceptions, plugin
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    30
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    31
class RelationFactory(api.FactoryBase):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    32
    @ classmethod
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    33
    def get_relation_by_name(cls, relation_name):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    34
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    35
        Get the class name by file extension.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    36
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    37
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    38
            return rules.RELATIONS.get(relation_name)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    39
        except KeyError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    40
            raise exceptions.NotSupportedException("No Relation class found for name %s" % relation_name)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    41
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    42
    @ classmethod
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    43
    def get_relations(cls, configuration, relation):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    44
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    45
            relations = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    46
            (left_expression,relation_name,right_expression) = parse_rule(relation)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    47
            relation = cls.get_relation_by_name(relation_name)(configuration, left_expression, right_expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    48
            relations.append(relation)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    49
            propagated_relations = cls.get_relations(configuration, right_expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    50
            if propagated_relations:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    51
                for relation in propagated_relations:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    52
                    relations.append(relation)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    53
            return relations
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    54
        except exceptions.ParseError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    55
            return None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    56
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    57
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    58
class ConfigurationContext(rules.DefaultContext):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    59
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    60
    def __init__(self, data):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    61
        rules.DefaultContext.__init__(self, data)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    62
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    63
        # A note on the callback variables that follow:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    64
        # in order to collect rule execution results for the
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    65
        # generation report, a callback system is implemented in
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    66
        # ConfigurationContext.  It all boils down to ConfigureRelation
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    67
        # using configure_expression_result_callback to catch the result
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    68
        # in its execute() method. The ConfigurationContext just works as
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    69
        # a "callback hub" because a reference to the context is available
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    70
        # in all expression evaluations.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    71
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    72
        # Callback called with a plugin.RelationExecutionResult object
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    73
        # when a ConfigureExpression has been evaluated
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    74
        self.configure_expression_result_callback = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    75
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    76
        # Callback called with the setting reference when a setting is dereferenced
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    77
        # as a terminal expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    78
        self.ref_terminal_callback = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    79
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    80
        # Callback called with the setting reference when a setting is dereferenced
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    81
        # inside an EvalExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    82
        self.ref_eval_callback = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    83
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    84
        # Callback called with the setting reference when the value of a setting
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    85
        # is set inside a SetExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    86
        self.ref_set_callback = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    87
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    88
    def handle_terminal(self, expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    89
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    90
            value = self.data.get_default_view().get_feature(expression).get_value()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    91
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    92
            # Got a valid ref, call the callback
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    93
            if self.ref_terminal_callback:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    94
                self.ref_terminal_callback(expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    95
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    96
            return value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    97
        except exceptions.NotFound,e:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    98
            """ return the expression itself if it is not a fearef """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    99
            #print "handle_terminal constant %s" % (expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   100
            try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   101
                return eval(expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   102
            except (NameError,SyntaxError), e:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   103
                return expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   104
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   105
    def eval(self, ast, expression, value):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   106
        #print "expression %s = %s" % (expression,value)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   107
        pass
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   108
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   109
class ConfigurationBaseRelation(rules.BaseRelation):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   110
    def __init__(self, data, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   111
        self.context = ConfigurationContext(data)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   112
        super(ConfigurationBaseRelation, self).__init__(data, left, right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   113
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   114
class RequireRelation(ConfigurationBaseRelation):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   115
    KEY = 'requires'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   116
    def __init__(self, data, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   117
        super(RequireRelation, self).__init__(data, left, right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   118
        self.context = ConfigurationContext(data)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   119
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   120
class ConfigureRelation(ConfigurationBaseRelation):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   121
    KEY = 'configures'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   122
    def __init__(self, data, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   123
        self.context = ConfigurationContext(data)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   124
        super(ConfigureRelation, self).__init__(data, left, right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   125
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   126
        # A plugin.RelationExecutionResult object is stored here
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   127
        self._execution_result = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   128
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   129
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   130
    def execute(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   131
        self._execution_result = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   132
        exec_results = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   133
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   134
        # Call BaseRelation.execute() and catch any ConfigureExpression result objects
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   135
        self.context.configure_expression_result_callback = lambda result: exec_results.append(result)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   136
        result = rules.BaseRelation.execute(self)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   137
        self.context.configure_expression_result_callback = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   138
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   139
        if len(exec_results) > 0:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   140
            # There should be only one ConfigureExpression inside a ConfigureRelation
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   141
            if len(exec_results) > 1:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   142
                log.warning("Execution of ConfigureRelation returned more than one result, ignoring all except the first")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   143
            self._execution_result = exec_results[0]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   144
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   145
        return result
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   146
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   147
    def get_execution_result(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   148
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   149
        Return the execution result from the most recent call to execute().
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   150
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   151
        return self._execution_result
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   152
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   153
def handle_configure(self, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   154
    if left and right:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   155
        return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   156
    elif not left:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   157
        return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   158
    return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   159
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   160
def handle_set(self, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   161
    left.set_value(right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   162
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   163
def handle_filenamejoin(self, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   164
    def extract_dirname(path):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   165
        """Extract directory name (will always contain a trailing slash or backslash)"""
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   166
        pos = max(path.rfind('/'), path.rfind('\\'))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   167
        if pos == -1:   return path + '/'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   168
        else:           return path[:pos + 1]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   169
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   170
    def extract_filename(path):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   171
        pos = max(path.rfind('/'), path.rfind('\\'))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   172
        if pos == -1:   return path
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   173
        else:           return path[pos + 1:]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   174
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   175
    return extract_dirname(left) + extract_filename(right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   176
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   177
def handle_plus(self, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   178
    return left + right
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   179
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   180
def handle_minus(self, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   181
    return left - right
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   182
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   183
def handle_multiply(self, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   184
    return left * right
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   185
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   186
def handle_divide(self, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   187
    return left / right
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   188
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   189
class ConfigureExpression(rules.TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   190
    PRECEDENCE = rules.PRECEDENCES['RELATION_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   191
    KEY = 'configures'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   192
    OP = handle_configure
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   193
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   194
    def eval(self, context):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   195
        input_refs = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   196
        affected_refs = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   197
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   198
        # Evaluate the left-hand side expression, catching refs for the result
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   199
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   200
            context.ref_terminal_callback = lambda ref: input_refs.append(ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   201
            context.ref_eval_callback = lambda ref: input_refs.append(ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   202
            evaluated_left = self.left.eval(context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   203
        finally:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   204
            context.ref_terminal_callback = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   205
            context.ref_eval_callback = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   206
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   207
        if evaluated_left:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   208
            # If left evaluated to True, evaluate the right-hand side and
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   209
            # catch refs from SetExpression evaluations
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   210
            try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   211
                context.ref_set_callback = lambda ref: affected_refs.append(ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   212
                self.value = self.right.eval(context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   213
            finally:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   214
                context.ref_set_callback = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   215
        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   216
            self.value = True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   217
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   218
        if not self.value:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   219
            left_keys = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   220
            for ref in self.ast.extract_refs(str(self.left)):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   221
                for key in context.get_keys(ref):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   222
                    left_keys.append(key)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   223
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   224
            for key in left_keys:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   225
                self.ast.add_error(key, { 'error_string' : 'CONFIGURES right side value is "False"',
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   226
                                          'left_key' : key,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   227
                                          'rule' : self.ast.expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   228
                                          })
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   229
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   230
        # Return a RelationExecutionResult if necessary
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   231
        if input_refs or affected_refs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   232
            if context.configure_expression_result_callback:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   233
                result = plugin.RelationExecutionResult(utils.distinct_array(input_refs),
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   234
                                                        utils.distinct_array(affected_refs))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   235
                context.configure_expression_result_callback(result)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   236
                
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   237
        return self.value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   238
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   239
class MultiplyExpression(rules.TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   240
    expression = "multiply_operation"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   241
    PRECEDENCE = rules.PRECEDENCES['MULDIV_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   242
    KEY= '*'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   243
    OP = handle_multiply
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   244
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   245
class DivideExpression(rules.TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   246
    expression = "divide_operation"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   247
    PRECEDENCE = rules.PRECEDENCES['MULDIV_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   248
    KEY= '/'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   249
    OP = handle_divide
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   250
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   251
class PlusExpression(rules.TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   252
    expression = "plus_operation"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   253
    PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   254
    KEY= '+'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   255
    OP = handle_plus
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   256
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   257
class MinusExpression(rules.TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   258
    expression = "minus_operation"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   259
    PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   260
    KEY= '-'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   261
    OP = handle_minus
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   262
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   263
class EvalExpression(rules.OneParamExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   264
    expression = "__eval__"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   265
    PRECEDENCE = rules.PRECEDENCES['PREFIX_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   266
    KEY = '__eval__'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   267
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   268
    def __init__(self, ast, expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   269
        super(rules.OneParamExpression, self).__init__(ast)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   270
        self.expression = expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   271
        self._str_to_eval = eval(expression.expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   272
        #self.default_view = default_view
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   273
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   274
    def extract_refs(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   275
        result = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   276
        result.extend(utils.extract_delimited_tokens(self._str_to_eval, delimiters=('${', '}')))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   277
        result.extend(utils.extract_delimited_tokens(self._str_to_eval, delimiters=('@{', '}')))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   278
        return result
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   279
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   280
    def eval(self, context):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   281
        # Using the configuration to pass the eval globals dictionary to here,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   282
        # since there isn't any easy way to do this more elegantly
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   283
        globals_and_locals = {}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   284
        if hasattr(context.data, '_eval_expression_globals_dict'):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   285
            globals_and_locals = context.data._eval_expression_globals_dict
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   286
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   287
        str_to_eval = self._str_to_eval
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   288
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   289
        def expand_feature_ref(ref, index):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   290
            var_name = "__fea_%05d" % index
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   291
            globals_and_locals[var_name] = context.data.get_default_view().get_feature(ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   292
            if context.ref_eval_callback:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   293
                context.ref_eval_callback(ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   294
            return var_name
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   295
        def expand_value_ref(ref, index):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   296
            var_name = "__feaval_%05d" % index
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   297
            globals_and_locals[var_name] = context.data.get_default_view().get_feature(ref).get_value()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   298
            if context.ref_eval_callback:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   299
                context.ref_eval_callback(ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   300
            return var_name
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   301
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   302
        str_to_eval = utils.expand_delimited_tokens(str_to_eval, expand_feature_ref, delimiters=('@{', '}'))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   303
        str_to_eval = utils.expand_delimited_tokens(str_to_eval, expand_value_ref, delimiters=('${', '}'))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   304
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   305
        # Strip leading and trailing whitespace to avoid indentation problems
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   306
        str_to_eval = str_to_eval.strip()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   307
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   308
        ret = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   309
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   310
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   311
            ret = eval(str_to_eval, globals_and_locals)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   312
            return ret
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   313
        except SyntaxError, e:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   314
            logging.getLogger('cone.ruleml').warning("Invalid syntax in eval: %s" % (str_to_eval) )
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   315
            self.ast.add_error(self.expression, { 'error_string' : 'Invalid syntax in eval', 'str_to_eval' : str_to_eval, 'rule' : self.ast.expression })
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   316
        except Exception, e:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   317
            logging.getLogger('cone.ruleml').warning("Execution failed for eval: %s %s: %s" % (str_to_eval, type(e), e) )
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   318
            self.ast.add_error(self.expression, { 'error_string' : 'Execution failed for eval', 'str_to_eval' : str_to_eval, 'rule' : self.ast.expression })
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   319
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   320
rules.OPERATORS[EvalExpression.KEY] = EvalExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   321
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   322
class FilenamejoinExpression(rules.TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   323
    expression = "filenamejoin"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   324
    PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   325
    KEY = 'filenamejoin'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   326
    OP = handle_filenamejoin
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   327
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   328
rules.OPERATORS[FilenamejoinExpression.KEY] = FilenamejoinExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   329
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   330
class SetExpression(rules.TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   331
    PRECEDENCE = rules.PRECEDENCES['SET_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   332
    KEY= '='
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   333
    OP = handle_set
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   334
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   335
    def eval(self, context):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   336
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   337
            variable = context.data.get_default_view().get_feature(self.left.expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   338
            value = self.right.eval(context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   339
            variable.set_value(value)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   340
            logging.getLogger('cone.ruleml').info("Set %r = %r from %r" % (self.left.expression, value, self.right.expression) )
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   341
            if context.ref_set_callback:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   342
                context.ref_set_callback(self.left.expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   343
            return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   344
        except exceptions.NotFound,e:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   345
            self.ast.add_error(self.left.expression, { 'error_string' : 'Setting value failed, because of %s' % e,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   346
                               'left_key' : self.left.expression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   347
                               'rule' : self.ast.expression})
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   348
            return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   349
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   350
_relations_and_operators_backup = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   351
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   352
def register():
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   353
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   354
    Register the relations and operators to ConE rules.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   355
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   356
    global _relations_and_operators_backup
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   357
    if _relations_and_operators_backup is None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   358
        # Create the backup copies of the dictionaries
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   359
        rels_backup = rules.RELATIONS.copy()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   360
        ops_backup = rules.OPERATORS.copy()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   361
        assert rels_backup is not rules.RELATIONS
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   362
        assert ops_backup is not rules.OPERATORS
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   363
        _relations_and_operators_backup = (rels_backup, ops_backup)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   364
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   365
        # Register relations and operators to rules
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   366
        rules.RELATIONS[RequireRelation.KEY] = RequireRelation
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   367
        rules.RELATIONS[ConfigureRelation.KEY] = ConfigureRelation
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   368
        rules.OPERATORS[ConfigureExpression.KEY] = ConfigureExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   369
        rules.OPERATORS[PlusExpression.KEY] = PlusExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   370
        rules.OPERATORS[SetExpression.KEY] = SetExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   371
        rules.OPERATORS[MinusExpression.KEY] = MinusExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   372
        rules.OPERATORS[MultiplyExpression.KEY] = MultiplyExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   373
        rules.OPERATORS[DivideExpression.KEY] = DivideExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   374
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   375
def unregister():
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   376
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   377
    Undo the changes made by a call to register().
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   378
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   379
    global _relations_and_operators_backup
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   380
    if _relations_and_operators_backup is not None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   381
        rules.RELATIONS = _relations_and_operators_backup[0]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   382
        rules.OPERATORS = _relations_and_operators_backup[1]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   383
        _relations_and_operators_backup = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   384
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   385
def parse_rule(rulestring):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   386
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   387
    Divide the given rule string into (left side, relation, right side) components. 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   388
    @return: Triple (left side, relation, right side)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   389
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   390
    left_expression = ''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   391
    relation_name = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   392
    right_expression = ''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   393
    for token in rules.get_tokens(rulestring):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   394
        if relation_name == None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   395
            if token in rules.RELATIONS.keys():
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   396
                relation_name = token
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   397
            else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   398
                left_expression += ' ' + token
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   399
        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   400
            right_expression += ' ' + token
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   401
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   402
    if relation_name == None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   403
        raise exceptions.ParseError('invalid rule definition %s' % rulestring)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   404
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   405
    return (left_expression,relation_name,right_expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   406