summaryrefslogtreecommitdiffstats
path: root/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Report.java
blob: 0f1b7c3413c0588efd4c1e30f7a556f73913beb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package org.onap.sdc.dcae.checker;

import java.io.IOException;

import java.util.LinkedList;
import java.util.Collections;

import org.yaml.snakeyaml.error.MarkedYAMLException;
import kwalify.ValidationException;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;

/**
 * Represents a collection of errors that occured during one of the stages
 * of the checker: yaml parsing, yaml validation (tosca syntax), tosca checking
 */
/*
 * This needs some re-thinking: while it is useful to have all original errors introducing
 * the custom json conversion (just to help the service) is not great either.
 * I was torn between this approach or creating a custom deserializer and object mapper (which
 * would have kept all the customized serialization in the service but then the error analysis
 * would be duplicated there too ..).  
 */
@JsonSerialize(contentUsing=org.onap.sdc.dcae.checker.Report.ReportEntrySerializer.class)
public class Report<T extends Throwable> extends LinkedList<T> {

	public Report() {
	}

	public Report(T[] theErrors) {
		Collections.addAll(this, theErrors);
	}

	public boolean hasErrors() {
		return !this.isEmpty();
	}

	public boolean addOnce(T theError) {
		for (T e: this) {
			if (e.getMessage().equals(theError.getMessage()))
				return false;
		}
		return add(theError);
	}

	public String toString() {
    StringBuilder sb = new StringBuilder(this.size() + " errors");
    for (Throwable x: this) {
      sb.append("\n")
				.append("[")
        .append(location(x))
        .append("] ")
				.append(x.getMessage());
				if (x.getCause() != null) {
					sb.append("\n\tCaused by:\n")
          	.append(x.getCause());
				}
    }
		sb.append("\n");
		return sb.toString();
	}

	private static String location(Throwable theError) {
		if (theError instanceof MarkedYAMLException) {
			MarkedYAMLException mx = (MarkedYAMLException)theError;
			return "line " + mx.getProblemMark().getLine() + ", column " + mx.getProblemMark().getColumn();
		}
		if (theError instanceof ValidationException) {
      ValidationException vx = (ValidationException)theError;
      return vx.getPath();
    }
		if (theError instanceof TargetError) {
    	TargetError tx = (TargetError)theError;
      return tx.getLocation();
		}
		return "unknown"; 
	}


	public static class ReportEntrySerializer extends StdSerializer<Throwable> {
		
		public ReportEntrySerializer() {
			super(Throwable.class);
		}

    @Override
    public void serialize(Throwable theError, JsonGenerator theGenerator, SerializerProvider theProvider) 
																												      throws IOException, JsonProcessingException {
      theGenerator.writeStartObject();
      theGenerator.writeStringField("location", location(theError));
      theGenerator.writeStringField("message", theError.getMessage());
			if (theError.getCause() != null)
      	theGenerator.writeStringField("cause", theError.getCause().toString());
      theGenerator.writeEndObject();
    }
	}
}