001/* 002 * JDrupes Builder 003 * Copyright (C) 2025, 2026 Michael N. Lipp 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <https://www.gnu.org/licenses/>. 017 */ 018 019package org.jdrupes.builder.core; 020 021import java.time.Instant; 022import java.util.Optional; 023import java.util.stream.Stream; 024import org.jdrupes.builder.api.ExecResult; 025import org.jdrupes.builder.api.Resource; 026import org.jdrupes.builder.api.ResourceProvider; 027 028/// Default implementation of a test result. 029/// 030/// @param <T> the generic type 031/// 032public class DefaultExecResult<T extends Resource> extends ResourceObject 033 implements ExecResult<T> { 034 035 private final ResourceProvider provider; 036 private final int exitValue; 037 private boolean isFaulty; 038 private final StreamCollector<T> resources; 039 private Instant asOf; 040 041 /// Initializes a new default exec result. Note that an `exitValue` 042 /// different from 0 does not automatically mark the result as faulty. 043 /// 044 /// @param provider the provider 045 /// @param name the name 046 /// @param exitValue the exit value 047 /// 048 @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") 049 protected DefaultExecResult(ResourceProvider provider, 050 String name, int exitValue) { 051 name(name); 052 this.provider = provider; 053 this.exitValue = exitValue; 054 resources = new StreamCollector<>(true); 055 } 056 057 /// Returns the [ResourceProvider] that generated this result. 058 /// 059 /// @return the resource provider 060 /// 061 public ResourceProvider provider() { 062 return provider; 063 } 064 065 @Override 066 public int exitValue() { 067 return exitValue; 068 } 069 070 @Override 071 public boolean isFaulty() { 072 return isFaulty; 073 } 074 075 @Override 076 public DefaultExecResult<T> setFaulty() { 077 isFaulty = true; 078 return this; 079 } 080 081 @Override 082 public Stream<T> resources() { 083 return resources.stream(); 084 } 085 086 /// Sets the resources associated with this result. 087 /// 088 /// @param resources the resources 089 /// @return the default exec result 090 /// 091 public DefaultExecResult<T> resources(Stream<T> resources) { 092 this.resources.add(resources); 093 return this; 094 } 095 096 @Override 097 public DefaultExecResult<T> asOf(Instant asOf) { 098 if (this.asOf != null) { 099 throw new IllegalStateException("asOf() may only be called once."); 100 } 101 this.asOf = asOf; 102 return this; 103 } 104 105 @Override 106 public Optional<Instant> asOf() { 107 if (asOf == null) { 108 return Optional.empty(); 109 } 110 return Optional.of(asOf); 111 } 112 113 @Override 114 public String toString() { 115 return ExecResult.class.getSimpleName() 116 + " from " + provider.name() 117 + name().map(n -> ": " + n).orElse("") 118 + " {exitValue=" + exitValue + "}"; 119 } 120}