@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { String name = entry.getKey(); String[] choices = result.getInvalidEnumChoices().get(name); String defaultValue = result.getDefaultValues() != null ? result.getDefaultValues().get(entry.getKey()) : null; String str = Arrays.asList(choices).toString(); String msg = "Invalid enum value: " + entry.getValue() + ". Possible values: " + str; if (result.getInvalidEnumChoices() != null) { String[] suggestions = result.getInvalidEnumChoices().get(name); if (suggestions != null && suggestions.length > 0) { str = Arrays.asList(suggestions).toString(); msg += ". Did you mean: " + str; } } if (defaultValue != null) { msg += ". Default value: " + defaultValue; } return msg; }
@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { String name = entry.getKey(); String[] choices = result.getInvalidEnumChoices().get(name); String defaultValue = result.getDefaultValues() != null ? result.getDefaultValues().get(entry.getKey()) : null; String str = Arrays.asList(choices).toString(); String msg = name + " has invalid enum value: " + entry.getValue() + ". Possible values: " + str; if (result.getInvalidEnumChoices() != null) { String[] suggestions = result.getInvalidEnumChoices().get(name); if (suggestions != null && suggestions.length > 0) { str = Arrays.asList(suggestions).toString(); msg += ". Did you mean: " + str; } } if (defaultValue != null) { msg += ". Default value: " + defaultValue; } return msg; }
private void extractSetValue(EndpointValidationResult result, Set<String> validationSet, String fromElement, PsiElement element, AnnotationHolder holder, CamelAnnotatorEndpointMessage msg, boolean lenient) { if (validationSet != null && (lenient || !result.isSuccess())) { for (String entry : validationSet) { String propertyValue = entry; int startIdxQueryParameters = fromElement.indexOf("?" + propertyValue); startIdxQueryParameters = (startIdxQueryParameters == -1) ? fromElement.indexOf("&" + propertyValue) : fromElement.indexOf("?"); int propertyIdx = fromElement.indexOf(propertyValue, startIdxQueryParameters); int propertyLength = propertyValue.length(); propertyIdx = getIdeaUtils().isJavaLanguage(element) || getIdeaUtils().isXmlLanguage(element) ? propertyIdx + 1 : propertyIdx; TextRange range = new TextRange(element.getTextRange().getStartOffset() + propertyIdx, element.getTextRange().getStartOffset() + propertyIdx + propertyLength); if (msg.isInfoLevel()) { holder.createInfoAnnotation(range, summaryMessage(result, propertyValue, msg)); } else if (msg.isWarnLevel()) { holder.createWarningAnnotation(range, summaryMessage(result, propertyValue, msg)); } else { holder.createErrorAnnotation(range, summaryMessage(result, propertyValue, msg)); } } } }
private void extractMapValue(EndpointValidationResult result, Map<String, String> validationMap, String fromElement, @NotNull PsiElement element, @NotNull AnnotationHolder holder, CamelAnnotatorEndpointMessage msg) { if ((!result.isSuccess()) && validationMap != null) { for (Map.Entry<String, String> entry : validationMap.entrySet()) { String propertyValue = entry.getValue(); String propertyKey = entry.getKey(); int startIdxQueryParameters = fromElement.indexOf("?"); int propertyIdx = fromElement.indexOf(propertyKey, startIdxQueryParameters); int startIdx = propertyIdx; int equalsSign = fromElement.indexOf("=", propertyIdx); if (equalsSign > 0) { startIdx = equalsSign + 1; } int propertyLength = propertyValue.isEmpty() ? propertyKey.length() : propertyValue.length(); propertyLength = element instanceof XmlToken ? propertyLength - 1 : propertyLength; startIdx = propertyValue.isEmpty() ? propertyIdx + 1 : fromElement.indexOf(propertyValue, startIdx) + 1; startIdx = getIdeaUtils().isJavaLanguage(element) || getIdeaUtils().isXmlLanguage(element) ? startIdx : startIdx - 1; TextRange range = new TextRange(element.getTextRange().getStartOffset() + startIdx, element.getTextRange().getStartOffset() + startIdx + propertyLength); holder.createErrorAnnotation(range, summaryMessage(result, entry, msg)); } } }
@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { boolean empty = entry.getValue() == null || entry.getValue().length() == 0; if (empty) { return "Empty boolean value"; } else { return "Invalid boolean value: " + entry.getValue(); } }
@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { boolean empty = isEmpty(entry.getValue()); if (empty) { return "Empty reference value"; } else if (!entry.getValue().startsWith("#")) { return "Invalid reference value: " + entry.getValue() + " must start with #"; } else { return "Invalid reference value: " + entry.getValue(); } }
@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { boolean empty = isEmpty(entry.getValue()); if (empty) { return "Empty integer value"; } else { return "Invalid integer value: " + entry.getValue(); } }
@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { boolean empty = isEmpty(entry.getValue()); if (empty) { return "Empty number value"; } else { return "Invalid number value: " + entry.getValue(); } }
/** * A human readable summary of the validation. * * @return the summary, or <tt>empty</tt> if no validation errors */ @SuppressWarnings("unchecked") private <T> String summaryMessage(EndpointValidationResult result, T entry, CamelAnnotatorEndpointMessage msg) { if (result.getIncapable() != null) { return "Incapable of parsing uri: " + result.getIncapable(); } else if (result.getSyntaxError() != null) { return "Syntax error: " + result.getSyntaxError(); } else if (result.getUnknownComponent() != null) { return "Unknown component: " + result.getUnknownComponent(); } return msg.getErrorMessage(result, entry); }
private void extractSetValue(EndpointValidationResult result, Set<String> validationSet, String fromElement, PsiElement element, final @NotNull ProblemsHolder holder, boolean isOnTheFly, CamelAnnotatorEndpointMessage msg) { if ((!result.isSuccess()) && validationSet != null) { for (String entry : validationSet) { String desc = summaryErrorMessage(result, entry, msg); holder.registerProblem(element, desc); } } }
private void extractMapValue(EndpointValidationResult result, Map<String, String> validationMap, String fromElement, @NotNull PsiElement element, final @NotNull ProblemsHolder holder, boolean isOnTheFly, CamelAnnotatorEndpointMessage msg) { if ((!result.isSuccess()) && validationMap != null) { for (Map.Entry<String, String> entry : validationMap.entrySet()) { String desc = summaryErrorMessage(result, entry, msg); holder.registerProblem(element, desc); } } }
@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { String name = entry.getKey(); boolean empty = entry.getValue() == null || entry.getValue().length() == 0; if (empty) { return name + " has empty boolean value"; } else { return name + " has invalid boolean value: " + entry.getValue(); } }
@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { String name = entry.getKey(); boolean empty = isEmpty(entry.getValue()); if (empty) { return name + " has empty reference value"; } else if (!entry.getValue().startsWith("#")) { return name + " has invalid reference value: " + entry.getValue() + " must start with #"; } else { return name + " has invalid reference value: " + entry.getValue(); } }
@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { String name = entry.getKey(); boolean empty = isEmpty(entry.getValue()); if (empty) { return name + " is empty integer value"; } else { return name + " is invalid integer value: " + entry.getValue(); } }
@Override public String getErrorMessage(EndpointValidationResult result, Map.Entry<String, String> entry) { String name = entry.getKey(); boolean empty = isEmpty(entry.getValue()); if (empty) { return name + " has empty numeric value"; } else { return name + " has invalid numeric value: " + entry.getValue(); } }
/** * A human readable summary of the validation errors. * * @return the summary, or <tt>empty</tt> if no validation errors */ @SuppressWarnings("unchecked") private <T> String summaryErrorMessage(EndpointValidationResult result, T entry, CamelAnnotatorEndpointMessage msg) { if (result.getIncapable() != null) { return "Incapable of parsing uri: " + result.getIncapable(); } else if (result.getSyntaxError() != null) { return "Syntax error: " + result.getSyntaxError(); } else if (result.getUnknownComponent() != null) { return "Unknown component: " + result.getUnknownComponent(); } return msg.getErrorMessage(result, entry); }
@Test public void validateProperties() throws Exception { // spell typo error EndpointValidationResult result = catalog.validateEndpointProperties("log:mylog?levl=WARN"); assertFalse(result.isSuccess()); assertTrue(result.getUnknown().contains("levl")); assertEquals("level", result.getUnknownSuggestions().get("levl")[0]); assertEquals(1, result.getNumberOfErrors()); }
/** * Validate endpoint options list aka properties. eg "timer:trigger?delay=1000&bridgeErrorHandler=true" * if the URI is not valid a error annotation is created and highlight the invalid value. */ void validateText(@NotNull PsiElement element, @NotNull AnnotationHolder holder, @NotNull String uri) { if (QueryUtils.isQueryContainingCamelComponent(element.getProject(), uri)) { CamelCatalog catalogService = ServiceManager.getService(element.getProject(), CamelCatalogService.class).get(); IElementType type = element.getNode().getElementType(); LOG.trace("Element " + element + " of type: " + type + " to validate endpoint uri: " + uri); // skip special values such as configuring ActiveMQ brokerURL if (getCamelIdeaUtils().skipEndpointValidation(element)) { LOG.debug("Skipping element " + element + " for validation with text: " + uri); return; } // camel catalog expects & as & when it parses so replace all & as & String camelQuery = getIdeaUtils().getInnerText(uri); camelQuery = camelQuery.replaceAll("&", "&"); // strip up ending incomplete parameter if (camelQuery.endsWith("&") || camelQuery.endsWith("?")) { camelQuery = camelQuery.substring(0, camelQuery.length() - 1); } boolean stringFormat = getCamelIdeaUtils().isFromStringFormatEndpoint(element); if (stringFormat) { // if the node is fromF or toF, then replace all %X with {{%X}} as we cannot parse that value camelQuery = camelQuery.replaceAll("%s", "\\{\\{\\%s\\}\\}"); camelQuery = camelQuery.replaceAll("%d", "\\{\\{\\%d\\}\\}"); camelQuery = camelQuery.replaceAll("%b", "\\{\\{\\%b\\}\\}"); } boolean consumerOnly = getCamelIdeaUtils().isConsumerEndpoint(element); boolean producerOnly = getCamelIdeaUtils().isProducerEndpoint(element); try { CamelPreferenceService preference = getCamelPreferenceService(); EndpointValidationResult result = catalogService.validateEndpointProperties(camelQuery, false, consumerOnly, producerOnly); extractMapValue(result, result.getInvalidBoolean(), uri, element, holder, new BooleanErrorMsg()); extractMapValue(result, result.getInvalidEnum(), uri, element, holder, new EnumErrorMsg()); extractMapValue(result, result.getInvalidInteger(), uri, element, holder, new IntegerErrorMsg()); extractMapValue(result, result.getInvalidNumber(), uri, element, holder, new NumberErrorMsg()); extractMapValue(result, result.getInvalidReference(), uri, element, holder, new ReferenceErrorMsg()); extractSetValue(result, result.getUnknown(), uri, element, holder, new UnknownErrorMsg(), false); extractSetValue(result, result.getLenient(), uri, element, holder, new LenientOptionMsg(preference.isHighlightCustomOptions()), true); extractSetValue(result, result.getNotConsumerOnly(), uri, element, holder, new NotConsumerOnlyErrorMsg(), false); extractSetValue(result, result.getNotProducerOnly(), uri, element, holder, new NotProducerOnlyErrorMsg(), false); } catch (Throwable e) { LOG.warn("Error validating Camel endpoint: " + uri, e); } } }
@Override public String getErrorMessage(EndpointValidationResult result, String property) { return "Unknown option"; }
@Override public String getErrorMessage(EndpointValidationResult result, String property) { return property + " is a custom option that is not part of the Camel component"; }
@Override public String getErrorMessage(EndpointValidationResult result, String property) { return "Option not applicable in consumer only mode"; }
@Override public String getErrorMessage(EndpointValidationResult result, String property) { return "Option not applicable in producer only mode"; }
private void validateEndpoint(@NotNull PsiElement element, final @NotNull ProblemsHolder holder, @NotNull String text, boolean isOnTheFly) { CamelCatalog catalogService = ServiceManager.getService(element.getProject(), CamelCatalogService.class).get(); IElementType type = element.getNode().getElementType(); LOG.trace("Element " + element + " of type: " + type + " to inspect endpoint uri: " + text); // skip special values such as configuring ActiveMQ brokerURL if (getCamelIdeaUtils().skipEndpointValidation(element)) { LOG.debug("Skipping element " + element + " for validation with text: " + text); return; } // camel catalog expects & as & when it parses so replace all & as & String camelQuery = text; camelQuery = camelQuery.replaceAll("&", "&"); // strip up ending incomplete parameter if (camelQuery.endsWith("&") || camelQuery.endsWith("?")) { camelQuery = camelQuery.substring(0, camelQuery.length() - 1); } boolean stringFormat = getCamelIdeaUtils().isFromStringFormatEndpoint(element); if (stringFormat) { // if the node is fromF or toF, then replace all %X with {{%X}} as we cannot parse that value camelQuery = camelQuery.replaceAll("%s", "\\{\\{\\%s\\}\\}"); camelQuery = camelQuery.replaceAll("%d", "\\{\\{\\%d\\}\\}"); camelQuery = camelQuery.replaceAll("%b", "\\{\\{\\%b\\}\\}"); } boolean consumerOnly = getCamelIdeaUtils().isConsumerEndpoint(element); boolean producerOnly = getCamelIdeaUtils().isProducerEndpoint(element); try { EndpointValidationResult result = catalogService.validateEndpointProperties(camelQuery, false, consumerOnly, producerOnly); extractMapValue(result, result.getInvalidBoolean(), text, element, holder, isOnTheFly, new AbstractCamelInspection.BooleanErrorMsg()); extractMapValue(result, result.getInvalidEnum(), text, element, holder, isOnTheFly, new AbstractCamelInspection.EnumErrorMsg()); extractMapValue(result, result.getInvalidInteger(), text, element, holder, isOnTheFly, new AbstractCamelInspection.IntegerErrorMsg()); extractMapValue(result, result.getInvalidNumber(), text, element, holder, isOnTheFly, new AbstractCamelInspection.NumberErrorMsg()); extractMapValue(result, result.getInvalidReference(), text, element, holder, isOnTheFly, new AbstractCamelInspection.ReferenceErrorMsg()); extractSetValue(result, result.getUnknown(), text, element, holder, isOnTheFly, new AbstractCamelInspection.UnknownErrorMsg()); extractSetValue(result, result.getNotConsumerOnly(), text, element, holder, isOnTheFly, new AbstractCamelInspection.NotConsumerOnlyErrorMsg()); extractSetValue(result, result.getNotProducerOnly(), text, element, holder, isOnTheFly, new AbstractCamelInspection.NotProducerOnlyErrorMsg()); } catch (Throwable e) { LOG.warn("Error inspecting Camel endpoint: " + text, e); } }
@Override public String getErrorMessage(EndpointValidationResult result, String property) { return property + " is unknown option"; }
@Override public String getErrorMessage(EndpointValidationResult result, String property) { return property + " is not applicable in consumer only mode"; }
@Override public String getErrorMessage(EndpointValidationResult result, String property) { return property + " is not applicable in producer only mode"; }
/** * Return error messaged constructed to match the validation result. * * @param endpointValidationResult - The validation result return from the {@link org.apache.camel.catalog.CamelCatalog} validator * @param valueObj - The key and value object validated. */ String getErrorMessage(EndpointValidationResult endpointValidationResult, T valueObj);