|
|
|
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 com.fr.event.Event;
|
|
|
|
import com.fr.event.EventDispatcher;
|
|
|
|
import com.fr.event.Listener;
|
|
|
|
import com.fr.workspace.Workspace;
|
|
|
|
import com.fr.workspace.WorkspaceEvent;
|
|
|
|
|
|
|
|
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<>();
|
|
|
|
private boolean running = false;
|
|
|
|
|
|
|
|
// 监听连接断开事件
|
|
|
|
private Listener<Workspace> disconnectListener = new Listener<Workspace>() {
|
|
|
|
@Override
|
|
|
|
public void on(Event event, Workspace workspace) {
|
|
|
|
if (scheduler != null && !scheduler.isShutdown()) {
|
|
|
|
scheduler.shutdown();
|
|
|
|
scheduler = null;
|
|
|
|
FineLoggerFactory.getLogger().info("Connection lost, edit lock checker stopped");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// 监听连接恢复事件
|
|
|
|
private Listener<Workspace> connectListener = new Listener<Workspace>() {
|
|
|
|
@Override
|
|
|
|
public void on(Event event, Workspace workspace) {
|
|
|
|
if (running && scheduler == null) {
|
|
|
|
FineLoggerFactory.getLogger().info("Connection restored, restarting edit lock checker");
|
|
|
|
startScheduler();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 轮询任务,如果是远程设计状态,每隔30s查询一次相应lockItem的锁状态是否改变
|
|
|
|
*/
|
|
|
|
public void start() {
|
|
|
|
running = true;
|
|
|
|
startListeners();
|
|
|
|
startScheduler();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 启动事件监听器
|
|
|
|
*/
|
|
|
|
private void startListeners() {
|
|
|
|
if (!WorkContext.getCurrent().isLocal()) {
|
|
|
|
// 确保不会重复注册
|
|
|
|
EventDispatcher.stopListen(disconnectListener);
|
|
|
|
EventDispatcher.stopListen(connectListener);
|
|
|
|
|
|
|
|
EventDispatcher.listen(WorkspaceEvent.LostConnect, disconnectListener);
|
|
|
|
EventDispatcher.listen(WorkspaceEvent.ConnectSuccess, connectListener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 启动调度器
|
|
|
|
*/
|
|
|
|
private void startScheduler() {
|
|
|
|
// 已经有调度器运行中,不需要重新创建
|
|
|
|
if (scheduler != null && !scheduler.isShutdown()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("EditLockChangeChecker"));
|
|
|
|
this.scheduler.scheduleWithFixedDelay(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) {
|
|
|
|
setLocked(locked);
|
|
|
|
fireChange();
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
FineLoggerFactory.getLogger().error("Edit lock check error: " + e.getMessage(), e);
|
|
|
|
}
|
|
|
|
} else if (isLocked()){
|
|
|
|
// 如果不是远程环境,且此前的远程状态下为锁定的话,切换回来后需要将其修改为不锁定
|
|
|
|
setLocked(false);
|
|
|
|
fireChange();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 0, INTERVAL, TimeUnit.MILLISECONDS);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void stop() {
|
|
|
|
running = false;
|
|
|
|
// 移除事件监听
|
|
|
|
EventDispatcher.stopListen(disconnectListener);
|
|
|
|
EventDispatcher.stopListen(connectListener);
|
|
|
|
|
|
|
|
// 关闭调度器
|
|
|
|
if (this.scheduler != null && !this.scheduler.isShutdown()) {
|
|
|
|
this.scheduler.shutdown();
|
|
|
|
this.scheduler = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isLocked() {
|
|
|
|
return this.isLocked;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setLocked(boolean locked) {
|
|
|
|
this.isLocked = locked;
|
|
|
|
}
|
|
|
|
}
|