<commit_before>package annis.rest.provider;

import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;

import org.corpus_tools.graphannis.errors.AQLSyntaxError;
import org.corpus_tools.graphannis.errors.GraphANNISException;

import annis.model.AqlParseError;
import annis.model.ParsedEntityLocation;

public abstract class AQLErrorMapperBase<T extends GraphANNISException> implements ExceptionMapper<T> {

    private static final Pattern locationPattern = Pattern.compile(
                "\\[(?<startline>[0-9]+):(?<startcol>[0-9]+)(-(?<endline>[0-9]+):(?<endcol>[0-9]+))?\\]");

    public AQLErrorMapperBase() {
        super();
    }

    @Override
    public Response toResponse(T exception) {
     
        List<AqlParseError> errors = new LinkedList<>();
        String[] errorMessageBlocks = exception.getMessage().split("---+\n");
        
        for(String block : errorMessageBlocks) {
            
            String[] msgLines = block.split("\n");
            
            AqlParseError e = new AqlParseError();
            if(msgLines.length > 0) {
                StringBuilder sb = new StringBuilder(msgLines[0]);
                // append the hints as well
                for(int i=2; i < msgLines.length; i++) {
                    sb.append("\n");
                    sb.append(msgLines[i]);
                }
                e.setMessage(sb.toString());
            }
            
            if(msgLines.length > 1) {
               // get the position information
               Matcher m = locationPattern.matcher(msgLines[1]);
               if(m.matches()) {
                   ParsedEntityLocation loc = new ParsedEntityLocation();
                   String startLine = m.group("startline");
                   String startCol = m.group("startcol");
                   String endLine = m.group("endline");
                   String endCol = m.group("endcol");
                   
                   loc.setStartLine(Integer.parseInt(startLine));
                   loc.setStartColumn(Integer.parseInt(startCol));
                   
                   if(endLine != null &&  endCol != null) {
                       loc.setEndLine(Integer.parseInt(endLine));
                       loc.setEndColumn(Integer.parseInt(endCol));
                   } else {
                       loc.setEndLine(loc.getStartLine());
                       loc.setEndColumn(loc.getStartColumn());
                   }
                   e.setLocation(loc);
               }
            }
            errors.add(e);
        }
    
        return Response.status(Response.Status.BAD_REQUEST)
                .entity(new GenericEntity<List<AqlParseError>>(errors) {
                }).type("application/xml").build();
    }

}<commit_msg>Adapt to new (simpler) format of the error messsages<commit_after>package annis.rest.provider;

import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;

import org.corpus_tools.graphannis.errors.AQLSyntaxError;
import org.corpus_tools.graphannis.errors.GraphANNISException;

import annis.model.AqlParseError;
import annis.model.ParsedEntityLocation;

public abstract class AQLErrorMapperBase<T extends GraphANNISException> implements ExceptionMapper<T> {

    private static final Pattern locationPattern = Pattern.compile(
                "\\[(?<startline>[0-9]+):(?<startcol>[0-9]+)(-(?<endline>[0-9]+):(?<endcol>[0-9]+))?\\]( (?<msg>.+))?");

    
    public AQLErrorMapperBase() {
        super();
    }
    

    @Override
    public Response toResponse(T exception) {
     
        List<AqlParseError> errors = new LinkedList<>();
        String[] errorMessageBlocks = exception.getMessage().split("---+\n");
        
        for(String block : errorMessageBlocks) {
            
            String[] msgLines = block.split("\n");
            
            AqlParseError e = new AqlParseError();
            
            StringBuilder msg = new StringBuilder();
            
            for(int i=0; i < msgLines.length; i++) {
                if(i == 0) {
                    // check for optional location
                    Matcher m = locationPattern.matcher(msgLines[i]);
                    if(m.matches()) {
                        ParsedEntityLocation loc = new ParsedEntityLocation();
                        String startLine = m.group("startline");
                        String startCol = m.group("startcol");
                        String endLine = m.group("endline");
                        String endCol = m.group("endcol");
                        
                        loc.setStartLine(Integer.parseInt(startLine));
                        loc.setStartColumn(Integer.parseInt(startCol));
                        
                        if(endLine != null &&  endCol != null) {
                            loc.setEndLine(Integer.parseInt(endLine));
                            loc.setEndColumn(Integer.parseInt(endCol));
                        } else {
                            loc.setEndLine(loc.getStartLine());
                            loc.setEndColumn(loc.getStartColumn());
                        }
                        e.setLocation(loc);
                        
                        String msgPart = m.group("msg");
                        if(msgPart != null) {
                            msg.append(msgPart);
                        }
                    }
                } else {
                    // append whole line
                    msg.append(msgLines[i]);
                }
                if(i < msgLines.length-1) {
                    msg.append('\n');
                }
            } // end for each line
            e.setMessage(msg.toString());
            errors.add(e);
        }
    
        return Response.status(Response.Status.BAD_REQUEST)
                .entity(new GenericEntity<List<AqlParseError>>(errors) {
                }).type("application/xml").build();
    }

}
{'fraction_non_alphanumeric': 0.1189102564102564, 'fraction_numerical': 0.0038461538461538464, 'mean_word_length': 1.5853355426677713, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7322390', 'n_tokens_mistral': 1677, 'n_tokens_neox': 1593, 'n_words': 272}