添加 UnifiedResponse 以替代 RestfulResult;重构 RegexUtil。 (#4)

Reviewed-on: plusone/plusone-commons#4
feature/net-util
ZhouXY108 2023-08-09 20:23:31 +08:00
parent f2aba52c4c
commit ef43b4dd87
12 changed files with 611 additions and 100 deletions

View File

@ -16,15 +16,12 @@
package xyz.zhouxy.plusone.commons.base; package xyz.zhouxy.plusone.commons.base;
import xyz.zhouxy.plusone.commons.exception.BaseException;
/** /**
* {@code getCode} * {@code getCode}
* {@code code} * {@code code}
* 便 {@code code} * 便 {@code code}
* *
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a> * @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
* @see BaseException
*/ */
public interface IWithIntCode { public interface IWithIntCode {
int getCode(); int getCode();

View File

@ -0,0 +1,28 @@
/*
* Copyright 2022-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 xyz.zhouxy.plusone.commons.base;
/**
* {@code getCode}
* {@code code}
* 便 {@code code}
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
public interface IWithLongCode {
long getCode();
}

View File

@ -22,6 +22,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
@ -29,6 +30,8 @@ import javax.annotation.Nullable;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
import xyz.zhouxy.plusone.commons.util.ConcurrentHashMapUtil;
@Beta @Beta
public abstract class AbstractMapWrapper<K, V, T extends AbstractMapWrapper<K, V, T>> { public abstract class AbstractMapWrapper<K, V, T extends AbstractMapWrapper<K, V, T>> {
@ -141,12 +144,12 @@ public abstract class AbstractMapWrapper<K, V, T extends AbstractMapWrapper<K, V
} }
public final V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { public final V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
V v = this.map.get(key); if (this.map instanceof ConcurrentHashMap) {
if (null == v) { return ConcurrentHashMapUtil.computIfAbsent(
this.map.putIfAbsent(key, mappingFunction.apply(key)); (ConcurrentHashMap<K, V>) this.map, key, mappingFunction);
v = this.map.get(key); } else {
return this.map.computeIfAbsent(key, mappingFunction);
} }
return v;
} }
public final Map<K, V> exportMap() { public final Map<K, V> exportMap() {

View File

@ -1,14 +1,30 @@
/*
* Copyright 2022-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 xyz.zhouxy.plusone.commons.collection; package xyz.zhouxy.plusone.commons.collection;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function; import java.util.function.Function;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import xyz.zhouxy.plusone.commons.base.JRE; import xyz.zhouxy.plusone.commons.util.ConcurrentHashMapUtil;
// TODO 添加文档注释
@ThreadSafe @ThreadSafe
public class SafeConcurrentHashMap<K, V> extends ConcurrentHashMap<K, V> { public class SafeConcurrentHashMap<K, V> extends ConcurrentHashMap<K, V> {
@ -86,27 +102,6 @@ public class SafeConcurrentHashMap<K, V> extends ConcurrentHashMap<K, V> {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction); return ConcurrentHashMapUtil.computIfAbsent(this, key, mappingFunction);
if (JRE.isJava8()) {
V v = get(key);
if (null == v) {
// this bug fix methods maybe cause `mappingFunction.apply` multiple calls.
v = mappingFunction.apply(key);
if (null == v) {
return null;
}
final V res = putIfAbsent(key, v);
if (null != res) {
// if pre value present, means other thread put value already,
// and putIfAbsent not effect
// return exist value
return res;
}
// if pre value is null, means putIfAbsent effected, return current value
}
return v;
} else {
return computeIfAbsent(key, mappingFunction);
}
} }
} }

View File

@ -45,7 +45,7 @@ public abstract class BaseException extends RuntimeException implements IWithInt
} }
@Override @Override
public int getCode() { public final int getCode() {
return this.code; return this.code;
} }
} }

View File

@ -0,0 +1,50 @@
/*
* Copyright 2022-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 xyz.zhouxy.plusone.commons.util;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import xyz.zhouxy.plusone.commons.base.JRE;
public class ConcurrentHashMapUtil { // TODO 添加文档注释
public static <K, V> V computIfAbsent(ConcurrentHashMap<K, V> map, final K key, final Function<? super K, ? extends V> mappingFunction) {
if (JRE.isJava8()) {
Objects.requireNonNull(mappingFunction);
V v = map.get(key);
if (null == v) {
v = mappingFunction.apply(key);
if (null == v) {
return null;
}
final V res = map.putIfAbsent(key, v);
if (null != res) {
return res;
}
}
return v;
} else {
return map.computeIfAbsent(key, mappingFunction);
}
}
private ConcurrentHashMapUtil() {
throw new IllegalStateException("Utility class");
}
}

View File

@ -0,0 +1,40 @@
package xyz.zhouxy.plusone.commons.util;
import com.google.common.base.Strings;
import xyz.zhouxy.plusone.commons.base.IWithCode;
/**
*
*
* @author zhouxy
*/
final class ErrorResult extends UnifiedResponse {
private static final String DEFAULT_ERR_STATUS = "9999999";
ErrorResult(String message) {
super(DEFAULT_ERR_STATUS, message);
}
ErrorResult(String message, Object data) {
super(DEFAULT_ERR_STATUS, message, data);
}
ErrorResult(Object status, String message) {
super(status, message);
}
ErrorResult(Object status, String message, Object data) {
super(status, message, data);
}
ErrorResult(Object status, Throwable e) {
super(status, Strings.nullToEmpty(e.getMessage()));
}
<E extends Throwable & IWithCode<?>> ErrorResult(E e) {
super(e.getCode(), Strings.nullToEmpty(e.getMessage()));
}
private static final long serialVersionUID = -1680792957826923092L;
}

View File

@ -0,0 +1,19 @@
package xyz.zhouxy.plusone.commons.util;
/**
*
*
* @author zhouxy
*/
final class OrdinaryResult extends UnifiedResponse {
OrdinaryResult(Object status, String message) {
super(status, message);
}
OrdinaryResult(Object status, String message, Object data) {
super(status, message, data);
}
private static final long serialVersionUID = -5794887914598566589L;
}

View File

@ -18,9 +18,11 @@ package xyz.zhouxy.plusone.commons.util;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
@ -28,7 +30,7 @@ import com.google.common.base.Preconditions;
import xyz.zhouxy.plusone.commons.collection.SafeConcurrentHashMap; import xyz.zhouxy.plusone.commons.collection.SafeConcurrentHashMap;
/** /**
* {@link Pattern} 256 * {@link Pattern} 256
* *
* @author ZhouXY * @author ZhouXY
* *
@ -37,8 +39,8 @@ public final class RegexUtil {
private static final int DEFAULT_CACHE_INITIAL_CAPACITY = 64; private static final int DEFAULT_CACHE_INITIAL_CAPACITY = 64;
private static final int MAX_CACHE_SIZE = 256; private static final int MAX_CACHE_SIZE = 256;
private static final Map<String, Pattern> PATTERN_CACHE = new SafeConcurrentHashMap<>( private static final Map<String, Pattern> PATTERN_CACHE
DEFAULT_CACHE_INITIAL_CAPACITY); = new SafeConcurrentHashMap<>(DEFAULT_CACHE_INITIAL_CAPACITY);
/** /**
* {@link Pattern} * {@link Pattern}
@ -49,15 +51,7 @@ public final class RegexUtil {
*/ */
public static Pattern getPattern(final String pattern, final boolean cachePattern) { public static Pattern getPattern(final String pattern, final boolean cachePattern) {
Preconditions.checkNotNull(pattern, "The pattern can not be null."); Preconditions.checkNotNull(pattern, "The pattern can not be null.");
Pattern result = PATTERN_CACHE.get(pattern); return cachePattern ? getAndCachePatternInternal(pattern) : getPatternInternal(pattern);
if (result == null) {
result = Pattern.compile(pattern);
if (cachePattern && PATTERN_CACHE.size() < MAX_CACHE_SIZE) {
PATTERN_CACHE.putIfAbsent(pattern, result);
result = PATTERN_CACHE.get(pattern);
}
}
return result;
} }
/** /**
@ -68,11 +62,7 @@ public final class RegexUtil {
*/ */
public static Pattern getPattern(final String pattern) { public static Pattern getPattern(final String pattern) {
Preconditions.checkNotNull(pattern, "The pattern can not be null."); Preconditions.checkNotNull(pattern, "The pattern can not be null.");
Pattern result = PATTERN_CACHE.get(pattern); return getPatternInternal(pattern);
if (result == null) {
result = Pattern.compile(pattern);
}
return result;
} }
/** /**
@ -83,10 +73,11 @@ public final class RegexUtil {
* @return {@link Pattern} * @return {@link Pattern}
*/ */
public static Pattern[] getPatterns(final String[] patterns, final boolean cachePattern) { public static Pattern[] getPatterns(final String[] patterns, final boolean cachePattern) {
Preconditions.checkNotNull(patterns, "The patterns can not be null."); Preconditions.checkNotNull(patterns, "Patterns can not be null.");
return Arrays.stream(patterns) Preconditions.checkArgument(allNotNull(patterns), "The pattern can not be null.");
.map(pattern -> getPattern(pattern, cachePattern)) return cachePattern
.toArray(Pattern[]::new); ? getAndCachePatternsInternal(patterns)
: getPatternsInternal(patterns);
} }
/** /**
@ -96,10 +87,9 @@ public final class RegexUtil {
* @return {@link Pattern} * @return {@link Pattern}
*/ */
public static Pattern[] getPatterns(final String[] patterns) { public static Pattern[] getPatterns(final String[] patterns) {
Preconditions.checkNotNull(patterns, "The patterns can not be null."); Preconditions.checkNotNull(patterns, "Patterns can not be null.");
return Arrays.stream(patterns) Preconditions.checkArgument(allNotNull(patterns), "The pattern can not be null.");
.map(RegexUtil::getPattern) return getPatternsInternal(patterns);
.toArray(Pattern[]::new);
} }
/** /**
@ -109,12 +99,13 @@ public final class RegexUtil {
* @return Pattern {@code null} * @return Pattern {@code null}
*/ */
public static Pattern cachePattern(final Pattern pattern) { public static Pattern cachePattern(final Pattern pattern) {
Preconditions.checkNotNull(pattern, "The pattern can not be null.");
if (PATTERN_CACHE.size() >= MAX_CACHE_SIZE) { if (PATTERN_CACHE.size() >= MAX_CACHE_SIZE) {
return null; return null;
} }
final String patternStr = pattern.pattern(); final String patternStr = pattern.pattern();
PATTERN_CACHE.putIfAbsent(patternStr, pattern); final Pattern pre = PATTERN_CACHE.putIfAbsent(patternStr, pattern);
return PATTERN_CACHE.get(patternStr); return pre != null ? pre : pattern;
} }
/** /**
@ -126,7 +117,7 @@ public final class RegexUtil {
*/ */
public static boolean matches(@Nullable final CharSequence input, final Pattern pattern) { public static boolean matches(@Nullable final CharSequence input, final Pattern pattern) {
Preconditions.checkNotNull(pattern, "The pattern can not be null."); Preconditions.checkNotNull(pattern, "The pattern can not be null.");
return input != null && pattern.matcher(input).matches(); return matchesInternal(input, pattern);
} }
/** /**
@ -137,16 +128,9 @@ public final class RegexUtil {
* @return * @return
*/ */
public static boolean matchesOne(@Nullable final CharSequence input, final Pattern[] patterns) { public static boolean matchesOne(@Nullable final CharSequence input, final Pattern[] patterns) {
Preconditions.checkNotNull(patterns, "The patterns can not be null."); Preconditions.checkNotNull(patterns, "Patterns can not be null.");
if (input == null) { Preconditions.checkArgument(allNotNull(patterns), "The pattern can not be null.");
return false; return matchesOneInternal(input, patterns);
}
for (Pattern pattern : patterns) {
if (matches(input, pattern)) {
return true;
}
}
return false;
} }
/** /**
@ -157,16 +141,9 @@ public final class RegexUtil {
* @return * @return
*/ */
public static boolean matchesAll(@Nullable final CharSequence input, final Pattern[] patterns) { public static boolean matchesAll(@Nullable final CharSequence input, final Pattern[] patterns) {
Preconditions.checkNotNull(patterns, "The patterns can not be null."); Preconditions.checkNotNull(patterns, "Patterns can not be null.");
if (input == null) { Preconditions.checkArgument(allNotNull(patterns), "The pattern can not be null.");
return false; return matchesAllInternal(input, patterns);
}
for (Pattern pattern : patterns) {
if (!matches(input, pattern)) {
return false;
}
}
return true;
} }
/** /**
@ -179,7 +156,11 @@ public final class RegexUtil {
*/ */
public static boolean matches(@Nullable final CharSequence input, final String pattern, public static boolean matches(@Nullable final CharSequence input, final String pattern,
final boolean cachePattern) { final boolean cachePattern) {
return matches(input, getPattern(pattern, cachePattern)); Preconditions.checkNotNull(pattern, "The pattern can not be null.");
Pattern p = cachePattern
? getAndCachePatternInternal(pattern)
: getPatternInternal(pattern);
return matchesInternal(input, p);
} }
/** /**
@ -190,7 +171,8 @@ public final class RegexUtil {
* @return * @return
*/ */
public static boolean matches(@Nullable final CharSequence input, final String pattern) { public static boolean matches(@Nullable final CharSequence input, final String pattern) {
return matches(input, getPattern(pattern)); Preconditions.checkNotNull(pattern, "The pattern can not be null.");
return matchesInternal(input, getPatternInternal(pattern));
} }
/** /**
@ -203,8 +185,12 @@ public final class RegexUtil {
*/ */
public static boolean matchesOne(@Nullable final CharSequence input, final String[] patterns, public static boolean matchesOne(@Nullable final CharSequence input, final String[] patterns,
final boolean cachePattern) { final boolean cachePattern) {
final Pattern[] patternSet = getPatterns(patterns, cachePattern); Preconditions.checkNotNull(patterns, "Patterns can not be null.");
return matchesOne(input, patternSet); Preconditions.checkArgument(allNotNull(patterns), "The pattern can not be null.");
final Pattern[] patternSet = cachePattern
? getAndCachePatternsInternal(patterns)
: getPatternsInternal(patterns);
return matchesOneInternal(input, patternSet);
} }
/** /**
@ -215,8 +201,10 @@ public final class RegexUtil {
* @return * @return
*/ */
public static boolean matchesOne(@Nullable final CharSequence input, final String[] patterns) { public static boolean matchesOne(@Nullable final CharSequence input, final String[] patterns) {
final Pattern[] patternSet = getPatterns(patterns); Preconditions.checkNotNull(patterns, "Patterns can not be null.");
return matchesOne(input, patternSet); Preconditions.checkArgument(allNotNull(patterns), "The pattern can not be null.");
final Pattern[] patternSet = getPatternsInternal(patterns);
return matchesOneInternal(input, patternSet);
} }
/** /**
@ -229,8 +217,12 @@ public final class RegexUtil {
*/ */
public static boolean matchesAll(@Nullable final CharSequence input, final String[] patterns, public static boolean matchesAll(@Nullable final CharSequence input, final String[] patterns,
final boolean cachePattern) { final boolean cachePattern) {
final Pattern[] patternSet = getPatterns(patterns, cachePattern); Preconditions.checkNotNull(patterns, "Patterns can not be null.");
return matchesAll(input, patternSet); Preconditions.checkArgument(allNotNull(patterns), "The pattern can not be null.");
final Pattern[] patternSet = cachePattern
? getAndCachePatternsInternal(patterns)
: getPatternsInternal(patterns);
return matchesAllInternal(input, patternSet);
} }
/** /**
@ -241,25 +233,27 @@ public final class RegexUtil {
* @return * @return
*/ */
public static boolean matchesAll(@Nullable final CharSequence input, final String[] patterns) { public static boolean matchesAll(@Nullable final CharSequence input, final String[] patterns) {
final Pattern[] patternSet = getPatterns(patterns); Preconditions.checkNotNull(patterns, "Patterns can not be null.");
return matchesAll(input, patternSet); Preconditions.checkArgument(allNotNull(patterns), "The pattern can not be null.");
final Pattern[] patternSet = getPatternsInternal(patterns);
return matchesAllInternal(input, patternSet);
} }
/** /**
* * Matcher
* *
* @param input * @param input
* @param pattern * @param pattern
* @return * @return
*/ */
public static Matcher getMatcher(final CharSequence input, final Pattern pattern) { public static Matcher getMatcher(final CharSequence input, final Pattern pattern) {
Preconditions.checkNotNull(input, "The input can not be null"); Preconditions.checkNotNull(input, "The input can not be null.");
Preconditions.checkNotNull(pattern, "The pattern can not be null"); Preconditions.checkNotNull(pattern, "The pattern can not be null.");
return pattern.matcher(input); return pattern.matcher(input);
} }
/** /**
* * Matcher
* *
* @param input * @param input
* @param pattern * @param pattern
@ -267,20 +261,132 @@ public final class RegexUtil {
* @return * @return
*/ */
public static Matcher getMatcher(final CharSequence input, final String pattern, boolean cachePattern) { public static Matcher getMatcher(final CharSequence input, final String pattern, boolean cachePattern) {
Preconditions.checkNotNull(input, "The input can not be null"); Preconditions.checkNotNull(input, "The input can not be null.");
return getPattern(pattern, cachePattern).matcher(input); Preconditions.checkNotNull(pattern, "The pattern can not be null.");
final Pattern p = cachePattern
? getAndCachePatternInternal(pattern)
: getPatternInternal(pattern);
return p.matcher(input);
} }
/** /**
* {@link Pattern} * Matcher {@link Pattern}
* *
* @param input * @param input
* @param pattern * @param pattern
* @return * @return
*/ */
public static Matcher getMatcher(final CharSequence input, final String pattern) { public static Matcher getMatcher(final CharSequence input, final String pattern) {
Preconditions.checkNotNull(input, "The input can not be null"); Preconditions.checkNotNull(input, "The input can not be null.");
return getPattern(pattern).matcher(input); Preconditions.checkNotNull(pattern, "The pattern can not be null.");
return getPatternInternal(pattern).matcher(input);
}
// ========== internal methods ==========
/**
* {@link Pattern}
*
* @param pattern
* @param cachePattern {@link Pattern}
* @return {@link Pattern}
*/
@SuppressWarnings("null")
@Nonnull
private static Pattern getAndCachePatternInternal(@Nonnull final String pattern) {
if (PATTERN_CACHE.size() < MAX_CACHE_SIZE) {
return PATTERN_CACHE.computeIfAbsent(pattern, Pattern::compile);
}
Pattern result = PATTERN_CACHE.get(pattern);
if (result != null) {
return result;
}
return Pattern.compile(pattern);
}
/**
* {@link Pattern}
*
* @param pattern
* @return {@link Pattern}
*/
@SuppressWarnings("null")
@Nonnull
private static Pattern getPatternInternal(@Nonnull final String pattern) {
Pattern result = PATTERN_CACHE.get(pattern);
if (result == null) {
result = Pattern.compile(pattern);
}
return result;
}
/**
* {@link Pattern}
*
* @param patterns
* @return {@link Pattern}
*/
@SuppressWarnings("null")
@Nonnull
private static Pattern[] getAndCachePatternsInternal(@Nonnull final String[] patterns) {
return Arrays.stream(patterns)
.map(RegexUtil::getAndCachePatternInternal)
.toArray(Pattern[]::new);
}
/**
* {@link Pattern}
*
* @param patterns
* @return {@link Pattern}
*/
@SuppressWarnings("null")
@Nonnull
private static Pattern[] getPatternsInternal(@Nonnull final String[] patterns) {
return Arrays.stream(patterns)
.map(RegexUtil::getPatternInternal)
.toArray(Pattern[]::new);
}
/**
* {@code input} {@code pattern}
*
* @param input
* @param pattern
* @return
*/
private static boolean matchesInternal(@Nullable final CharSequence input, @Nonnull final Pattern pattern) {
return input != null && pattern.matcher(input).matches();
}
@SuppressWarnings("null")
private static boolean matchesOneInternal(@Nullable final CharSequence input, @Nonnull final Pattern[] patterns) {
if (input == null) {
return false;
}
for (Pattern pattern : patterns) {
if (matchesInternal(input, pattern)) {
return true;
}
}
return false;
}
@SuppressWarnings("null")
private static boolean matchesAllInternal(final CharSequence input, final Pattern[] patterns) {
if (input == null) {
return false;
}
for (Pattern pattern : patterns) {
if (!matchesInternal(input, pattern)) {
return false;
}
}
return true;
}
private static <T> boolean allNotNull(T[] array) {
return Arrays.stream(array).allMatch(Objects::nonNull);
} }
private RegexUtil() { private RegexUtil() {

View File

@ -28,7 +28,9 @@ import com.google.common.base.Preconditions;
* *
* *
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a> * @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
* @deprecated {@link UnifiedResponse}
*/ */
@Deprecated
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class RestfulResult { public class RestfulResult {

View File

@ -0,0 +1,25 @@
package xyz.zhouxy.plusone.commons.util;
/**
*
*
* @author zhouxy
*/
final class SuccessResult extends UnifiedResponse {
private static final String SUCCESS_STATUS = "000000";
private static final String DEFAULT_SUCCESS_MSG = "SUCCESS";
SuccessResult() {
super(SUCCESS_STATUS, DEFAULT_SUCCESS_MSG);
}
SuccessResult(String message) {
super(SUCCESS_STATUS, message);
}
SuccessResult(String message, Object data) {
super(SUCCESS_STATUS, message, data);
}
private static final long serialVersionUID = -7509096647748429661L;
}

View File

@ -0,0 +1,246 @@
/*
* Copyright 2022-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 xyz.zhouxy.plusone.commons.util;
import xyz.zhouxy.plusone.commons.base.IWithCode;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
import java.util.function.Supplier;
import com.google.common.base.Preconditions;
/**
*
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
*/
public abstract class UnifiedResponse extends HashMap<String, Object> {
private static final long serialVersionUID = -6198220274571286031L;
private static final String STATUS_KEY = "status";
private static final String MESSAGE_KEY = "message";
private static final String DATA_KEY = "data";
public static UnifiedResponse success() {
return new SuccessResult();
}
public static UnifiedResponse success(String message) {
return new SuccessResult(message);
}
public static UnifiedResponse success(String message, Object data) {
return new SuccessResult(message, data);
}
public static UnifiedResponse error(String message) {
return new ErrorResult(message);
}
public static UnifiedResponse error(String message, Object data) {
return new ErrorResult(message, data);
}
public static UnifiedResponse error(Object status, String message) {
return new ErrorResult(status, message);
}
public static UnifiedResponse error(Object status, String message, Object data) {
return new ErrorResult(status, message, data);
}
public static UnifiedResponse error(Object status, Throwable e) {
return new ErrorResult(status, e);
}
public static <E extends Throwable & IWithCode<?>> UnifiedResponse error(E e) {
return new ErrorResult(e);
}
public static UnifiedResponse of(Object status, String message) {
return new OrdinaryResult(status, message);
}
public static UnifiedResponse of(Object status, String message, Object data) {
return new OrdinaryResult(status, message, data);
}
public static UnifiedResponse of(final boolean isSuccess,
final Supplier<SuccessResult> success, final Supplier<ErrorResult> error) {
Preconditions.checkNotNull(success, "Success supplier must not be null.");
Preconditions.checkNotNull(error, "Error supplier must not be null.");
return isSuccess ? success.get() : error.get();
}
public static UnifiedResponse of(final BooleanSupplier isSuccess,
final Supplier<SuccessResult> success, final Supplier<ErrorResult> error) {
Preconditions.checkNotNull(isSuccess, "Conditions for success must not be null.");
Preconditions.checkNotNull(success, "Success supplier must not be null.");
Preconditions.checkNotNull(error, "Error supplier must not be null.");
return isSuccess.getAsBoolean() ? success.get() : error.get();
}
protected UnifiedResponse(Object status, String message) {
setStatus(status);
setMessage(message);
}
protected UnifiedResponse(Object status, String message, Object data) {
setStatus(status);
setMessage(message);
setData(data);
}
private void setStatus(Object status) {
Objects.requireNonNull(status);
if (status instanceof String) {
super.put(STATUS_KEY, status);
} else {
super.put(STATUS_KEY, status.toString());
}
}
private void setData(Object data) {
super.put(DATA_KEY, Objects.requireNonNull(data));
}
private void setMessage(String message) {
super.put(MESSAGE_KEY, Objects.requireNonNull(message));
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public Object put(String key, Object value) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public void putAll(Map<? extends String, ?> m) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public Object remove(Object key) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public void clear() {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public Object putIfAbsent(String key, Object value) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public boolean replace(String key, Object oldValue, Object newValue) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public Object replace(String key, Object value) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public Object computeIfAbsent(String key, Function<? super String, ?> mappingFunction) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public Object computeIfPresent(String key, BiFunction<? super String, ? super Object, ?> remappingFunction) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public Object compute(String key, BiFunction<? super String, ? super Object, ?> remappingFunction) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public Object merge(String key, Object value, BiFunction<? super Object, ? super Object, ?> remappingFunction) {
throw new UnsupportedOperationException();
}
/**
* @deprecated Unsupported operation.
*/
@Deprecated
@Override
public void replaceAll(BiFunction<? super String, ? super Object, ?> function) {
throw new UnsupportedOperationException();
}
}