File size: 7,248 Bytes
d04c26a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
package com.jetbrains.help.context;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.jetbrains.help.util.FileTools;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class PluginsContextHolder {
private static final String PLUGIN_BASIC_URL = "https://plugins.jetbrains.com";
private static final String PLUGIN_LIST_URL = PLUGIN_BASIC_URL + "/api/searchPlugins?max=10000&offset=0&orderBy=name";
private static final String PLUGIN_INFO_URL = PLUGIN_BASIC_URL + "/api/plugins/";
private static final String PLUGIN_JSON_FILE_NAME = "external/data/plugin.json";
private static List<PluginCache> pluginCacheList;
private static File pluginsJsonFile;
public static void init() {
log.info("Plugin context init loading...");
pluginsJsonFile = FileTools.getFileOrCreat(PLUGIN_JSON_FILE_NAME);
String pluginJsonArray;
try {
pluginJsonArray = IoUtil.readUtf8(FileUtil.getInputStream(pluginsJsonFile));
} catch (IORuntimeException e) {
throw new IllegalArgumentException(CharSequenceUtil.format("{} File read failed", PLUGIN_JSON_FILE_NAME), e);
}
if (CharSequenceUtil.isBlank(pluginJsonArray) || !JSONUtil.isTypeJSON(pluginJsonArray)) {
refreshJsonFile();
} else {
pluginCacheList = JSONUtil.toList(pluginJsonArray, PluginCache.class);
log.info("Plugin context init success !");
}
}
public static List<PluginCache> pluginCacheList() {
return PluginsContextHolder.pluginCacheList;
}
public static void refreshJsonFile() {
log.info("Init or Refresh plugin context from 'JetBrains.com' loading...");
CompletableFuture
.supplyAsync(PluginsContextHolder::pluginList)
.thenApply(PluginsContextHolder::pluginListFilter)
.thenApply(PluginsContextHolder::pluginConversion)
.thenAccept(PluginsContextHolder::overrideJsonFile)
.exceptionally(throwable -> {
log.error("Plugin context init or refresh failed", throwable);
return null;
});
log.info("Init or Refresh plugin context success !");
}
public static void overrideJsonFile(List<PluginCache> pluginCaches) {
pluginCacheList.addAll(pluginCaches);
String jsonStr = JSONUtil.toJsonStr(pluginCacheList);
try {
FileUtil.writeString(jsonStr, pluginsJsonFile, StandardCharsets.UTF_8);
} catch (IORuntimeException e) {
throw new IllegalArgumentException(CharSequenceUtil.format("{} File write failed", PLUGIN_JSON_FILE_NAME), e);
}
}
public static PluginList pluginList() {
return HttpUtil.createGet(PLUGIN_LIST_URL)
.thenFunction(response -> {
try (InputStream is = response.bodyStream()) {
if (!response.isOk()) {
throw new IllegalArgumentException(CharSequenceUtil.format("{} The request failed = {}", PLUGIN_LIST_URL, response));
}
return IoUtil.readObj(is, PluginList.class);
} catch (IOException e) {
throw new IllegalArgumentException(CharSequenceUtil.format("{} The request io read failed", PLUGIN_LIST_URL), e);
}
});
}
public static List<PluginList.Plugin> pluginListFilter(PluginList pluginList) {
return pluginList.getPlugins()
.stream()
.filter(plugin -> !PluginsContextHolder.pluginCacheList.contains(new PluginCache().setId(plugin.getId())))
.filter(plugin -> !CharSequenceUtil.equals(plugin.getPricingModel(), "FREE"))
.toList();
}
public static List<PluginCache> pluginConversion(List<PluginList.Plugin> pluginList) {
return pluginList
.stream()
.map(plugin -> {
String productCode = pluginInfo(plugin.getId()).getPurchaseInfo().getProductCode();
return new PluginCache()
.setId(plugin.getId())
.setProductCode(productCode)
.setName(plugin.getName())
.setPricingModel(plugin.getPricingModel())
.setIcon(PLUGIN_BASIC_URL + plugin.getIcon())
;
})
.toList();
}
public static PluginInfo pluginInfo(Long pluginId) {
return HttpUtil.createGet(PLUGIN_INFO_URL + pluginId)
.thenFunction(response -> {
try (InputStream is = response.bodyStream()) {
if (!response.isOk()) {
throw new IllegalArgumentException(CharSequenceUtil.format("{} The request failed = {}", PLUGIN_INFO_URL, response));
}
return IoUtil.readObj(is, PluginInfo.class);
} catch (IOException e) {
throw new IllegalArgumentException(CharSequenceUtil.format("{} The request io read failed", PLUGIN_LIST_URL), e);
}
});
}
@Data
public static class PluginCache {
private Long id;
private String productCode;
private String name;
private String pricingModel;
private String icon;
@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PluginCache that)) return false;
return id.equals(that.id);
}
@Override
public int hashCode() {
return id.hashCode();
}
}
@Data
public static class PluginInfo {
private Long id;
private PurchaseInfo purchaseInfo;
@Data
public static class PurchaseInfo {
private String productCode;
}
}
@Data
public static class PluginList {
private List<Plugin> plugins;
private Long total;
@Data
public static class Plugin {
private Long id;
private String name;
private String preview;
private Integer downloads;
private String pricingModel;
private String organization;
private String icon;
private String previewImage;
private Double rating;
private VendorInfo vendorInfo;
}
@Data
public static class VendorInfo {
private String name;
private Boolean isVerified;
}
}
}
|