package ajtest;

//Emulate database tests
public class Main {
  //Type of the database tested
  static final String TESTED_DATABASE =
      System.getProperty("tested-database", "other");

  public static void main(String[] args) {
    System.out.println("Database to test: " + TESTED_DATABASE);

    TestSuite testCases = new TestSuite();
    //Test the database with three tests at most
    testCases.test1();
    testCases.test2();
    testCases.test3();

    System.out.println("test cases - success");
  }
}

//There are three tests to perform at most
//For certain databases some of them must be disabled
class TestSuite {
  void test1() {
    System.out.println("test1 - success");
  }
  void test2() {
    System.out.println("test2 - success");
  }
  void test3() {
    System.out.println("test3 - success");
  }
}

//TestSwitch defines what to do for the disabled tests
abstract aspect TestSwitch {
  //the subaspects define which test methods must be disabled in this pointcut
  abstract pointcut unsupportedTests();

  //around() works in the exclusive mode
  //if a test-case is unsupported by some of the databases
  //check whether it is not supported by the current database - 'useSwitch()'
  //if so go around, otherwise the test is supported and we can 'proceed()'
  //with it
  void around() : unsupportedTests() {
    if (useSwitch()) {
      System.out.println("Test Case is disabled: " +
                         thisJoinPointStaticPart.getSignature());
    } else {
      proceed();
    }
  }

  boolean useSwitch() {
    return Main.TESTED_DATABASE.equals(getServicedDatabaseName());
  }

  abstract String getServicedDatabaseName();
}

//Each subaspect corresponds to a certain database type and defines
//the tests unsupported by it.

aspect OtherSwitch extends TestSwitch {
  pointcut unsupportedTests() :
      call(void TestSuite.test2()) ||
      call(void TestSuite.test3());

  String getServicedDatabaseName() {
    return "other";
  }
}

aspect OracleSwitch extends TestSwitch {
  pointcut unsupportedTests();

  String getServicedDatabaseName() {
    return "oracle";
  }
}

aspect FirebirdSwitch extends TestSwitch {
  pointcut unsupportedTests() :
      call(void TestSuite.test1());

  String getServicedDatabaseName() {
    return "firebird";
  }
}
