diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java index 823a551ff..cec7b921d 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java @@ -20,6 +20,7 @@ import com.fr.design.locale.impl.ProductImproveMark; import com.fr.design.login.DesignerLoginType; import com.fr.design.login.config.DesignerLoginConfigManager; import com.fr.design.mainframe.ComponentReuseNotifyUtil; +import com.fr.design.mainframe.simple.SimpleDesignerConfig; import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo; import com.fr.design.mainframe.vcs.VcsConfigManager; import com.fr.design.notification.SnapChatConfig; @@ -226,6 +227,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { private boolean propertiesUsable; + private SimpleDesignerConfig fvsDesignerConfig = SimpleDesignerConfig.getInstance("FvsDesignerConfig"); + /** * DesignerEnvManager. */ @@ -1012,6 +1015,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { this.designerStartupConfig.setEnabled(enabled); } + public SimpleDesignerConfig getFvsDesignerConfig() { + return fvsDesignerConfig; + } + /** * 返回环境名称迭代器 */ @@ -1863,6 +1870,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { readSnapChatConfig(reader); } else if (name.equals(DesignerLoginConfigManager.XML_TAG)) { readDesignerLoginAttr(reader); + } else if (name.equals(fvsDesignerConfig.getName())) { + readFvsDesignerConfig(reader); } else { readLayout(reader, name); } @@ -2113,6 +2122,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { writeSnapChatConfig(writer); writeComponentReuseNotificationInfo(writer); writeDesignerLoginAttr(writer); + writeFvsDesignerConfig(writer); writer.end(); } @@ -2419,6 +2429,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { this.designerLoginConfigManager.writeXML(writer); } + private void readFvsDesignerConfig(XMLableReader reader) { + reader.readXMLObject(fvsDesignerConfig); + } + + private void writeFvsDesignerConfig(XMLPrintWriter writer) { + this.fvsDesignerConfig.writeXML(writer); + } + enum XmlHandler { Self; diff --git a/designer-base/src/main/java/com/fr/design/data/MapCompareUtils.java b/designer-base/src/main/java/com/fr/design/data/MapCompareUtils.java index f7492aefc..331e98083 100644 --- a/designer-base/src/main/java/com/fr/design/data/MapCompareUtils.java +++ b/designer-base/src/main/java/com/fr/design/data/MapCompareUtils.java @@ -16,6 +16,8 @@ public final class MapCompareUtils { /** * 对比两个map 查找出相比orig,other中有哪些是新增的、删除的或者被修改的,并分别进行处理 * + * 对比时默认用equals方法来判断是否为 EntryEventKind#UPDATED + * * @param orig 原始map * @param other 参考的新map * @param eventHandler 有区别时的事件处理器 @@ -24,12 +26,29 @@ public final class MapCompareUtils { */ public static void contrastMapEntries(@NotNull Map orig, @NotNull Map other, @NotNull EventHandler eventHandler) { + contrastMapEntries(orig, other, eventHandler, UpdateRule.DEFAULT); + } + + /** + * 对比两个map 查找出相比orig,other中有哪些是新增的、删除的或者被修改的,并分别进行处理 + * + * 对比时用自定义的规则来判断是否为 EntryEventKind#UPDATED + * + * @param orig 原始map + * @param other 参考的新map + * @param eventHandler 有区别时的事件处理器 + * @param updateRule 自定义的Update事件判定规则 + * @param + * @param + */ + public static void contrastMapEntries(@NotNull Map orig, @NotNull Map other, @NotNull EventHandler eventHandler, @NotNull UpdateRule updateRule) { + Map copiedOrig = new LinkedHashMap<>(orig); other.forEach((k, v) -> { V existedV = copiedOrig.remove(k); if (existedV != null) { - if (!v.equals(existedV)) { + if (updateRule.needUpdate(existedV, v)) { eventHandler.on(EntryEventKind.UPDATED, k, v); } } else { @@ -41,10 +60,31 @@ public final class MapCompareUtils { } + /** + * 事件处理器,对应比较后的三种结果的事件处理 + * @param + * @param + */ public interface EventHandler { void on(EntryEventKind entryEventKind, K k, V v); } + /** + * 数据被修改(EntryEventKind.UPDATED) 的判定规则 + * @param + * @param + */ + public interface UpdateRule { + + EntryEventKind eventKind = EntryEventKind.UPDATED; + + UpdateRule DEFAULT = new UpdateRule() {}; + + default boolean needUpdate(V origin, V v) { + return !v.equals(origin); + } + } + public enum EntryEventKind { ADDED, REMOVED, diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index e750fa348..f9ae5948f 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -192,6 +192,32 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh default: break; } + }, new MapCompareUtils.UpdateRule() { + @Override + public boolean needUpdate(Connection origin, Connection connection) { + return needUpdate0(origin, connection); + } + + /** + * 是否需要更新处理 + * 1. Connection本身equals为false,代表字段修改 + * 2. 非内置的Connection,即插件提供的Connection + * todo 原本一个equals方法就可以搞定,但是插件里面没有实现equals,结果导致不能正确判断,只能主代码里做兼容,很恶心,先记个todo,以后看有没有办法改掉 + * @param origin + * @param connection + * @return + */ + private boolean needUpdate0(Connection origin, Connection connection) { + return !connection.equals(origin) || !isEmbedConnection(connection); + } + + /** + * 是否是主工程里内置的Connection + * @return + */ + private boolean isEmbedConnection(Connection connection) { + return connection instanceof JDBCDatabaseConnection || connection instanceof JNDIDatabaseConnection; + } }); this.validateConnections(addedOrUpdatedConnections); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/simple/SimpleDesignerConfig.java b/designer-base/src/main/java/com/fr/design/mainframe/simple/SimpleDesignerConfig.java new file mode 100644 index 000000000..37cfbb180 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/simple/SimpleDesignerConfig.java @@ -0,0 +1,72 @@ +package com.fr.design.mainframe.simple; + +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLable; +import com.fr.stable.xml.XMLableReader; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Wei + * 一个简单属性(字符串)存储类,用于自定义简单属性的存储 + * 如:getInstance("FVSDesignerConfig")可在FineReportEnv.xml中定义一个存储FVS相关配置 + */ +public class SimpleDesignerConfig implements XMLable { + + private static final HashMap configs = new HashMap<>(); + + private SimpleDesignerConfig(String name) { + this.name = name; + } + + public static SimpleDesignerConfig getInstance(String name) { + SimpleDesignerConfig config = configs.get(name); + if(config == null) { + config = new SimpleDesignerConfig(name); + configs.put(name, config); + } + return config; + } + + private String name = ""; + + private HashMap content = new HashMap<>(); + + public void addAttr(String key, String value) { + content.put(key, value); + } + + public Map getContent() { + return content; + } + + @Override + public void readXML(XMLableReader reader) { + if (reader.isAttr()) { + content.putAll(reader.getAttrs()); + } + } + + @Override + public void writeXML(XMLPrintWriter writer) { + writer.startTAG(name); + content.forEach(writer::attr); + writer.end(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + SimpleDesignerConfig cloned = (SimpleDesignerConfig) super.clone(); + cloned.content = new HashMap<>(content); + return cloned; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +}