package com.fujica.parkingtool.oss;
import java.util.Objects;
import java.util.prefs.Preferences;
/**
* 阿里云 OSS 配置。
*
*
4 项核心字段:address / accessKey / secretKey / bucket。
* 全部不为空且 address 是合法主机时被视作"有效配置",否则 {@link #isUsable()} 返回 false,
* 用于让上层选择"不传图片"。
*
* address 不需要带协议前缀;不含 bucket 子域名(即只是 OSS endpoint,
* 例如 oss-cn-hangzhou.aliyuncs.com)。
* 上传时会自动拼成 https://{bucket}.{address}/{key}。
*
* 配置持久化在用户 Preferences 节点 /com/fujica/parkingtool/oss 下。
*/
public final class OssSettings {
private static final String PREF_ROOT = "/com/fujica/parkingtool/oss";
private static final String KEY_ADDRESS = "address";
private static final String KEY_ACCESS_KEY = "accessKey";
private static final String KEY_SECRET_KEY = "secretKey";
private static final String KEY_BUCKET = "bucket";
private static final String KEY_PATH_PREFIX= "pathPrefix";
/** OSS endpoint,不带 https://,不带 bucket 子域名 */
private String address = "";
private String accessKey = "";
private String secretKey = "";
private String bucket = "";
/** 上传路径前缀,默认 parking-simulator */
private String pathPrefix = "parking-simulator";
public OssSettings() { }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address == null ? "" : address.trim(); }
public String getAccessKey() { return accessKey; }
public void setAccessKey(String accessKey) { this.accessKey = accessKey == null ? "" : accessKey.trim(); }
public String getSecretKey() { return secretKey; }
public void setSecretKey(String secretKey) { this.secretKey = secretKey == null ? "" : secretKey; }
public String getBucket() { return bucket; }
public void setBucket(String bucket) { this.bucket = bucket == null ? "" : bucket.trim(); }
public String getPathPrefix() { return pathPrefix; }
public void setPathPrefix(String pathPrefix) {
if (pathPrefix == null) { this.pathPrefix = ""; return; }
String p = pathPrefix.trim();
// 去除首尾的多余斜杠
while (p.startsWith("/")) p = p.substring(1);
while (p.endsWith("/")) p = p.substring(0, p.length() - 1);
this.pathPrefix = p;
}
/** 4 项核心字段全部非空,且 address 形如 host[:port] 才算有效。 */
public boolean isUsable() {
if (isBlank(address) || isBlank(accessKey) || isBlank(secretKey) || isBlank(bucket)) {
return false;
}
String cleaned = cleanAddress(address);
// 简单校验:不能是带协议的 URL;必须包含一个点
return !cleaned.contains("://") && cleaned.contains(".");
}
/** 去除可能错误粘进来的协议前缀和尾部斜杠,返回纯 host[:port] */
public static String cleanAddress(String raw) {
if (raw == null) return "";
String s = raw.trim();
if (s.startsWith("https://")) s = s.substring(8);
if (s.startsWith("http://")) s = s.substring(7);
while (s.endsWith("/")) s = s.substring(0, s.length() - 1);
return s;
}
/** 拼装最终公网 URL(https):{bucket}.{address}/{key} */
public String publicUrl(String key) {
String addr = cleanAddress(address);
String k = key == null ? "" : (key.startsWith("/") ? key.substring(1) : key);
return "https://" + bucket + "." + addr + "/" + k;
}
private static boolean isBlank(String s) {
return s == null || s.trim().isEmpty();
}
public static OssSettings load() {
OssSettings s = new OssSettings();
Preferences p = node();
s.address = p.get(KEY_ADDRESS, s.address);
s.accessKey = p.get(KEY_ACCESS_KEY, s.accessKey);
s.secretKey = p.get(KEY_SECRET_KEY, s.secretKey);
s.bucket = p.get(KEY_BUCKET, s.bucket);
s.pathPrefix = p.get(KEY_PATH_PREFIX,s.pathPrefix);
return s;
}
public void save() {
Preferences p = node();
p.put(KEY_ADDRESS, address);
p.put(KEY_ACCESS_KEY, accessKey);
p.put(KEY_SECRET_KEY, secretKey);
p.put(KEY_BUCKET, bucket);
p.put(KEY_PATH_PREFIX,pathPrefix);
}
public OssSettings copy() {
OssSettings s = new OssSettings();
s.address = address;
s.accessKey = accessKey;
s.secretKey = secretKey;
s.bucket = bucket;
s.pathPrefix = pathPrefix;
return s;
}
private static Preferences node() {
return Preferences.userRoot().node(PREF_ROOT);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof OssSettings that)) return false;
return Objects.equals(address, that.address)
&& Objects.equals(accessKey, that.accessKey)
&& Objects.equals(secretKey, that.secretKey)
&& Objects.equals(bucket, that.bucket)
&& Objects.equals(pathPrefix, that.pathPrefix);
}
@Override
public int hashCode() {
return Objects.hash(address, accessKey, secretKey, bucket, pathPrefix);
}
}