Ejemplo n.º 1
0
  /**
   * Create a UML modelelement (i.e. check if a creation function exists). Then deletes it, looses
   * the reference and then checks that the object is reclaimed.
   *
   * @param factory the DataTypesFactory
   * @param names the UML elements to test
   * @param arguments the arguments of the UML elements
   */
  public static void createAndRelease(Object factory, Iterable<String> names, Object[] arguments) {
    Class[] argTypes = new Class[arguments.length];
    for (int i = 0; i < arguments.length; i++) {
      argTypes[i] = arguments[i].getClass();
    }

    // Multiplicity, MultiplicityRange, and all Expression subtypes
    // don't have 0-argument create methods, so we special case them.
    Integer[] multArgs = {1, 1};
    Class[] multArgTypes = {int.class, int.class};
    String[] exprArgs = {"body text", "language text"};
    Class[] exprArgTypes = {String.class, String.class};

    for (String name : names) {
      Class[] types;
      Object[] args;
      if (name == null) {
        continue;
      } else if (name.startsWith("Multiplicity")) {
        types = multArgTypes;
        args = multArgs;
      } else if (name.endsWith("Expression")) {
        types = exprArgTypes;
        args = exprArgs;
      } else {
        types = argTypes;
        args = arguments;
      }
      String methodName = "create" + name;
      Method createMethod;

      // Find the create method in the offical API
      createMethod = findMethod(factory.getClass(), Factory.class, methodName, types);
      if (createMethod == null) {
        TestCase.fail(
            "Method "
                + methodName
                + " does not exist in any interface of factory "
                + factory.getClass().getName());
        return;
      }

      Method isAMethod;
      String isAMethodName = "isA" + name;
      Object facade = Model.getFacade();
      try {
        // Now get the factory implementation method to be invoked
        isAMethod = Facade.class.getDeclaredMethod(isAMethodName, new Class[] {Object.class});
      } catch (NoSuchMethodException e) {
        TestCase.fail("Method " + isAMethodName + " does not exist in Facade");
        return;
      }

      Method getMethod;
      String getMethodName = "get" + name;
      if ("Class".equals(name)) {
        getMethodName = "getUMLClass";
      }
      Object metatypes = Model.getMetaTypes();
      try {
        getMethod = MetaTypes.class.getDeclaredMethod(getMethodName, new Class[] {});
      } catch (NoSuchMethodException e) {
        TestCase.fail("Method " + getMethodName + " does not exist in MetaTypes");
        return;
      }
      try {
        // Extra careful now, not to keep any references to the
        // second argument.
        try {
          Object element = invoke(createMethod, factory, args);
          TestCase.assertTrue(
              "Facade method " + isAMethodName + " returned false",
              (Boolean) invoke(isAMethod, facade, new Object[] {element}));
          TestCase.assertTrue(Model.getFacade().isA(name, element));
          Object metaElement = invoke(getMethod, metatypes, new Object[0]);
          TestCase.assertTrue(((Class) metaElement).isAssignableFrom(element.getClass()));
          deleteAndRelease(createMethod.invoke(factory, args), name);
        } catch (ClassCastException e) {
          // Here it is another object sent to the test.
          deleteAndRelease(createMethod.invoke(factory, args));
        } catch (IllegalArgumentException e) {
          // Here it is another object sent to the test.
          deleteAndRelease(createMethod.invoke(factory, args));
        }
      } catch (IllegalAccessException e) {
        TestCase.fail("Method create" + name + " in " + factory + " cannot be called");
        return;
      } catch (InvocationTargetException e) {
        TestCase.fail("Method create" + name + " in " + factory + " throws an exception.");
        return;
      }
    }
  }