Browse Source
Merge in DESIGN/design from ~YVAN/design:REPORT-43833 to release/10.0 * commit 'e5585ff488ed78cd428a8a23ba4606243d7a61ea': REPORT-43833 【10.0.14】远程设计数据连接/服务器数据集增加锁定 1. 将本地实现作为默认实现,注册起来,以兼容远程连接老版服务器的情况 2. 之前清理脏数据的逻辑有点问题,修改方式为:为LockItem对象添加一个成员变量birth,代表其创建时间,并且会为每个ClientID在对应的服务中存上一个key=clientID,value=LockItem的键值对,在用户登入时初始化,每隔30s更新创建时间,用户登出时清除,并且在轮询任务中加入检查当前各个LockItem对应的服务下这个键值对里value的birth是否超时了,如果超时,清理脏数据 3. 将之前使用的applyForService修改为applyForCleanableService,便于集群重启时清理服务数据 REPORT-43833 【10.0.14】远程设计数据连接/服务器数据集增加锁定 将通知组件的操作放到EDT中 REPORT-43833 【10.0.14】远程设计数据连接/服务器数据集增加锁定 将弹窗关闭后解锁的操作,放到afterCommit中 REPORT-43833 【10.0.14】远程设计数据连接/服务器数据集增加锁定 【问题原因】自测+修改一些bug 【改动思路】自测+修改一些bug REPORT-43833 【10.0.14】远程设计数据连接/服务器数据集增加锁定 【问题原因】迭代提交 【改动思路】迭代提交feature/big-screen
ju|剧浩宇
4 years ago
20 changed files with 625 additions and 63 deletions
@ -0,0 +1,25 @@
|
||||
package com.fr.design.editlock; |
||||
|
||||
|
||||
import com.fr.report.LockItem; |
||||
|
||||
/** |
||||
* @author Yvan |
||||
* @version 10.0 |
||||
* Created by Yvan on 2021/1/20 |
||||
* 定义数据连接的checker |
||||
*/ |
||||
public class ConnectionLockChangeChecker extends EditLockChangeChecker{ |
||||
|
||||
private static class Holder { |
||||
private static final ConnectionLockChangeChecker INSTANCE = new ConnectionLockChangeChecker(); |
||||
} |
||||
|
||||
public static ConnectionLockChangeChecker getInstance() { |
||||
return ConnectionLockChangeChecker.Holder.INSTANCE; |
||||
} |
||||
|
||||
public ConnectionLockChangeChecker() { |
||||
this.lockItem = LockItem.CONNECTION; |
||||
} |
||||
} |
@ -0,0 +1,73 @@
|
||||
package com.fr.design.editlock; |
||||
|
||||
import com.fr.concurrent.NamedThreadFactory; |
||||
import com.fr.design.ui.util.UIUtil; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.workspace.WorkContext; |
||||
import com.fr.workspace.server.lock.editlock.EditLockOperator; |
||||
import com.fr.report.LockItem; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.concurrent.Executors; |
||||
import java.util.concurrent.ScheduledExecutorService; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
/** |
||||
* @author Yvan |
||||
* @version 10.0 |
||||
* Created by Yvan on 2021/1/19 |
||||
* 判断当前设计器在远程设计服务器中的锁状态是否发生了改变 |
||||
*/ |
||||
public abstract class EditLockChangeChecker { |
||||
|
||||
private static final int INTERVAL = 30000; |
||||
private ScheduledExecutorService scheduler; |
||||
protected LockItem lockItem; |
||||
private boolean isLocked = false; |
||||
private List<EditLockChangeListener> listeners = new ArrayList<>(); |
||||
|
||||
/** |
||||
* 轮询任务,如果是远程设计状态,每隔30s查询一次相应lockItem的锁状态是否改变 |
||||
*/ |
||||
public void start() { |
||||
this.scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("EditLockChangeChecker")); |
||||
this.scheduler.scheduleAtFixedRate(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
// 判断是否为远程设计环境
|
||||
if (!WorkContext.getCurrent().isLocal()) { |
||||
try { |
||||
EditLockOperator operator = WorkContext.getCurrent().get(EditLockOperator.class); |
||||
boolean locked = operator.isLocked(lockItem); |
||||
if (isLocked != locked) { |
||||
isLocked = locked; |
||||
fireChange(); |
||||
} |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
} |
||||
}, 0, INTERVAL, TimeUnit.MILLISECONDS); |
||||
} |
||||
|
||||
public void stop() { |
||||
this.scheduler.shutdown(); |
||||
} |
||||
|
||||
public void addEditLockChangeListener(EditLockChangeListener listener) { |
||||
this.listeners.add(listener); |
||||
} |
||||
|
||||
private void fireChange() { |
||||
UIUtil.invokeLaterIfNeeded(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
for (EditLockChangeListener listener : EditLockChangeChecker.this.listeners) { |
||||
listener.updateLockedState(new EditLockChangeEvent(isLocked)); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
} |
@ -0,0 +1,25 @@
|
||||
package com.fr.design.editlock; |
||||
|
||||
import java.util.EventObject; |
||||
|
||||
/** |
||||
* @author Yvan |
||||
* @version 10.0 |
||||
* Created by Yvan on 2021/1/20 |
||||
*/ |
||||
public class EditLockChangeEvent extends EventObject { |
||||
|
||||
private boolean isLocked; |
||||
|
||||
/** |
||||
* @param source 锁状态发生了改变,且当前锁状态就是source |
||||
*/ |
||||
public EditLockChangeEvent(boolean source) { |
||||
super(source); |
||||
this.isLocked = source; |
||||
} |
||||
|
||||
public boolean isLocked() { |
||||
return isLocked; |
||||
} |
||||
} |
@ -0,0 +1,16 @@
|
||||
package com.fr.design.editlock; |
||||
|
||||
import java.util.EventListener; |
||||
|
||||
/** |
||||
* @author Yvan |
||||
* @version 10.0 |
||||
* Created by Yvan on 2021/1/20 |
||||
*/ |
||||
public interface EditLockChangeListener extends EventListener { |
||||
/** |
||||
* 锁定状态改变后执行的动作 |
||||
* @param event 事件 |
||||
*/ |
||||
void updateLockedState(EditLockChangeEvent event); |
||||
} |
@ -0,0 +1,79 @@
|
||||
package com.fr.design.editlock; |
||||
|
||||
import com.fr.base.svg.IconUtils; |
||||
import com.fr.base.svg.SVGLoader; |
||||
import com.fr.design.dialog.FineJOptionPane; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.workspace.WorkContext; |
||||
import com.fr.workspace.server.lock.editlock.EditLockOperator; |
||||
import com.fr.report.LockItem; |
||||
import org.jetbrains.annotations.Nullable; |
||||
|
||||
import javax.swing.Icon; |
||||
import javax.swing.JOptionPane; |
||||
import java.awt.Image; |
||||
|
||||
/** |
||||
* @author Yvan |
||||
* @version 10.0 |
||||
* Created by Yvan on 2021/1/20 |
||||
* 关于编辑锁定的一些常量和静态方法 |
||||
*/ |
||||
public class EditLockUtils { |
||||
|
||||
/** |
||||
* 数据连接锁定标志 |
||||
*/ |
||||
public static final Icon CONNECTION_LOCKED_ICON = IconUtils.readIcon("/com/fr/design/images/m_web/connection_locked"); |
||||
|
||||
/** |
||||
* 小锁图片 |
||||
*/ |
||||
public static final @Nullable Image LOCKED_IMAGE = SVGLoader.load("/com/fr/design/images/m_web/locked_normal.svg"); |
||||
|
||||
/** |
||||
* 提示弹窗中的提示标志 |
||||
*/ |
||||
public static final Icon TOOLTIPS_ICON = IOUtils.readIcon("/com/fr/design/images/m_web/warningIcon.png"); |
||||
|
||||
/** |
||||
* 数据连接锁定中 |
||||
*/ |
||||
public static final String CONNECTION_LOCKED_TOOLTIPS = Toolkit.i18nText("Fine_Designer_Remote_Design_Data_Connection_Locked"); |
||||
|
||||
/** |
||||
* 服务器数据集锁定中 |
||||
*/ |
||||
public static final String SERVER_TABLEDATA_LOCKED_TOOLTIPS = Toolkit.i18nText("Fine_Designer_Remote_Design_Server_TableData_Locked"); |
||||
|
||||
/** |
||||
* 提示弹窗中的提示信息 |
||||
*/ |
||||
public static final String LOCKED_MESSAGE = Toolkit.i18nText("Fine_Designer_Remote_Design_Locked_Message"); |
||||
|
||||
/** |
||||
* 提示弹窗中的标题 |
||||
*/ |
||||
public static final String TOOLTIPS = Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Title_Hint"); |
||||
|
||||
/** |
||||
* 已经被锁,跳出弹窗提示 |
||||
*/ |
||||
public static void showLockMessage() { |
||||
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), EditLockUtils.LOCKED_MESSAGE, EditLockUtils.TOOLTIPS, JOptionPane.INFORMATION_MESSAGE, EditLockUtils.TOOLTIPS_ICON); |
||||
} |
||||
|
||||
public static boolean lock(LockItem lockItem) { |
||||
return WorkContext.getCurrent().get(EditLockOperator.class).lock(lockItem); |
||||
} |
||||
|
||||
public static boolean unlock(LockItem lockItem) { |
||||
return WorkContext.getCurrent().get(EditLockOperator.class).unlock(lockItem); |
||||
} |
||||
|
||||
public static boolean isLocked(LockItem lockItem) { |
||||
return WorkContext.getCurrent().get(EditLockOperator.class).isLocked(lockItem); |
||||
} |
||||
} |
@ -0,0 +1,23 @@
|
||||
package com.fr.design.editlock; |
||||
|
||||
import com.fr.report.LockItem; |
||||
|
||||
/** |
||||
* @author Yvan |
||||
* @version 10.0 |
||||
* Created by Yvan on 2021/1/20 |
||||
* 服务器数据集的checker |
||||
*/ |
||||
public class ServerTableDataLockChangeChecker extends EditLockChangeChecker{ |
||||
private static class Holder { |
||||
private static final ServerTableDataLockChangeChecker INSTANCE = new ServerTableDataLockChangeChecker(); |
||||
} |
||||
|
||||
public static ServerTableDataLockChangeChecker getInstance() { |
||||
return ServerTableDataLockChangeChecker.Holder.INSTANCE; |
||||
} |
||||
|
||||
public ServerTableDataLockChangeChecker() { |
||||
this.lockItem = LockItem.SERVER_TABLE_DATA; |
||||
} |
||||
} |
@ -0,0 +1,55 @@
|
||||
package com.fr.design.gui.ibutton; |
||||
|
||||
import com.fr.design.editlock.EditLockChangeEvent; |
||||
import com.fr.design.editlock.EditLockChangeListener; |
||||
import com.fr.design.editlock.EditLockUtils; |
||||
import com.fr.report.LockItem; |
||||
|
||||
import javax.swing.Icon; |
||||
|
||||
/** |
||||
* @author Yvan |
||||
* @version 10.0 |
||||
* Created by Yvan on 2021/1/20 |
||||
*/ |
||||
public class UILockButton extends UIButton implements EditLockChangeListener { |
||||
|
||||
/** |
||||
* 锁定状态图标 |
||||
*/ |
||||
private Icon lockedIcon; |
||||
/** |
||||
* 正常状态图标 |
||||
*/ |
||||
private Icon normalIcon; |
||||
/** |
||||
* 锁定状态的提示信息 |
||||
*/ |
||||
private String lockedTooltips; |
||||
/** |
||||
* 正常状态的提示信息 |
||||
*/ |
||||
private String normalTooltips; |
||||
|
||||
public UILockButton(Icon lockedIcon, Icon normalIcon, String lockedTooltips, String normalTooltips) { |
||||
super(); |
||||
this.lockedIcon = lockedIcon; |
||||
this.normalIcon = normalIcon; |
||||
this.lockedTooltips = lockedTooltips; |
||||
this.normalTooltips = normalTooltips; |
||||
init(); |
||||
} |
||||
|
||||
private void init() { |
||||
boolean locked = EditLockUtils.isLocked(LockItem.CONNECTION); |
||||
this.setIcon(locked ? lockedIcon : normalIcon); |
||||
this.setToolTipText(locked ? lockedTooltips : normalTooltips); |
||||
} |
||||
|
||||
@Override |
||||
public void updateLockedState(EditLockChangeEvent event) { |
||||
this.setIcon(event.isLocked() ? lockedIcon : normalIcon); |
||||
this.setToolTipText(event.isLocked() ? lockedTooltips : normalTooltips); |
||||
this.repaint(); |
||||
} |
||||
} |
@ -0,0 +1,47 @@
|
||||
package com.fr.design.gui.imenu; |
||||
|
||||
import com.fr.design.editlock.EditLockChangeEvent; |
||||
import com.fr.design.editlock.EditLockChangeListener; |
||||
import com.fr.report.LockItem; |
||||
|
||||
import javax.swing.Action; |
||||
|
||||
/** |
||||
* @author Yvan |
||||
* @version 10.0 |
||||
* Created by Yvan on 2021/1/20 |
||||
*/ |
||||
public class UILockMenuItem extends UIMenuItem implements EditLockChangeListener { |
||||
|
||||
/** |
||||
* 锁定状态的提示信息 |
||||
*/ |
||||
private String lockedTooltips; |
||||
/** |
||||
* 正常状态的提示信息 |
||||
*/ |
||||
private String normalTooltips; |
||||
|
||||
/** |
||||
* 当前锁定项 |
||||
*/ |
||||
private LockItem lockItem; |
||||
|
||||
public UILockMenuItem(Action action, String lockedTooltips, String normalTooltips, LockItem lockItem) { |
||||
super(action); |
||||
this.lockedTooltips = lockedTooltips; |
||||
this.normalTooltips = normalTooltips; |
||||
this.lockItem = lockItem; |
||||
setUI(new UILockMenuItemUI()); |
||||
} |
||||
|
||||
public LockItem getLockItem() { |
||||
return lockItem; |
||||
} |
||||
|
||||
@Override |
||||
public void updateLockedState(EditLockChangeEvent event) { |
||||
this.setToolTipText(event.isLocked() ? lockedTooltips : normalTooltips); |
||||
this.repaint(); |
||||
} |
||||
} |
@ -0,0 +1,28 @@
|
||||
package com.fr.design.gui.imenu; |
||||
|
||||
import com.fr.design.editlock.EditLockUtils; |
||||
|
||||
import javax.swing.JMenuItem; |
||||
import java.awt.Graphics; |
||||
import java.awt.Rectangle; |
||||
|
||||
/** |
||||
* @author Yvan |
||||
* @version 10.0 |
||||
* Created by Yvan on 2021/1/20 |
||||
*/ |
||||
public class UILockMenuItemUI extends UIMenuItemUI{ |
||||
|
||||
@Override |
||||
protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { |
||||
super.paintText(g, menuItem, textRect, text); |
||||
// 除了绘制text之外,还需要画一下锁定图标
|
||||
UILockMenuItem lockMenuItem = (UILockMenuItem) menuItem; |
||||
if (EditLockUtils.isLocked(lockMenuItem.getLockItem())) { |
||||
int width = menuItem.getWidth(); |
||||
int height = menuItem.getHeight(); |
||||
g.drawImage(EditLockUtils.LOCKED_IMAGE, (int) Math.round(width * 0.9), (int) Math.round(height * 0.1), 16, 16, null); |
||||
} |
||||
|
||||
} |
||||
} |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 959 B |
After Width: | Height: | Size: 1.2 KiB |
Loading…
Reference in new issue