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.
5 from compiled_file_system
import Unicode
6 from extensions_paths
import (
7 API_FEATURES
, JSON_TEMPLATES
, MANIFEST_FEATURES
, PERMISSION_FEATURES
)
8 import features_utility
9 from future
import Gettable
, Future
10 from third_party
.json_schema_compiler
.json_parse
import Parse
13 def _AddPlatformsFromDependencies(feature
,
19 'manifest': manifest_features
,
20 'permission': permission_features
,
22 dependencies
= feature
.get('dependencies')
23 if dependencies
is None:
24 return ['apps', 'extensions']
26 for dependency
in dependencies
:
27 dep_type
, dep_name
= dependency
.split(':')
28 dependency_features
= features_map
[dep_type
]
29 dependency_feature
= dependency_features
.get(dep_name
)
30 # If the dependency can't be resolved, it is inaccessible and therefore
32 if dependency_feature
is None:
34 platforms
= platforms
.union(dependency_feature
['platforms'])
35 feature
['platforms'] = list(platforms
)
38 class _FeaturesCache(object):
39 def __init__(self
, file_system
, compiled_fs_factory
, *json_paths
):
40 self
._cache
= compiled_fs_factory
.Create(
41 file_system
, self
._CreateCache
, type(self
))
42 self
._text
_cache
= compiled_fs_factory
.ForUnicode(file_system
)
43 self
._json
_path
= json_paths
[0]
44 self
._extra
_paths
= json_paths
[1:]
47 def _CreateCache(self
, _
, features_json
):
48 extra_path_futures
= [self
._text
_cache
.GetFromFile(path
)
49 for path
in self
._extra
_paths
]
50 features
= features_utility
.Parse(Parse(features_json
))
51 for path_future
in extra_path_futures
:
52 extra_json
= path_future
.Get()
53 features
= features_utility
.MergedWith(
54 features_utility
.Parse(Parse(extra_json
)), features
)
57 def GetFeatures(self
):
58 if self
._json
_path
is None:
59 return Future(value
={})
60 return self
._cache
.GetFromFile(self
._json
_path
)
63 class FeaturesBundle(object):
64 '''Provides access to properties of API, Manifest, and Permission features.
66 def __init__(self
, file_system
, compiled_fs_factory
, object_store_creator
):
67 self
._api
_cache
= _FeaturesCache(
71 self
._manifest
_cache
= _FeaturesCache(
75 '%s/manifest.json' % JSON_TEMPLATES
)
76 self
._permission
_cache
= _FeaturesCache(
80 '%s/permissions.json' % JSON_TEMPLATES
)
81 self
._object
_store
= object_store_creator
.Create(_FeaturesCache
, 'features')
83 def GetPermissionFeatures(self
):
84 return self
._permission
_cache
.GetFeatures()
86 def GetManifestFeatures(self
):
87 return self
._manifest
_cache
.GetFeatures()
89 def GetAPIFeatures(self
):
90 api_features
= self
._object
_store
.Get('api_features').Get()
91 if api_features
is not None:
92 return Future(value
=api_features
)
94 api_features_future
= self
._api
_cache
.GetFeatures()
95 manifest_features_future
= self
._manifest
_cache
.GetFeatures()
96 permission_features_future
= self
._permission
_cache
.GetFeatures()
98 api_features
= api_features_future
.Get()
99 manifest_features
= manifest_features_future
.Get()
100 permission_features
= permission_features_future
.Get()
101 # TODO(rockot): Handle inter-API dependencies more gracefully.
102 # Not yet a problem because there is only one such case (windows -> tabs).
103 # If we don't store this value before annotating platforms, inter-API
104 # dependencies will lead to infinite recursion.
105 for feature
in api_features
.itervalues():
106 _AddPlatformsFromDependencies(
107 feature
, api_features
, manifest_features
, permission_features
)
108 self
._object
_store
.Set('api_features', api_features
)
110 return Future(delegate
=Gettable(resolve
))