Return-Path: X-Original-To: apmail-camel-commits-archive@www.apache.org Delivered-To: apmail-camel-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B85A218994 for ; Wed, 23 Dec 2015 08:44:28 +0000 (UTC) Received: (qmail 75405 invoked by uid 500); 23 Dec 2015 08:43:54 -0000 Delivered-To: apmail-camel-commits-archive@camel.apache.org Received: (qmail 75350 invoked by uid 500); 23 Dec 2015 08:43:54 -0000 Mailing-List: contact commits-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list commits@camel.apache.org Received: (qmail 75338 invoked by uid 99); 23 Dec 2015 08:43:54 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 23 Dec 2015 08:43:54 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 2F05AE07D9; Wed, 23 Dec 2015 08:43:54 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: davsclaus@apache.org To: commits@camel.apache.org Date: Wed, 23 Dec 2015 08:43:55 -0000 Message-Id: <60bd264d1a8e48b4806c422d62bc8d92@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [02/14] camel git commit: Revert "Camel catalog - Move stuff to util package" lets wait to move them as 3rd party may use these util classes. Revert "Camel catalog - Move stuff to util package" lets wait to move them as 3rd party may use these util classes. This reverts commit 360e93807be4661bc571402b89500abacfd8ed22. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/8210db44 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/8210db44 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/8210db44 Branch: refs/heads/master Commit: 8210db4439c6953ff945d2aa88b54dd75a908399 Parents: 01581e5 Author: Claus Ibsen Authored: Tue Dec 22 10:29:40 2015 +0100 Committer: Claus Ibsen Committed: Wed Dec 23 09:05:13 2015 +0100 ---------------------------------------------------------------------- .../org/apache/camel/catalog/CatalogHelper.java | 146 ++++++++ .../camel/catalog/DefaultCamelCatalog.java | 31 +- .../apache/camel/catalog/JSonSchemaHelper.java | 244 +++++++++++++ .../org/apache/camel/catalog/URISupport.java | 365 +++++++++++++++++++ .../catalog/UnsafeUriCharactersEncoder.java | 206 +++++++++++ .../org/apache/camel/catalog/VersionHelper.java | 73 ++++ .../camel/catalog/util/CatalogHelper.java | 146 -------- .../camel/catalog/util/JSonSchemaHelper.java | 244 ------------- .../apache/camel/catalog/util/URISupport.java | 365 ------------------- .../util/UnsafeUriCharactersEncoder.java | 206 ----------- .../camel/catalog/util/VersionHelper.java | 73 ---- .../apache/camel/catalog/CamelCatalogTest.java | 2 +- 12 files changed, 1048 insertions(+), 1053 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/CatalogHelper.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/CatalogHelper.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/CatalogHelper.java new file mode 100644 index 0000000..2ce8089 --- /dev/null +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/CatalogHelper.java @@ -0,0 +1,146 @@ +/** + * 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.catalog; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.util.List; + +public final class CatalogHelper { + + private CatalogHelper() { + } + + + /** + * Loads the entire stream into memory as a String and returns it. + *

+ * Notice: This implementation appends a \n as line + * terminator at the of the text. + *

+ * Warning, don't use for crazy big streams :) + */ + public static void loadLines(InputStream in, List lines) throws IOException { + InputStreamReader isr = new InputStreamReader(in); + try { + BufferedReader reader = new LineNumberReader(isr); + while (true) { + String line = reader.readLine(); + if (line != null) { + lines.add(line); + } else { + break; + } + } + } finally { + isr.close(); + in.close(); + } + } + + /** + * Loads the entire stream into memory as a String and returns it. + *

+ * Notice: This implementation appends a \n as line + * terminator at the of the text. + *

+ * Warning, don't use for crazy big streams :) + */ + public static String loadText(InputStream in) throws IOException { + StringBuilder builder = new StringBuilder(); + InputStreamReader isr = new InputStreamReader(in); + try { + BufferedReader reader = new LineNumberReader(isr); + while (true) { + String line = reader.readLine(); + if (line != null) { + builder.append(line); + builder.append("\n"); + } else { + break; + } + } + return builder.toString(); + } finally { + isr.close(); + in.close(); + } + } + + /** + * Matches the name with the pattern. + * + * @param name the name + * @param pattern the pattern + * @return true if matched, or false if not + */ + public static boolean matchWildcard(String name, String pattern) { + // we have wildcard support in that hence you can match with: file* to match any file endpoints + if (pattern.endsWith("*") && name.startsWith(pattern.substring(0, pattern.length() - 1))) { + return true; + } + return false; + } + + /** + * Returns the string after the given token + * + * @param text the text + * @param after the token + * @return the text after the token, or null if text does not contain the token + */ + public static String after(String text, String after) { + if (!text.contains(after)) { + return null; + } + return text.substring(text.indexOf(after) + after.length()); + } + + /** + * Returns the string before the given token + * + * @param text the text + * @param before the token + * @return the text before the token, or null if text does not contain the token + */ + public static String before(String text, String before) { + if (!text.contains(before)) { + return null; + } + return text.substring(0, text.indexOf(before)); + } + + /** + * Returns the string between the given tokens + * + * @param text the text + * @param after the before token + * @param before the after token + * @return the text between the tokens, or null if text does not contain the tokens + */ + public static String between(String text, String after, String before) { + text = after(text, after); + if (text == null) { + return null; + } + return before(text, before); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java index 451bcb2..d9aebec 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java @@ -40,24 +40,19 @@ import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; -import org.apache.camel.catalog.util.CatalogHelper; -import org.apache.camel.catalog.util.JSonSchemaHelper; -import org.apache.camel.catalog.util.URISupport; -import org.apache.camel.catalog.util.VersionHelper; - -import static org.apache.camel.catalog.util.CatalogHelper.after; -import static org.apache.camel.catalog.util.JSonSchemaHelper.getPropertyDefaultValue; -import static org.apache.camel.catalog.util.JSonSchemaHelper.getPropertyEnum; -import static org.apache.camel.catalog.util.JSonSchemaHelper.getRow; -import static org.apache.camel.catalog.util.JSonSchemaHelper.isPropertyBoolean; -import static org.apache.camel.catalog.util.JSonSchemaHelper.isPropertyInteger; -import static org.apache.camel.catalog.util.JSonSchemaHelper.isPropertyNumber; -import static org.apache.camel.catalog.util.JSonSchemaHelper.isPropertyObject; -import static org.apache.camel.catalog.util.JSonSchemaHelper.isPropertyRequired; -import static org.apache.camel.catalog.util.URISupport.createQueryString; -import static org.apache.camel.catalog.util.URISupport.isEmpty; -import static org.apache.camel.catalog.util.URISupport.normalizeUri; -import static org.apache.camel.catalog.util.URISupport.stripQuery; +import static org.apache.camel.catalog.CatalogHelper.after; +import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyDefaultValue; +import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyEnum; +import static org.apache.camel.catalog.JSonSchemaHelper.getRow; +import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyBoolean; +import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyInteger; +import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyNumber; +import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyObject; +import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyRequired; +import static org.apache.camel.catalog.URISupport.createQueryString; +import static org.apache.camel.catalog.URISupport.isEmpty; +import static org.apache.camel.catalog.URISupport.normalizeUri; +import static org.apache.camel.catalog.URISupport.stripQuery; /** * Default {@link CamelCatalog}. http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java new file mode 100644 index 0000000..f0755ef --- /dev/null +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java @@ -0,0 +1,244 @@ +/** + * 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.catalog; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class JSonSchemaHelper { + + private static final Pattern PATTERN = Pattern.compile("\"(.+?)\"|\\[(.+)\\]"); + 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 component, componentProperties, or properties. + * @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> parseJsonSchema(String group, String json, boolean parseProperties) { + List> answer = new ArrayList>(); + 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 row = new LinkedHashMap(); + 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) { + value = matcher.group(2); + // its an enum so strip out " and trim spaces after comma + value = value.replaceAll("\"", ""); + value = value.replaceAll(", ", ","); + } + if (value != null) { + value = value.trim(); + // decode + value = value.replaceAll(QUOT, "\""); + value = decodeJson(value); + } + 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 isPropertyRequired(List> rows, String name) { + for (Map 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 boolean isPropertyBoolean(List> rows, String name) { + for (Map 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> rows, String name) { + for (Map 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> rows, String name) { + for (Map 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> rows, String name) { + for (Map 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> rows, String name) { + for (Map 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 getPropertyEnum(List> rows, String name) { + for (Map row : rows) { + String enums = null; + String defaultValue = 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 Map getRow(List> rows, String key) { + for (Map row : rows) { + if (key.equals(row.get("name"))) { + return row; + } + } + return null; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java new file mode 100644 index 0000000..e0c16b7 --- /dev/null +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java @@ -0,0 +1,365 @@ +/** + * 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.catalog; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Copied from org.apache.camel.util.URISupport + */ +public final class URISupport { + + public static final String RAW_TOKEN_START = "RAW("; + public static final String RAW_TOKEN_END = ")"; + + private static final String CHARSET = "UTF-8"; + + private URISupport() { + // Helper class + } + + /** + * Normalizes the URI so unsafe charachters is encoded + * + * @param uri the input uri + * @return as URI instance + * @throws URISyntaxException is thrown if syntax error in the input uri + */ + public static URI normalizeUri(String uri) throws URISyntaxException { + return new URI(UnsafeUriCharactersEncoder.encode(uri, true)); + } + + /** + * Strips the query parameters from the uri + * + * @param uri the uri + * @return the uri without the query parameter + */ + public static String stripQuery(String uri) { + int idx = uri.indexOf('?'); + if (idx > -1) { + uri = uri.substring(0, idx); + } + return uri; + } + + /** + * Parses the query parameters of the uri (eg the query part). + * + * @param uri the uri + * @return the parameters, or an empty map if no parameters (eg never null) + * @throws URISyntaxException is thrown if uri has invalid syntax. + */ + public static Map parseParameters(URI uri) throws URISyntaxException { + String query = uri.getQuery(); + if (query == null) { + String schemeSpecificPart = uri.getSchemeSpecificPart(); + int idx = schemeSpecificPart.indexOf('?'); + if (idx < 0) { + // return an empty map + return new LinkedHashMap(0); + } else { + query = schemeSpecificPart.substring(idx + 1); + } + } else { + query = stripPrefix(query, "?"); + } + return parseQuery(query); + } + + /** + * Strips the prefix from the value. + *

+ * Returns the value as-is if not starting with the prefix. + * + * @param value the value + * @param prefix the prefix to remove from value + * @return the value without the prefix + */ + public static String stripPrefix(String value, String prefix) { + if (value != null && value.startsWith(prefix)) { + return value.substring(prefix.length()); + } + return value; + } + + /** + * Parses the query part of the uri (eg the parameters). + *

+ * The URI parameters will by default be URI encoded. However you can define a parameter + * values with the syntax: key=RAW(value) which tells Camel to not encode the value, + * and use the value as is (eg key=value) and the value has not been encoded. + * + * @param uri the uri + * @return the parameters, or an empty map if no parameters (eg never null) + * @throws URISyntaxException is thrown if uri has invalid syntax. + * @see #RAW_TOKEN_START + * @see #RAW_TOKEN_END + */ + public static Map parseQuery(String uri) throws URISyntaxException { + return parseQuery(uri, false); + } + + /** + * Parses the query part of the uri (eg the parameters). + *

+ * The URI parameters will by default be URI encoded. However you can define a parameter + * values with the syntax: key=RAW(value) which tells Camel to not encode the value, + * and use the value as is (eg key=value) and the value has not been encoded. + * + * @param uri the uri + * @param useRaw whether to force using raw values + * @return the parameters, or an empty map if no parameters (eg never null) + * @throws URISyntaxException is thrown if uri has invalid syntax. + * @see #RAW_TOKEN_START + * @see #RAW_TOKEN_END + */ + public static Map parseQuery(String uri, boolean useRaw) throws URISyntaxException { + // must check for trailing & as the uri.split("&") will ignore those + if (uri != null && uri.endsWith("&")) { + throw new URISyntaxException(uri, "Invalid uri syntax: Trailing & marker found. " + + "Check the uri and remove the trailing & marker."); + } + + if (isEmpty(uri)) { + // return an empty map + return new LinkedHashMap(0); + } + + // need to parse the uri query parameters manually as we cannot rely on splitting by &, + // as & can be used in a parameter value as well. + + try { + // use a linked map so the parameters is in the same order + Map rc = new LinkedHashMap(); + + boolean isKey = true; + boolean isValue = false; + boolean isRaw = false; + StringBuilder key = new StringBuilder(); + StringBuilder value = new StringBuilder(); + + // parse the uri parameters char by char + for (int i = 0; i < uri.length(); i++) { + // current char + char ch = uri.charAt(i); + // look ahead of the next char + char next; + if (i <= uri.length() - 2) { + next = uri.charAt(i + 1); + } else { + next = '\u0000'; + } + + // are we a raw value + isRaw = value.toString().startsWith(RAW_TOKEN_START); + + // if we are in raw mode, then we keep adding until we hit the end marker + if (isRaw) { + if (isKey) { + key.append(ch); + } else if (isValue) { + value.append(ch); + } + + // we only end the raw marker if its )& or at the end of the value + + boolean end = ch == RAW_TOKEN_END.charAt(0) && (next == '&' || next == '\u0000'); + if (end) { + // raw value end, so add that as a parameter, and reset flags + addParameter(key.toString(), value.toString(), rc, useRaw || isRaw); + key.setLength(0); + value.setLength(0); + isKey = true; + isValue = false; + isRaw = false; + // skip to next as we are in raw mode and have already added the value + i++; + } + continue; + } + + // if its a key and there is a = sign then the key ends and we are in value mode + if (isKey && ch == '=') { + isKey = false; + isValue = true; + isRaw = false; + continue; + } + + // the & denote parameter is ended + if (ch == '&') { + // parameter is ended, as we hit & separator + addParameter(key.toString(), value.toString(), rc, useRaw || isRaw); + key.setLength(0); + value.setLength(0); + isKey = true; + isValue = false; + isRaw = false; + continue; + } + + // regular char so add it to the key or value + if (isKey) { + key.append(ch); + } else if (isValue) { + value.append(ch); + } + } + + // any left over parameters, then add that + if (key.length() > 0) { + addParameter(key.toString(), value.toString(), rc, useRaw || isRaw); + } + + return rc; + + } catch (UnsupportedEncodingException e) { + URISyntaxException se = new URISyntaxException(e.toString(), "Invalid encoding"); + se.initCause(e); + throw se; + } + } + + @SuppressWarnings("unchecked") + private static void addParameter(String name, String value, Map map, boolean isRaw) throws UnsupportedEncodingException { + name = URLDecoder.decode(name, CHARSET); + if (!isRaw) { + // need to replace % with %25 + value = URLDecoder.decode(value.replaceAll("%", "%25"), CHARSET); + } + + // does the key already exist? + if (map.containsKey(name)) { + // yes it does, so make sure we can support multiple values, but using a list + // to hold the multiple values + Object existing = map.get(name); + List list; + if (existing instanceof List) { + list = (List) existing; + } else { + // create a new list to hold the multiple values + list = new ArrayList(); + String s = existing != null ? existing.toString() : null; + if (s != null) { + list.add(s); + } + } + list.add(value); + map.put(name, list); + } else { + map.put(name, value); + } + } + + /** + * Assembles a query from the given map. + * + * @param options the map with the options (eg key/value pairs) + * @param ampersand to use & for Java code, and & for XML + * @return a query string with key1=value&key2=value2&..., or an empty string if there is no options. + * @throws URISyntaxException is thrown if uri has invalid syntax. + */ + @SuppressWarnings("unchecked") + public static String createQueryString(Map options, String ampersand, boolean encode) throws URISyntaxException { + try { + if (options.size() > 0) { + StringBuilder rc = new StringBuilder(); + boolean first = true; + for (Object o : options.keySet()) { + if (first) { + first = false; + } else { + rc.append(ampersand); + } + + String key = (String) o; + Object value = options.get(key); + + // use the value as a String + String s = value != null ? value.toString() : null; + appendQueryStringParameter(key, s, rc, encode); + } + return rc.toString(); + } else { + return ""; + } + } catch (UnsupportedEncodingException e) { + URISyntaxException se = new URISyntaxException(e.toString(), "Invalid encoding"); + se.initCause(e); + throw se; + } + } + + private static void appendQueryStringParameter(String key, String value, StringBuilder rc, boolean encode) throws UnsupportedEncodingException { + if (encode) { + rc.append(URLEncoder.encode(key, CHARSET)); + } else { + rc.append(key); + } + // only append if value is not null + if (value != null) { + rc.append("="); + if (value.startsWith(RAW_TOKEN_START) && value.endsWith(RAW_TOKEN_END)) { + // do not encode RAW parameters + rc.append(value); + } else { + if (encode) { + rc.append(URLEncoder.encode(value, CHARSET)); + } else { + rc.append(value); + } + } + } + } + + /** + * Tests whether the value is null or an empty string. + * + * @param value the value, if its a String it will be tested for text length as well + * @return true if empty + */ + public static boolean isEmpty(Object value) { + return !isNotEmpty(value); + } + + /** + * Tests whether the value is not null or an empty string. + * + * @param value the value, if its a String it will be tested for text length as well + * @return true if not empty + */ + public static boolean isNotEmpty(Object value) { + if (value == null) { + return false; + } else if (value instanceof String) { + String text = (String) value; + return text.trim().length() > 0; + } else { + return true; + } + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/UnsafeUriCharactersEncoder.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/UnsafeUriCharactersEncoder.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/UnsafeUriCharactersEncoder.java new file mode 100644 index 0000000..2a58f3f --- /dev/null +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/UnsafeUriCharactersEncoder.java @@ -0,0 +1,206 @@ +/** + * 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.catalog; + +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Encoder for unsafe URI characters. + *

+ * A good source for details is wikipedia url encode article. + */ +public final class UnsafeUriCharactersEncoder { + private static BitSet unsafeCharactersRfc1738; + private static BitSet unsafeCharactersHttp; + private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', + 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'}; + + static { + unsafeCharactersRfc1738 = new BitSet(256); + unsafeCharactersRfc1738.set(' '); + unsafeCharactersRfc1738.set('"'); + unsafeCharactersRfc1738.set('<'); + unsafeCharactersRfc1738.set('>'); + unsafeCharactersRfc1738.set('#'); + unsafeCharactersRfc1738.set('%'); + unsafeCharactersRfc1738.set('{'); + unsafeCharactersRfc1738.set('}'); + unsafeCharactersRfc1738.set('|'); + unsafeCharactersRfc1738.set('\\'); + unsafeCharactersRfc1738.set('^'); + unsafeCharactersRfc1738.set('~'); + unsafeCharactersRfc1738.set('['); + unsafeCharactersRfc1738.set(']'); + unsafeCharactersRfc1738.set('`'); + } + + static { + unsafeCharactersHttp = new BitSet(256); + unsafeCharactersHttp.set(' '); + unsafeCharactersHttp.set('"'); + unsafeCharactersHttp.set('<'); + unsafeCharactersHttp.set('>'); + unsafeCharactersHttp.set('#'); + unsafeCharactersHttp.set('%'); + unsafeCharactersHttp.set('{'); + unsafeCharactersHttp.set('}'); + unsafeCharactersHttp.set('|'); + unsafeCharactersHttp.set('\\'); + unsafeCharactersHttp.set('^'); + unsafeCharactersHttp.set('~'); + unsafeCharactersHttp.set('`'); + } + + private UnsafeUriCharactersEncoder() { + // util class + } + + public static String encode(String s) { + return encode(s, unsafeCharactersRfc1738); + } + + public static String encodeHttpURI(String s) { + return encode(s, unsafeCharactersHttp); + } + + public static String encode(String s, BitSet unsafeCharacters) { + return encode(s, unsafeCharacters, false); + } + + public static String encode(String s, boolean checkRaw) { + return encode(s, unsafeCharactersRfc1738, checkRaw); + } + + public static String encodeHttpURI(String s, boolean checkRaw) { + return encode(s, unsafeCharactersHttp, checkRaw); + } + + private static List checkRAW(String s) { + Pattern pattern = Pattern.compile("RAW\\([^\\)]+\\)"); + Matcher matcher = pattern.matcher(s); + List answer = new ArrayList(); + // Check all occurrences + while (matcher.find()) { + answer.add(new Pair(matcher.start(), matcher.end())); + } + return answer; + } + + private static boolean isRaw(int index, List pairs) { + for (Pair pair : pairs) { + if (index < pair.left) { + return false; + } else { + if (index >= pair.left) { + if (index <= pair.right) { + return true; + } else { + continue; + } + } + } + } + return false; + } + + private static class Pair { + int left; + int right; + + public Pair(int left, int right) { + this.left = left; + this.right = right; + } + } + + // Just skip the encode for isRAW part + public static String encode(String s, BitSet unsafeCharacters, boolean checkRaw) { + List rawPairs; + if (checkRaw) { + rawPairs = checkRAW(s); + } else { + rawPairs = new ArrayList(); + } + + int n = s == null ? 0 : s.length(); + if (n == 0) { + return s; + } + + // First check whether we actually need to encode + char chars[] = s.toCharArray(); + for (int i = 0;;) { + // just deal with the ascii character + if (chars[i] > 0 && chars[i] < 128) { + if (unsafeCharacters.get(chars[i])) { + break; + } + } + if (++i >= chars.length) { + return s; + } + } + + // okay there are some unsafe characters so we do need to encode + // see details at: http://en.wikipedia.org/wiki/Url_encode + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < chars.length; i++) { + char ch = chars[i]; + if (ch > 0 && ch < 128 && unsafeCharacters.get(ch)) { + // special for % sign as it may be a decimal encoded value + if (ch == '%') { + char next = i + 1 < chars.length ? chars[i + 1] : ' '; + char next2 = i + 2 < chars.length ? chars[i + 2] : ' '; + + if (isHexDigit(next) && isHexDigit(next2) && !isRaw(i, rawPairs)) { + // its already encoded (decimal encoded) so just append as is + sb.append(ch); + } else { + // must escape then, as its an unsafe character + appendEscape(sb, (byte) ch); + } + } else { + // must escape then, as its an unsafe character + appendEscape(sb, (byte) ch); + } + } else { + sb.append(ch); + } + } + return sb.toString(); + } + + private static void appendEscape(StringBuilder sb, byte b) { + sb.append('%'); + sb.append(HEX_DIGITS[(b >> 4) & 0x0f]); + sb.append(HEX_DIGITS[(b >> 0) & 0x0f]); + } + + private static boolean isHexDigit(char ch) { + for (char hex : HEX_DIGITS) { + if (hex == ch) { + return true; + } + } + return false; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/VersionHelper.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/VersionHelper.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/VersionHelper.java new file mode 100644 index 0000000..e1c69bc --- /dev/null +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/VersionHelper.java @@ -0,0 +1,73 @@ +/** + * 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.catalog; + +import java.io.InputStream; +import java.util.Properties; + +/** + * To get the version of this catalog. + */ +public class VersionHelper { + + private static volatile String version; + + public synchronized String getVersion() { + if (version != null) { + return version; + } + InputStream is = null; + // try to load from maven properties first + try { + Properties p = new Properties(); + is = getClass().getResourceAsStream("/META-INF/maven/org.apache.camel/camel-catalog/pom.properties"); + if (is != null) { + p.load(is); + version = p.getProperty("version", ""); + } + } catch (Exception e) { + // ignore + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception e) { + // ignore + } + } + } + + // fallback to using Java API + if (version == null) { + Package aPackage = getClass().getPackage(); + if (aPackage != null) { + version = aPackage.getImplementationVersion(); + if (version == null) { + version = aPackage.getSpecificationVersion(); + } + } + } + + if (version == null) { + // we could not compute the version so use a blank + version = ""; + } + + return version; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/util/CatalogHelper.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/CatalogHelper.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/util/CatalogHelper.java deleted file mode 100644 index 9f430c2..0000000 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/CatalogHelper.java +++ /dev/null @@ -1,146 +0,0 @@ -/** - * 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.catalog.util; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.util.List; - -public final class CatalogHelper { - - private CatalogHelper() { - } - - - /** - * Loads the entire stream into memory as a String and returns it. - *

- * Notice: This implementation appends a \n as line - * terminator at the of the text. - *

- * Warning, don't use for crazy big streams :) - */ - public static void loadLines(InputStream in, List lines) throws IOException { - InputStreamReader isr = new InputStreamReader(in); - try { - BufferedReader reader = new LineNumberReader(isr); - while (true) { - String line = reader.readLine(); - if (line != null) { - lines.add(line); - } else { - break; - } - } - } finally { - isr.close(); - in.close(); - } - } - - /** - * Loads the entire stream into memory as a String and returns it. - *

- * Notice: This implementation appends a \n as line - * terminator at the of the text. - *

- * Warning, don't use for crazy big streams :) - */ - public static String loadText(InputStream in) throws IOException { - StringBuilder builder = new StringBuilder(); - InputStreamReader isr = new InputStreamReader(in); - try { - BufferedReader reader = new LineNumberReader(isr); - while (true) { - String line = reader.readLine(); - if (line != null) { - builder.append(line); - builder.append("\n"); - } else { - break; - } - } - return builder.toString(); - } finally { - isr.close(); - in.close(); - } - } - - /** - * Matches the name with the pattern. - * - * @param name the name - * @param pattern the pattern - * @return true if matched, or false if not - */ - public static boolean matchWildcard(String name, String pattern) { - // we have wildcard support in that hence you can match with: file* to match any file endpoints - if (pattern.endsWith("*") && name.startsWith(pattern.substring(0, pattern.length() - 1))) { - return true; - } - return false; - } - - /** - * Returns the string after the given token - * - * @param text the text - * @param after the token - * @return the text after the token, or null if text does not contain the token - */ - public static String after(String text, String after) { - if (!text.contains(after)) { - return null; - } - return text.substring(text.indexOf(after) + after.length()); - } - - /** - * Returns the string before the given token - * - * @param text the text - * @param before the token - * @return the text before the token, or null if text does not contain the token - */ - public static String before(String text, String before) { - if (!text.contains(before)) { - return null; - } - return text.substring(0, text.indexOf(before)); - } - - /** - * Returns the string between the given tokens - * - * @param text the text - * @param after the before token - * @param before the after token - * @return the text between the tokens, or null if text does not contain the tokens - */ - public static String between(String text, String after, String before) { - text = after(text, after); - if (text == null) { - return null; - } - return before(text, before); - } - -} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/util/JSonSchemaHelper.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/JSonSchemaHelper.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/util/JSonSchemaHelper.java deleted file mode 100644 index 8f7f9dd..0000000 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/JSonSchemaHelper.java +++ /dev/null @@ -1,244 +0,0 @@ -/** - * 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.catalog.util; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public final class JSonSchemaHelper { - - private static final Pattern PATTERN = Pattern.compile("\"(.+?)\"|\\[(.+)\\]"); - 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 component, componentProperties, or properties. - * @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> parseJsonSchema(String group, String json, boolean parseProperties) { - List> answer = new ArrayList>(); - 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 row = new LinkedHashMap(); - 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) { - value = matcher.group(2); - // its an enum so strip out " and trim spaces after comma - value = value.replaceAll("\"", ""); - value = value.replaceAll(", ", ","); - } - if (value != null) { - value = value.trim(); - // decode - value = value.replaceAll(QUOT, "\""); - value = decodeJson(value); - } - 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 isPropertyRequired(List> rows, String name) { - for (Map 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 boolean isPropertyBoolean(List> rows, String name) { - for (Map 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> rows, String name) { - for (Map 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> rows, String name) { - for (Map 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> rows, String name) { - for (Map 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> rows, String name) { - for (Map 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 getPropertyEnum(List> rows, String name) { - for (Map row : rows) { - String enums = null; - String defaultValue = 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 Map getRow(List> rows, String key) { - for (Map row : rows) { - if (key.equals(row.get("name"))) { - return row; - } - } - return null; - } - -} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/util/URISupport.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/URISupport.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/util/URISupport.java deleted file mode 100644 index d173c87..0000000 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/URISupport.java +++ /dev/null @@ -1,365 +0,0 @@ -/** - * 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.catalog.util; - -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * Copied from org.apache.camel.util.URISupport - */ -public final class URISupport { - - public static final String RAW_TOKEN_START = "RAW("; - public static final String RAW_TOKEN_END = ")"; - - private static final String CHARSET = "UTF-8"; - - private URISupport() { - // Helper class - } - - /** - * Normalizes the URI so unsafe charachters is encoded - * - * @param uri the input uri - * @return as URI instance - * @throws URISyntaxException is thrown if syntax error in the input uri - */ - public static URI normalizeUri(String uri) throws URISyntaxException { - return new URI(UnsafeUriCharactersEncoder.encode(uri, true)); - } - - /** - * Strips the query parameters from the uri - * - * @param uri the uri - * @return the uri without the query parameter - */ - public static String stripQuery(String uri) { - int idx = uri.indexOf('?'); - if (idx > -1) { - uri = uri.substring(0, idx); - } - return uri; - } - - /** - * Parses the query parameters of the uri (eg the query part). - * - * @param uri the uri - * @return the parameters, or an empty map if no parameters (eg never null) - * @throws URISyntaxException is thrown if uri has invalid syntax. - */ - public static Map parseParameters(URI uri) throws URISyntaxException { - String query = uri.getQuery(); - if (query == null) { - String schemeSpecificPart = uri.getSchemeSpecificPart(); - int idx = schemeSpecificPart.indexOf('?'); - if (idx < 0) { - // return an empty map - return new LinkedHashMap(0); - } else { - query = schemeSpecificPart.substring(idx + 1); - } - } else { - query = stripPrefix(query, "?"); - } - return parseQuery(query); - } - - /** - * Strips the prefix from the value. - *

- * Returns the value as-is if not starting with the prefix. - * - * @param value the value - * @param prefix the prefix to remove from value - * @return the value without the prefix - */ - public static String stripPrefix(String value, String prefix) { - if (value != null && value.startsWith(prefix)) { - return value.substring(prefix.length()); - } - return value; - } - - /** - * Parses the query part of the uri (eg the parameters). - *

- * The URI parameters will by default be URI encoded. However you can define a parameter - * values with the syntax: key=RAW(value) which tells Camel to not encode the value, - * and use the value as is (eg key=value) and the value has not been encoded. - * - * @param uri the uri - * @return the parameters, or an empty map if no parameters (eg never null) - * @throws URISyntaxException is thrown if uri has invalid syntax. - * @see #RAW_TOKEN_START - * @see #RAW_TOKEN_END - */ - public static Map parseQuery(String uri) throws URISyntaxException { - return parseQuery(uri, false); - } - - /** - * Parses the query part of the uri (eg the parameters). - *

- * The URI parameters will by default be URI encoded. However you can define a parameter - * values with the syntax: key=RAW(value) which tells Camel to not encode the value, - * and use the value as is (eg key=value) and the value has not been encoded. - * - * @param uri the uri - * @param useRaw whether to force using raw values - * @return the parameters, or an empty map if no parameters (eg never null) - * @throws URISyntaxException is thrown if uri has invalid syntax. - * @see #RAW_TOKEN_START - * @see #RAW_TOKEN_END - */ - public static Map parseQuery(String uri, boolean useRaw) throws URISyntaxException { - // must check for trailing & as the uri.split("&") will ignore those - if (uri != null && uri.endsWith("&")) { - throw new URISyntaxException(uri, "Invalid uri syntax: Trailing & marker found. " - + "Check the uri and remove the trailing & marker."); - } - - if (isEmpty(uri)) { - // return an empty map - return new LinkedHashMap(0); - } - - // need to parse the uri query parameters manually as we cannot rely on splitting by &, - // as & can be used in a parameter value as well. - - try { - // use a linked map so the parameters is in the same order - Map rc = new LinkedHashMap(); - - boolean isKey = true; - boolean isValue = false; - boolean isRaw = false; - StringBuilder key = new StringBuilder(); - StringBuilder value = new StringBuilder(); - - // parse the uri parameters char by char - for (int i = 0; i < uri.length(); i++) { - // current char - char ch = uri.charAt(i); - // look ahead of the next char - char next; - if (i <= uri.length() - 2) { - next = uri.charAt(i + 1); - } else { - next = '\u0000'; - } - - // are we a raw value - isRaw = value.toString().startsWith(RAW_TOKEN_START); - - // if we are in raw mode, then we keep adding until we hit the end marker - if (isRaw) { - if (isKey) { - key.append(ch); - } else if (isValue) { - value.append(ch); - } - - // we only end the raw marker if its )& or at the end of the value - - boolean end = ch == RAW_TOKEN_END.charAt(0) && (next == '&' || next == '\u0000'); - if (end) { - // raw value end, so add that as a parameter, and reset flags - addParameter(key.toString(), value.toString(), rc, useRaw || isRaw); - key.setLength(0); - value.setLength(0); - isKey = true; - isValue = false; - isRaw = false; - // skip to next as we are in raw mode and have already added the value - i++; - } - continue; - } - - // if its a key and there is a = sign then the key ends and we are in value mode - if (isKey && ch == '=') { - isKey = false; - isValue = true; - isRaw = false; - continue; - } - - // the & denote parameter is ended - if (ch == '&') { - // parameter is ended, as we hit & separator - addParameter(key.toString(), value.toString(), rc, useRaw || isRaw); - key.setLength(0); - value.setLength(0); - isKey = true; - isValue = false; - isRaw = false; - continue; - } - - // regular char so add it to the key or value - if (isKey) { - key.append(ch); - } else if (isValue) { - value.append(ch); - } - } - - // any left over parameters, then add that - if (key.length() > 0) { - addParameter(key.toString(), value.toString(), rc, useRaw || isRaw); - } - - return rc; - - } catch (UnsupportedEncodingException e) { - URISyntaxException se = new URISyntaxException(e.toString(), "Invalid encoding"); - se.initCause(e); - throw se; - } - } - - @SuppressWarnings("unchecked") - private static void addParameter(String name, String value, Map map, boolean isRaw) throws UnsupportedEncodingException { - name = URLDecoder.decode(name, CHARSET); - if (!isRaw) { - // need to replace % with %25 - value = URLDecoder.decode(value.replaceAll("%", "%25"), CHARSET); - } - - // does the key already exist? - if (map.containsKey(name)) { - // yes it does, so make sure we can support multiple values, but using a list - // to hold the multiple values - Object existing = map.get(name); - List list; - if (existing instanceof List) { - list = (List) existing; - } else { - // create a new list to hold the multiple values - list = new ArrayList(); - String s = existing != null ? existing.toString() : null; - if (s != null) { - list.add(s); - } - } - list.add(value); - map.put(name, list); - } else { - map.put(name, value); - } - } - - /** - * Assembles a query from the given map. - * - * @param options the map with the options (eg key/value pairs) - * @param ampersand to use & for Java code, and & for XML - * @return a query string with key1=value&key2=value2&..., or an empty string if there is no options. - * @throws URISyntaxException is thrown if uri has invalid syntax. - */ - @SuppressWarnings("unchecked") - public static String createQueryString(Map options, String ampersand, boolean encode) throws URISyntaxException { - try { - if (options.size() > 0) { - StringBuilder rc = new StringBuilder(); - boolean first = true; - for (Object o : options.keySet()) { - if (first) { - first = false; - } else { - rc.append(ampersand); - } - - String key = (String) o; - Object value = options.get(key); - - // use the value as a String - String s = value != null ? value.toString() : null; - appendQueryStringParameter(key, s, rc, encode); - } - return rc.toString(); - } else { - return ""; - } - } catch (UnsupportedEncodingException e) { - URISyntaxException se = new URISyntaxException(e.toString(), "Invalid encoding"); - se.initCause(e); - throw se; - } - } - - private static void appendQueryStringParameter(String key, String value, StringBuilder rc, boolean encode) throws UnsupportedEncodingException { - if (encode) { - rc.append(URLEncoder.encode(key, CHARSET)); - } else { - rc.append(key); - } - // only append if value is not null - if (value != null) { - rc.append("="); - if (value.startsWith(RAW_TOKEN_START) && value.endsWith(RAW_TOKEN_END)) { - // do not encode RAW parameters - rc.append(value); - } else { - if (encode) { - rc.append(URLEncoder.encode(value, CHARSET)); - } else { - rc.append(value); - } - } - } - } - - /** - * Tests whether the value is null or an empty string. - * - * @param value the value, if its a String it will be tested for text length as well - * @return true if empty - */ - public static boolean isEmpty(Object value) { - return !isNotEmpty(value); - } - - /** - * Tests whether the value is not null or an empty string. - * - * @param value the value, if its a String it will be tested for text length as well - * @return true if not empty - */ - public static boolean isNotEmpty(Object value) { - if (value == null) { - return false; - } else if (value instanceof String) { - String text = (String) value; - return text.trim().length() > 0; - } else { - return true; - } - } - -} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/util/UnsafeUriCharactersEncoder.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/UnsafeUriCharactersEncoder.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/util/UnsafeUriCharactersEncoder.java deleted file mode 100644 index 5fa387d..0000000 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/UnsafeUriCharactersEncoder.java +++ /dev/null @@ -1,206 +0,0 @@ -/** - * 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.catalog.util; - -import java.util.ArrayList; -import java.util.BitSet; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Encoder for unsafe URI characters. - *

- * A good source for details is wikipedia url encode article. - */ -public final class UnsafeUriCharactersEncoder { - private static BitSet unsafeCharactersRfc1738; - private static BitSet unsafeCharactersHttp; - private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', - 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'}; - - static { - unsafeCharactersRfc1738 = new BitSet(256); - unsafeCharactersRfc1738.set(' '); - unsafeCharactersRfc1738.set('"'); - unsafeCharactersRfc1738.set('<'); - unsafeCharactersRfc1738.set('>'); - unsafeCharactersRfc1738.set('#'); - unsafeCharactersRfc1738.set('%'); - unsafeCharactersRfc1738.set('{'); - unsafeCharactersRfc1738.set('}'); - unsafeCharactersRfc1738.set('|'); - unsafeCharactersRfc1738.set('\\'); - unsafeCharactersRfc1738.set('^'); - unsafeCharactersRfc1738.set('~'); - unsafeCharactersRfc1738.set('['); - unsafeCharactersRfc1738.set(']'); - unsafeCharactersRfc1738.set('`'); - } - - static { - unsafeCharactersHttp = new BitSet(256); - unsafeCharactersHttp.set(' '); - unsafeCharactersHttp.set('"'); - unsafeCharactersHttp.set('<'); - unsafeCharactersHttp.set('>'); - unsafeCharactersHttp.set('#'); - unsafeCharactersHttp.set('%'); - unsafeCharactersHttp.set('{'); - unsafeCharactersHttp.set('}'); - unsafeCharactersHttp.set('|'); - unsafeCharactersHttp.set('\\'); - unsafeCharactersHttp.set('^'); - unsafeCharactersHttp.set('~'); - unsafeCharactersHttp.set('`'); - } - - private UnsafeUriCharactersEncoder() { - // util class - } - - public static String encode(String s) { - return encode(s, unsafeCharactersRfc1738); - } - - public static String encodeHttpURI(String s) { - return encode(s, unsafeCharactersHttp); - } - - public static String encode(String s, BitSet unsafeCharacters) { - return encode(s, unsafeCharacters, false); - } - - public static String encode(String s, boolean checkRaw) { - return encode(s, unsafeCharactersRfc1738, checkRaw); - } - - public static String encodeHttpURI(String s, boolean checkRaw) { - return encode(s, unsafeCharactersHttp, checkRaw); - } - - private static List checkRAW(String s) { - Pattern pattern = Pattern.compile("RAW\\([^\\)]+\\)"); - Matcher matcher = pattern.matcher(s); - List answer = new ArrayList(); - // Check all occurrences - while (matcher.find()) { - answer.add(new Pair(matcher.start(), matcher.end())); - } - return answer; - } - - private static boolean isRaw(int index, List pairs) { - for (Pair pair : pairs) { - if (index < pair.left) { - return false; - } else { - if (index >= pair.left) { - if (index <= pair.right) { - return true; - } else { - continue; - } - } - } - } - return false; - } - - private static class Pair { - int left; - int right; - - public Pair(int left, int right) { - this.left = left; - this.right = right; - } - } - - // Just skip the encode for isRAW part - public static String encode(String s, BitSet unsafeCharacters, boolean checkRaw) { - List rawPairs; - if (checkRaw) { - rawPairs = checkRAW(s); - } else { - rawPairs = new ArrayList(); - } - - int n = s == null ? 0 : s.length(); - if (n == 0) { - return s; - } - - // First check whether we actually need to encode - char chars[] = s.toCharArray(); - for (int i = 0;;) { - // just deal with the ascii character - if (chars[i] > 0 && chars[i] < 128) { - if (unsafeCharacters.get(chars[i])) { - break; - } - } - if (++i >= chars.length) { - return s; - } - } - - // okay there are some unsafe characters so we do need to encode - // see details at: http://en.wikipedia.org/wiki/Url_encode - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < chars.length; i++) { - char ch = chars[i]; - if (ch > 0 && ch < 128 && unsafeCharacters.get(ch)) { - // special for % sign as it may be a decimal encoded value - if (ch == '%') { - char next = i + 1 < chars.length ? chars[i + 1] : ' '; - char next2 = i + 2 < chars.length ? chars[i + 2] : ' '; - - if (isHexDigit(next) && isHexDigit(next2) && !isRaw(i, rawPairs)) { - // its already encoded (decimal encoded) so just append as is - sb.append(ch); - } else { - // must escape then, as its an unsafe character - appendEscape(sb, (byte) ch); - } - } else { - // must escape then, as its an unsafe character - appendEscape(sb, (byte) ch); - } - } else { - sb.append(ch); - } - } - return sb.toString(); - } - - private static void appendEscape(StringBuilder sb, byte b) { - sb.append('%'); - sb.append(HEX_DIGITS[(b >> 4) & 0x0f]); - sb.append(HEX_DIGITS[(b >> 0) & 0x0f]); - } - - private static boolean isHexDigit(char ch) { - for (char hex : HEX_DIGITS) { - if (hex == ch) { - return true; - } - } - return false; - } - -} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/main/java/org/apache/camel/catalog/util/VersionHelper.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/VersionHelper.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/util/VersionHelper.java deleted file mode 100644 index 19ce4f8..0000000 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/util/VersionHelper.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * 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.catalog.util; - -import java.io.InputStream; -import java.util.Properties; - -/** - * To get the version of this catalog. - */ -public class VersionHelper { - - private static volatile String version; - - public synchronized String getVersion() { - if (version != null) { - return version; - } - InputStream is = null; - // try to load from maven properties first - try { - Properties p = new Properties(); - is = getClass().getResourceAsStream("/META-INF/maven/org.apache.camel/camel-catalog/pom.properties"); - if (is != null) { - p.load(is); - version = p.getProperty("version", ""); - } - } catch (Exception e) { - // ignore - } finally { - if (is != null) { - try { - is.close(); - } catch (Exception e) { - // ignore - } - } - } - - // fallback to using Java API - if (version == null) { - Package aPackage = getClass().getPackage(); - if (aPackage != null) { - version = aPackage.getImplementationVersion(); - if (version == null) { - version = aPackage.getSpecificationVersion(); - } - } - } - - if (version == null) { - // we could not compute the version so use a blank - version = ""; - } - - return version; - } - -} http://git-wip-us.apache.org/repos/asf/camel/blob/8210db44/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java index 944456a..162b09b 100644 --- a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java +++ b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java @@ -27,7 +27,7 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.camel.catalog.util.CatalogHelper.loadText; +import static org.apache.camel.catalog.CatalogHelper.loadText; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull;