private void handleLockFailure(final LockInfo lockInfo) { if (lockInfo != null) { updateLockInfo(lockInfo); lockNotification.fire( new NotificationEvent( WorkbenchConstants.INSTANCE.lockedMessage(lockInfo.lockedBy()), NotificationEvent.NotificationType.INFO, true, lockTarget.getPlace(), 20)); } else { lockNotification.fire( new NotificationEvent( WorkbenchConstants.INSTANCE.lockError(), NotificationEvent.NotificationType.ERROR, true, lockTarget.getPlace(), 20)); } // Delay reloading slightly in case we're dealing with a flood of events if (reloadTimer == null) { reloadTimer = new Timer() { public void run() { reload(); } }; } if (!reloadTimer.isRunning()) { reloadTimer.schedule(250); } }
private void updateLockInfo(@Observes LockInfo lockInfo) { if (lockTarget != null && lockInfo.getFile().equals(lockTarget.getPath())) { this.lockInfo = lockInfo; this.lockSyncComplete = true; fireChangeTitleEvent(); fireUpdatedLockStatusEvent(); for (Runnable runnable : syncCompleteRunnables) { runnable.run(); } syncCompleteRunnables.clear(); } }
private void acquireLock() { if (lockInfo.isLocked()) { handleLockFailure(lockInfo); } else if (!lockRequestPending) { lockRequestPending = true; final ParameterizedCommand<LockResult> command = new ParameterizedCommand<LockResult>() { @Override public void execute(final LockResult result) { if (result.isSuccess()) { updateLockInfo(result.getLockInfo()); releaseLockOnClose(); } else { handleLockFailure(result.getLockInfo()); } lockRequestPending = false; } }; lockService.acquireLock(lockTarget.getPath(), command); } }
/** * Default implementation of {@link LockManager} using the {@link VFSLockServiceProxy} for lock * management. */ @Dependent public class LockManagerImpl implements LockManager { @Inject private VFSLockServiceProxy lockService; @Inject private javax.enterprise.event.Event<ChangeTitleWidgetEvent> changeTitleEvent; @Inject private javax.enterprise.event.Event<UpdatedLockStatusEvent> updatedLockStatusEvent; @Inject private javax.enterprise.event.Event<NotificationEvent> lockNotification; @Inject private LockDemandDetector lockDemandDetector; @Inject private User user; private LockTarget lockTarget; private LockInfo lockInfo = LockInfo.unlocked(); private HandlerRegistration closeHandler; private boolean lockRequestPending; private boolean unlockRequestPending; private boolean lockSyncComplete; private List<Runnable> syncCompleteRunnables = new ArrayList<Runnable>(); private Timer reloadTimer; @Override public void init(final LockTarget lockTarget) { this.lockTarget = lockTarget; final ParameterizedCommand<LockInfo> command = new ParameterizedCommand<LockInfo>() { @Override public void execute(final LockInfo lockInfo) { if (!lockRequestPending && !unlockRequestPending) { updateLockInfo(lockInfo); } } }; lockService.retrieveLockInfo(lockTarget.getPath(), command); } @Override public void onFocus() { publishJsApi(); fireChangeTitleEvent(); fireUpdatedLockStatusEvent(); } @Override public void acquireLockOnDemand() { if (lockTarget == null) return; final Element element = lockTarget.getWidget().getElement(); acquireLockOnDemand(element); lockTarget .getWidget() .addAttachHandler( new AttachEvent.Handler() { @Override public void onAttachOrDetach(AttachEvent event) { // Handle widget reattachment/reparenting if (event.isAttached()) { acquireLockOnDemand(element); } } }); } public EventListener acquireLockOnDemand(final Element element) { Event.sinkEvents(element, lockDemandDetector.getLockDemandEventTypes()); EventListener lockDemandListener = new EventListener() { @Override public void onBrowserEvent(Event event) { if (isLockedByCurrentUser()) { return; } if (lockDemandDetector.isLockRequired(event)) { acquireLock(); } } }; Event.setEventListener(element, lockDemandListener); return lockDemandListener; } private void acquireLock() { if (lockInfo.isLocked()) { handleLockFailure(lockInfo); } else if (!lockRequestPending) { lockRequestPending = true; final ParameterizedCommand<LockResult> command = new ParameterizedCommand<LockResult>() { @Override public void execute(final LockResult result) { if (result.isSuccess()) { updateLockInfo(result.getLockInfo()); releaseLockOnClose(); } else { handleLockFailure(result.getLockInfo()); } lockRequestPending = false; } }; lockService.acquireLock(lockTarget.getPath(), command); } } @Override public void releaseLock() { final Runnable releaseLock = new Runnable() { @Override public void run() { releaseLockInternal(); } }; if (lockSyncComplete) { releaseLock.run(); } else { syncCompleteRunnables.add(releaseLock); } } private void releaseLockInternal() { if (isLockedByCurrentUser() && !unlockRequestPending) { unlockRequestPending = true; ParameterizedCommand<LockResult> command = new ParameterizedCommand<LockResult>() { @Override public void execute(final LockResult result) { updateLockInfo(result.getLockInfo()); if (result.isSuccess()) { if (closeHandler != null) { closeHandler.removeHandler(); } } unlockRequestPending = false; } }; lockService.releaseLock(lockTarget.getPath(), command); } } private void releaseLockOnClose() { closeHandler = Window.addWindowClosingHandler( new ClosingHandler() { @Override public void onWindowClosing(ClosingEvent event) { releaseLock(); } }); } private void handleLockFailure(final LockInfo lockInfo) { if (lockInfo != null) { updateLockInfo(lockInfo); lockNotification.fire( new NotificationEvent( WorkbenchConstants.INSTANCE.lockedMessage(lockInfo.lockedBy()), NotificationEvent.NotificationType.INFO, true, lockTarget.getPlace(), 20)); } else { lockNotification.fire( new NotificationEvent( WorkbenchConstants.INSTANCE.lockError(), NotificationEvent.NotificationType.ERROR, true, lockTarget.getPlace(), 20)); } // Delay reloading slightly in case we're dealing with a flood of events if (reloadTimer == null) { reloadTimer = new Timer() { public void run() { reload(); } }; } if (!reloadTimer.isRunning()) { reloadTimer.schedule(250); } } private void reload() { lockTarget.getReloadRunnable().run(); } private boolean isLockedByCurrentUser() { return lockInfo.isLocked() && lockInfo.lockedBy().equals(user.getIdentifier()); } private void updateLockInfo(@Observes LockInfo lockInfo) { if (lockTarget != null && lockInfo.getFile().equals(lockTarget.getPath())) { this.lockInfo = lockInfo; this.lockSyncComplete = true; fireChangeTitleEvent(); fireUpdatedLockStatusEvent(); for (Runnable runnable : syncCompleteRunnables) { runnable.run(); } syncCompleteRunnables.clear(); } } void onResourceAdded(@Observes ResourceAddedEvent res) { if (lockTarget != null && res.getPath().equals(lockTarget.getPath())) { releaseLock(); } } void onResourceUpdated(@Observes ResourceUpdatedEvent res) { if (lockTarget != null && res.getPath().equals(lockTarget.getPath())) { if (!res.getSessionInfo().getIdentity().equals(user)) { reload(); } releaseLock(); } } void onSaveInProgress(@Observes SaveInProgressEvent evt) { if (lockTarget != null && evt.getPath().equals(lockTarget.getPath())) { releaseLock(); } } void onLockRequired(@Observes LockRequiredEvent event) { if (lockTarget != null && isVisible() && !isLockedByCurrentUser()) { acquireLock(); } } private native void publishJsApi() /*-{ var lockManager = this; $wnd.isLocked = function () { return [email protected]::isLocked()(); } $wnd.isLockedByCurrentUser = function () { return [email protected]::isLockedByCurrentUser()(); } $wnd.acquireLock = function () { [email protected]::acquireLock()(); } $wnd.releaseLock = function () { [email protected]::releaseLock()(); } $wnd.reload = function () { return [email protected]::reload()(); } }-*/; private boolean isLocked() { return lockInfo.isLocked(); } private void fireChangeTitleEvent() { changeTitleEvent.fire(LockTitleWidgetEvent.create(lockTarget, lockInfo, user)); } private void fireUpdatedLockStatusEvent() { if (isVisible()) { updatedLockStatusEvent.fire( new UpdatedLockStatusEvent(lockInfo.isLocked(), isLockedByCurrentUser())); } } private boolean isVisible() { Element element = lockTarget.getWidget().getElement(); boolean visible = UIObject.isVisible(element) && (element.getAbsoluteLeft() != 0) && (element.getAbsoluteTop() != 0); return visible; } }
private void fireUpdatedLockStatusEvent() { if (isVisible()) { updatedLockStatusEvent.fire( new UpdatedLockStatusEvent(lockInfo.isLocked(), isLockedByCurrentUser())); } }
private boolean isLocked() { return lockInfo.isLocked(); }
private boolean isLockedByCurrentUser() { return lockInfo.isLocked() && lockInfo.lockedBy().equals(user.getIdentifier()); }