Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / api_models.py
blobb5686a10dec94d95ef2a8d3a9c4986aa4efc7a66
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 import os
6 import posixpath
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
16 @SingleFile
17 @Unicode
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.
26 '''
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)
33 def GetNames(self):
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')]
67 def resolve():
68 for future in futures:
69 try:
70 return future.Get()
71 except FileNotFoundError: pass
72 # Propagate the first FileNotFoundError if neither were found.
73 futures[0].Get()
74 return Future(delegate=Gettable(resolve))
76 def IterModels(self):
77 future_models = [(name, self.GetModel(name)) for name in self.GetNames()]
78 for name, future_model in future_models:
79 try:
80 model = future_model.Get()
81 except FileNotFoundError:
82 continue
83 if model:
84 yield name, model