package at.gv.egiz.moazs.scheme; import at.gv.zustellung.app2mzs.xsd.DeliveryNotificationType; import at.gv.zustellung.app2mzs.xsd.*; import at.gv.zustellung.msg.xsd.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.xml.bind.JAXBElement; import java.math.BigInteger; import java.util.List; import java.util.Optional; import static at.gv.egiz.moazs.MoaZSException.moaZSException; import static at.gv.zustellung.app2mzs.xsd.DeliveryNotificationType.AdditionalFormat.additionalFormatBuilder; import static at.gv.zustellung.app2mzs.xsd.DeliveryNotificationType.deliveryNotificationTypeBuilder; import static at.gv.zustellung.app2mzs.xsd.DeliveryResponseType.deliveryResponseTypeBuilder; import static at.gv.zustellung.app2mzs.xsd.ErrorType.errorTypeBuilder; import static at.gv.zustellung.app2mzs.xsd.PartialSuccessType.partialSuccessTypeBuilder; import static at.gv.zustellung.app2mzs.xsd.SuccessType.successTypeBuilder; import static java.util.stream.Collectors.toList; @Component public class Msg2MzsConverter { private static final Logger log = LoggerFactory.getLogger(Msg2MzsConverter.class); private static final String ANSWERS_MISSING_ERROR_MSG = "msg:DeliveryNotification contains no msg:Answer elements" + " and cannot be converted to mzs:DeliveryNotification."; private static final String UNKNOWN_ANSWER_ERROR_MSG = "msg:DeliveryNotification/msg:Answer is of unknown type" + " and cannot be converted."; private static final String TOO_MANY_ANSWERS_MSG = "msg:DeliveryNotification contains more msg:Answer elements than" + " expected. All answers except the first one will be ignored."; public DeliveryResponseType convert(DeliveryRequestStatusType status, Optional signedStatus) { var responseBuilder = deliveryResponseTypeBuilder(); if (status.getError() != null) { responseBuilder.withError(convert(status.getError(), signedStatus)); } else if (status.getSuccess() != null) { responseBuilder.withSuccess(convert(status.getSuccess(), signedStatus)); } else { responseBuilder.withPartialSuccess(convert(status.getPartialSuccess(), signedStatus)); } return responseBuilder.build(); } private SuccessType convert(DeliveryRequestStatusType.Success success, Optional signedStatus) { return successTypeBuilder() .withAppDeliveryID(success.getAppDeliveryID()) .withDeliverySystem(success.getDeliverySystem()) .withGZ(success.getGZ()) .withZSDeliveryID(success.getZSDeliveryID()) .withSignedDeliveryRequestStatus(signedStatus.orElse(null)) .withRelayedViaERV(success.isRelayedViaERV()) .withDeliveryTimestamp(success.getDeliveryTimestamp()) .build(); } private PartialSuccessType convert(DeliveryAnswerType answer, Optional signedStatus) { return partialSuccessTypeBuilder() .withAppDeliveryID(answer.getAppDeliveryID()) .withDeliverySystem(answer.getDeliverySystem()) .withGZ(answer.getGZ()) .withZSDeliveryID(answer.getZSDeliveryID()) .withSignedDeliveryRequestStatus(signedStatus.orElse(null)) .build(); } private ErrorType convert(DeliveryRequestStatusType.Error error, Optional signedStatus) { var builder = errorTypeBuilder() .withAppDeliveryID(error.getAppDeliveryID()) .withDeliverySystem(error.getDeliverySystem()) .withGZ(error.getGZ()) .withZSDeliveryID(error.getZSDeliveryID()) .withSignedDeliveryRequestStatus(signedStatus.orElse(null)) .withPreAdviceNoteSent(error.getPreAdviceNoteSent()) .withCode(new BigInteger(error.getErrorInfo().getCode())); if(error.getErrorInfo().getText() != null) builder.withText(error.getErrorInfo().getText()); return builder.build(); } public DeliveryNotificationType convert(at.gv.zustellung.msg.xsd.DeliveryNotificationType msgNotification, Optional signedNotification) { var builder = deliveryNotificationTypeBuilder(); if (msgNotification.getAnswer().isEmpty()) { throw moaZSException(ANSWERS_MISSING_ERROR_MSG); } if (msgNotification.getAnswer().size() > 1) { log.warn(TOO_MANY_ANSWERS_MSG); } JAXBElement answer = msgNotification.getAnswer().get(0); if(answer.getValue() instanceof AcceptedType) { var accepted = (AcceptedType) answer.getValue(); builder.withSuccess(extractSuccess(msgNotification, signedNotification)) .withNotificationsPerformed(accepted.getNotificationsPerformed()); } else if(answer.getValue() instanceof DeliveryErrorType) { var error = (DeliveryErrorType) answer.getValue(); builder.withError(extractError(msgNotification, error, signedNotification)) .withNotificationsPerformed(error.getNotificationsPerformed()); } else { throw moaZSException(UNKNOWN_ANSWER_ERROR_MSG); } return builder .withSenderDetails(msgNotification.getSenderDetails()) .withReceiverDetails(msgNotification.getReceiverDetails()) .withUser(msgNotification.getUser()) .withAdditionalFormat(convert(msgNotification.getAdditionalFormat())) .build(); } private ErrorType extractError(at.gv.zustellung.msg.xsd.DeliveryNotificationType msgNotification, DeliveryErrorType error, Optional signedNotification) { return errorTypeBuilder() .withAppDeliveryID(msgNotification.getAppDeliveryID()) .withDeliverySystem(msgNotification.getDeliverySystem()) .withZSDeliveryID(msgNotification.getZSDeliveryID()) .withGZ(msgNotification.getGZ()) .withSignedDeliveryRequestStatus(signedNotification.orElse(null)) .withCode(new BigInteger(error.getErrorInfo().getCode())) .withText(error.getErrorInfo().getText()) .build(); } private SuccessType extractSuccess(at.gv.zustellung.msg.xsd.DeliveryNotificationType msgNotification, Optional signedNotification) { return successTypeBuilder() .withAppDeliveryID(msgNotification.getAppDeliveryID()) .withDeliverySystem(msgNotification.getDeliverySystem()) .withZSDeliveryID(msgNotification.getZSDeliveryID()) .withGZ(msgNotification.getGZ()) .withSignedDeliveryRequestStatus(signedNotification.orElse(null)) .withRelayedViaERV(msgNotification.isRelayedViaERV()) .withDeliveryTimestamp(msgNotification.getTimestamp()) .build(); } private List convert( List additionalFormat) { return additionalFormat.stream() .map(this::convert) .collect(toList()); } private DeliveryNotificationType.AdditionalFormat convert( at.gv.zustellung.msg.xsd.DeliveryNotificationType.AdditionalFormat format) { return additionalFormatBuilder() .withType(format.getType()) .withValue(format.getValue()) .build(); } }