예제 #1
0
  /**
   * Returns the first annotation descriptor matching the given method.
   *
   * @param method The method to match.
   * @param entity The request entity or null.
   * @return The annotation descriptor.
   */
  private AnnotationInfo getAnnotation(Method method, Representation entity) {
    if (isAnnotated()) {
      return AnnotationUtils.getAnnotation(
          getAnnotations(), method, entity, getMetadataService(), getConverterService());
    }

    return null;
  }
  private static void completeOperationThrows(
      CollectInfo collectInfo,
      Operation operation,
      MethodAnnotationInfo mai,
      List<? extends IntrospectionHelper> introspectionHelper) {
    Class<?>[] thrownClasses = mai.getJavaMethod().getExceptionTypes();
    if (thrownClasses != null) {
      for (Class<?> thrownClass : thrownClasses) {
        ThrowableAnnotationInfo throwableAnnotationInfo =
            AnnotationUtils.getInstance().getThrowableAnnotationInfo(thrownClass);
        if (throwableAnnotationInfo != null) {
          int statusCode = throwableAnnotationInfo.getStatus().getCode();
          Response response = new Response();
          response.setCode(statusCode);
          response.setName(Status.valueOf(statusCode).getReasonPhrase());
          response.setMessage("Status " + statusCode);

          Class<?> outputPayloadType =
              throwableAnnotationInfo.isSerializable() ? thrownClass : StatusInfo.class;
          TypeInfo outputTypeInfo = null;
          try {
            outputTypeInfo = Types.getTypeInfo(outputPayloadType, null);
          } catch (UnsupportedTypeException e) {
            LOGGER.warning(
                "Could not add output payload for exception "
                    + thrownClass
                    + " throws by method "
                    + mai.getJavaMethod()
                    + ". "
                    + e.getMessage());
            continue;
          }

          RepresentationCollector.addRepresentation(
              collectInfo, outputTypeInfo, introspectionHelper);

          PayLoad outputPayLoad = new PayLoad();
          outputPayLoad.setType(outputTypeInfo.getRepresentationName());
          response.setOutputPayLoad(outputPayLoad);
          operation.getResponses().add(response);
        }
      }
    }
  }
예제 #3
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;
  }
예제 #4
0
 /**
  * Returns the annotation descriptors.
  *
  * @return The annotation descriptors.
  */
 private List<AnnotationInfo> getAnnotations() {
   return isAnnotated() ? AnnotationUtils.getAnnotations(getClass()) : null;
 }
  public static void collectResource(
      CollectInfo collectInfo,
      ServerResource sr,
      String basePath,
      ChallengeScheme scheme,
      List<? extends IntrospectionHelper> introspectionHelper) {
    Resource resource = getResource(collectInfo, sr, basePath, scheme);

    // add operations
    ArrayList<Operation> operations = new ArrayList<>();

    List<AnnotationInfo> annotations =
        sr.isAnnotated() ? AnnotationUtils.getInstance().getAnnotations(sr.getClass()) : null;

    if (annotations != null) {
      for (AnnotationInfo annotationInfo : annotations) {
        if (annotationInfo instanceof MethodAnnotationInfo) {
          MethodAnnotationInfo methodAnnotationInfo = (MethodAnnotationInfo) annotationInfo;

          Method method = methodAnnotationInfo.getRestletMethod();

          Operation operation = getOperationFromMethod(method);

          if (StringUtils.isNullOrEmpty(operation.getName())) {
            operation.setName(methodAnnotationInfo.getJavaMethod().getName());
          }

          completeOperation(collectInfo, operation, methodAnnotationInfo, sr, introspectionHelper);

          for (IntrospectionHelper helper : introspectionHelper) {
            List<Class<?>> representationClasses =
                helper.processOperation(
                    resource, operation, sr.getClass(), methodAnnotationInfo.getJavaMethod());
            if (representationClasses != null && !representationClasses.isEmpty()) {
              for (Class<?> representationClazz : representationClasses) {
                TypeInfo typeInfo;
                try {
                  typeInfo = Types.getTypeInfo(representationClazz, null);
                } catch (UnsupportedTypeException e) {
                  LOGGER.warning(
                      "Could not add representation class "
                          + representationClazz.getName()
                          + ". "
                          + e.getMessage());
                  continue;
                }
                RepresentationCollector.addRepresentation(
                    collectInfo, typeInfo, introspectionHelper);
              }
            }
          }
          operations.add(operation);
        }
      }
      if (!operations.isEmpty()) {
        sortOperationsByMethod(operations);
        resource.setOperations(operations);
        addSectionsForResource(collectInfo, resource);
        collectInfo.addResource(resource);
      } else {
        LOGGER.warning("Resource " + resource.getName() + " has no methods.");
      }
    } else {
      LOGGER.warning("Resource " + resource.getName() + " has no methods.");
    }

    for (IntrospectionHelper helper : introspectionHelper) {
      helper.processResource(resource, sr.getClass());
    }
  }