Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / tools / json_schema_compiler / schema_loader.py
index 80f1d3f..b896991 100644 (file)
@@ -3,24 +3,65 @@
 # found in the LICENSE file.
 
 import os
+import re
 import sys
 
 import idl_schema
 import json_schema
-from model import Model
+from cpp_namespace_environment import CppNamespaceEnvironment
+from model import Model, UnixName
+
+def GenerateFilenames(full_namespace):
+  # Try to find the file defining the namespace. Eg. for
+  # nameSpace.sub_name_space.Type' the following heuristics looks for:
+  # 1. name_space_sub_name_space.json,
+  # 2. name_space_sub_name_space.idl,
+  # 3. sub_name_space.json,
+  # 4. sub_name_space.idl,
+  # 5. etc.
+  sub_namespaces = full_namespace.split('.')
+  filenames = [ ]
+  basename = None
+  for namespace in reversed(sub_namespaces):
+    if basename is not None:
+      basename = UnixName(namespace + '.' + basename)
+    else:
+      basename = UnixName(namespace)
+    for ext in ['json', 'idl']:
+      filenames.append('%s.%s' % (basename, ext))
+  return filenames
 
 class SchemaLoader(object):
   '''Resolves a type name into the namespace the type belongs to.
 
   Properties:
-  - |display_path| path to the directory with the API header files, intended for
-  use with the Model.
-  - |real_path| path to the directory with the API header files, used for file
-  access.
+  - |root| path to the root directory.
+  - |path| path to the directory with the API header files, relative to the
+    root.
+  - |include_rules| List containing tuples with (path, cpp_namespace_pattern)
+    used when searching for types.
+  - |cpp_namespace_pattern| Default namespace pattern
   '''
-  def __init__(self, display_path, real_path):
-    self._display_path = display_path
-    self._real_path = real_path
+  def __init__(self,
+               root,
+               path,
+               include_rules,
+               cpp_namespace_pattern):
+    self._root = root
+    self._include_rules = [(path, cpp_namespace_pattern)]
+    self._include_rules.extend(include_rules)
+
+  def ResolveNamespace(self, full_namespace):
+    filenames = GenerateFilenames(full_namespace)
+    for path, cpp_namespace in self._include_rules:
+      for filename in reversed(filenames):
+        filepath = os.path.join(path, filename);
+        if os.path.exists(os.path.join(self._root, filepath)):
+          return Model().AddNamespace(
+              self.LoadSchema(filepath)[0],
+              filepath,
+              environment=CppNamespaceEnvironment(cpp_namespace))
+    return None
 
   def ResolveType(self, full_name, default_namespace):
     name_parts = full_name.rsplit('.', 1)
@@ -28,30 +69,18 @@ class SchemaLoader(object):
       if full_name not in default_namespace.types:
         return None
       return default_namespace
-    namespace_name, type_name = name_parts
-    real_name = None
-    for ext in ['json', 'idl']:
-      filename = '%s.%s' % (namespace_name, ext)
-      filepath = os.path.join(self._real_path, filename);
-      if os.path.exists(filepath):
-        real_name = filename
-        break
-    if real_name is None:
-      return None
-    namespace = Model().AddNamespace(
-        self.LoadSchema(real_name)[0],
-        os.path.join(self._display_path, real_name))
-    if type_name not in namespace.types:
-      return None
-    return namespace
+    full_namespace, type_name = full_name.rsplit('.', 1)
+    namespace = self.ResolveNamespace(full_namespace)
+    if namespace and type_name in namespace.types:
+      return namespace
+    return None
 
   def LoadSchema(self, schema):
     '''Load a schema definition. The schema parameter must be a file name
-    without any path component - the file is loaded from the path defined by
-    the real_path argument passed to the constructor.'''
+    with the full path relative to the root.'''
     schema_filename, schema_extension = os.path.splitext(schema)
 
-    schema_path = os.path.join(self._real_path, schema);
+    schema_path = os.path.join(self._root, schema)
     if schema_extension == '.json':
       api_defs = json_schema.Load(schema_path)
     elif schema_extension == '.idl':
@@ -59,8 +88,5 @@ class SchemaLoader(object):
     else:
       sys.exit('Did not recognize file extension %s for schema %s' %
                (schema_extension, schema))
-    if len(api_defs) != 1:
-      sys.exit('File %s has multiple schemas. Files are only allowed to contain'
-               'a single schema.' % schema)
 
     return api_defs