Ejemplo n.º 1
0
  /**
   * Wraps the client resource to proxy calls to the given Java interface into Restlet method calls.
   *
   * @param <T>
   * @param resourceInterface The annotated resource interface class to proxy.
   * @return The proxy instance.
   */
  @SuppressWarnings("unchecked")
  public <T> T wrap(Class<? extends T> resourceInterface) {
    T result = null;

    // Introspect the interface for Restlet annotations
    final List<org.restlet.engine.resource.AnnotationInfo> annotations =
        org.restlet.engine.resource.AnnotationUtils.getAnnotations(resourceInterface);
    final ClientResource clientResource = this;

    // Create the client resource proxy
    java.lang.reflect.InvocationHandler h =
        new java.lang.reflect.InvocationHandler() {

          @SuppressWarnings("rawtypes")
          public Object invoke(Object proxy, java.lang.reflect.Method javaMethod, Object[] args)
              throws Throwable {
            Object result = null;

            if (javaMethod.equals(Object.class.getMethod("toString"))) {
              // Help debug
              result = "ClientProxy for resource: " + clientResource;
            } else if (javaMethod.equals(ClientProxy.class.getMethod("getClientResource"))) {
              result = clientResource;
            } else {
              org.restlet.engine.resource.AnnotationInfo annotation =
                  org.restlet.engine.resource.AnnotationUtils.getAnnotation(
                      annotations, javaMethod);

              if (annotation != null) {
                Representation requestEntity = null;
                boolean isSynchronous = true;

                if ((args != null) && args.length > 0) {
                  // Checks if the user has defined its own
                  // callback.
                  for (int i = 0; i < args.length; i++) {
                    Object o = args[i];

                    if (o == null) {
                      requestEntity = null;
                    } else if (Result.class.isAssignableFrom(o.getClass())) {
                      // Asynchronous mode where a callback
                      // object is to be called.
                      isSynchronous = false;

                      // Get the kind of result expected.
                      final Result rCallback = (Result) o;
                      java.lang.reflect.Type[] genericParameterTypes =
                          javaMethod.getGenericParameterTypes();
                      java.lang.reflect.Type genericParameterType = genericParameterTypes[i];
                      java.lang.reflect.ParameterizedType parameterizedType =
                          (genericParameterType instanceof java.lang.reflect.ParameterizedType)
                              ? (java.lang.reflect.ParameterizedType) genericParameterType
                              : null;
                      final Class<?> actualType =
                          (parameterizedType.getActualTypeArguments()[0] instanceof Class<?>)
                              ? (Class<?>) parameterizedType.getActualTypeArguments()[0]
                              : null;

                      // Define the callback
                      Uniform callback =
                          new Uniform() {
                            public void handle(Request request, Response response) {
                              if (response.getStatus().isError()) {
                                rCallback.onFailure(new ResourceException(response.getStatus()));
                              } else {
                                if (actualType != null) {
                                  rCallback.onSuccess(toObject(response.getEntity(), actualType));
                                } else {
                                  rCallback.onSuccess(null);
                                }
                              }
                            }
                          };

                      setOnResponse(callback);
                    } else {
                      requestEntity = toRepresentation(args[i], null);
                    }
                  }
                }

                // Clone the prototype request
                Request request = createRequest(getRequest());

                // The Java method was annotated
                request.setMethod(annotation.getRestletMethod());

                // Set the entity
                request.setEntity(requestEntity);

                // Updates the client preferences
                List<org.restlet.representation.Variant> responseVariants =
                    annotation.getResponseVariants(getMetadataService(), getConverterService());

                if (responseVariants != null) {
                  request.setClientInfo(new ClientInfo(responseVariants));
                }

                // Effectively handle the call
                Response response = handle(request);

                // Handle the response
                if (isSynchronous) {
                  if (response.getStatus().isError()) {
                    throw new ResourceException(response.getStatus());
                  }

                  if (!annotation.getJavaOutputType().equals(void.class)) {
                    result =
                        toObject(
                            (response == null ? null : response.getEntity()),
                            annotation.getJavaOutputType());
                  }
                }
              }
            }

            return result;
          }
        };

    // Instantiate our dynamic proxy
    result =
        (T)
            java.lang.reflect.Proxy.newProxyInstance(
                org.restlet.engine.Engine.getInstance().getClassLoader(),
                new Class<?>[] {ClientProxy.class, resourceInterface},
                h);

    return result;
  }
Ejemplo n.º 2
0
 /**
  * Returns the annotation descriptors.
  *
  * @return The annotation descriptors.
  */
 private List<AnnotationInfo> getAnnotations() {
   return isAnnotated() ? AnnotationUtils.getAnnotations(getClass()) : null;
 }