All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.assertj.swing.lock.ScreenLock Maven / Gradle / Ivy

There is a newer version: 3.17.1
Show newest version
/**
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 * Copyright 2012-2015 the original author or authors.
 */
package org.assertj.swing.lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;

import org.assertj.swing.exception.ScreenLockException;

/**
 * A lock that each GUI test should acquire before being executed, to guarantee sequential execution of GUI tests and to
 * prevent GUI tests from blocking each other.
 * 
 * @author Yvonne Wang
 * @author Alex Ruiz
 */
@ThreadSafe
public final class ScreenLock {
  private final Lock lock = new ReentrantLock();
  private final Condition released = lock.newCondition();

  @GuardedBy("lock")
  private Object owner;

  @GuardedBy("lock")
  private boolean acquired;

  /**
   * Acquires this lock. If this lock was already acquired by another object, this method will block until the lock is
   * released.
   * 
   * @param newOwner the new owner of the lock.
   */
  public void acquire(@Nonnull Object newOwner) {
    lock.lock();
    try {
      if (alreadyAcquiredBy(newOwner)) {
        return;
      }
      while (acquired) {
        released.await();
      }
      owner = newOwner;
      acquired = true;
    } catch (InterruptedException ignored) {
      Thread.currentThread().interrupt();
    } finally {
      lock.unlock();
    }
  }

  /**
   * Releases this lock.
   * 
   * @param currentOwner the current owner of the lock.
   * @throws ScreenLockException if the lock has not been previously acquired.
   * @throws ScreenLockException if the given owner is not the same as the current owner of the lock.
   */
  public void release(@Nonnull Object currentOwner) {
    lock.lock();
    try {
      if (!acquired) {
        throw new ScreenLockException("No lock to release");
      }
      if (owner != currentOwner) {
        throw new ScreenLockException(String.format("%s is not the lock owner", currentOwner.toString()));
      }
      acquired = false;
      owner = null;
      released.signal();
    } finally {
      lock.unlock();
    }
  }

  /**
   * Indicates whether this lock was acquired by the given object.
   * 
   * @param possibleOwner the given object, which could be owning the lock.
   * @return {@code true} if the given object is owning the lock; {@code false} otherwise.
   */
  public boolean acquiredBy(@Nonnull Object possibleOwner) {
    lock.lock();
    try {
      return alreadyAcquiredBy(possibleOwner);
    } finally {
      lock.unlock();
    }
  }

  private boolean alreadyAcquiredBy(@Nonnull Object possibleOwner) {
    return acquired && owner == possibleOwner;
  }

  /**
   * Indicates whether this lock is already acquired.
   * 
   * @return {@code true} if the lock is already acquired; {@code false} otherwise.
   * @see #acquiredBy(Object)
   */
  public boolean acquired() {
    lock.lock();
    try {
      return acquired;
    } finally {
      lock.unlock();
    }
  }

  /**
   * @return the object currently owning the lock. Or null if no object is owning the lock. If
   *         {@link #acquired()} is true calling {@link #acquiredBy(Object)} with {@link #getOwner()}
   *         returns true.
   */
  public @Nullable Object getOwner() {
    lock.lock();
    try {
      return owner;
    } finally {
      lock.unlock();
    }
  }

  /**
   * @return the singleton instance of this class.
   */
  public static @Nonnull ScreenLock instance() {
    return ScreenLockHolder.instance;
  }

  private static class ScreenLockHolder {
    static ScreenLock instance = new ScreenLock();
  }

  ScreenLock() {
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy