1# Copyright 2013 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5from copy import deepcopy 6from operator import itemgetter 7 8from third_party.json_schema_compiler.json_parse import OrderedDict, Parse 9 10class ManifestDataSource(object): 11 '''Provides a template with access to manifest properties specific to apps or 12 extensions. 13 ''' 14 def __init__(self, 15 compiled_fs_factory, 16 file_system, 17 manifest_path, 18 features_path): 19 self._manifest_path = manifest_path 20 self._features_path = features_path 21 self._file_system = file_system 22 self._cache = compiled_fs_factory.Create( 23 self._CreateManifestData, ManifestDataSource) 24 25 def _ApplyAppsTransformations(self, manifest): 26 manifest['required'][0]['example'] = 'Application' 27 manifest['optional'][-1]['is_last'] = True 28 29 def _ApplyExtensionsTransformations(self, manifest): 30 manifest['optional'][-1]['is_last'] = True 31 32 def _CreateManifestData(self, _, content): 33 '''Take the contents of |_manifest_path| and create apps and extensions 34 versions of a manifest example based on the contents of |_features_path|. 35 ''' 36 def create_manifest_dict(): 37 manifest_dict = OrderedDict() 38 for category in ('required', 'only_one', 'recommended', 'optional'): 39 manifest_dict[category] = [] 40 return manifest_dict 41 42 apps = create_manifest_dict() 43 extensions = create_manifest_dict() 44 45 manifest_json = Parse(content) 46 features_json = Parse(self._file_system.ReadSingle( 47 self._features_path)) 48 49 def add_property(feature, manifest_key, category): 50 '''If |feature|, from features_json, has the correct extension_types, add 51 |manifest_key| to either apps or extensions. 52 ''' 53 added = False 54 extension_types = feature['extension_types'] 55 if extension_types == 'all' or 'platform_app' in extension_types: 56 apps[category].append(deepcopy(manifest_key)) 57 added = True 58 if extension_types == 'all' or 'extension' in extension_types: 59 extensions[category].append(deepcopy(manifest_key)) 60 added = True 61 return added 62 63 # Property types are: required, only_one, recommended, and optional. 64 for category in manifest_json: 65 for manifest_key in manifest_json[category]: 66 # If a property is in manifest.json but not _manifest_features, this 67 # will cause an error. 68 feature = features_json[manifest_key['name']] 69 if add_property(feature, manifest_key, category): 70 del features_json[manifest_key['name']] 71 72 # All of the properties left in features_json are assumed to be optional. 73 for feature in features_json.keys(): 74 item = features_json[feature] 75 # Handles instances where a features entry is a union with a whitelist. 76 if isinstance(item, list): 77 item = item[0] 78 add_property(item, {'name': feature}, 'optional') 79 80 apps['optional'].sort(key=itemgetter('name')) 81 extensions['optional'].sort(key=itemgetter('name')) 82 83 self._ApplyAppsTransformations(apps) 84 self._ApplyExtensionsTransformations(extensions) 85 86 return {'apps': apps, 'extensions': extensions} 87 88 def get(self, key): 89 return self._cache.GetFromFile(self._manifest_path)[key] 90