/* * Copyright (c) 2014 Magnet Systems, Inc. * All rights reserved. * * 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 com.magnet.plugin.r2m.helpers; import com.magnet.langpack.builder.rest.parser.validation.DocLocation; import com.magnet.langpack.builder.rest.parser.validation.ValidationResultEntry; import com.magnet.plugin.r2m.constants.JSONErrorType; import com.magnet.plugin.r2m.models.JSONError; import java.io.IOException; import java.io.StringReader; import java.util.LinkedList; import java.util.List; /** * Convert raw errors in JSON payload into proper messages errors */ public class JsonErrorConverter { private int currentLine; private int currentIndex; private String text; private List<String> lines; private List<ValidationResultEntry> validationResultEntries; public JsonErrorConverter(String text, List<ValidationResultEntry> validationResultEntries) { this.text = text; try { lines = org.apache.commons.io.IOUtils.readLines(new StringReader(text)); } catch (IOException e) { e.printStackTrace(); } this.validationResultEntries = validationResultEntries; } public List<JSONError> convert() { List<JSONError> result = new LinkedList<JSONError>(); for(ValidationResultEntry errorEntry : validationResultEntries) { int startIndex = 0; int endIndex = 0; if (null != errorEntry.getDocLocation()) { if(errorEntry.getDocLocation().getLine() > lines.size()) { // line number out of bound int lastLineNum = lines.size() - 1; startIndex = getLineStartIndex(lines.size()); endIndex = startIndex + lines.get(lastLineNum).length(); // Reset location since it seems out of bound errorEntry = new ValidationResultEntry(errorEntry.getPropertyName(), errorEntry.getErrorType(), new DocLocation(lines.size(), lines.get(lastLineNum).length()), errorEntry.getMessage()); } else if(errorEntry.getDocLocation().getCol() > lines.get(errorEntry.getDocLocation().getLine() - 1).length()) { // column out of bound startIndex = getLineStartIndex(errorEntry.getDocLocation().getLine()) + lines.get(errorEntry.getDocLocation().getLine() - 1).length() -1; endIndex = startIndex + 1; // Reset location since it seems out of bound errorEntry = new ValidationResultEntry(errorEntry.getPropertyName(), errorEntry.getErrorType(), new DocLocation(errorEntry.getDocLocation().getLine(), lines.get(errorEntry.getDocLocation().getLine() - 1).length()), errorEntry.getMessage()); } else { startIndex = getLineStartIndex(errorEntry.getDocLocation().getLine()) + errorEntry.getDocLocation().getCol() - 1; switch (errorEntry.getErrorType()) { case INVALID_FORMAT: startIndex = startIndex - 1; Integer nextQuota = text.indexOf("\"", startIndex) + 1; Integer nextComma = text.indexOf(",", startIndex) + 1; Integer endOfLine = currentIndex + lines.get(currentLine).length() + 1; if (nextQuota != 0 && nextQuota < nextComma) { endIndex = nextQuota; int possibleStartIndex = text.lastIndexOf("\"", startIndex); if (possibleStartIndex > 0) { startIndex = possibleStartIndex; } } else if (nextComma != 0 && nextQuota < endOfLine) { endIndex = nextComma; int possibleStartIndex = startIndex = text.lastIndexOf(":", endIndex); if (possibleStartIndex > 0) { startIndex = possibleStartIndex + 1; } } else if (endOfLine < text.length()) { endIndex = endOfLine; startIndex = currentIndex; } else { endIndex = startIndex + 1; } break; case EMPTY_ARRAY: startIndex = startIndex - 1; endIndex = text.indexOf("]", startIndex) + 1; break; case EMPTY_OBJECT: startIndex = startIndex - 1; endIndex = text.indexOf("}", startIndex) + 1; break; default: //case NULL_PROPERTY: endIndex = startIndex + 4; } } } result.add(new JSONError(errorEntry, startIndex, endIndex)); } return result; } private int getLineStartIndex(int lineRequested) { if(currentLine < lineRequested - 1) { for(int i = 0; i < (lineRequested - currentLine - 1); i++) { currentIndex += lines.get(currentLine + i).length() + 1; } currentLine = lineRequested - 1; } return currentIndex; } private JSONErrorType convertErrorType(ValidationResultEntry.ErrorType validationErrorType) { switch (validationErrorType) { case INVALID_FORMAT: return JSONErrorType.ERROR_MISSING_COMMA; case EMPTY_ARRAY: return JSONErrorType.ERROR_EMPTY_ARRAY; case EMPTY_OBJECT: return JSONErrorType.ERROR_EMPTY_DICTIONARY; default: //case NULL_PROPERTY: return JSONErrorType.ERROR_NULL_VALUE; } } }