api_models.py revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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 5import logging 6import os 7import posixpath 8 9from file_system import FileNotFoundError 10from future import Gettable, Future 11from schema_util import ProcessSchema 12from svn_constants import API_PATH 13from third_party.json_schema_compiler.model import Namespace, UnixName 14 15 16def _CreateAPIModel(path, data): 17 schema = ProcessSchema(path, data) 18 if os.path.splitext(path)[1] == '.json': 19 schema = schema[0] 20 return Namespace(schema, schema['namespace']) 21 22 23class APIModels(object): 24 '''Tracks APIs and their Models. 25 ''' 26 27 def __init__(self, features_bundle, compiled_fs_factory, file_system): 28 self._features_bundle = features_bundle 29 self._model_cache = compiled_fs_factory.Create( 30 file_system, _CreateAPIModel, APIModels) 31 32 def GetNames(self): 33 return self._features_bundle.GetAPIFeatures().keys() 34 35 def GetModel(self, api_name): 36 # Callers sometimes specify a filename which includes .json or .idl - if 37 # so, believe them. They may even include the 'api/' prefix. 38 if os.path.splitext(api_name)[1] in ('.json', '.idl'): 39 if not api_name.startswith(API_PATH + '/'): 40 api_name = posixpath.join(API_PATH, api_name) 41 return self._model_cache.GetFromFile(api_name) 42 43 assert not api_name.startswith(API_PATH) 44 45 # API names are given as declarativeContent and app.window but file names 46 # will be declarative_content and app_window. 47 file_name = UnixName(api_name).replace('.', '_') 48 # Devtools APIs are in API_PATH/devtools/ not API_PATH/, and have their 49 # "devtools" names removed from the file names. 50 basename = posixpath.basename(file_name) 51 if basename.startswith('devtools_'): 52 file_name = posixpath.join( 53 'devtools', file_name.replace(basename, basename[len('devtools_'):])) 54 55 futures = [self._model_cache.GetFromFile('%s/%s.%s' % 56 (API_PATH, file_name, ext)) 57 for ext in ('json', 'idl')] 58 def resolve(): 59 for future in futures: 60 try: 61 return future.Get() 62 except FileNotFoundError: pass 63 # Propagate the first FileNotFoundError if neither were found. 64 futures[0].Get() 65 return Future(delegate=Gettable(resolve)) 66