15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import copy 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import json_parse 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdochdef DeleteNodes(item, delete_key=None, matcher=None): 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch """Deletes certain nodes in item, recursively. If |delete_key| is set, all 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dicts with |delete_key| as an attribute are deleted. If a callback is passed 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch as |matcher|, |DeleteNodes| will delete all dicts for which matcher(dict) 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch returns True. 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch assert (delete_key is not None) != (matcher is not None) 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def ShouldDelete(thing): 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return json_parse.IsDict(thing) and ( 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete_key is not None and delete_key in thing or 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch matcher is not None and matcher(thing)) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if json_parse.IsDict(item): 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toDelete = [] 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key, value in item.items(): 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ShouldDelete(value): 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toDelete.append(key) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DeleteNodes(value, delete_key, matcher) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key in toDelete: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) del item[key] 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif type(item) == list: 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch item[:] = [DeleteNodes(thing, delete_key, matcher) 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for thing in item if not ShouldDelete(thing)] 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Load(filename): 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) with open(filename, 'r') as handle: 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) schemas = json_parse.Parse(handle.read()) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return schemas 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A dictionary mapping |filename| to the object resulting from loading the JSON 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# at |filename|. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_cache = {} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CachedLoad(filename): 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Equivalent to Load(filename), but caches results for subsequent calls""" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if filename not in _cache: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _cache[filename] = Load(filename) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Return a copy of the object so that any changes a caller makes won't affect 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # the next caller. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return copy.deepcopy(_cache[filename]) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 58