Index: tools/json_schema_compiler/preview.py |
diff --git a/tools/json_schema_compiler/preview.py b/tools/json_schema_compiler/preview.py |
index 5c5fee084bac400572f50e86468aa042ecf74630..050af9637efbe9ca7eb5d5d6c5819e23c5a4162e 100755 |
--- a/tools/json_schema_compiler/preview.py |
+++ b/tools/json_schema_compiler/preview.py |
@@ -16,11 +16,13 @@ import json_schema |
import model |
import optparse |
import os |
-import schema_loader |
+import shlex |
import urlparse |
from highlighters import ( |
pygments_highlighter, none_highlighter, hilite_me_highlighter) |
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer |
+from cpp_namespace_environment import CppNamespaceEnvironment |
+from schema_loader import SchemaLoader |
class CompilerHandler(BaseHTTPRequestHandler): |
@@ -176,27 +178,6 @@ window.addEventListener('hashchange', updateEverything, false); |
updateEverything(); |
</script>''') |
- def _LoadModel(self, basedir, name): |
- """Loads and returns the model for the |name| API from either its JSON or |
- IDL file, e.g. |
- name=contextMenus will be loaded from |basedir|/context_menus.json, |
- name=alarms will be loaded from |basedir|/alarms.idl. |
- """ |
- loaders = { |
- 'json': json_schema.Load, |
- 'idl': idl_schema.Load |
- } |
- # APIs are referred to like "webRequest" but that's in a file |
- # "web_request.json" so we need to unixify the name. |
- unix_name = model.UnixName(name) |
- for loader_ext, loader_fn in loaders.items(): |
- file_path = '%s/%s.%s' % (basedir, unix_name, loader_ext) |
- if os.path.exists(file_path): |
- # For historical reasons these files contain a singleton list with the |
- # model, so just return that single object. |
- return (loader_fn(file_path)[0], file_path) |
- raise ValueError('File for model "%s" not found' % name) |
- |
def _ShowCompiledFile(self, parsed_url, head, body): |
"""Show the compiled version of a json or idl file given the path to the |
compiled file. |
@@ -207,34 +188,25 @@ updateEverything(); |
(file_root, file_ext) = os.path.splitext(request_path) |
(filedir, filename) = os.path.split(file_root) |
+ schema_loader = SchemaLoader("./", |
+ filedir, |
+ self.server.include_rules, |
+ self.server.cpp_namespace_pattern) |
try: |
# Get main file. |
- (api_def, file_path) = self._LoadModel(filedir, filename) |
- namespace = api_model.AddNamespace(api_def, file_path) |
+ namespace = schema_loader.ResolveNamespace(filename) |
type_generator = cpp_type_generator.CppTypeGenerator( |
api_model, |
- schema_loader.SchemaLoader(filedir), |
+ schema_loader, |
namespace) |
- # Get the model's dependencies. |
- for dependency in api_def.get('dependencies', []): |
- # Dependencies can contain : in which case they don't refer to APIs, |
- # rather, permissions or manifest keys. |
- if ':' in dependency: |
- continue |
- (api_def, file_path) = self._LoadModel(filedir, dependency) |
- referenced_namespace = api_model.AddNamespace(api_def, file_path) |
- if referenced_namespace: |
- type_generator.AddNamespace(referenced_namespace, |
- cpp_util.Classname(referenced_namespace.name).lower()) |
- |
# Generate code |
cpp_namespace = 'generated_api_schemas' |
if file_ext == '.h': |
- cpp_code = (h_generator.HGenerator(type_generator, cpp_namespace) |
+ cpp_code = (h_generator.HGenerator(type_generator) |
.Generate(namespace).Render()) |
elif file_ext == '.cc': |
- cpp_code = (cc_generator.CCGenerator(type_generator, cpp_namespace) |
+ cpp_code = (cc_generator.CCGenerator(type_generator) |
.Generate(namespace).Render()) |
else: |
self.send_error(404, "File not found: %s" % request_path) |
@@ -328,9 +300,16 @@ updateEverything(); |
class PreviewHTTPServer(HTTPServer, object): |
- def __init__(self, server_address, handler, highlighters): |
+ def __init__(self, |
+ server_address, |
+ handler, |
+ highlighters, |
+ include_rules, |
+ cpp_namespace_pattern): |
super(PreviewHTTPServer, self).__init__(server_address, handler) |
self.highlighters = highlighters |
+ self.include_rules = include_rules |
+ self.cpp_namespace_pattern = cpp_namespace_pattern |
if __name__ == '__main__': |
@@ -339,9 +318,26 @@ if __name__ == '__main__': |
usage='usage: %prog [option]...') |
parser.add_option('-p', '--port', default='8000', |
help='port to run the server on') |
+ parser.add_option('-n', '--namespace', default='generated_api_schemas', |
+ help='C++ namespace for generated files. e.g extensions::api.') |
+ parser.add_option('-I', '--include-rules', |
+ help='A list of paths to include when searching for referenced objects,' |
+ ' with the namespace separated by a \':\'. Example: ' |
+ '/foo/bar:Foo::Bar::%(namespace)s') |
(opts, argv) = parser.parse_args() |
+ def split_path_and_namespace(path_and_namespace): |
+ if ':' not in path_and_namespace: |
+ raise ValueError('Invalid include rule "%s". Rules must be of ' |
+ 'the form path:namespace' % path_and_namespace) |
+ return path_and_namespace.split(':', 1) |
+ |
+ include_rules = [] |
+ if opts.include_rules: |
+ include_rules = map(split_path_and_namespace, |
+ shlex.split(opts.include_rules)) |
+ |
try: |
print('Starting previewserver on port %s' % opts.port) |
print('The extension documentation can be found at:') |
@@ -360,7 +356,9 @@ if __name__ == '__main__': |
server = PreviewHTTPServer(('', int(opts.port)), |
CompilerHandler, |
- highlighters) |
+ highlighters, |
+ include_rules, |
+ opts.namespace) |
server.serve_forever() |
except KeyboardInterrupt: |
server.socket.close() |