From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-biz-common/jnpf-biz-common-onlyoffice/src/main/java/jnpf/bizcommon/onlyoffice/service/impl/OnlyOfficePluginResolver.java | 141 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 141 insertions(+), 0 deletions(-)
diff --git a/jnpf-biz-common/jnpf-biz-common-onlyoffice/src/main/java/jnpf/bizcommon/onlyoffice/service/impl/OnlyOfficePluginResolver.java b/jnpf-biz-common/jnpf-biz-common-onlyoffice/src/main/java/jnpf/bizcommon/onlyoffice/service/impl/OnlyOfficePluginResolver.java
new file mode 100644
index 0000000..a86bc28
--- /dev/null
+++ b/jnpf-biz-common/jnpf-biz-common-onlyoffice/src/main/java/jnpf/bizcommon/onlyoffice/service/impl/OnlyOfficePluginResolver.java
@@ -0,0 +1,141 @@
+package jnpf.bizcommon.onlyoffice.service.impl;
+
+import jnpf.bizcommon.onlyoffice.entity.OnlyOfficeConfigParam;
+import jnpf.bizcommon.onlyoffice.entity.OnlyOfficeProperties;
+import jnpf.exception.DataException;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.LinkedHashMap;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+@Component
+@RequiredArgsConstructor
+public class OnlyOfficePluginResolver {
+
+ private static final Pattern PATH_COMPONENT_PATTERN = Pattern.compile("[A-Za-z0-9._-]+");
+
+ private final OnlyOfficeProperties properties;
+
+ public List<ResolvedPlugin> resolve(OnlyOfficeConfigParam param) {
+ if (ObjectUtils.isEmpty(param.getBizScene())) {
+ return java.util.Collections.emptyList();
+ }
+
+ OnlyOfficeProperties.PluginSceneMapping mapping = properties.getPlugins().getScenes().stream()
+ .filter(item -> param.getBizScene().equals(item.getBizScene()))
+ .findFirst()
+ .orElseThrow(() -> new DataException("鏈厤缃殑 OnlyOffice 鎻掍欢鍦烘櫙锛�" + param.getBizScene()));
+ if (!mapping.getBizModule().equals(param.getBizModule())) {
+ throw new DataException("OnlyOffice 鎻掍欢鍦烘櫙涓庝笟鍔℃ā鍧椾笉鍖归厤");
+ }
+ if (ObjectUtils.isEmpty(param.getBizDataId())) {
+ throw new DataException("鍚敤 OnlyOffice 鎻掍欢鏃� bizDataId 涓嶈兘涓虹┖");
+ }
+
+ if (ObjectUtils.isEmpty(mapping.getPluginCodes())) {
+ throw new DataException("OnlyOffice 鎻掍欢鍦烘櫙鏈厤缃彃浠�");
+ }
+ String autostartPluginCode = mapping.getAutostartPluginCode();
+ if (!ObjectUtils.isEmpty(autostartPluginCode)
+ && !mapping.getPluginCodes().contains(autostartPluginCode)) {
+ throw new DataException("OnlyOffice 鑷姩鍚姩鎻掍欢鏈寘鍚湪褰撳墠鍦烘櫙涓�");
+ }
+ List<ResolvedPlugin> resolved = new ArrayList<>();
+ Set<String> guids = new HashSet<>();
+ for (String pluginCode : mapping.getPluginCodes()) {
+ if (ObjectUtils.isEmpty(pluginCode) || !PATH_COMPONENT_PATTERN.matcher(pluginCode).matches()) {
+ throw new DataException("OnlyOffice 鎻掍欢缂栫爜閰嶇疆鏃犳晥");
+ }
+ OnlyOfficeProperties.PluginDefinition definition = properties.getPlugins().getDefinitions().get(pluginCode);
+ if (definition == null) {
+ throw new DataException("OnlyOffice 鎻掍欢瀹氫箟涓嶅瓨鍦細" + pluginCode);
+ }
+ String guid = definition.getGuid();
+ if (ObjectUtils.isEmpty(guid) || !guids.add(guid)) {
+ throw new DataException("OnlyOffice 鎻掍欢 GUID 閰嶇疆鏃犳晥鎴栭噸澶�");
+ }
+ String version = definition.getVersion();
+ String release = definition.getRelease();
+ if (!validPathComponent(version) || !validPathComponent(release)) {
+ throw new DataException("OnlyOffice 鎻掍欢鐗堟湰鎴� release 閰嶇疆鏃犳晥");
+ }
+ String baseUrl = normalizedUrl(definition.getPublicBaseUrl(), "public-base-url");
+ String apiBaseUrl = normalizedUrl(definition.getApiBaseUrl(), "api-base-url");
+ resolved.add(new ResolvedPlugin(pluginCode, guid, version,
+ baseUrl + "/" + release + "/" + pluginCode + "/config.json",
+ apiBaseUrl, mapping.getBizScene(), mapping.getBizModule(),
+ pluginCode.equals(autostartPluginCode), mapping.getDisabledPluginGuids()));
+ }
+ return resolved;
+ }
+
+ private boolean validPathComponent(String value) {
+ return !ObjectUtils.isEmpty(value) && PATH_COMPONENT_PATTERN.matcher(value).matches();
+ }
+
+ private String normalizedUrl(String value, String name) {
+ if (ObjectUtils.isEmpty(value)) {
+ throw new DataException("OnlyOffice 鎻掍欢 " + name + " 鏈厤缃�");
+ }
+ String normalized = value.replaceAll("/+$", "");
+ try {
+ URI uri = new URI(normalized);
+ if (!("http".equals(uri.getScheme()) || "https".equals(uri.getScheme()))
+ || ObjectUtils.isEmpty(uri.getHost()) || uri.getQuery() != null || uri.getFragment() != null) {
+ throw new DataException("OnlyOffice 鎻掍欢 " + name + " 閰嶇疆鏃犳晥");
+ }
+ } catch (URISyntaxException e) {
+ throw new DataException("OnlyOffice 鎻掍欢 " + name + " 閰嶇疆鏃犳晥");
+ }
+ return normalized;
+ }
+
+ @Getter
+ public static class ResolvedPlugin {
+
+ private final String manifestUrl;
+ private final String pluginCode;
+ private final String guid;
+ private final String version;
+ private final String apiBaseUrl;
+ private final String bizScene;
+ private final String bizModule;
+ private final boolean autostart;
+ private final List<String> disabledPluginGuids;
+
+ private ResolvedPlugin(String pluginCode, String guid, String version, String manifestUrl, String apiBaseUrl,
+ String bizScene, String bizModule, boolean autostart,
+ List<String> disabledPluginGuids) {
+ this.pluginCode = pluginCode;
+ this.guid = guid;
+ this.version = version;
+ this.manifestUrl = manifestUrl;
+ this.apiBaseUrl = apiBaseUrl;
+ this.bizScene = bizScene;
+ this.bizModule = bizModule;
+ this.autostart = autostart;
+ this.disabledPluginGuids = new ArrayList<>(disabledPluginGuids);
+ }
+
+ public Map<String, Object> runtimeContext(String documentId, String bizDataId) {
+ Map<String, Object> context = new LinkedHashMap<>();
+ context.put("apiBaseUrl", apiBaseUrl);
+ context.put("documentId", documentId);
+ context.put("bizDataId", bizDataId);
+ context.put("bizModule", bizModule);
+ context.put("bizScene", bizScene);
+ context.put("pluginVersion", version);
+ return context;
+ }
+ }
+}
--
Gitblit v1.8.0