/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 * 
 *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
 *    
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotools.data.ows;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.geotools.ows.ServiceException;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

/**
 * Utility class that will parse ServiceExceptions out of an inputStream.
 * 
 * @author rgould
 *
 *
 *
 *
 * @source $URL$
 */
public class ServiceExceptionParser {

    /**
     * Tries to read a ServiceExceptionReport from the input stream, and 
     * construct a chain of ServiceExceptions.
     * 
     * ServiceExceptions beyond the first can be accessed using 
     * ServiceException.next();
     * 
     * @param inputStream
     * @throws JDOMException
     * @throws IOException
     */
    public static ServiceException parse(InputStream inputStream) throws JDOMException, IOException {
        SAXBuilder builder = new SAXBuilder();
        Document document = builder.build(inputStream);
        
        Element root = document.getRootElement();
        List serviceExceptions = root.getChildren("ServiceException");
                
        /*
         * ServiceExceptions with codes get bumped to the top of the list.
         */
        List codes = new ArrayList();
        List noCodes = new ArrayList();
        for (int i = 0; i < serviceExceptions.size(); i++) {
            Element element = (Element) serviceExceptions.get(i);
            ServiceException exception = parseSE(element);
            if (exception.getCode() != null && exception.getCode().length() != 0 ) {
                codes.add(exception);
            } else {
                noCodes.add(exception);
            }
        }
        
        /*
         * Now chain them.
         */
        ServiceException firstException = null;
        ServiceException recentException = null;
        for (int i = 0; i < codes.size(); i++) {
            ServiceException exception = (ServiceException) codes.get(i);
            if (firstException == null) {
                firstException = exception;
                recentException = exception;
            } else {
                recentException.setNext(exception);
                recentException = exception;
            }
        }
        codes = null;
        for (int i = 0; i < noCodes.size(); i++) {
            ServiceException exception = (ServiceException) noCodes.get(i);
            if (firstException == null) {
                firstException = exception;
                recentException = exception;
            } else {
                recentException.setNext(exception);
                recentException = exception;
            }
        }
        noCodes = null;
        
        return firstException;
    }

    private static ServiceException parseSE(Element element) {
        String errorMessage = element.getText();
        String code = element.getAttributeValue("code");
        
        return new ServiceException(errorMessage, code);
    }

}

@@ -750,21 +750,16 @@
 va.util.
-Array
 List;%0Aim
@@ -773,20 +773,33 @@
 va.util.
-Li
 st
+ream.Collectors
 ;%0A%0Aimpor
@@ -1736,16 +1736,25 @@
     List
+%3CElement%3E
  service
@@ -1935,174 +1935,45 @@
 List
- codes = new ArrayList();%0A        List noCodes = new ArrayList();%0A        for (int i = 0; i %3C serviceExceptions.size(); i++) %7B%0A            Element element = (Element)
+%3CServiceException%3E parsedExceptions =
  ser
@@ -1987,23 +1987,24 @@
 eptions.
-get(i);
+stream()
 %0A       
@@ -2000,32 +2000,37 @@
 m()%0A            
+.map(
 ServiceException
@@ -2033,255 +2033,120 @@
 tion
- exception = parseSE(element);%0A            if (exception.getCode() != null && exception.getCode().length() != 0 ) %7B%0A                codes.add(exception);%0A            %7D else %7B%0A                noCodes.add(exception);%0A            %7D%0A        %7D%0A        
+Parser::parseSE)%0A            .sorted(ServiceExceptionParser::compare)%0A            .collect(Collectors.toList());
 %0A   
@@ -2306,117 +2306,56 @@
 or (
-int i = 0; i %3C codes.size(); i++) %7B%0A            ServiceException exception = (ServiceException) codes.get(i);
+ServiceException exception : parsedExceptions) %7B
 %0A   
@@ -2636,375 +2636,333 @@
     
-codes = null;%0A        for (int i = 0; i %3C noCodes.size(); i++) %7B%0A 
+%0A        return firstException;%0A
     
+%7D%0A%0A
     
-   ServiceException exception = (ServiceException) noCodes.get(i);%0A            if (firstException == null) %7B%0A                firstException = exception;%0A                recentException = exception;%0A            %7D else %7B%0A                recentException.setNext(exception
+private static ServiceException parseSE(Element element) %7B%0A        String errorMessage = element.getText();%0A        String code = element.getAttributeValue(%22code%22);%0A        %0A        return new ServiceException(errorMessage, code
 );%0A    
- 
+%7D%0A
     
+%0A
     
-   recent
+private static int sortValue(Service
 Exce
@@ -2958,34 +2958,32 @@
 ServiceException
- =
  exception;%0A    
@@ -2980,104 +2980,101 @@
 tion
-;%0A            %7D%0A        %7D%0A        noCodes = null;%0A        %0A        return firstException
+) %7B%0A        return exception.getCode() != null && !exception.getCode().isEmpty() ?0:1
 ;%0A    %7D%0A
 %0A   
@@ -3061,32 +3061,36 @@
 y() ?0:1;%0A    %7D%0A
+    
 %0A    private sta
@@ -3085,32 +3085,44 @@
  private static 
+int compare(
 ServiceException
@@ -3126,204 +3126,108 @@
 ion 
-parseSE(Element element) %7B%0A        String errorMessage = element.getText();%0A        String code = element.getAttributeValue(%22code%22);%0A        %0A        return new ServiceException(errorMessage, code
+exception1, ServiceException exception2) %7B%0A        return sortValue(exception1)-sortValue(exception2
 );%0A 
@@ -3231,11 +3231,10 @@
 ;%0A    %7D%0A
-%0A
 %7D%0A

Tidy ServiceExceptionParser