public static void generateNativeMethodStubs(
     AnnotationProcessorEnvironment env,
     TypeMap type_map,
     PrintWriter writer,
     InterfaceDeclaration d,
     boolean generate_error_checks,
     boolean context_specific) {
   for (MethodDeclaration method : d.getMethods()) {
     Alternate alt_annotation = method.getAnnotation(Alternate.class);
     if (alt_annotation != null && !alt_annotation.nativeAlt()) continue;
     generateMethodStub(
         env,
         type_map,
         writer,
         Utils.getQualifiedClassName(d),
         method,
         Mode.NORMAL,
         generate_error_checks,
         context_specific);
     if (Utils.hasMethodBufferObjectParameter(method))
       generateMethodStub(
           env,
           type_map,
           writer,
           Utils.getQualifiedClassName(d),
           method,
           Mode.BUFFEROBJECT,
           generate_error_checks,
           context_specific);
   }
 }
  private static void generateMethodStub(
      AnnotationProcessorEnvironment env,
      TypeMap type_map,
      PrintWriter writer,
      String interface_name,
      MethodDeclaration method,
      Mode mode,
      boolean generate_error_checks,
      boolean context_specific) {
    if (!context_specific && method.getAnnotation(Alternate.class) == null) writer.print("static ");
    else writer.print("JNIEXPORT ");

    TypeMirror result_type = Utils.getMethodReturnType(method);

    if (method.getAnnotation(GLpointer.class) != null) {
      writer.print("jlong");
    } else {
      JNITypeTranslator translator = new JNITypeTranslator();
      result_type.accept(translator);
      writer.print(translator.getSignature());
    }
    writer.print(" JNICALL ");

    writer.print(
        Utils.getQualifiedNativeMethodName(
            interface_name, method, generate_error_checks, context_specific));
    if (mode == Mode.BUFFEROBJECT) writer.print(Utils.BUFFER_OBJECT_METHOD_POSTFIX);
    writer.print("(JNIEnv *env, jclass clazz");
    generateParameters(writer, method.getParameters(), mode);
    if (Utils.getNIOBufferType(result_type) != null) {
      CachedResult cached_result_annotation = method.getAnnotation(CachedResult.class);
      if (cached_result_annotation == null || !cached_result_annotation.isRange())
        writer.print(", jlong " + Utils.RESULT_SIZE_NAME);
      if (cached_result_annotation != null) writer.print(", jobject " + Utils.CACHED_BUFFER_NAME);
    }
    if (context_specific) {
      writer.print(", jlong " + Utils.FUNCTION_POINTER_VAR_NAME);
    }
    writer.println(") {");
    generateBufferParameterAddresses(type_map, writer, method, mode);
    Alternate alt_annotation = method.getAnnotation(Alternate.class);
    if (context_specific) {
      String typedef_name = Utils.getTypedefName(method);
      writer.print(
          "\t"
              + typedef_name
              + " "
              + (alt_annotation == null ? method.getSimpleName() : alt_annotation.value()));
      writer.print(" = (" + typedef_name + ")((intptr_t)");
      writer.println(Utils.FUNCTION_POINTER_VAR_NAME + ");");
    }
    generateStringListInits(writer, method.getParameters());
    writer.print("\t");
    if (!result_type.equals(env.getTypeUtils().getVoidType())) {
      Declaration return_declaration;
      ParameterDeclaration result_param = Utils.getResultParameter(method);
      if (result_param != null) return_declaration = result_param;
      else return_declaration = method;
      NativeTypeTranslator native_translator =
          new NativeTypeTranslator(type_map, return_declaration);
      result_type.accept(native_translator);
      writer.print(native_translator.getSignature() + " " + Utils.RESULT_VAR_NAME);
      if (result_param != null) {
        writer.println(";");
        writer.print("\t");
      } else writer.print(" = ");
    }
    writer.print((alt_annotation == null ? method.getSimpleName() : alt_annotation.value()) + "(");
    generateCallParameters(writer, type_map, method.getParameters());
    writer.print(")");
    writer.println(";");
    generateStringDeallocations(writer, method.getParameters());
    if (!result_type.equals(env.getTypeUtils().getVoidType())) {
      writer.print("\treturn ");
      Class java_result_type = Utils.getJavaType(result_type);
      if (Buffer.class.isAssignableFrom(java_result_type)) {
        if (method.getAnnotation(CachedResult.class) != null)
          writer.print("safeNewBufferCached(env, ");
        else writer.print("safeNewBuffer(env, ");
      } else if (String.class.equals(java_result_type)) {
        writer.print("NewStringNativeUnsigned(env, ");
      } else if (method.getAnnotation(GLpointer.class) != null) {
        writer.print("(intptr_t)");
      }
      writer.print(Utils.RESULT_VAR_NAME);
      if (Buffer.class.isAssignableFrom(java_result_type)) {
        writer.print(", ");
        if (method.getAnnotation(CachedResult.class) != null
            && method.getAnnotation(CachedResult.class).isRange())
          Utils.printExtraCallArguments(
              writer, method, method.getAnnotation(AutoResultSize.class).value());
        else Utils.printExtraCallArguments(writer, method, Utils.RESULT_SIZE_NAME);
      }
      if (Buffer.class.isAssignableFrom(java_result_type) || String.class.equals(java_result_type))
        writer.print(")");
      writer.println(";");
    }
    writer.println("}");
    writer.println();
  }
  private static boolean generateBufferParameterAddress(
      TypeMap type_map,
      PrintWriter writer,
      MethodDeclaration method,
      ParameterDeclaration param,
      Mode mode,
      boolean loopDeclared) {
    NativeTypeTranslator translator = new NativeTypeTranslator(type_map, param);
    param.getType().accept(translator);
    writer.print("\t" + translator.getSignature() + param.getSimpleName());
    writer.print(BUFFER_ADDRESS_POSTFIX + " = ((");
    writer.print(translator.getSignature());
    Check check_annotation = param.getAnnotation(Check.class);
    writer.print(")");
    if (mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null) {
      writer.print(
          "offsetToPointer("
              + param.getSimpleName()
              + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX
              + "))");
    } else {
      Class java_type = Utils.getJavaType(param.getType());
      if (Buffer.class.isAssignableFrom(java_type)
          || java_type.equals(CharSequence.class)
          || java_type.equals(CharSequence[].class)) {
        boolean explicitly_byte_sized =
            java_type.equals(Buffer.class)
                || translator.getAnnotationType().equals(type_map.getVoidType());
        if (explicitly_byte_sized) writer.print("(((char *)");
        if (method.getAnnotation(GenerateAutos.class) != null
            || (check_annotation != null && check_annotation.canBeNull())) {
          writer.print("safeGetBufferAddress(env, " + param.getSimpleName());
        } else {
          writer.print("(*env)->GetDirectBufferAddress(env, " + param.getSimpleName());
        }
        writer.print("))");
        writer.print(" + " + param.getSimpleName() + BUFFER_POSITION_POSTFIX);
        if (explicitly_byte_sized) writer.print("))");
      } else if (java_type.equals(String.class)) {
        writer.print("GetStringNativeChars(env, " + param.getSimpleName() + "))");
      } else throw new RuntimeException("Illegal type " + java_type);
    }
    writer.println(";");

    if (param.getAnnotation(StringList.class) != null) {
      if (Utils.getJavaType(param.getType()) != CharSequence[].class
          && (param.getAnnotation(GLchar.class) == null
              || param.getAnnotation(NullTerminated.class) == null
              || param.getAnnotation(NullTerminated.class).value().length() == 0))
        throw new RuntimeException(
            "StringList annotation can only be applied on null-terminated GLchar buffers.");

      if ("_str".equals(param.getSimpleName()))
        throw new RuntimeException(
            "The name '_str' is not valid for arguments annotated with StringList");

      // Declare loop counters and allocate string array
      if (!loopDeclared) {
        writer.println("\tunsigned int _str_i;");
        writer.println("\tGLchar *_str_address;");
        loopDeclared = true;
      }
      writer.println(
          "\tGLchar **"
              + param.getSimpleName()
              + STRING_LIST_POSTFIX
              + " = (GLchar **) malloc("
              + param.getAnnotation(StringList.class).value()
              + "*sizeof(GLchar*));");
    }
    return loopDeclared;
  }
