/*******************************************************************************
 * Copyright 2017 xlate.io LLC, http://www.xlate.io
 *
 * Licensed 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 io.xlate.edi.stream;

public class EDIStreamException extends Exception {

    private static final long serialVersionUID = -1232370584780899896L;

    protected final transient Location location;

    /**
     * Construct an exception with the associated message.
     *
     * @param message
     *            the message to report
     */
    public EDIStreamException(String message) {
        super(message);
        location = null;
    }

    /**
     * Construct an exception with the associated exception
     *
     * @param cause
     *            a nested exception
     */
    public EDIStreamException(Throwable cause) {
        super(cause);
        location = null;
    }

    private static String displayLocation(Location location) {
        StringBuilder display = new StringBuilder();

        display.append("segment ");

        if (location.getSegmentTag() != null) {
            display.append(location.getSegmentTag());
        }

        display.append(" at position ");
        display.append(String.valueOf(location.getSegmentPosition()));

        if (location.getElementPosition() > -1) {
            display.append(", element ");
            display.append(String.valueOf(location.getElementPosition()));

            if (location.getElementOccurrence() > -1) {
                display.append("(occurrence ");
                display.append(String.valueOf(location.getElementOccurrence()));
                display.append(')');
            }
        }

        if (location.getComponentPosition() > -1) {
            display.append(", component ");
            display.append(String.valueOf(location.getComponentPosition()));
        }

        return display.toString();
    }

    /**
     * Construct an exception with the associated message, exception and
     * location.
     *
     * @param message
     *            the message to report
     * @param location
     *            the location of the error
     * @param cause
     *            a nested error / exception
     */
    public EDIStreamException(String message, Location location, Throwable cause) {
        super(message + " in " + displayLocation(location), cause);
        this.location = location;
    }

    /**
     * Construct an exception with the associated message, exception and
     * location.
     *
     * @param message
     *            the message to report
     * @param location
     *            the location of the error
     */
    public EDIStreamException(String message, Location location) {
        super(message + " in " + displayLocation(location));
        this.location = location;
    }

    /**
     * Gets the location of the exception
     *
     * @return the location of the exception, may be null if none is available
     */
    public Location getLocation() {
        return location;
    }
}

@@ -1583,32 +1583,206 @@
         
-display.append(%22
+if (location.getSegmentPosition() %3C 0) %7B%0A            display.append(%22at offset %22);%0A            display.append(location.getCharacterOffset());%0A        %7D else %7B%0A            display.append(%22in 
 segment 
@@ -1782,24 +1782,28 @@
 egment %22);%0A%0A
+    
         if (
@@ -1842,32 +1842,36 @@
 ) %7B%0A            
+    
 display.append(l
@@ -1896,35 +1896,103 @@
 Tag());%0A        
-%7D%0A%0A
+    %7D else %7B%0A                display.append(%22???%22);%0A            %7D%0A%0A    
         display.
@@ -2012,24 +2012,28 @@
 osition %22);%0A
+    
         disp
@@ -2092,32 +2092,36 @@
 n()));%0A%0A        
+   
+ 
 if (location.get
@@ -2138,32 +2138,36 @@
 ition() %3E -1) %7B%0A
+    
             disp
@@ -2196,32 +2196,36 @@
 %22);%0A            
+    
 display.append(S
@@ -2276,32 +2276,36 @@
 );%0A%0A            
+ 
+   
 if (location.get
@@ -2340,32 +2340,36 @@
                 
+    
 display.append(%22
@@ -2392,32 +2392,36 @@
                 
+   
+ 
 display.append(S
@@ -2477,32 +2477,36 @@
                 
+    
 display.append('
@@ -2522,16 +2522,20 @@
         
+    
 %7D%0A      
@@ -2528,35 +2528,43 @@
       %7D%0A        
+ 
-%7D%0A%0A
+   %7D%0A%0A    
         if (loca
@@ -2603,32 +2603,36 @@
 ) %7B%0A            
+   
+ 
 display.append(%22
@@ -2639,32 +2639,36 @@
 , component %22);%0A
+    
             disp
@@ -2724,24 +2724,38 @@
 sition()));%0A
+            %7D%0A
         %7D%0A%0A 
@@ -3203,35 +3203,32 @@
 uper(message + %22
- in
  %22 + displayLoca
@@ -3626,19 +3626,16 @@
 sage + %22
- in
  %22 + dis

Improve location of exception in EDIStreamException message (again)