configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/ruleml.py
author m2lahtel
Wed, 08 Sep 2010 12:20:56 +0300
changeset 4 0951727b8815
parent 3 e7e0ae78773e
permissions -rw-r--r--
Updated to 1.2.13 release
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
     1
#
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
     2
# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
     3
# All rights reserved.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
     4
# This component and the accompanying materials are made available
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
     5
# under the terms of "Eclipse Public License v1.0"
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
     6
# which accompanies this distribution, and is available
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
     7
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
     8
#
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
     9
# Initial Contributors:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    10
# Nokia Corporation - initial contribution.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    11
#
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    12
# Contributors:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    13
#
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    14
# Description: 
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    15
#
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    16
'''
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    17
Legacy RuleML plug-in to support RuleML 1 and 2 after rule engine changes
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    18
in cone.public.rules. The new RuleML version is 3, and it uses the setting
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    19
reference format ${MyFeature.MySetting} in the rules.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    20
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    21
The rule engine (rules.py) before the change is contained in this plug-in.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    22
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    23
NOTE THAT THIS PLUG-IN WILL NOT BE MAINTAINED, ALL NEW DEVELOPMENT SHOULD
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    24
HAPPEN IN THE NEW RULE PLUG-IN. IF NEW FUNCTIONALITY IS REQUIRED IN AN
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    25
EXISTING RULEML FILE, THE CHANGES SHOULD BE MADE TO THE NEW RULE PLUG-IN
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    26
AND THE EXISTING RULEML FILE CONVERTED TO RULEML 3.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    27
'''
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    28
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    29
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    30
import os
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    31
import sys
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    32
import logging
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    33
import shutil
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    34
import pkg_resources
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    35
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    36
import __init__
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    37
import re
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    38
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    39
from legacyruleplugin import relations, rules
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    40
from cone.public import exceptions,plugin,utils,api
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    41
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    42
class RuleImpl(plugin.ImplBase):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    43
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    44
    MakeImpl plugin finds feature references that are configured in a .ruleml file
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    45
    and generate a rule from them
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    46
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    47
    IMPL_TYPE_ID = 'ruleml'
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    48
    DEFAULT_INVOCATION_PHASE = 'pre'
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    49
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    50
    def __init__(self, ref, configuration, relation_container):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    51
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    52
        Overloading the default constructor
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    53
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    54
        plugin.ImplBase.__init__(self,ref,configuration)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    55
        self.relation_container = relation_container
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    56
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    57
    def list_output_files(self):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    58
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    59
        Return a list of output files as an array. 
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    60
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    61
        return []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    62
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    63
    def generate(self, context=None):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    64
        relation_container = self.get_relation_container()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    65
        relation_container.context = context
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    66
        return relation_container.execute(context)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    67
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    68
    def has_tag(self, tags, policy=None):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    69
        # RuleML should always be executed, regardless of the tags
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    70
        return True
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    71
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    72
    def get_relation_container(self):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    73
        return self.relation_container
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    74
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    75
    def get_refs(self):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    76
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    77
        Return a list of all ConfML setting references that affect this
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    78
        implementation. May also return None if references are not relevant
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    79
        for the implementation.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    80
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    81
        refs = []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    82
        relations = self.get_relations()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    83
        for relation in relations:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    84
            # get refs from relation return a tuple (left side refs, right side refs)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    85
            # only the left side refs are the "input" refs  
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    86
            refs += relation.get_refs()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    87
        # If the rules do not have any references return None to disable filter by refs 
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    88
        if refs == []: 
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    89
            refs = None
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    90
        return refs
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    91
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    92
    def get_relations(self):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    93
        return self.relation_container.get_relations()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    94
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    95
class RuleBuiltinsModule(object):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    96
    pass
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    97
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    98
class RulemlRelationContainer(plugin.RelationContainer):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    99
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   100
    Relation container for RuleML rules.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   101
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   102
    Basically this is a wrapper for rules.RelationContainer that adapts
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   103
    it to the interface of plugin.RelationContainer.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   104
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   105
    def __init__(self, configuration, source, rule_list, eval_globals):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   106
        plugin.RelationContainer.__init__(self, configuration, source=source)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   107
        self.configuration = configuration
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   108
        self.relation_container = rules.RelationContainerImpl()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   109
        self.eval_globals = eval_globals
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   110
        self.context = None
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   111
        for rule in rule_list:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   112
            self.relation_container.add_relation(rule)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   113
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   114
    def execute(self, context=None):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   115
        results = []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   116
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   117
        # Create the autoconfig if not done already
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   118
        autoconfig = plugin.get_autoconfig(self.configuration)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   119
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   120
        # Register relations etc. to the rule engine.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   121
        # Due to unit test issues the relations are not registered
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   122
        # in the relations module, but only for the duration of
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   123
        # rule parsing and execution
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   124
        relations.register()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   125
        try:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   126
            # Using the configuration to pass the eval globals dict to the
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   127
            # eval expression. The configuration only contains the globals
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   128
            # dict for the duration of the rule execution, so hopefully this
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   129
            # shouldn't mess anything up
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   130
            self._set_builtin_eval_globals()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   131
            context._eval_expression_globals_dict = self.eval_globals
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   132
            for i, rel in enumerate(self.relation_container):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   133
                index = i + 1
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   134
                
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   135
                # Execute
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   136
                self._execute_relation_and_log_error(rel, self.source, index, context)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   137
                
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   138
                # Collect execution result if supported
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   139
                if hasattr(rel, 'get_execution_result'):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   140
                    result = rel.get_execution_result()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   141
                    if isinstance(result, plugin.RelationExecutionResult):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   142
                        result.source = self.source
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   143
                        result.index = index
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   144
                        results.append(result)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   145
            
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   146
            del context._eval_expression_globals_dict
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   147
            
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   148
            if self.relation_container.has_errors():
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   149
                for error in self.relation_container.get_errors():
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   150
                    logging.getLogger('cone.ruleml_relation_container(%s)' % self.source).error(error)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   151
            
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   152
            if self.context:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   153
                self.context.results += results
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   154
            return results
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   155
        finally:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   156
            relations.unregister()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   157
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   158
    def get_relation_count(self):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   159
        return len(self.relation_container)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   160
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   161
    def get_relations(self):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   162
        return list(self.relation_container)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   163
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   164
    def _set_builtin_eval_globals(self):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   165
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   166
        Add built-in attributes into the eval globals dictionary.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   167
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   168
                
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   169
        builtins = RuleBuiltinsModule()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   170
        builtins.configuration = self.configuration
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   171
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   172
        self.eval_globals['ruleml'] = builtins
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   173
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   174
class RuleImplReaderBase(plugin.ReaderBase):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   175
    NAMESPACE = None # Used as a base class, so should have no namespace
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   176
    FILE_EXTENSIONS = ['ruleml']
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   177
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   178
    def __init__(self, resource_ref, configuration):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   179
        self.resource_ref = resource_ref
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   180
        self.configuration = configuration
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   181
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   182
    @classmethod
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   183
    def read_impl(cls, resource_ref, configuration, etree):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   184
        reader = cls(resource_ref, configuration)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   185
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   186
        # Register relations etc. to the rule engine.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   187
        # Due to unit test issues the relations are not registered
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   188
        # in the relations module, but only for the duration of
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   189
        # rule parsing and execution
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   190
        relations.register()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   191
        try:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   192
            rules = reader.parse_rules(resource_ref, etree)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   193
            eval_globals = reader.parse_eval_globals(etree)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   194
            lineno = utils.etree.get_lineno(etree)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   195
            
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   196
            # Create an ImplContainer to hold each rule as its own
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   197
            # RuleML implementation
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   198
            main_impl = plugin.ImplContainer(resource_ref, configuration)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   199
            main_impl.lineno = lineno
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   200
            
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   201
            for rule in rules:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   202
                relation_container = RulemlRelationContainer(
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   203
                    configuration   = configuration,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   204
                    source          = "%s:%d" % (resource_ref, rule.lineno),
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   205
                    rule_list       = [rule],
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   206
                    eval_globals    = eval_globals)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   207
            
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   208
                impl = RuleImpl(resource_ref, configuration, relation_container)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   209
                impl.lineno = rule.lineno
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   210
                rule.implml = impl
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   211
                
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   212
                main_impl.append(impl)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   213
        finally:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   214
            relations.unregister()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   215
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   216
        return main_impl
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   217
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   218
class RuleImplReader1(RuleImplReaderBase):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   219
    NAMESPACE = 'http://www.s60.com/xml/ruleml/1'
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   220
    NAMESPACE_ID = 'ruleml1'
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   221
    ROOT_ELEMENT_NAME = 'ruleml'
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   222
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   223
    def __init__(self, resource_ref, configuration):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   224
        RuleImplReaderBase.__init__(self, resource_ref, configuration)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   225
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   226
    @classmethod
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   227
    def get_schema_data(cls):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   228
        return pkg_resources.resource_string('legacyruleplugin', 'xsd/ruleml.xsd')
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   229
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   230
    def parse_rules(self, ref, etree):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   231
        rules = []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   232
        for elem in etree.getiterator("{%s}rule" % self.NAMESPACE):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   233
            lineno = utils.etree.get_lineno(elem)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   234
            for rule in relations.RelationFactory.get_relations(self.configuration, elem.text):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   235
                rule.ref = ref
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   236
                rule.lineno = lineno
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   237
                rules.append(rule)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   238
        return rules
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   239
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   240
    def parse_eval_globals(self, etree):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   241
        return {}
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   242
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   243
class RuleImplReader2(RuleImplReaderBase):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   244
    NAMESPACE = 'http://www.s60.com/xml/ruleml/2'
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   245
    NAMESPACE_ID = 'ruleml2'
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   246
    ROOT_ELEMENT_NAME = 'ruleml'
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   247
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   248
    def __init__(self, resource_ref, configuration):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   249
        RuleImplReaderBase.__init__(self, resource_ref, configuration)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   250
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   251
    @classmethod
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   252
    def get_schema_data(cls):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   253
        return pkg_resources.resource_string('legacyruleplugin', 'xsd/ruleml2.xsd')
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   254
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   255
    def parse_rules(self, ref, etree):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   256
        rules = []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   257
        for elem in etree.getiterator("{%s}rule" % self.NAMESPACE):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   258
            lineno = utils.etree.get_lineno(elem)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   259
            for rule in relations.RelationFactory.get_relations(self.configuration, self._replace_eval_blocks(elem.text)):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   260
                rule.ref = ref
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   261
                rule.lineno = lineno
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   262
                rules.append(rule)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   263
        return rules
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   264
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   265
    def parse_eval_globals(self, etree):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   266
        eval_globals = {}
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   267
        for elem in etree.getiterator("{%s}eval_globals" % self.NAMESPACE):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   268
            text = ""
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   269
            if elem.get('file') != None:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   270
                self._read_eval_globals_from_file(elem.get('file'), eval_globals)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   271
            else:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   272
                try: 
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   273
                    # Strip surrounding whitespace, otherwise there might be Python
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   274
                    # indentation errors
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   275
                    text = elem.text.strip()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   276
                    exec(text, eval_globals)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   277
                except Exception, e:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   278
                    logging.getLogger('cone.ruleml(%s)' % self.resource_ref).warning('Failed to evaluate eval_globals block, exception: %s' % (e))
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   279
        return eval_globals
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   280
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   281
    def _read_eval_globals_from_file(self, relative_path, eval_globals):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   282
        # Get the actual path (relative to the current implementation file)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   283
        base_path = os.path.dirname(self.resource_ref)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   284
        pyfile_path = os.path.normpath(os.path.join(base_path, relative_path)).replace('\\', '/')
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   285
        # Read the data and execute
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   286
        try:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   287
            resource = None
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   288
            resource = self.configuration.get_resource(pyfile_path)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   289
            text = resource.read()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   290
            exec(text.replace('\r', ''), eval_globals)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   291
        except Exception, e:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   292
            logging.getLogger('cone.ruleml(%s)' % self.resource_ref).warning('Cannot import eval file: %s. Exception: %s' % (pyfile_path, e))
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   293
        finally:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   294
            if resource is not None: resource.close()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   295
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   296
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   297
    @classmethod
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   298
    def _replace_eval_blocks(cls, code):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   299
        return utils.expand_delimited_tokens(
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   300
            string          = code,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   301
            expander_func   = lambda ref, index: '__eval__ %r' % ref,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   302
            delimiters      =('{%', '%}'))