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.
8 from compiled_file_system
import SingleFile
, Unicode
9 from extensions_paths
import API
10 from file_system
import FileNotFoundError
11 from future
import Gettable
, Future
12 from schema_util
import ProcessSchema
13 from third_party
.json_schema_compiler
.model
import Namespace
, UnixName
18 def _CreateAPIModel(path
, data
):
19 schema
= ProcessSchema(path
, data
)[0]
20 if not schema
: return None
21 return Namespace(schema
, schema
['namespace'])
24 class APIModels(object):
25 '''Tracks APIs and their Models.
28 def __init__(self
, features_bundle
, compiled_fs_factory
, file_system
):
29 self
._features
_bundle
= features_bundle
30 self
._model
_cache
= compiled_fs_factory
.Create(
31 file_system
, _CreateAPIModel
, APIModels
)
34 # API names appear alongside some of their methods/events/etc in the
35 # features file. APIs are those which either implicitly or explicitly have
36 # no parent feature (e.g. app, app.window, and devtools.inspectedWindow are
37 # APIs; runtime.onConnectNative is not).
38 api_features
= self
._features
_bundle
.GetAPIFeatures().Get()
39 return [name
for name
, feature
in api_features
.iteritems()
40 if ('.' not in name
or
41 name
.rsplit('.', 1)[0] not in api_features
or
42 feature
.get('noparent'))]
44 def GetModel(self
, api_name
):
45 # Callers sometimes specify a filename which includes .json or .idl - if
46 # so, believe them. They may even include the 'api/' prefix.
47 if os
.path
.splitext(api_name
)[1] in ('.json', '.idl'):
48 if not api_name
.startswith(API
+ '/'):
49 api_name
= posixpath
.join(API
, api_name
)
50 return self
._model
_cache
.GetFromFile(api_name
)
52 assert not api_name
.startswith(API
)
54 # API names are given as declarativeContent and app.window but file names
55 # will be declarative_content and app_window.
56 file_name
= UnixName(api_name
).replace('.', '_')
57 # Devtools APIs are in API/devtools/ not API/, and have their
58 # "devtools" names removed from the file names.
59 basename
= posixpath
.basename(file_name
)
60 if 'devtools_' in basename
:
61 file_name
= posixpath
.join(
62 'devtools', file_name
.replace(basename
,
63 basename
.replace('devtools_' , '')))
65 futures
= [self
._model
_cache
.GetFromFile('%s/%s.%s' % (API
, file_name
, ext
))
66 for ext
in ('json', 'idl')]
68 for future
in futures
:
71 except FileNotFoundError
: pass
72 # Propagate the first FileNotFoundError if neither were found.
74 return Future(delegate
=Gettable(resolve
))
77 future_models
= [(name
, self
.GetModel(name
)) for name
in self
.GetNames()]
78 for name
, future_model
in future_models
:
80 model
= future_model
.Get()
81 except FileNotFoundError
: