/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.camel.runtimecatalog; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class JSonSchemaHelper { // 0 = text, 1 = enum, 2 = boolean, 3 = integer or number private static final Pattern PATTERN = Pattern.compile("\"(.+?)\"|\\[(.+)\\]|(true|false)|(-?\\d+\\.?\\d*)"); private static final String QUOT = """; private JSonSchemaHelper() { } /** * Parses the json schema to split it into a list or rows, where each row contains key value pairs with the metadata * * @param group the group to parse from such as <tt>component</tt>, <tt>componentProperties</tt>, or <tt>properties</tt>. * @param json the json * @return a list of all the rows, where each row is a set of key value pairs with metadata */ public static List<Map<String, String>> parseJsonSchema(String group, String json, boolean parseProperties) { List<Map<String, String>> answer = new ArrayList<Map<String, String>>(); if (json == null) { return answer; } boolean found = false; // parse line by line String[] lines = json.split("\n"); for (String line : lines) { // we need to find the group first if (!found) { String s = line.trim(); found = s.startsWith("\"" + group + "\":") && s.endsWith("{"); continue; } // we should stop when we end the group if (line.equals(" },") || line.equals(" }")) { break; } // need to safe encode \" so we can parse the line line = line.replaceAll("\"\\\\\"\"", '"' + QUOT + '"'); Map<String, String> row = new LinkedHashMap<String, String>(); Matcher matcher = PATTERN.matcher(line); String key; if (parseProperties) { // when parsing properties the first key is given as name, so the first parsed token is the value of the name key = "name"; } else { key = null; } while (matcher.find()) { if (key == null) { key = matcher.group(1); } else { String value = matcher.group(1); if (value != null) { // its text based value = value.trim(); // decode value = value.replaceAll(QUOT, "\""); value = decodeJson(value); } if (value == null) { // not text then its maybe an enum? value = matcher.group(2); if (value != null) { // its an enum so strip out " and trim spaces after comma value = value.replaceAll("\"", ""); value = value.replaceAll(", ", ","); value = value.trim(); } } if (value == null) { // not text then its maybe a boolean? value = matcher.group(3); } if (value == null) { // not text then its maybe a integer? value = matcher.group(4); } if (value != null) { row.put(key, value); } // reset key = null; } } if (!row.isEmpty()) { answer.add(row); } } return answer; } private static String decodeJson(String value) { // json encodes a \ as \\ so we need to decode from \\ back to \ if ("\\\\".equals(value)) { value = "\\"; } return value; } public static boolean isComponentLenientProperties(List<Map<String, String>> rows) { for (Map<String, String> row : rows) { if (row.containsKey("lenientProperties")) { return "true".equals(row.get("lenientProperties")); } } return false; } public static boolean isComponentConsumerOnly(List<Map<String, String>> rows) { for (Map<String, String> row : rows) { if (row.containsKey("consumerOnly")) { return "true".equals(row.get("consumerOnly")); } } return false; } public static boolean isComponentProducerOnly(List<Map<String, String>> rows) { for (Map<String, String> row : rows) { if (row.containsKey("producerOnly")) { return "true".equals(row.get("producerOnly")); } } return false; } public static boolean isPropertyConsumerOnly(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String labels = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("label")) { labels = row.get("label"); } if (found) { return labels != null && labels.contains("consumer"); } } return false; } public static boolean isPropertyProducerOnly(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String labels = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("label")) { labels = row.get("label"); } if (found) { return labels != null && labels.contains("producer"); } } return false; } public static boolean isPropertyRequired(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { boolean required = false; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("required")) { required = "true".equals(row.get("required")); } if (found) { return required; } } return false; } public static String getPropertyKind(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String kind = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("kind")) { kind = row.get("kind"); } if (found) { return kind; } } return null; } public static boolean isPropertyBoolean(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String type = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("type")) { type = row.get("type"); } if (found) { return "boolean".equals(type); } } return false; } public static boolean isPropertyInteger(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String type = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("type")) { type = row.get("type"); } if (found) { return "integer".equals(type); } } return false; } public static boolean isPropertyNumber(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String type = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("type")) { type = row.get("type"); } if (found) { return "number".equals(type); } } return false; } public static boolean isPropertyObject(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String type = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("type")) { type = row.get("type"); } if (found) { return "object".equals(type); } } return false; } public static String getPropertyDefaultValue(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String defaultValue = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("defaultValue")) { defaultValue = row.get("defaultValue"); } if (found) { return defaultValue; } } return null; } public static String stripOptionalPrefixFromName(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String optionalPrefix = null; boolean found = false; if (row.containsKey("optionalPrefix")) { optionalPrefix = row.get("optionalPrefix"); } if (row.containsKey("name")) { if (optionalPrefix != null && name.startsWith(optionalPrefix)) { name = name.substring(optionalPrefix.length()); // try again return stripOptionalPrefixFromName(rows, name); } else { found = name.equals(row.get("name")); } } if (found) { return name; } } return name; } public static String getPropertyEnum(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String enums = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("enum")) { enums = row.get("enum"); } if (found) { return enums; } } return null; } public static String getPropertyPrefix(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String prefix = null; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("prefix")) { prefix = row.get("prefix"); } if (found) { return prefix; } } return null; } public static boolean isPropertyMultiValue(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { boolean multiValue = false; boolean found = false; if (row.containsKey("name")) { found = name.equals(row.get("name")); } if (row.containsKey("multiValue")) { multiValue = "true".equals(row.get("multiValue")); } if (found) { return multiValue; } } return false; } public static String getPropertyNameFromNameWithPrefix(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { String propertyName = null; boolean found = false; if (row.containsKey("name")) { propertyName = row.get("name"); } if (row.containsKey("prefix")) { String preifx = row.get("prefix"); found = name.startsWith(preifx); } if (found) { return propertyName; } } return null; } public static Map<String, String> getRow(List<Map<String, String>> rows, String key) { for (Map<String, String> row : rows) { if (key.equals(row.get("name"))) { return row; } } return null; } public static Set<String> getNames(List<Map<String, String>> rows) { Set<String> answer = new LinkedHashSet<String>(); for (Map<String, String> row : rows) { if (row.containsKey("name")) { answer.add(row.get("name")); } } return answer; } }