github.com/CycloneDX/sbom-utility@v0.16.0/schema/bom_traversal.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 /* 3 * Licensed to the Apache Software Foundation (ASF) under one or more 4 * contributor license agreements. See the NOTICE file distributed with 5 * this work for additional information regarding copyright ownership. 6 * The ASF licenses this file to You under the Apache License, Version 2.0 7 * (the "License"); you may not use this file except in compliance with 8 * the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package schema 20 21 func (bom *BOM) TrimBOMKeys(keys []string) { 22 // initialize map to root of BOM document 23 if len(keys) > 0 { 24 bom.TrimEntityKeys(bom.GetJSONMap(), keys) 25 } 26 } 27 28 func (bom *BOM) TrimEntityKeys(jsonMap interface{}, keys []string) { 29 // initialize map to root of BOM document 30 // ALWAYS default to document root for trim operation 31 if jsonMap != nil { 32 for _, key := range keys { 33 if key != "" { 34 bom.TrimEntityKey(jsonMap, key) 35 } 36 } 37 } 38 } 39 40 // Note: this method is recursive 41 func (bom *BOM) TrimEntityKey(entity interface{}, key string) { 42 switch typedEntity := entity.(type) { 43 case map[string]interface{}: 44 jsonMap := typedEntity 45 _, ok := jsonMap[key] 46 if ok { 47 // TODO: make it an option to just "nil" out the value 48 // as this is faster as well as sufficient for json.Marshal() purposes 49 // as keys with nil values are already omitted. 50 // To be clear, using delete() is MUCH better as it works for all 51 // our existing/planned use cases; whereas using nil may cause other issues. 52 //jsonMap[key] = nil 53 delete(jsonMap, key) 54 } 55 for _, mapValue := range jsonMap { 56 // avoid making costly function calls for primitive types 57 switch typedValue := mapValue.(type) { 58 case map[string]interface{}: 59 bom.TrimEntityKey(typedValue, key) 60 case []interface{}: 61 bom.TrimEntityKey(typedValue, key) 62 } 63 } 64 case []interface{}: 65 // if type is other than above 66 sliceValue := typedEntity 67 for iSlice := range sliceValue { 68 bom.TrimEntityKey(sliceValue[iSlice], key) 69 } 70 default: 71 // if type is other than above 72 getLogger().Debugf("unhandled type: [%T]", typedEntity) 73 } 74 }