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