api_data_source.py revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1# Copyright (c) 2012 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 data_source import DataSource 6from docs_server_utils import StringIdentity 7from environment import IsPreviewServer 8from file_system import FileNotFoundError 9from future import Future, All 10from jsc_view import JSCView, GetEventByNameFromEvents 11from platform_util import GetPlatforms 12 13 14class _LazySamplesGetter(object): 15 '''This class is needed so that an extensions API page does not have to fetch 16 the apps samples page and vice versa. 17 ''' 18 19 def __init__(self, api_name, samples): 20 self._api_name = api_name 21 self._samples = samples 22 23 def get(self, key): 24 return self._samples.FilterSamples(key, self._api_name) 25 26 27class APIDataSource(DataSource): 28 '''This class fetches and loads JSON APIs from the FileSystem passed in with 29 |compiled_fs_factory|, so the APIs can be plugged into templates. 30 ''' 31 def __init__(self, server_instance, request): 32 file_system = server_instance.host_file_system_provider.GetTrunk() 33 self._json_cache = server_instance.compiled_fs_factory.ForJson(file_system) 34 self._template_cache = server_instance.compiled_fs_factory.ForTemplates( 35 file_system) 36 self._platform_bundle = server_instance.platform_bundle 37 self._view_cache = server_instance.object_store_creator.Create( 38 APIDataSource, 39 # Update the models when any of templates, APIs, or Features change. 40 category=StringIdentity(self._json_cache.GetIdentity(), 41 self._template_cache.GetIdentity(), 42 self._platform_bundle.GetIdentity())) 43 44 # This caches the result of _LoadEventByName. 45 self._event_byname_futures = {} 46 self._samples = server_instance.samples_data_source_factory.Create(request) 47 48 def _LoadEventByName(self, platform): 49 '''All events have some members in common. We source their description 50 from Event in events.json. 51 ''' 52 if platform not in self._event_byname_futures: 53 future = self._GetSchemaView(platform, 'events') 54 self._event_byname_futures[platform] = Future( 55 callback=lambda: GetEventByNameFromEvents(future.Get())) 56 return self._event_byname_futures[platform] 57 58 def _GetSchemaView(self, platform, api_name): 59 object_store_key = '/'.join((platform, api_name)) 60 api_models = self._platform_bundle.GetAPIModels(platform) 61 jsc_view_future = self._view_cache.Get(object_store_key) 62 model_future = api_models.GetModel(api_name) 63 content_script_apis_future = api_models.GetContentScriptAPIs() 64 def resolve(): 65 jsc_view = jsc_view_future.Get() 66 if jsc_view is None: 67 jsc_view = JSCView( 68 content_script_apis_future.Get(), 69 model_future.Get(), 70 self._platform_bundle.GetAvailabilityFinder(platform), 71 self._json_cache, 72 self._template_cache, 73 self._platform_bundle.GetFeaturesBundle(platform), 74 self._LoadEventByName(platform), 75 platform).ToDict() 76 self._view_cache.Set(object_store_key, jsc_view) 77 return jsc_view 78 return Future(callback=resolve) 79 80 def _GetImpl(self, platform, api_name): 81 jsc_view_future = self._GetSchemaView(platform, api_name) 82 def resolve(): 83 jsc_view = jsc_view_future.Get() 84 # Parsing samples on the preview server takes seconds and doesn't add 85 # anything. Don't do it. 86 if not IsPreviewServer(): 87 jsc_view['samples'] = _LazySamplesGetter( 88 jsc_view['name'], 89 self._samples) 90 return jsc_view 91 return Future(callback=resolve) 92 93 def get(self, platform): 94 '''Return a getter object so that templates can perform lookups such 95 as apis.extensions.runtime. 96 ''' 97 getter = lambda: 0 98 getter.get = lambda api_name: self._GetImpl(platform, api_name).Get() 99 return getter 100 101 def Cron(self): 102 futures = [] 103 for platform in GetPlatforms(): 104 futures += [self._GetImpl(platform, name) 105 for name in self._platform_bundle.GetAPIModels(platform).GetNames()] 106 return All(futures, except_pass=FileNotFoundError) 107