A appendTo(A appendable, Iterator> parts) throws IOException {
+ Objects.requireNonNull(appendable);
+ if (parts.hasNext()) {
+ appendable.append(toString(parts.next()));
+ while (parts.hasNext()) {
+ appendable.append(separator);
+ appendable.append(toString(parts.next()));
+ }
+ }
+ return appendable;
+ }
+
+ CharSequence toString(Object part) {
+ Objects.requireNonNull(part);
+ return (part instanceof CharSequence) ? (CharSequence) part : part.toString();
+ }
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/MapUtil.java b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/MapUtil.java
new file mode 100644
index 00000000..7436cfda
--- /dev/null
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/MapUtil.java
@@ -0,0 +1,167 @@
+/*
+ * 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 cn.hippo4j.common.toolkit;
+
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
+
+/**
+ * Map util.
+ */
+public class MapUtil {
+
+ /**
+ * Null-safe check if the specified Dictionary is empty.
+ *
+ * Null returns true.
+ *
+ * @param map the collection to check, may be null
+ * @return true if empty or null
+ */
+ public static boolean isEmpty(Map map) {
+ return (map == null || map.isEmpty());
+ }
+
+ /**
+ * Null-safe check if the specified Dictionary is empty.
+ *
+ *
Null returns true.
+ *
+ * @param coll the collection to check, may be null
+ * @return true if empty or null
+ */
+ public static boolean isEmpty(Dictionary coll) {
+ return (coll == null || coll.isEmpty());
+ }
+
+ /**
+ * Null-safe check if the specified Dictionary is not empty.
+ *
+ *
Null returns false.
+ *
+ * @param map the collection to check, may be null
+ * @return true if non-null and non-empty
+ */
+ public static boolean isNotEmpty(Map map) {
+ return !isEmpty(map);
+ }
+
+ /**
+ * Null-safe check if the specified Dictionary is not empty.
+ *
+ *
Null returns false.
+ *
+ * @param coll the collection to check, may be null
+ * @return true if non-null and non-empty
+ */
+ public static boolean isNotEmpty(Dictionary coll) {
+ return !isEmpty(coll);
+ }
+
+ /**
+ * Put into map if value is not null.
+ *
+ * @param target target map
+ * @param key key
+ * @param value value
+ */
+ public static void putIfValNoNull(Map target, Object key, Object value) {
+ Objects.requireNonNull(key, "key");
+ if (value != null) {
+ target.put(key, value);
+ }
+ }
+
+ /**
+ * Put into map if value is not empty.
+ *
+ * @param target target map
+ * @param key key
+ * @param value value
+ */
+ public static void putIfValNoEmpty(Map target, Object key, Object value) {
+ Objects.requireNonNull(key, "key");
+ if (value instanceof String) {
+ if (StringUtil.isNotEmpty((String) value)) {
+ target.put(key, value);
+ }
+ return;
+ }
+ if (value instanceof Collection) {
+ if (CollectionUtil.isNotEmpty((Collection) value)) {
+ target.put(key, value);
+ }
+ return;
+ }
+ if (value instanceof Map) {
+ if (isNotEmpty((Map) value)) {
+ target.put(key, value);
+ }
+ return;
+ }
+ if (value instanceof Dictionary) {
+ if (isNotEmpty((Dictionary) value)) {
+ target.put(key, value);
+ }
+ }
+ }
+
+ /**
+ * ComputeIfAbsent lazy load.
+ *
+ * @param target target Map data.
+ * @param key map key.
+ * @param mappingFunction function which is need to be executed.
+ * @param param1 function's parameter value1.
+ * @param param2 function's parameter value1.
+ * @return
+ */
+ public static V computeIfAbsent(Map target, K key, BiFunction mappingFunction, C param1,
+ T param2) {
+ Objects.requireNonNull(target, "target");
+ Objects.requireNonNull(key, "key");
+ Objects.requireNonNull(mappingFunction, "mappingFunction");
+ Objects.requireNonNull(param1, "param1");
+ Objects.requireNonNull(param2, "param2");
+ V val = target.get(key);
+ if (val == null) {
+ V ret = mappingFunction.apply(param1, param2);
+ target.put(key, ret);
+ return ret;
+ }
+ return val;
+ }
+
+ /**
+ * remove value, Thread safety depends on whether the Map is a thread-safe Map.
+ *
+ * @param map map
+ * @param key key
+ * @param removeJudge judge this key can be remove
+ * @param key type
+ * @param value type
+ * @return value
+ */
+ public static V removeKey(Map map, K key, Predicate removeJudge) {
+ return map.computeIfPresent(key, (k, v) -> removeJudge.test(v) ? null : v);
+ }
+}
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/Md5Util.java b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/Md5Util.java
index 2586f90d..931f683d 100644
--- a/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/Md5Util.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/Md5Util.java
@@ -33,6 +33,16 @@ public class Md5Util {
private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ private static final char XF0 = 0xF0;
+
+ private static final char XF = 0x0F;
+
+ private static final int DATA_ID_GROUP_ID_THREE_LEN = 3;
+
+ private static final int DATA_ID_GROUP_ID_FOUR_LEN = 4;
+
+ private static final int DISPLACEMENT = 4;
+
private static final ThreadLocal MESSAGE_DIGEST_LOCAL = ThreadLocal.withInitial(() -> {
try {
return MessageDigest.getInstance("MD5");
@@ -65,8 +75,8 @@ public class Md5Util {
int l = bytes.length;
char[] out = new char[l << 1];
for (int i = 0, j = 0; i < l; i++) {
- out[j++] = DIGITS_LOWER[(0xF0 & bytes[i]) >>> 4];
- out[j++] = DIGITS_LOWER[0x0F & bytes[i]];
+ out[j++] = DIGITS_LOWER[(XF0 & bytes[i]) >>> DISPLACEMENT];
+ out[j++] = DIGITS_LOWER[XF & bytes[i]];
}
return new String(out);
}
@@ -86,12 +96,12 @@ public class Md5Util {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[1]);
// if have tenant, then set it
- if (dataIdGroupId.length == 3) {
+ if (dataIdGroupId.length == DATA_ID_GROUP_ID_THREE_LEN) {
if (StringUtil.isNotBlank(dataIdGroupId[2])) {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[2]);
}
- } else if (dataIdGroupId.length == 4) {
+ } else if (dataIdGroupId.length == DATA_ID_GROUP_ID_FOUR_LEN) {
if (StringUtil.isNotBlank(dataIdGroupId[2])) {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[2]);
diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/MessageConvert.java b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/MessageConvert.java
index fdf529f9..3be85745 100644
--- a/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/MessageConvert.java
+++ b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/MessageConvert.java
@@ -41,7 +41,7 @@ public class MessageConvert {
MessageWrapper wrapper = new MessageWrapper();
wrapper.setResponseClass(message.getClass());
wrapper.setMessageType(message.getMessageType());
- List