Ejemplo n.º 4
0
  public ResourceMethod(MethodDeclaration delegate, Resource parent) {
    super(delegate);

    Set<String> httpMethods = new TreeSet<String>();
    Collection<AnnotationMirror> mirrors = delegate.getAnnotationMirrors();
    for (AnnotationMirror mirror : mirrors) {
      AnnotationTypeDeclaration annotationDeclaration = mirror.getAnnotationType().getDeclaration();
      HttpMethod httpMethodInfo = annotationDeclaration.getAnnotation(HttpMethod.class);
      if (httpMethodInfo != null) {
        // request method designator found.
        httpMethods.add(httpMethodInfo.value());
      }
    }

    if (httpMethods.isEmpty()) {
      throw new IllegalStateException(
          "A resource method must specify an HTTP method by using a request method designator annotation.");
    }

    this.httpMethods = httpMethods;

    Set<String> consumes;
    Consumes consumesInfo = delegate.getAnnotation(Consumes.class);
    if (consumesInfo != null) {
      consumes = new TreeSet<String>(Arrays.asList(JAXRSUtils.value(consumesInfo)));
    } else {
      consumes = new TreeSet<String>(parent.getConsumesMime());
    }
    this.consumesMime = consumes;

    Set<String> produces;
    Produces producesInfo = delegate.getAnnotation(Produces.class);
    if (producesInfo != null) {
      produces = new TreeSet<String>(Arrays.asList(JAXRSUtils.value(producesInfo)));
    } else {
      produces = new TreeSet<String>(parent.getProducesMime());
    }
    this.producesMime = produces;

    String subpath = null;
    Path pathInfo = delegate.getAnnotation(Path.class);
    if (pathInfo != null) {
      subpath = pathInfo.value();
    }

    ResourceEntityParameter entityParameter;
    List<ResourceEntityParameter> declaredEntityParameters =
        new ArrayList<ResourceEntityParameter>();
    List<ResourceParameter> resourceParameters;
    ResourceRepresentationMetadata outputPayload;
    ResourceMethodSignature signatureOverride =
        delegate.getAnnotation(ResourceMethodSignature.class);
    if (signatureOverride == null) {
      entityParameter = null;
      resourceParameters = new ArrayList<ResourceParameter>();
      // if we're not overriding the signature, assume we use the real method signature.
      for (ParameterDeclaration parameterDeclaration : getParameters()) {
        if (ResourceParameter.isResourceParameter(parameterDeclaration)) {
          resourceParameters.add(new ResourceParameter(parameterDeclaration));
        } else if (ResourceParameter.isFormBeanParameter(parameterDeclaration)) {
          resourceParameters.addAll(ResourceParameter.getFormBeanParameters(parameterDeclaration));
        } else if (parameterDeclaration.getAnnotation(Context.class) == null) {
          entityParameter = new ResourceEntityParameter(this, parameterDeclaration);
          declaredEntityParameters.add(entityParameter);
        }
      }

      DecoratedTypeMirror returnTypeMirror;
      TypeHint hintInfo = getAnnotation(TypeHint.class);
      if (hintInfo != null) {
        try {
          Class hint = hintInfo.value();
          AnnotationProcessorEnvironment env = net.sf.jelly.apt.Context.getCurrentEnvironment();
          if (TypeHint.NO_CONTENT.class.equals(hint)) {
            returnTypeMirror =
                (DecoratedTypeMirror)
                    TypeMirrorDecorator.decorate(env.getTypeUtils().getVoidType());
          } else {
            String hintName = hint.getName();

            if (TypeHint.NONE.class.equals(hint)) {
              hintName = hintInfo.qualifiedName();
            }

            if (!"##NONE".equals(hintName)) {
              TypeDeclaration type = env.getTypeDeclaration(hintName);
              returnTypeMirror =
                  (DecoratedTypeMirror)
                      TypeMirrorDecorator.decorate(env.getTypeUtils().getDeclaredType(type));
            } else {
              returnTypeMirror = (DecoratedTypeMirror) getReturnType();
            }
          }
        } catch (MirroredTypeException e) {
          returnTypeMirror = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(e.getTypeMirror());
        }
        returnTypeMirror.setDocComment(((DecoratedTypeMirror) getReturnType()).getDocComment());
      } else {
        returnTypeMirror = (DecoratedTypeMirror) getReturnType();

        if (getJavaDoc().get("returnWrapped")
            != null) { // support jax-doclets. see http://jira.codehaus.org/browse/ENUNCIATE-690
          String fqn = getJavaDoc().get("returnWrapped").get(0);
          AnnotationProcessorEnvironment env = net.sf.jelly.apt.Context.getCurrentEnvironment();
          TypeDeclaration type = env.getTypeDeclaration(fqn);
          if (type != null) {
            returnTypeMirror =
                (DecoratedTypeMirror)
                    TypeMirrorDecorator.decorate(env.getTypeUtils().getDeclaredType(type));
          }
        }

        // in the case where the return type is com.sun.jersey.api.JResponse,
        // we can use the type argument to get the entity type
        if (returnTypeMirror.isClass()
            && returnTypeMirror.isInstanceOf("com.sun.jersey.api.JResponse")) {
          DecoratedClassType jresponse = (DecoratedClassType) returnTypeMirror;
          if (!jresponse.getActualTypeArguments().isEmpty()) {
            DecoratedTypeMirror responseType =
                (DecoratedTypeMirror)
                    TypeMirrorDecorator.decorate(
                        jresponse.getActualTypeArguments().iterator().next());
            if (responseType.isDeclared()) {
              responseType.setDocComment(returnTypeMirror.getDocComment());
              returnTypeMirror = responseType;
            }
          }
        }
      }

      outputPayload =
          returnTypeMirror.isVoid() ? null : new ResourceRepresentationMetadata(returnTypeMirror);
    } else {
      entityParameter = loadEntityParameter(signatureOverride);
      declaredEntityParameters.add(entityParameter);
      resourceParameters = loadResourceParameters(signatureOverride);
      outputPayload = loadOutputPayload(signatureOverride);
    }

    JavaDoc.JavaDocTagList doclets =
        getJavaDoc()
            .get(
                "RequestHeader"); // support jax-doclets. see
                                  // http://jira.codehaus.org/browse/ENUNCIATE-690
    if (doclets != null) {
      for (String doclet : doclets) {
        int firstspace = doclet.indexOf(' ');
        String header = firstspace > 0 ? doclet.substring(0, firstspace) : doclet;
        String doc =
            ((firstspace > 0) && (firstspace + 1 < doclet.length()))
                ? doclet.substring(firstspace + 1)
                : "";
        resourceParameters.add(
            new ExplicitResourceParameter(this, doc, header, ResourceParameterType.HEADER));
      }
    }

    ArrayList<ResponseCode> statusCodes = new ArrayList<ResponseCode>();
    ArrayList<ResponseCode> warnings = new ArrayList<ResponseCode>();
    StatusCodes codes = getAnnotation(StatusCodes.class);
    if (codes != null) {
      for (org.codehaus.enunciate.jaxrs.ResponseCode code : codes.value()) {
        ResponseCode rc = new ResponseCode();
        rc.setCode(code.code());
        rc.setCondition(code.condition());
        statusCodes.add(rc);
      }
    }

    doclets =
        getJavaDoc()
            .get("HTTP"); // support jax-doclets. see http://jira.codehaus.org/browse/ENUNCIATE-690
    if (doclets != null) {
      for (String doclet : doclets) {
        int firstspace = doclet.indexOf(' ');
        String code = firstspace > 0 ? doclet.substring(0, firstspace) : doclet;
        String doc =
            ((firstspace > 0) && (firstspace + 1 < doclet.length()))
                ? doclet.substring(firstspace + 1)
                : "";
        try {
          ResponseCode rc = new ResponseCode();
          rc.setCode(Integer.parseInt(code));
          rc.setCondition(doc);
          statusCodes.add(rc);
        } catch (NumberFormatException e) {
          // fall through...
        }
      }
    }

    Warnings warningInfo = getAnnotation(Warnings.class);
    if (warningInfo != null) {
      for (org.codehaus.enunciate.jaxrs.ResponseCode code : warningInfo.value()) {
        ResponseCode rc = new ResponseCode();
        rc.setCode(code.code());
        rc.setCondition(code.condition());
        warnings.add(rc);
      }
    }

    codes = parent.getAnnotation(StatusCodes.class);
    if (codes != null) {
      for (org.codehaus.enunciate.jaxrs.ResponseCode code : codes.value()) {
        ResponseCode rc = new ResponseCode();
        rc.setCode(code.code());
        rc.setCondition(code.condition());
        statusCodes.add(rc);
      }
    }

    warningInfo = parent.getAnnotation(Warnings.class);
    if (warningInfo != null) {
      for (org.codehaus.enunciate.jaxrs.ResponseCode code : warningInfo.value()) {
        ResponseCode rc = new ResponseCode();
        rc.setCode(code.code());
        rc.setCondition(code.condition());
        warnings.add(rc);
      }
    }

    ResponseHeaders responseHeaders = parent.getAnnotation(ResponseHeaders.class);
    if (responseHeaders != null) {
      for (ResponseHeader header : responseHeaders.value()) {
        this.responseHeaders.put(header.name(), header.description());
      }
    }

    responseHeaders = getAnnotation(ResponseHeaders.class);
    if (responseHeaders != null) {
      for (ResponseHeader header : responseHeaders.value()) {
        this.responseHeaders.put(header.name(), header.description());
      }
    }

    doclets =
        getJavaDoc()
            .get(
                "ResponseHeader"); // support jax-doclets. see
                                   // http://jira.codehaus.org/browse/ENUNCIATE-690
    if (doclets != null) {
      for (String doclet : doclets) {
        int firstspace = doclet.indexOf(' ');
        String header = firstspace > 0 ? doclet.substring(0, firstspace) : doclet;
        String doc =
            ((firstspace > 0) && (firstspace + 1 < doclet.length()))
                ? doclet.substring(firstspace + 1)
                : "";
        this.responseHeaders.put(header, doc);
      }
    }

    this.entityParameter = entityParameter;
    this.resourceParameters = resourceParameters;
    this.subpath = subpath;
    this.parent = parent;
    this.statusCodes = statusCodes;
    this.warnings = warnings;
    this.representationMetadata = outputPayload;
    this.declaredEntityParameters = declaredEntityParameters;
  }