content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.camel.component.hl7;
  
  import ca.uhn.hl7v2.AcknowledgmentCode;
  import ca.uhn.hl7v2.ErrorCode;
  import ca.uhn.hl7v2.HL7Exception;
  import ca.uhn.hl7v2.model.Message;
  import org.apache.camel.Exchange;
  import org.apache.camel.ExchangePropertyKey;
  import org.apache.camel.RuntimeCamelException;
  import org.apache.camel.support.ExpressionAdapter;
  
  public class AckExpression extends ExpressionAdapter {
  
      private AcknowledgmentCode acknowledgementCode;
      private String errorMessage;
      private ErrorCode errorCode;
  
      public AckExpression() {
          this((AcknowledgmentCode) null, null, ErrorCode.APPLICATION_INTERNAL_ERROR);
      }
  
      public AckExpression(AcknowledgmentCode acknowledgementCode) {
          this(acknowledgementCode, null, ErrorCode.APPLICATION_INTERNAL_ERROR);
      }
  
      public AckExpression(AcknowledgmentCode acknowledgementCode, String errorMessage, ErrorCode errorCode) {
          this.acknowledgementCode = acknowledgementCode;
          this.errorMessage = errorMessage;
          this.errorCode = errorCode;
      }
  
      @Override
      public Object evaluate(Exchange exchange) {
          Throwable t = exchange.getProperty(ExchangePropertyKey.EXCEPTION_CAUGHT, Throwable.class);
          Message msg = exchange.getIn().getBody(Message.class);
          try {
              HL7Exception hl7e = generateHL7Exception(t);
              AcknowledgmentCode code = acknowledgementCode;
              if (t != null && code == null) {
                  code = AcknowledgmentCode.AE;
              }
              return msg.generateACK(code == null ? AcknowledgmentCode.AA : code, hl7e);
          } catch (Exception e) {
              throw RuntimeCamelException.wrapRuntimeCamelException(e);
          }
      }
  
      private HL7Exception generateHL7Exception(Throwable t) {
          HL7Exception hl7Exception = null;
          if (t == null) {
              if (acknowledgementCode != null && !isSuccess(acknowledgementCode)) {
                  hl7Exception = new HL7Exception(errorMessage, errorCode);
              }
          } else {
              if (t instanceof HL7Exception) {
                  hl7Exception = (HL7Exception) t;
              } else {
                  hl7Exception = new HL7Exception(
                          errorMessage != null ? errorMessage : t.getMessage(),
                          errorCode, t);
              }
          }
          return hl7Exception;
      }
  
      private boolean isSuccess(AcknowledgmentCode code) {
          return code.name().endsWith("A");
      }
  
  }
  