001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.oscal.lib.model.control; 007 008import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; 009import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; 010import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.InsertAnchorExtension.InsertAnchorNode; 011import gov.nist.secauto.metaschema.core.util.CollectionUtil; 012import gov.nist.secauto.metaschema.core.util.ObjectUtils; 013import gov.nist.secauto.oscal.lib.model.ControlPart; 014import gov.nist.secauto.oscal.lib.model.Link; 015import gov.nist.secauto.oscal.lib.model.Property; 016 017import java.net.URI; 018import java.util.LinkedList; 019import java.util.List; 020import java.util.Objects; 021import java.util.function.Predicate; 022import java.util.stream.Stream; 023 024import edu.umd.cs.findbugs.annotations.NonNull; 025 026public abstract class AbstractPart implements IPart { 027 028 @Override 029 @NonNull 030 public Stream<InsertAnchorNode> getInserts(@NonNull Predicate<InsertAnchorNode> filter) { 031 MarkupMultiline prose = getProse(); 032 033 @NonNull Stream<InsertAnchorNode> retval; 034 if (prose == null) { 035 retval = ObjectUtils.notNull(Stream.empty()); 036 } else { 037 List<InsertAnchorNode> result = prose.getInserts(filter); 038 retval = ObjectUtils.notNull(result.stream()); 039 } 040 return retval; 041 } 042 043 public Stream<IPart> getPartsRecursively() { 044 return Stream.concat( 045 Stream.of(this), 046 CollectionUtil.listOrEmpty(getParts()).stream() 047 .flatMap(AbstractPart::getPartsRecursively)); 048 } 049 050 @NonNull 051 public static Builder builder(@NonNull String name) { 052 return new Builder(name); 053 } 054 055 public static class Builder { 056 private String id; 057 @NonNull 058 private final String name; 059 private URI namespace; 060 private String clazz; 061 private MarkupMultiline prose; 062 private MarkupLine title; 063 private final List<Property> props = new LinkedList<>(); 064 private final List<Link> links = new LinkedList<>(); 065 private final List<ControlPart> parts = new LinkedList<>(); 066 067 public Builder(@NonNull String name) { 068 this.name = Objects.requireNonNull(name); 069 } 070 071 @SuppressWarnings("PMD.ShortMethodName") 072 @NonNull 073 public Builder id(@NonNull String value) { 074 this.id = Objects.requireNonNull(value); 075 return this; 076 } 077 078 @NonNull 079 public Builder namespace(@NonNull URI value) { 080 this.namespace = Objects.requireNonNull(value); 081 return this; 082 } 083 084 @NonNull 085 public Builder clazz(@NonNull String value) { 086 this.clazz = Objects.requireNonNull(value); 087 return this; 088 } 089 090 @NonNull 091 public Builder title(@NonNull String markdown) { 092 return title(MarkupLine.fromMarkdown(Objects.requireNonNull(markdown))); 093 } 094 095 @NonNull 096 public Builder title(@NonNull MarkupLine value) { 097 this.title = Objects.requireNonNull(value); 098 return this; 099 } 100 101 @NonNull 102 public Builder prose(@NonNull String markdown) { 103 return prose(MarkupMultiline.fromMarkdown(Objects.requireNonNull(markdown))); 104 } 105 106 @NonNull 107 public Builder prose(@NonNull MarkupMultiline value) { 108 this.prose = Objects.requireNonNull(value); 109 return this; 110 } 111 112 @NonNull 113 public Builder prop(@NonNull Property value) { 114 this.props.add(Objects.requireNonNull(value)); 115 return this; 116 } 117 118 @NonNull 119 public Builder link(@NonNull Link value) { 120 this.links.add(Objects.requireNonNull(value)); 121 return this; 122 } 123 124 @NonNull 125 public Builder part(@NonNull ControlPart value) { 126 this.parts.add(Objects.requireNonNull(value)); 127 return this; 128 } 129 130 @NonNull 131 public ControlPart build() { 132 ControlPart retval = new ControlPart(); 133 134 retval.setName(name); 135 136 if (id != null) { 137 retval.setId(id); 138 } 139 if (namespace != null) { 140 retval.setNs(namespace); 141 } 142 if (clazz != null) { 143 retval.setClazz(clazz); 144 } 145 if (prose != null) { 146 retval.setProse(prose); 147 } 148 if (title != null) { 149 retval.setTitle(title); 150 } 151 if (!props.isEmpty()) { 152 retval.setProps(props); 153 } 154 if (!links.isEmpty()) { 155 retval.setLinks(links); 156 } 157 if (!parts.isEmpty()) { 158 retval.setParts(parts); 159 } 160 return retval; 161 } 162 } 163}