configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/templatemlplugin.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
Template plugin for ConE that handles templateml files. Utilizes Jinja template engine.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    18
'''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    19
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    20
import re
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    21
import os
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    22
import sys
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    23
import logging
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    24
import codecs
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    25
import xml.parsers.expat
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    26
from jinja2 import Environment, PackageLoader, FileSystemLoader, Template, DictLoader
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    27
import traceback
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    28
try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    29
    from cElementTree import ElementTree
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    30
except ImportError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    31
    try:    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    32
        from elementtree import ElementTree
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    33
    except ImportError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    34
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    35
            from xml.etree import cElementTree as ElementTree
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    36
        except ImportError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    37
            from xml.etree import ElementTree
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    38
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    39
try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    40
    from cElementTree import ElementInclude
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    41
except ImportError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    42
    try:    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    43
        from elementtree import ElementInclude
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    44
    except ImportError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    45
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    46
            from xml.etree import cElementInclude as ElementInclude
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    47
        except ImportError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    48
            from xml.etree import ElementInclude
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    49
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    50
import __init__
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    51
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    52
from cone.public import exceptions,plugin,utils,api 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    53
from cone.confml import persistentconfml
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    54
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    55
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    56
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    57
class TemplatemlImpl(plugin.ImplBase):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    58
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    59
    context = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    60
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    61
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    62
    Implementation class of template plugin.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    63
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    64
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    65
    IMPL_TYPE_ID = "templateml" 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    66
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    67
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    68
    def __init__(self,ref,configuration, reader=None):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    69
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    70
        Overloading the default constructor
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    71
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    72
        plugin.ImplBase.__init__(self,ref,configuration)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    73
        self.logger = logging.getLogger('cone.templateml(%s)' % self.ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    74
        self.errors = False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    75
        self.reader = reader
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    76
        if self.reader and self.reader.tags:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    77
            self.set_tags(self.reader.tags)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    78
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    79
    def get_context(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    80
        if TemplatemlImpl.context == None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    81
            TemplatemlImpl.context = self.create_dict()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    82
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    83
        return TemplatemlImpl.context
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    84
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    85
    def generate(self, context=None):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    86
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    87
        Generate the given implementation.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    88
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    89
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    90
        self.create_output()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    91
        return 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    92
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    93
    def create_output(self, layers=None):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    94
        generator = Generator(self.reader.outputs, self.reader.filters, self.get_context(), self.configuration)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    95
        generator.generate(self.output, self.ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    96
        return
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    97
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    98
    def get_refs(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    99
        refs = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   100
        for output in self.reader.outputs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   101
            template = output.template.template
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   102
            refs.extend(self._extract_refs_from_template(template))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   103
        return refs
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   104
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   105
    @classmethod
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   106
    def _extract_refs_from_template(cls, template_text):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   107
        refs = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   108
        pattern = re.compile(r'feat_tree\.((?:\.?\w+)*)', re.UNICODE)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   109
        for m in re.finditer(pattern, template_text):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   110
            ref = m.group(1)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   111
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   112
            # ref may now be e.g. 'MyFeature.MySetting._value', so
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   113
            # remove the last part if it starts with an underscore 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   114
            index = ref.rfind('.')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   115
            if index != -1 and index < len(ref) and ref[index + 1] == '_':
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   116
                ref = ref[:index]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   117
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   118
            refs.append(ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   119
        return refs
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   120
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   121
    def has_ref(self, refs):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   122
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   123
        @returns True if the implementation uses the given ref as input value.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   124
        Otherwise return False.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   125
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   126
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   127
        # Does not support template inheritance
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   128
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   129
        if not isinstance(refs, list):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   130
            refs = [refs] 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   131
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   132
        for output in self.reader.outputs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   133
            if re.search("feat_list.*", output.template.template) != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   134
                return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   135
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   136
        refs_in_templates = self.get_refs()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   137
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   138
        for ref in refs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   139
            if ref in refs_in_templates:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   140
                return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   141
        return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   142
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   143
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   144
    def list_output_files(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   145
        """ Return a list of output files as an array. """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   146
        result = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   147
        for output in self.reader.outputs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   148
            result.append(os.path.normpath(os.path.join(self.output, output.path, output.filename)))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   149
        return result
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   150
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   151
    def create_dict(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   152
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   153
        Creates dict from configuration that can be passed to template engine.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   154
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   155
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   156
        context_dict = {}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   157
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   158
        if self.configuration:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   159
            dview = self.configuration.get_default_view()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   160
            feat_list = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   161
            feat_tree = {}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   162
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   163
            def add_feature(feature, feature_dict):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   164
                fea_dict = FeatureDictProxy(feature)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   165
                feat_list.append(fea_dict)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   166
                feature_dict[feature.ref] = fea_dict
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   167
                
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   168
                # Recursively add sub-features
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   169
                for sfeat in feature.list_features():
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   170
                    add_feature(feature.get_feature(sfeat), fea_dict)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   171
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   172
            for fea in dview.list_features():
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   173
                add_feature(dview.get_feature(fea), feat_tree)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   174
                
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   175
            context_dict['feat_list'] = feat_list
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   176
            context_dict['feat_tree'] = feat_tree
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   177
            context_dict['configuration'] = self.configuration
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   178
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   179
        return context_dict
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   180
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   181
def _expand_refs(text, config):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   182
    if config is not None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   183
        return utils.expand_refs_by_default_view(text, config.get_default_view())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   184
    else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   185
        return text
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   186
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   187
def _read_relative_file(configuration, relative_path, file_path):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   188
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   189
    Read data from a file relative to the given other file path.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   190
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   191
    # Get the actual path (relative to the current file)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   192
    base_path = os.path.dirname(file_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   193
    tempfile_path = os.path.normpath(os.path.join(base_path, relative_path)).replace('\\', '/')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   194
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   195
    # Read the file
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   196
    resource = configuration.get_resource(tempfile_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   197
    try:        return resource.read()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   198
    finally:    resource.close()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   199
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   200
class TemplatemlImplReader(plugin.ReaderBase):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   201
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   202
    Parses a single templateml file
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   203
    """ 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   204
    NAMESPACE = 'http://www.s60.com/xml/templateml/1'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   205
    FILE_EXTENSIONS = ['templateml']
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   206
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   207
    def __init__(self, resource_ref=None, configuration=None):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   208
        self.desc = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   209
        self.namespaces = [self.NAMESPACE]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   210
        self.outputs = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   211
        self.filters = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   212
        self.tags = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   213
        self.resource_ref = resource_ref
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   214
        self.configuration = configuration
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   215
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   216
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   217
    @classmethod
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   218
    def read_impl(cls, resource_ref, configuration, etree):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   219
        reader = TemplatemlImplReader(resource_ref, configuration)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   220
        reader.from_elementtree(etree)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   221
        return TemplatemlImpl(resource_ref, configuration, reader)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   222
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   223
    def fromstring(self, xml_string):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   224
        etree = ElementTree.fromstring(xml_string)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   225
        self.from_elementtree(etree)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   226
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   227
    def from_elementtree(self, etree):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   228
        ElementInclude.include(etree)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   229
        self.desc = self.parse_desc(etree)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   230
        self.outputs = self.parse_outputs(etree)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   231
        self.filters = self.parse_filters(etree)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   232
        self.tags = self.parse_tags(etree)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   233
         
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   234
    def parse_desc(self,etree):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   235
        desc = ""
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   236
        desc_elem = etree.find("{%s}desc" % self.namespaces[0])
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   237
        if desc_elem != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   238
            desc = desc_elem.text
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   239
        return desc
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   240
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   241
    def parse_filters(self, etree):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   242
        filters = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   243
        filter_elems = etree.findall("{%s}filter" % self.namespaces[0])
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   244
        for filter_elem in filter_elems:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   245
            if filter_elem != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   246
                filter = Filter()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   247
                
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   248
                if filter_elem.get('name') != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   249
                    name = filter_elem.get('name')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   250
                    if self.configuration != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   251
                        name = utils.expand_refs_by_default_view(name, self.configuration.get_default_view())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   252
                    filter.set_name(name)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   253
                if filter_elem.get('file') != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   254
                    file = filter_elem.get('file')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   255
                    if self.configuration != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   256
                        file = utils.expand_refs_by_default_view(file, self.configuration.get_default_view())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   257
                    filter.set_path(file)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   258
                if filter_elem.text != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   259
                    filter.set_code(filter_elem.text)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   260
                    if filter_elem.get('file') != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   261
                        logging.getLogger('cone.templateml').warning("In filter element file attribute and text defined. Using filter found from file attribute.")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   262
                filters.append(filter)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   263
        return filters
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   264
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   265
    def parse_tags(self, etree):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   266
        tags = {}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   267
        for tag in etree.getiterator("{%s}tag" % self.namespaces[0]):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   268
            tagname = tag.get('name','')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   269
            tagvalue = tag.get('value')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   270
            values = tags.get(tagname,[])
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   271
            values.append(tagvalue)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   272
            tags[tagname] = values
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   273
        return tags
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   274
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   275
    def parse_template(self, output_elem):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   276
        tempfile = TempFile()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   277
        template_elems = output_elem.findall("{%s}template" % self.namespaces[0])
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   278
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   279
        for template_elem in template_elems:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   280
            if template_elem.text != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   281
                tempfile.set_template(template_elem.text)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   282
            else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   283
                for selem in template_elem:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   284
                    tempfile.set_template(selem.text)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   285
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   286
            if template_elem.get('file') != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   287
                file = template_elem.get('file')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   288
                if template_elem.text != None: 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   289
                    logging.getLogger('cone.templateml').warning("In template element file attribute and text defined. Using template found from file attribute.")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   290
                template_text = _read_relative_file(self.configuration, file, self.resource_ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   291
                tempfile.set_template(template_text)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   292
        return tempfile
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   293
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   294
    def parse_outputs(self, etree):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   295
        outputs = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   296
        output_elems = etree.findall("{%s}output" % self.namespaces[0])
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   297
        for output_elem in output_elems:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   298
            if output_elem != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   299
                outputfile = OutputFile()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   300
                if output_elem.get('encoding') != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   301
                    encoding = output_elem.get('encoding')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   302
                    # Check the encoding
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   303
                    try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   304
                        codecs.lookup(encoding)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   305
                    except LookupError:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   306
                        raise exceptions.ParseError("Invalid output encoding: %s" % encoding)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   307
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   308
                    if self.configuration != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   309
                        encoding = utils.expand_refs_by_default_view(encoding, self.configuration.get_default_view())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   310
                    outputfile.set_encoding(encoding)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   311
                if output_elem.get('file') != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   312
                    file = output_elem.get('file')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   313
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   314
                    if self.configuration != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   315
                        file = utils.expand_refs_by_default_view(file, self.configuration.get_default_view())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   316
                    outputfile.set_filename(file)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   317
                if output_elem.get('dir') != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   318
                    dir = output_elem.get('dir')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   319
                    if self.configuration != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   320
                        dir = utils.expand_refs_by_default_view(dir, self.configuration.get_default_view())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   321
                    outputfile.set_path(dir)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   322
                if output_elem.get('ref'):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   323
                    # Fetch the output value from a configuration reference
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   324
                    fea = self.configuration.get_default_view().get_feature(output_elem.get('ref'))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   325
                    outputfile.set_filename(fea.value) 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   326
                if output_elem.get('bom'):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   327
                    outputfile.bom = output_elem.get('bom').lower() in ('1', 'true', 't', 'yes', 'y')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   328
                outputfile.set_template(self.parse_template(output_elem))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   329
                outputfile.set_filters(self.parse_filters(output_elem))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   330
                outputs.append(outputfile)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   331
        return outputs
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   332
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   333
class Generator(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   334
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   335
    Class that generates
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   336
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   337
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   338
    def __init__(self, outputs, filters, context, configuration=None):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   339
        self.outputs = outputs
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   340
        self.filters = filters
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   341
        self.context = context
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   342
        self.configuration = configuration
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   343
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   344
    def generate(self, output_path, ref):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   345
        """ 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   346
        Generates output based on templates 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   347
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   348
        if self.outputs != None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   349
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   350
            for output in self.outputs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   351
                try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   352
                    logging.getLogger('cone.templateml').debug(output)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   353
                    out_path = os.path.abspath(os.path.join(output_path, output.path))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   354
                    if out_path != '':
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   355
                        if not os.path.exists(out_path):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   356
                            os.makedirs(out_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   357
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   358
                    out_file = open(os.path.join(out_path, output.filename), 'wb')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   359
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   360
                    if output.template.path:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   361
                        output.template.template = _read_relative_file(self.configuration, output.template.path, ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   362
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   363
                    dict_loader = DictLoader({'template': output.template.template})
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   364
                    env = Environment(loader=dict_loader)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   365
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   366
                    # Common filters
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   367
                    for filter in self.filters:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   368
                        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   369
                        if filter.path:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   370
                            filter.code = _read_relative_file(self.configuration, filter.path, ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   371
                        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   372
                        if not filter.code:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   373
                            logging.getLogger('cone.templateml').warning("Skipping empty filter definition.")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   374
                        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   375
                            env.filters[str(filter.name)] = eval(filter.code)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   376
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   377
                    # Output file specific filters
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   378
                    for filter in output.filters:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   379
                        if filter.path:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   380
                           filter.code = _read_relative_file(self.configuration, filter.path, ref)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   381
                        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   382
                        if not filter.code:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   383
                            logging.getLogger('cone.templateml').warning("Skipping empty filter definition.")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   384
                        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   385
                            env.filters[str(filter.name)] = eval(filter.code)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   386
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   387
                    template = env.get_template('template')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   388
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   389
                    file_string = template.render(self.context)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   390
                    out_file.write(self._encode_data(file_string, output.encoding, output.bom))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   391
                    out_file.close()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   392
                    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   393
                except Exception, e:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   394
                    logging.getLogger('cone.templateml').error('Failed to generate template: %s %s\n%s' % (type(e), e, traceback.format_exc()) )
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   395
        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   396
            logging.getLogger('cone.templateml').info('No (valid) templates found.')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   397
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   398
    def _encode_data(self, data, encoding, write_bom):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   399
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   400
        Encode the given data using the given encoding and BOM definition.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   401
        @param data: The data to encode.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   402
        @param encoding: The encoding to use.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   403
        @param write_bom: True or False to define whether the BOM should be written
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   404
            for Unicode encodings, None for default.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   405
        """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   406
        data = data.encode(encoding)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   407
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   408
        # Check if we need to do special handling for BOM
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   409
        if write_bom is not None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   410
            BOM_MAPPING = {'utf-8'      : codecs.BOM_UTF8,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   411
                           'utf-16'     : codecs.BOM_UTF16,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   412
                           'utf-16-be'  : codecs.BOM_UTF16_BE,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   413
                           'utf-16-le'  : codecs.BOM_UTF16_LE}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   414
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   415
            # Use the name from a CodecInfo object to account for
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   416
            # aliases (e.g. U8 and UTF-8 both map to utf-8)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   417
            codec_info = codecs.lookup(encoding)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   418
            if codec_info.name in BOM_MAPPING:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   419
                # Add or remove as necessary
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   420
                BOM = BOM_MAPPING[codec_info.name]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   421
                if write_bom == True and not data.startswith(BOM):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   422
                    data = BOM + data
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   423
                elif write_bom == False and data.startswith(BOM):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   424
                    data = data[len(BOM):]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   425
        return data
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   426
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   427
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   428
class OutputFile(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   429
    def __init__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   430
        self.filename = ''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   431
        self.path = ''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   432
        self.encoding = "utf-8"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   433
        self.template = TempFile()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   434
        self.filters = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   435
        self.bom = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   436
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   437
    def set_filename(self, filename):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   438
        self.filename = filename
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   439
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   440
    def set_path(self, path):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   441
        self.path = path
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   442
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   443
    def set_encoding(self, encoding):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   444
        self.encoding = encoding
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   445
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   446
    def set_template(self, template):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   447
        self.template = template
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   448
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   449
    def add_filter(self, filter):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   450
        self.filters.append(filters)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   451
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   452
    def set_filters(self, filters):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   453
        self.filters = filters
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   454
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   455
    def __eq__(self, other):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   456
        if (self.template == other.template and self.encoding == other.encoding and self.path == other.path and self.filename == other.filename and self.filters == other.filters):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   457
            return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   458
        return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   459
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   460
    def __repr__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   461
        return "OutputFile(filename=%r, path=%r, encoding=%r, template=%r, filters=%r" % (self.filename, self.path, self.encoding, self.template, self.filters)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   462
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   463
class TempFile(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   464
    def __init__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   465
        self.template = ""
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   466
        self.extensions = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   467
        self.filters = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   468
        self.path = ''
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   469
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   470
    def set_path(self, path):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   471
        self.path = path
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   472
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   473
    def set_template(self, template):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   474
        self.template = template
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   475
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   476
    def add_extension(self, extension):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   477
        self.extensions.append(extension)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   478
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   479
    def add_filter(self, filter):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   480
        self.filters.append(filter)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   481
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   482
    def add_filter2(self, name, code):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   483
        self.filters.append(Filter(name, code))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   484
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   485
    def __eq__(self, other):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   486
        if self.template == other.template and self.filters == other.filters and self.extensions == other.extensions and self.path == other.path:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   487
            return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   488
        return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   489
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   490
class Filter(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   491
    def __init__(self, name, code):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   492
        self.name = name
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   493
        self.code = code
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   494
        self.path = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   495
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   496
    def __init__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   497
        self.name = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   498
        self.code = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   499
        self.path = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   500
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   501
    def set_path(self, path):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   502
        self.path = path
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   503
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   504
    def set_name(self, name):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   505
        self.name = name
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   506
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   507
    def set_code(self, code):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   508
        self.code = code
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   509
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   510
    def __eq__(self, other):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   511
        if self.name == other.name and self.code == other.code and self.path == other.path:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   512
            return True
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   513
        return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   514
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   515
class FeatureDictProxy(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   516
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   517
    Proxy class that behaves like a dictionary, but loads attributes from
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   518
    the Feature object it proxies only when they are requested.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   519
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   520
    def __init__(self, feature):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   521
        self._feature = feature
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   522
        self._children = {}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   523
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   524
    def _get_dict(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   525
        result = {
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   526
            '_name'        : self._feature.name,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   527
            '_namespace'   : self._feature.namespace,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   528
            '_value'       : self._feature.get_value(),
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   529
            '_fqr'         : self._feature.fqr,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   530
            '_type'        : self._feature.type}
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   531
        for ref, obj in self._children.iteritems():
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   532
            result[ref] = obj
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   533
        return result
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   534
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   535
    def items(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   536
        return self._get_dict().items()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   537
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   538
    def iteritems(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   539
        return self._get_dict().iteritems()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   540
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   541
    def __getitem__(self, name):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   542
        if name == '_name':         return self._feature.name        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   543
        elif name == '_namespace':  return self._feature.namespace
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   544
        elif name == '_value':      return self._feature.get_value()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   545
        elif name == '_fqr':        return self._feature.fqr
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   546
        elif name == '_type':       return self._feature.type
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   547
        else:                       return self._children[name]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   548
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   549
    def __setitem__(self, name, value):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   550
        self._children[name] = value
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   551
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   552
    def __len__(self):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   553
        return len(self._get_dict())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   554
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   555
    def __eq__(self, other):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   556
        if not isinstance(other, dict):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   557
            return False
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   558
        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   559
            return self._get_dict() == other
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   560
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   561
    def __ne__(self, other):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   562
        return not (self == other)