001package ca.cdr.api.pub.hl7v2.model; 002 003/*- 004 * #%L 005 * Smile CDR - CDR 006 * %% 007 * Copyright (C) 2016 - 2024 Smile CDR, Inc. 008 * %% 009 * All rights reserved. 010 * #L% 011 */ 012 013import com.fasterxml.jackson.annotation.JsonProperty; 014import com.fasterxml.jackson.annotation.JsonPropertyOrder; 015import org.apache.commons.lang3.Validate; 016import org.apache.commons.lang3.builder.EqualsBuilder; 017import org.apache.commons.lang3.builder.HashCodeBuilder; 018import org.apache.commons.lang3.builder.ToStringBuilder; 019import org.apache.commons.lang3.builder.ToStringStyle; 020 021import static ca.cdr.api.pub.hl7v2.model.MappingMessage.LEVEL; 022import static ca.cdr.api.pub.hl7v2.model.MappingMessage.MESSAGE; 023import static ca.cdr.api.pub.hl7v2.model.MappingMessage.PATH; 024import static ca.cdr.api.pub.hl7v2.model.MappingMessage.PATH_TYPE; 025import static org.apache.commons.lang3.StringUtils.isBlank; 026 027/** 028 * This class represents a message, issue detected, warning, etc. when processing a transaction 029 * in Smile CDR. It can be used to track mapping errors, and will generally result in 030 * log entries in the transaction log. 031 */ 032@JsonPropertyOrder({LEVEL, MESSAGE, PATH, PATH_TYPE}) 033public class MappingMessage { 034 035 public static final String LEVEL = "level"; 036 public static final String MESSAGE = "message"; 037 public static final String PATH = "path"; 038 public static final String PATH_TYPE = "pathType"; 039 040 @JsonProperty(LEVEL) 041 private MessageLevel myLevel; 042 043 @JsonProperty(MESSAGE) 044 private String myMessage; 045 046 @JsonProperty(PATH) 047 private String myPath; 048 049 @JsonProperty(PATH_TYPE) 050 private PathType myPathType; 051 052 /** 053 * Constructor 054 */ 055 public MappingMessage() { 056 super(); 057 } 058 059 /** 060 * Constructor 061 * 062 * @param thePath The terser path (may be <code>null</code> or empty) to the location in the message where the issue was detected, such as <code>PATIENT_RESULT/PID-3(1)-2</code> 063 * @param theLevel The severity. Note that adding a message with level {@link MessageLevel#ERROR} indicates that the processing failed and should not be completed. 064 * @param theMessage The actual message 065 */ 066 public MappingMessage(String thePath, PathType thePathType, MessageLevel theLevel, String theMessage) { 067 myPath = thePath; 068 myPathType = thePathType; 069 myLevel = theLevel; 070 myMessage = theMessage; 071 } 072 073 public PathType getPathType() { 074 return myPathType; 075 } 076 077 @Override 078 public boolean equals(Object theO) { 079 if (this == theO) { 080 return true; 081 } 082 083 if (theO == null || getClass() != theO.getClass()) { 084 return false; 085 } 086 087 MappingMessage that = (MappingMessage) theO; 088 089 return new EqualsBuilder() 090 .append(getLevel(), that.getLevel()) 091 .append(myMessage, that.myMessage) 092 .append(getPath(), that.getPath()) 093 .isEquals(); 094 } 095 096 /** 097 * @return The severity 098 */ 099 public MessageLevel getLevel() { 100 return myLevel; 101 } 102 103 /** 104 * @param theLevel The severity. Note that adding a message with level {@link MessageLevel#ERROR} indicates that the processing failed and should not be completed. 105 */ 106 public MappingMessage setLevel(MessageLevel theLevel) { 107 myLevel = theLevel; 108 return this; 109 } 110 111 /** 112 * @return The actual message 113 */ 114 public String getMessage() { 115 return myMessage; 116 } 117 118 /** 119 * @param theMessage The actual message 120 */ 121 public MappingMessage setMessage(String theMessage) { 122 myMessage = theMessage; 123 return this; 124 } 125 126 /** 127 * @return The terser path (may be <code>null</code> or empty) to the location in the message where the issue was detected, such as <code>PATIENT_RESULT/PID-3(1)-2</code> 128 */ 129 public String getPath() { 130 return myPath; 131 } 132 133 /** 134 * @param thePath The terser path (may be <code>null</code> or empty) to the location in the message where the issue was detected, such as <code>PATIENT_RESULT/PID-3(1)-2</code> 135 */ 136 public MappingMessage setPath(String thePath, PathType thePathType) { 137 Validate.isTrue(isBlank(thePath) ^ thePathType != null); 138 myPath = thePath; 139 myPathType = thePathType; 140 return this; 141 } 142 143 @Override 144 public int hashCode() { 145 return new HashCodeBuilder(17, 37) 146 .append(getLevel()) 147 .append(myMessage) 148 .append(getPath()) 149 .toHashCode(); 150 } 151 152 @Override 153 public String toString() { 154 ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 155 b.append("path", myPath); 156 b.append("level", myLevel); 157 b.append("message", myMessage); 158 return b.build(); 159 } 160 161 /** 162 * Severity level 163 */ 164 public enum MessageLevel { 165 // Do not sort! 166 /** 167 * Informational message 168 */ 169 INFO, 170 /** 171 * Warning (does not cause failure) 172 */ 173 WARNING, 174 /** 175 * Error (does cause failure) 176 */ 177 ERROR 178 } 179 180 public enum PathType { 181 182 /** 183 * HL7 v2 Terser Path notation 184 */ 185 HL7V2, 186 187 /** 188 * FHIR dotted path notation 189 */ 190 FHIR; 191 } 192}