configurationengine/source/cone/public/rules.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
import operator as ops
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    18
import logging
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    19
import tokenize
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    20
from token import ENDMARKER, NAME, ERRORTOKEN
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    21
import StringIO
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    22
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    23
from cone.public import container
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    24
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    25
RELATIONS = {}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    26
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    27
def abstract():
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    28
    import inspect
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    29
    caller = inspect.getouterframes(inspect.currentframe())[1][3]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    30
    raise NotImplementedError(caller + ' needs to be implemented')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    31
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    32
def get_tokens(tokenstr):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    33
    result = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    34
    tokens = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    35
    tokenstr = tokenstr.replace('\r', '')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    36
    name_buffer = [] # Temp buffer for reading name tokens
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    37
    last_epos = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    38
    for toknum, tokval, spos, epos, _  in tokenize.generate_tokens(StringIO.StringIO(unicode(tokenstr)).readline):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    39
        #print "toknum: %r, tokval: %r, spos: %r, epos: %r" % (toknum, tokval, spos, epos)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    40
        val = tokval.strip('\r\n\t ')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    41
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    42
        if toknum == ENDMARKER and name_buffer:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    43
            tokens.append(''.join(name_buffer))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    44
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    45
        # Ignore whitespace (this ignores also the end marker,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    46
        # since its value is empty)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    47
        if val == '': continue
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    48
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    49
        # Put NAME, and ERRORTOKEN tokens through the temp
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    50
        # buffer
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    51
        if toknum in (NAME, ERRORTOKEN):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    52
            # If this and the previous token in the temp buffer are not adjacent,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    53
            # they belong to separate tokens
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    54
            if name_buffer and spos[1] != last_epos[1]:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    55
                tokens.append(''.join(name_buffer))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    56
                name_buffer = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    57
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    58
            name_buffer.append(val)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    59
            last_epos = epos
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    60
        # Other tokens can just go directly to the token list
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    61
        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    62
            if name_buffer:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    63
                tokens.append(''.join(name_buffer))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    64
                name_buffer = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    65
            tokens.append(val)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    66
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    67
    while len(tokens) > 0:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    68
        val = tokens.pop(0)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    69
        # Join the refs with dot in between them to make them dotted refs
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    70
        if val == '.':
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    71
            newval = ".".join([result.pop(),tokens.pop(0)])
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    72
            result.append( newval )
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    73
        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    74
            result.append( val )
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    75
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    76
    return result
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    77
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    78
class RelationException(Exception):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    79
    pass
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    80
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    81
#### The containers are here ####
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    82
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    83
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    84
class RelationBase(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    85
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    86
    RelationBase defines a base class for all named relations that can be applied between objects. 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    87
    e.g. Relation depends, that can be applied in Rule
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    88
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    89
    relation_name = "RelationBase"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    90
    def __init__(self, data, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    91
        self.description = ""
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    92
        self.data = data or container.DataContainer()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    93
        self.left = left
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    94
        self.right = right
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    95
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    96
    def __str__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    97
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    98
        @return: A string presentation of the relation object
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    99
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   100
        return "%s %s %s" % (self.left,self.relation_name,self.right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   101
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   102
    def get_name(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   103
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   104
        @return: The relation name.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   105
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   106
        return self.relation_name
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   107
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   108
    def get_description(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   109
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   110
        @return: a possible description of the relation.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   111
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   112
        return self.description
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   113
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   114
    def execute(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   115
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   116
        Execute the relation object.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   117
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   118
        pass
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   119
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   120
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   121
class RelationContainer(RelationBase, list):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   122
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   123
    This class provides the RelationContainer interface for collecting
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   124
    relation sets into one place which can be executed through the container.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   125
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   126
    def __init__(self, data=None):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   127
        super(RelationContainer, self).__init__(data, 'LContainer', 'RContainer')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   128
        self.value_list = list()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   129
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   130
    def append(self, value):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   131
        self.value_list.append(value)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   132
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   133
    def __iter__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   134
        return self.value_list.__iter__()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   135
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   136
    def __len__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   137
        return len(self.value_list)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   138
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   139
    def __or__(self, other):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   140
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   141
        This function adds two RelationContainers to each other and removes
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   142
        duplicates from the result.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   143
        The modification is inplace and the returned value is called object.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   144
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   145
        self.value_list = set(self.value_list) | set(other.value_list)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   146
        return self
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   147
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   148
    def __unicode__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   149
        if self:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   150
            ret = ''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   151
            for value in self:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   152
                ret += unicode(value)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   153
        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   154
            ret = 'No relations'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   155
        return ret
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   156
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   157
    def find_relations(self, refs): abstract()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   158
    def add_relation(self, relation): abstract()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   159
    def has_errors(self): abstract()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   160
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   161
class RelationContainerImpl(RelationContainer):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   162
    """ Base implementation for RelationContainer to use in ConE rules
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   163
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   164
    def execute(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   165
        ret = True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   166
        i = 0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   167
        for relation in self:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   168
            i += 1
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   169
            r = relation.execute()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   170
            ret = ret and r
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   171
        return ret
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   172
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   173
    def find_relations(self, refs):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   174
        relations = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   175
        for ref in refs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   176
            for relation in self:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   177
                if relation.has_ref(ref):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   178
                    relations.append(relation)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   179
        return relations
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   180
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   181
    def add_relation(self, relation):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   182
        self.append(relation)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   183
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   184
    def has_ref(self, refs):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   185
        for ref in refs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   186
            for relation in self:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   187
                if relation.has_ref(ref):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   188
                    return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   189
        return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   190
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   191
    def has_errors(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   192
        for relation in self:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   193
            if relation.has_errors():
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   194
                return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   195
        return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   196
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   197
    def get_errors(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   198
        errors = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   199
        for relation in self:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   200
            errors += relation.get_errors()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   201
        return errors
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   202
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   203
#### The relations are here ####
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   204
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   205
class BaseRelation(RelationBase):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   206
    """ BaseRelation implements the basic evaluation logic for relations
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   207
    This class abstract and should be extended for concrete implementation of
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   208
    relation type.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   209
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   210
    Subclasses need to set their own context in their constructor before this
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   211
    class's constructor is called if custom context is needed. If context not
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   212
    set then DefaultContext is used.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   213
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   214
    KEY = 'base_relation'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   215
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   216
    def __init__(self, data, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   217
        # Context needs to be overridden for special purposes
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   218
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   219
            self.__getattribute__('context')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   220
        except AttributeError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   221
            self.context = DefaultContext(data)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   222
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   223
        left = self.expand_rule_elements(left)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   224
        right = self.expand_rule_elements(right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   225
        super(BaseRelation, self).__init__(data, left, right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   226
        self.interpreter = ASTInterpreter(context=self.context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   227
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   228
    def execute(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   229
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   230
        @return Returns error dictionary
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   231
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   232
        In the client code proper way to check if the rule applies:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   233
        info = relation.execute()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   234
        if not info.has_errors():
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   235
        else: HANDLE ERRORS
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   236
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   237
        # logger.debug("Interpreter context %s" % self.interpreter.context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   238
        self.interpreter.create_ast('%s %s %s' % (self.left, self.KEY, self.right))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   239
        ret = self.interpreter.eval()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   240
        return ret
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   241
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   242
    def get_keys(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   243
        """ Returns the references from this relation.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   244
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   245
        refs = ASTInterpreter.extract_refs(self.left)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   246
        refs += ASTInterpreter.extract_refs(self.right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   247
        return refs
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   248
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   249
    def has_ref(self, ref):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   250
        """ Returns if the 'ref' is included in this relation
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   251
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   252
        return ref in self.get_keys()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   253
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   254
    def has_errors(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   255
        return bool(self.interpreter.errors)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   256
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   257
    def get_refs(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   258
        return (ASTInterpreter.extract_refs(self.left), ASTInterpreter.extract_refs(self.right))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   259
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   260
    def _eval_rside_value(self, value): abstract()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   261
    def _compare_value(self, value): abstract()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   262
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   263
    def extract_erroneus_features_with_values(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   264
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   265
        Extract references who have errors.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   266
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   267
        Returns dictionary { 'reference' : 'value' }
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   268
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   269
        data_dict = {}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   270
        for ref in ASTInterpreter.extract_refs(self.right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   271
            value = self.data.get_feature(ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   272
            if self._compare_value(value):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   273
                data_dict[ref] = value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   274
            elif value == None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   275
                data_dict[ref] = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   276
        return data_dict
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   277
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   278
    def get_errors(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   279
        return self.interpreter.errors
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   280
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   281
    def expand_rule_elements(self, rule):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   282
        """ Expans rule elements base on the reference.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   283
        Context is used for fetching the child elements for parent references
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   284
        which uses asterisk identifier for selecting all child features: 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   285
        'parent_feature.*' -> 'child_fea_1 and child_fea_2'.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   286
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   287
        tokens = get_tokens(rule) # [token for token in rule.split()]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   288
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   289
        expanded_rule = ""
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   290
        for token in tokens:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   291
            if token.endswith('.*'):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   292
                index = token.index('.*')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   293
                parent_ref = token[:index]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   294
                children = self.context.get_children_for_reference(parent_ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   295
                expanded_element = ' and '.join([child.reference for child in children])
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   296
                if expanded_rule:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   297
                    expanded_rule = '%s and %s' % (expanded_rule, expanded_element.rstrip())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   298
                else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   299
                    expanded_rule = expanded_element.rstrip()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   300
            elif token.lower() in OPERATORS:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   301
                expanded_rule += ' %s ' % token
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   302
            else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   303
                if expanded_rule:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   304
                    expanded_rule += '%s'% token
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   305
                else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   306
                    expanded_rule = token
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   307
        return expanded_rule.strip()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   308
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   309
class RequireRelation(BaseRelation):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   310
    KEY = 'requires'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   311
RELATIONS[RequireRelation.KEY] = RequireRelation
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   312
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   313
class ExcludesRelation(BaseRelation):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   314
    KEY = 'excludes'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   315
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   316
RELATIONS['excludes'] = ExcludesRelation
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   317
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   318
################################
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   319
# Abstract syntax tree builder #
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   320
################################
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   321
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   322
def nor(expression, a, b):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   323
    return not ops.or_(a, b)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   324
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   325
def nand(expression, a, b):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   326
    return not ops.and_(a, b)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   327
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   328
def truth_and(expression, a, b):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   329
    return ops.truth(a) and ops.truth(b)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   330
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   331
class DefaultContext(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   332
    """ DefaultContext implements ConE specific context for handling rules
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   333
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   334
    def __init__(self, data):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   335
        self.data = data
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   336
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   337
    def eval(self, ast, expression, value):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   338
        pass
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   339
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   340
    def get_keys(self, refs):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   341
        return ASTInterpreter.extract_refs(refs)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   342
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   343
    def get_children_for_reference(self, reference):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   344
        # implement ConE specific children expansion
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   345
        pass
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   346
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   347
    def handle_terminal(self, expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   348
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   349
            return int(expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   350
        except:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   351
            return expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   352
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   353
PRECEDENCES = {
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   354
    'PREFIX_OPERATORS' : 10,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   355
    'MULDIV_OPERATORS' : 8,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   356
    'ADDSUB_OPERATORS' : 7,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   357
    'SHIFT_OPERATORS' : 6,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   358
    'BITWISE_OPERATORS' : 5,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   359
    'COMPARISON_OPERATORS' : 4,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   360
    'SET_OPERATORS' : 3,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   361
    'BOOLEAN_OPERATORS' : 2, 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   362
    'RELATION_OPERATORS' : 1,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   363
    'NOT_DEFINED' : 0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   364
}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   365
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   366
class Expression(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   367
    PRECEDENCE = PRECEDENCES['NOT_DEFINED']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   368
    KEY = 'base_expression'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   369
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   370
    def __init__(self, ast):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   371
        self.ast = ast
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   372
        self.value = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   373
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   374
    def get_title(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   375
        return self.KEY
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   376
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   377
    def eval(self, context): pass
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   378
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   379
class OneParamExpression(Expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   380
    PARAM_COUNT = 1
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   381
    def __init__(self, ast, expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   382
        super(OneParamExpression, self).__init__(ast)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   383
        self.expression = expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   384
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   385
    def __unicode__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   386
        return u'%s %s' % (self.KEY, self.expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   387
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   388
    def eval(self, context):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   389
        self.value = self.OP(self.expression.eval(context))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   390
        context.eval(self.ast, self, self.value)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   391
        return self.value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   392
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   393
class TwoOperatorExpression(Expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   394
    PARAM_COUNT = 2
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   395
    OP = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   396
    EVAL_AS_BOOLS = True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   397
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   398
    def __init__(self, ast, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   399
        super(TwoOperatorExpression, self).__init__(ast)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   400
        self.left = left
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   401
        self.right = right
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   402
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   403
    def __unicode__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   404
        return u'%s %s %s' % (self.left, self.KEY, self.right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   405
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   406
    def eval(self, context):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   407
        self.value = self.OP(self.left.eval(context), self.right.eval(context))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   408
        context.eval(self.ast, self, self.value)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   409
        return self.value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   410
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   411
class TwoOperatorBooleanExpression(TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   412
    def eval(self, context):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   413
        self.value = self.OP(bool(self.left.eval(context)), bool(self.right.eval(context)))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   414
        context.eval(self.ast, self, self.value)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   415
        return self.value         
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   416
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   417
class TerminalExpression(Expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   418
    KEY = 'terminal'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   419
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   420
    def __init__(self, ast, expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   421
        super(TerminalExpression, self).__init__(ast)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   422
        self.expression = expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   423
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   424
    def eval(self, context):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   425
        """ Use context to eval the value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   426
        Expression on TerminalExpression is feature reference or value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   427
        context should handle the reference conversion to correct value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   428
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   429
        self.value = context.handle_terminal(self.expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   430
        return self.value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   431
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   432
    def __unicode__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   433
        return self.expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   434
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   435
    def __repr__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   436
        return self.expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   437
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   438
class NegExpression(OneParamExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   439
    PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   440
    KEY= '-'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   441
    OP = ops.neg
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   442
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   443
class AndExpression(TwoOperatorBooleanExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   444
    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   445
    KEY= 'and'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   446
    OP = truth_and
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   447
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   448
class NandExpression(TwoOperatorBooleanExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   449
    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   450
    KEY = 'nand'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   451
    OP = nand
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   452
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   453
class OrExpression(TwoOperatorBooleanExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   454
    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   455
    KEY = 'or'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   456
    OP = ops.or_
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   457
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   458
class XorExpression(TwoOperatorBooleanExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   459
    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   460
    KEY = 'xor'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   461
    OP = ops.xor
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   462
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   463
class NorExpression(TwoOperatorBooleanExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   464
    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   465
    KEY = 'nor'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   466
    OP = nor
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   467
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   468
class EqualExpression(TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   469
    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   470
    KEY = '=='
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   471
    OP = ops.eq
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   472
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   473
class NotEqualExpression(TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   474
    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   475
    KEY = '!='
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   476
    OP = ops.ne
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   477
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   478
class LessThanExpression(TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   479
    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   480
    KEY = '<'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   481
    OP = ops.lt
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   482
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   483
class GreaterThanExpression(TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   484
    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   485
    KEY = '>'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   486
    OP = ops.gt
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   487
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   488
class LessThanEqualExpression(TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   489
    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   490
    KEY = '<='
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   491
    OP = ops.le
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   492
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   493
class GreaterThanEqualExpression(TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   494
    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   495
    KEY = '>='
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   496
    OP = ops.ge
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   497
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   498
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   499
def handle_require(expression, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   500
    if left and right:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   501
        return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   502
    elif not left:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   503
        return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   504
    return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   505
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   506
class RequireExpression(TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   507
    PRECEDENCE = PRECEDENCES['RELATION_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   508
    KEY = 'requires'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   509
    OP = handle_require
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   510
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   511
    def eval(self, context):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   512
        super(RequireExpression, self).eval(context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   513
        if not self.value:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   514
            left_keys = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   515
            for ref in self.ast.extract_refs(unicode(self.left)):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   516
                for key in context.get_keys(ref):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   517
                    left_keys.append(key)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   518
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   519
            for key in left_keys:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   520
                self.ast.add_error(key, { 'error_string' : 'REQUIRES right side value is "False"',
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   521
                                          'left_key' : key,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   522
                                          'rule' : self.ast.expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   523
                                          })
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   524
        return self.value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   525
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   526
def handle_exclude(expression, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   527
    if left and not right:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   528
        return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   529
    elif not left:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   530
        return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   531
    return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   532
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   533
class ExcludeExpression(TwoOperatorExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   534
    PRECEDENCE = PRECEDENCES['RELATION_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   535
    KEY = 'excludes'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   536
    OP = handle_exclude
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   537
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   538
    def eval(self, context):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   539
        super(ExcludeExpression, self).eval(context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   540
        if not self.value:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   541
            left_keys = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   542
            for ref in self.ast.extract_refs(unicode(self.left)):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   543
                for key in context.get_keys(ref):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   544
                    left_keys.append(key)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   545
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   546
            for key in left_keys:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   547
                self.ast.add_error(key, { 'error_string' : 'EXCLUDE right side value is "True"',
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   548
                                          'left_key' : key,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   549
                                          'rule' : self.ast.expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   550
                                          })
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   551
        return self.value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   552
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   553
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   554
class NotExpression(OneParamExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   555
    PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   556
    KEY = 'not'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   557
    OP = ops.not_
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   558
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   559
class TruthExpression(OneParamExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   560
    PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   561
    KEY = 'truth'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   562
    OP = ops.truth
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   563
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   564
LEFT_PARENTHESIS = '('
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   565
RIGHT_PARENTHESIS = ')'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   566
class SimpleCondition(EqualExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   567
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   568
    A simple condition object that can refer to a model object and evaluate if the value matches  
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   569
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   570
    def __init__(self, left, right):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   571
        lterm = TerminalExpression(None, left)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   572
        rterm = TerminalExpression(None, right)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   573
        EqualExpression.__init__(self, None, lterm, rterm)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   574
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   575
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   576
# in format KEY : OPERATOR CLASS
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   577
OPERATORS = {
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   578
    'and' : AndExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   579
    'nand' : NandExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   580
    'or' : OrExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   581
    'xor' : XorExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   582
    'nor' : NorExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   583
    'not' : NotExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   584
    'truth' : TruthExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   585
    '==' : EqualExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   586
    '!=' : NotEqualExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   587
    '<' : LessThanExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   588
    '>' : GreaterThanExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   589
    '<=' : LessThanEqualExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   590
    '>=' : GreaterThanEqualExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   591
    'requires' : RequireExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   592
    'excludes' : ExcludeExpression,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   593
    '-' : NegExpression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   594
    }
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   595
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   596
def add_operator(key, operator_class=None, baseclass=RequireExpression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   597
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   598
    Add new operator key and operator class.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   599
    If operator class isn't provided the baseclass parameter is used as
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   600
    operator base. The baseclass parameter is RequireExpression by default
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   601
    which has success condition left_rule=True and right_rule=True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   602
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   603
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   604
    OPERATORS[key] = operator_class or create_new_class(key, baseclass)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   605
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   606
def create_new_class(key, baseclass):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   607
    ns = baseclass.__dict__.copy()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   608
    ns['KEY'] = key
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   609
    key_pieces = key.split('_')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   610
    class_prefix = ''.join([key_piece.capitalize() for key_piece in key_pieces])
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   611
    new_class = type(class_prefix + 'Expression', (baseclass,), ns)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   612
    return new_class
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   613
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   614
class ParseException(Exception): pass
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   615
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   616
class ASTInterpreter(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   617
    def __init__(self, infix_expression=None, context=None):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   618
        """ Takes infix expression as string """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   619
        self.context = context or DefaultContext(None)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   620
        # logger.debug("AST init context: %s" % self.context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   621
        self._init_locals(infix_expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   622
        if infix_expression:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   623
            self.create_ast()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   624
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   625
    def _init_locals(self, infix_expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   626
        # The result value of full eval of the parse_tree
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   627
        self.value = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   628
        self.warnings = {}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   629
        self.errors = {}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   630
        self.postfix_array = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   631
        self.parse_tree = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   632
        self.expression = infix_expression
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   633
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   634
    def __unicode__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   635
        s = ''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   636
        for expr in self.parse_tree:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   637
            s += unicode(expr)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   638
        return s
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   639
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   640
    def add_error(self, key, error_dict):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   641
        if self.errors.has_key(key):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   642
            self.errors[key].append(error_dict)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   643
        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   644
            self.errors[key] = [error_dict]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   645
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   646
    def create_ast(self, infix_expression=None):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   647
        if infix_expression:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   648
            self._init_locals(infix_expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   649
        self._infix_to_postfix()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   650
        self._create_parse_tree()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   651
        return self.parse_tree
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   652
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   653
    def _infix_to_postfix(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   654
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   655
        Shunting yard algorithm used to convert infix presentation to postfix.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   656
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   657
        if not self.expression:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   658
            raise ParseException('Expression is None')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   659
        tokens = get_tokens(self.expression) # [token for token in self.expression.split()]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   660
        stack = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   661
        # logger.debug('TOKENS: %s' % tokens)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   662
        for token in tokens:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   663
            # logger.debug('TOKEN: %s' % token)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   664
            if token.lower() in OPERATORS:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   665
                op_class = OPERATORS.get(token)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   666
                if stack:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   667
                    while len(stack) != 0:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   668
                        top = stack[-1]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   669
                        if top in OPERATORS:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   670
                            top_operator = OPERATORS.get(top)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   671
                            if op_class.PRECEDENCE <= top_operator.PRECEDENCE:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   672
                                self.postfix_array.append(stack.pop())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   673
                            else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   674
                                # Break from loop if top operator precedence is less.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   675
                                break
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   676
                        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   677
                            # If top not operator break from loop
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   678
                            break
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   679
                stack.append(token)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   680
            elif token == LEFT_PARENTHESIS:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   681
                # logger.debug('Left parenthesis')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   682
                stack.append(token)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   683
            elif token == RIGHT_PARENTHESIS:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   684
                # logger.debug('Right parenthesis')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   685
                left_par_found = False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   686
                stack_token = stack.pop()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   687
                while stack_token:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   688
                    if stack_token != LEFT_PARENTHESIS:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   689
                        self.postfix_array.append(stack_token)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   690
                    else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   691
                        left_par_found = True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   692
                        break
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   693
                    if stack:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   694
                        stack_token = stack.pop()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   695
                    else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   696
                        stack_token = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   697
                        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   698
                if not left_par_found:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   699
                    raise ParseException('Mismatched parenthesis "%s".' % LEFT_PARENTHESIS)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   700
            else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   701
                # logger.debug('Adding value to output. %s' % repr((token)))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   702
                self.postfix_array.append((token))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   703
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   704
        # There should be only operators left in the stack
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   705
        if stack:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   706
            # logger.debug('Operators in stack.')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   707
            operator = stack.pop()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   708
            while operator:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   709
                if operator != LEFT_PARENTHESIS:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   710
                    self.postfix_array.append(operator)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   711
                else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   712
                    raise ParseException('Mismatched parenthesis "%s".' % LEFT_PARENTHESIS)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   713
                if stack:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   714
                    operator = stack.pop()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   715
                else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   716
                    operator = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   717
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   718
        # logger.debug('Infix to postfix conversion: %s' % self.postfix_array)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   719
        return self.postfix_array
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   720
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   721
    def _create_parse_tree(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   722
        self.parse_tree = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   723
        for token in self.postfix_array:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   724
            if token in OPERATORS:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   725
                # logger.debug('OP: %s' % (token))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   726
                expression_class = OPERATORS[token]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   727
                params = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   728
                for i in range(expression_class.PARAM_COUNT):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   729
                    try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   730
                        params.append(self.parse_tree.pop())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   731
                    except IndexError, e:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   732
                        raise ParseException('Syntax error: "%s"' % self.expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   733
                params.reverse()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   734
                expression = expression_class(self, *params)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   735
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   736
                # logger.debug('The operation: %s' % expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   737
                self.parse_tree.append(expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   738
            else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   739
                expression = TerminalExpression(self, token)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   740
                self.parse_tree.append(expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   741
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   742
        #logger.debug('THE STACK: %s' % self.parse_tree)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   743
        #for s in self.parse_tree:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   744
        #    logger.debug('Stack e: %s' % str(s))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   745
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   746
        return self.parse_tree
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   747
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   748
    def eval(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   749
        """ Evals the AST
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   750
        If empty expression is given, None is returned
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   751
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   752
        for expression in self.parse_tree:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   753
            self.value = expression.eval(self.context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   754
        return self.value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   755
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   756
    @staticmethod
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   757
    def extract_refs(expression):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   758
        tokens = get_tokens(expression)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   759
        refs = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   760
        for token in tokens:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   761
            if not token.lower() in OPERATORS and token != LEFT_PARENTHESIS and token != RIGHT_PARENTHESIS:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   762
                refs.append(token.strip('%s%s' % (LEFT_PARENTHESIS, RIGHT_PARENTHESIS)))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   763
        return refs
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   764
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   765
##################################################################
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   766
# Create and configure the main level logger
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   767
logger = logging.getLogger('cone')