Files
emo-grab/src/main/java/quant/rich/emoney/entity/config/DeviceInfoConfig.java

152 lines
5.2 KiB
Java

package quant.rich.emoney.entity.config;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import quant.rich.emoney.interfaces.ConfigInfo;
import quant.rich.emoney.interfaces.IConfig;
@Data
@Accessors(chain = true)
@Slf4j
@ConfigInfo(
field = "deviceInfo",
name = "设备信息设置",
initDefault = true,
managed = false)
public class DeviceInfoConfig implements IConfig<DeviceInfoConfig> {
private static final Random RANDOM = new Random();
@JsonView(IConfig.Views.Persistence.class)
List<DeviceInfo> deviceInfos;
public DeviceInfoConfig() {
deviceInfos = new ArrayList<>();
}
/**
* 获取随机设备信息
* @return
*/
public DeviceInfo getRandomDeviceInfo() {
if (deviceInfos.isEmpty()) return null;
return deviceInfos.get(RANDOM.nextInt(deviceInfos.size()));
}
@Data
@Accessors(chain=true)
@Slf4j
public static class DeviceInfo {
// 持久化在本地的 DeviceInfo 只有三个字段:
// model、deviceType 和 fingerprint
// 其中除 model 和 deviceType 外,其他字段全部从 fingerprint 派生
// 也就是说只要提供 model、deviceType 和 fingerprint 就能创建一个 DeviceInfo 实例
@JsonView(IConfig.Views.Persistence.class)
private String model;
private String brand;
private String product;
private String device;
@JsonView(IConfig.Views.Persistence.class)
private String deviceType;
private String versionRelease;
private String buildId;
private String buildNumber;
private String buildType;
private String buildTags;
/**
* 用以匹配 fingerprint 的正则表达式
*/
public static final Pattern PATTERN = Pattern.compile("^(?<brand>.*?)/(?<product>.*?)/(?<device>.*?):(?<versionRelease>.*?)/(?<buildId>.*?)/(?<buildNumber>.*?):(?<buildType>.*?)/(?<buildTags>.*?)$");
private DeviceInfo() {}
public DeviceInfo setFingerprint(String fingerprint) {
Matcher m = PATTERN.matcher(fingerprint);
if (!m.matches()) {
throw new IllegalArgumentException("Fingerprint not match the pattern: " + fingerprint);
}
this.setBrand(m.group("brand"));
this.setBuildId(m.group("buildId"));
this.setBuildNumber(m.group("buildNumber"));
this.setBuildTags(m.group("buildTags"));
this.setBuildType(m.group("buildType"));
this.setProduct(m.group("product"));
this.setVersionRelease(m.group("versionRelease"));
this.setDevice(m.group("device"));
return this;
}
public DeviceInfo setDeviceType(String deviceType) {
if (!"Mobile".equals(deviceType) && !"Pad".equals(deviceType)) {
throw new IllegalArgumentException("DeviceType must be \"Mobile\" or \"Pad\", but got \"" + deviceType + "\"");
}
this.deviceType = deviceType;
return this;
}
/**
* 根据指定 model、fingerprint 和 deviceType 返回 DeviceInfo
* @param model
* @param fingerprint
* @param deviceType
* @return
*/
public static DeviceInfo from(String model, String fingerprint, String deviceType) {
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.setModel(model);
deviceInfo.setFingerprint(fingerprint);
deviceInfo.setDeviceType(deviceType);
return deviceInfo;
}
public static DeviceInfo from(String model, String fingerprint) {
return from(model, fingerprint, "Mobile");
}
/**
* 从设备信息中还原 fingerprint
* @return
*/
@JsonView(IConfig.Views.Persistence.class)
public String getFingerprint() {
return String.format("%s/%s/%s:%s/%s/%s:%s/%s",
getBrand(), getProduct(), getDevice(), getVersionRelease(),
getBuildId(), getBuildNumber(), getBuildType(), getBuildTags()
);
}
public final String toString() {
return String.format("Model: %s, DeviceType: %s, Fingerprint: %s",
getModel(), getDeviceType(), getFingerprint()
);
}
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
DeviceInfo other = (DeviceInfo)obj;
return hashCode() == other.hashCode();
}
public int hashCode() {
return Objects.hash(getModel(), getDeviceType(), getFingerprint());
}
}
}