Ejemplo n.º 1
0
  /**
   * {@link InvocationHandler} implementation that allows strongly-typed access to the
   * configuration.
   *
   * <p>TODO: it might be a great performance improvement to have APT generate code that does this
   * during the development time by looking at the interface.
   */
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // serve java.lang.Object methods by ourselves
    Class<?> clazz = method.getDeclaringClass();
    if (clazz == Object.class) {
      try {
        return method.invoke(this, args);
      } catch (InvocationTargetException e) {
        throw e.getTargetException();
      }
    }

    if (method.getAnnotation(DuckTyped.class) != null) {
      return invokeDuckMethod(method, proxy, args);
    }
    if (method.getAnnotation(ConfigExtensionMethod.class) != null) {
      ConfigExtensionMethod cem = method.getAnnotation(ConfigExtensionMethod.class);
      ConfigExtensionHandler handler =
          (ConfigExtensionHandler)
              ((cem.value() != null)
                  ? getServiceLocator().getService(ConfigExtensionHandler.class, cem.value())
                  : getServiceLocator().getService(ConfigExtensionHandler.class));
      return invokeConfigExtensionMethod(handler, this, model.getProxyType(), args);
    }

    ConfigModel.Property p = model.toProperty(method);
    if (p == null)
      throw new IllegalArgumentException("No corresponding property found for method: " + method);

    if (args == null || args.length == 0) {
      // getter
      return getter(p, method.getGenericReturnType());
    } else {
      throw new PropertyVetoException(
          "Instance of "
              + getImplementation()
              + " named '"
              + getKey()
              + "' is not locked for writing when invoking method "
              + method.getName()
              + " you must use transaction semantics to access it.",
          null);
    }
  }