001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.oscal.lib.model.control.catalog; 007 008import gov.nist.secauto.metaschema.core.util.CollectionUtil; 009import gov.nist.secauto.metaschema.core.util.ObjectUtils; 010import gov.nist.secauto.oscal.lib.model.Catalog; 011import gov.nist.secauto.oscal.lib.model.CatalogGroup; 012import gov.nist.secauto.oscal.lib.model.Control; 013import gov.nist.secauto.oscal.lib.model.Parameter; 014 015import java.util.Objects; 016 017import edu.umd.cs.findbugs.annotations.NonNull; 018 019public abstract class AbstractCatalogVisitor<RESULT, CONTEXT> implements ICatalogVisitor<RESULT, CONTEXT> { 020 021 /** 022 * Get a new initial/default result for the visitor. 023 * 024 * @return the result 025 */ 026 protected abstract RESULT defaultResult(); 027 028 /** 029 * Aggregate two results into one. 030 * 031 * @param previous 032 * the first result 033 * @param current 034 * the next result 035 * @return the result produced by combining the two results 036 */ 037 protected RESULT aggregateResult(RESULT previous, RESULT current) { 038 return current; 039 } 040 041 @Override 042 public RESULT visitCatalog(Catalog catalog, CONTEXT context) { 043 RESULT result = CollectionUtil.listOrEmpty(catalog.getGroups()).stream() 044 .filter(Objects::nonNull) 045 .map(childGroup -> visitGroup(ObjectUtils.notNull(childGroup), context)) 046 .reduce(defaultResult(), this::aggregateResult); 047 result = CollectionUtil.listOrEmpty(catalog.getControls()).stream() 048 .filter(Objects::nonNull) 049 .map(childControl -> visitControl(ObjectUtils.notNull(childControl), context)) 050 .reduce(result, this::aggregateResult); 051 return CollectionUtil.listOrEmpty(catalog.getParams()).stream() 052 .filter(Objects::nonNull) 053 .map(childParameter -> visitParameter(ObjectUtils.notNull(childParameter), context)) 054 .reduce(result, this::aggregateResult); 055 } 056 057 @Override 058 public RESULT visitGroup(@NonNull CatalogGroup group, CONTEXT context) { 059 RESULT result = CollectionUtil.listOrEmpty(group.getGroups()).stream() 060 .filter(Objects::nonNull) 061 .map(childGroup -> visitGroup(ObjectUtils.notNull(childGroup), context)) 062 .reduce(defaultResult(), this::aggregateResult); 063 result = CollectionUtil.listOrEmpty(group.getControls()).stream() 064 .filter(Objects::nonNull) 065 .map(childControl -> visitControl(ObjectUtils.notNull(childControl), context)) 066 .reduce(result, this::aggregateResult); 067 return CollectionUtil.listOrEmpty(group.getParams()).stream() 068 .filter(Objects::nonNull) 069 .map(childParameter -> visitParameter(ObjectUtils.notNull(childParameter), context)) 070 .reduce(result, this::aggregateResult); 071 } 072 073 @Override 074 public RESULT visitControl(Control control, CONTEXT context) { 075 RESULT result = CollectionUtil.listOrEmpty(control.getControls()).stream() 076 .filter(Objects::nonNull) 077 .map(childControl -> visitControl(ObjectUtils.notNull(childControl), context)) 078 .reduce(defaultResult(), this::aggregateResult); 079 return CollectionUtil.listOrEmpty(control.getParams()).stream() 080 .filter(Objects::nonNull) 081 .map(childParameter -> visitParameter(ObjectUtils.notNull(childParameter), context)) 082 .reduce(result, this::aggregateResult); 083 } 084 085 @Override 086 public RESULT visitParameter(Parameter parameter, CONTEXT context) { 087 return defaultResult(); 088 } 089 090}