package com.timgroup.tucker.info;

import java.net.URI;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;

public abstract class Component {
    private final String id;
    private final String label;
    private final Runbook runbook;
    
    public Component(String id, String label) {
        this(id, label, null);
    }

    public Component(String id, String label, Runbook defaultRunbook) {
        this.id = id;
        this.label = label;
        this.runbook = defaultRunbook;
    }
    
    public final String getId() {
        return id;
    }
    
    public final String getLabel() {
        return label;
    }
    
    public final Optional<Runbook> getRunbook() {
        return Optional.ofNullable(runbook);
    }

    public final boolean hasRunbook() {
        return runbook != null;
    }

    public abstract Report getReport();

    public final Component mapReport(UnaryOperator<Report> operator) {
        return new Component(id, label, runbook) {
            @Override
            public Report getReport() {
                return operator.apply(Component.this.getReport());
            }

            @Override
            public String toString() {
                return Component.this.toString();
            }
        };
    }

    public final Component withRunbook(Runbook runbook) {
        return new Component(id, label, Objects.requireNonNull(runbook)) {
            @Override
            public Report getReport() {
                return Component.this.getReport();
            }

            @Override
            public String toString() {
                return Component.this.toString();
            }
        };
    }

    public final Component withRunbook(URI runbookUri) {
        return withRunbook(new Runbook(runbookUri.toString()));
    }

    public final Component mapValue(UnaryOperator<Object> operator) {
        return mapReport(r -> r.mapValue(operator));
    }

    public final Component mapStatus(UnaryOperator<Status> operator) { return mapReport(r -> r.mapStatus(operator)); }

    public final Component withStatusNoWorseThan(Status notWorse) { return mapReport(r -> r.withStatusNoWorseThan(notWorse)); }

    public static Component supplyReport(String id, String label, Supplier<Report> supplier) {
        return new Component(id, label) {
            @Override
            public Report getReport() {
                return supplier.get();
            }

            @Override
            public String toString() {
                return getId() + ":" + supplier;
            }
        };
    }

    public static Component supplyInfo(String id, String label, Supplier<String> supplier) {
        return new Component(id, label) {
            @Override
            public Report getReport() {
                return new Report(Status.INFO, supplier.get());
            }

            @Override
            public String toString() {
                return getId() + ":info:" + supplier;
            }
        };
    }
}

@@ -53,34 +53,8 @@
 RI;%0A
-import java.util.Objects;%0A
 impo
@@ -154,16 +154,65 @@
 rator;%0A%0A
+import static java.util.Objects.requireNonNull;%0A%0A
 public a
@@ -514,18 +514,34 @@
 is.id = 
+requireNonNull(
 id
+)
 ;%0A      
@@ -555,21 +555,37 @@
 label = 
+requireNonNull(
 label
+)
 ;%0A      
@@ -1047,32 +1047,66 @@
 rt%3E operator) %7B%0A
+        requireNonNull(operator);%0A
         return n
@@ -1525,24 +1525,16 @@
  label, 
-Objects.
 requireN
@@ -2013,32 +2013,66 @@
 ct%3E operator) %7B%0A
+        requireNonNull(operator);%0A
         return m
@@ -2185,16 +2185,58 @@
 rator) %7B
+%0A        requireNonNull(operator);%0A       
  return 
@@ -2273,16 +2273,20 @@
 rator));
+%0A   
  %7D%0A%0A    
@@ -2348,16 +2348,58 @@
 Worse) %7B
+%0A        requireNonNull(notWorse);%0A       
  return 
@@ -2448,16 +2448,20 @@
 Worse));
+%0A   
  %7D%0A%0A    
@@ -2543,32 +2543,66 @@
 rt%3E supplier) %7B%0A
+        requireNonNull(supplier);%0A
         return n
@@ -2970,32 +2970,66 @@
 ng%3E supplier) %7B%0A
+        requireNonNull(supplier);%0A
         return n

Check for null values to method/constructor parameters earlier in Component