【问题标题】:Regex Java Endpoint Annotations正则表达式 Java 端点注释
【发布时间】:2013-02-19 02:45:56
【问题描述】:

我有一个项目来记录一个非常大的项目中的所有端点。我只有源文件,所以我不能在上面运行某种文档工具。我唯一的资源(据我所知)是使用 perl 或 python 或类似的正则表达式。

这是一个方法上的注释示例:

/**
 * Method Javadoc
 */
@Endpoint
@POST
@Path("path/{objectid}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@TypeHint(SomeObject.class)
public Response deleteObject(@PathParam("objectid") Integer objectid) {
  //method code
}

我相信我唯一可以信任的是,每个端点方法都会有 @Endpoint 注释。它可能是也可能不是第一个注释。方法可以有任何签名。

任何关于正则表达式的帮助都会很棒。我希望匹配所有这些信息需要的不仅仅是一个正则表达式,所以一些,甚至也会有帮助!

只是为了让您知道我要做什么(我不希望您为我做这项工作,我主要是在寻找正则表达式的帮助),我想要的是一个带有以下构造:

SourceFile.java  |  MethodName  |      Path       | Method  |  QueryParams  |  FormParams  |  Consumes                  |  Produces                                                |  ReturnedObject
ClassName.java   | deleteObject | path/{objectid} |  POST   |  objectid,    |              | MediaType.APPLICATION_JSON |  {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML} | SomeObject.class

【问题讨论】:

    标签: python perl javascript java javascript python regex perl


    【解决方案1】:

    您对正则表达式作为唯一解决方案的准备程度如何? 假设你已经编译了代码(或可以编译它),并且你的注释是零售的,你可以编写一个遍历所有类的 java 方法,使用 class.forName() 加载它们,然后你有一个多种反射 API 供您使用,用于检查类、方法、字段等的注释。

    如果类被 jarred,您只需在运行时将 jar 添加到类路径中,然后使用 ZipInputStream 打开它,检查条目,然后使用 class.forName() 将它们一一加载。如果它“爆炸”(只是一堆 *.class 文件),你的工作就更容易了。

    浏览一个 zip(其中 *.jar、*.ear、*.war 是)类似于:

    ZipInputStream zis = new ZipInputStream(new FileInputStream("fileName"));
    ZipEntry entry;
    while ((entry = zis.getNextEntry())!=null) {
        if (entry.isDirectory()) {
            continue;
        }
        if (!entry.getName().endsWith(".class")) {
            continue;
        }
        Class theClass = Class.forName(entry.getName());
        Endpoint targetAnnotation = theClass.getAnnotation(Endpoint.class);
        if (targetAnnotation == null) {
            continue;
        }
        //probably what youre looking for
    }
    

    当然,您的程序需要在执行的 lasspath 上使用目标 *.war/jar/ear 执行,以便 Class.forName() 调用起作用。如果编译后的代码没有乱码,那么您可以简单地以非常相似的方式遍历文件系统。

    如果您所使用的注释在编译后没有保留,您可以考虑引入一个可以读取 java 代码并遍历语法树的库,例如 this

    【讨论】:

    • 我也许能够获得一个*.war 文件,这将使这成为可能。我以前用reflection 做过类似的事情,但我不熟悉ZipInputStream 或者一堆*.class 文件如何让我的工作更轻松。你能详细说明一下吗?
    • @kentcdodds - 我用模拟代码和另一种选择扩展了我的答案
    • 感谢您的帮助。我在 Class.forName() 上收到了 ClassNotFound。我的类路径中有*.war 文件。我不确定它有什么问题......
    • @kentcdodds - 战争/耳朵可能有一个更复杂的结构,这会阻止 java 类加载器正确查看它们的内容。也许您的 *.war 在 /lib 下包含更多 *.jars 或里面的东西?如果是这样,您将需要提取所有这些并处理它们(将所有内容放在类路径中并检查它们的所有内容)
    【解决方案2】:

    这样的东西可能在 Perl 中有效,例如,

    my $found_method;
    my $found_endpoint;
    
    # Iterate over each line of the input .java file
    while (<>) {
      $found_method = 0;
      $found_endpoint = 0;
    
      # Look for an @endpoint annotation, and capture what's between the
      # parenthesees.  Do the same for each annotation.
      if (/\@endpoint/i) {
        $found_endpoint = 1;
      } elsif (/\@path\(([^\)]+)\)/i) {
        $path = $+;
      } elsif (/\@consumes\(([^\)]+)\)/i) {
        $consumes = $+;
      } elsif (/\@produces\(([^\)]+)\)/i) {
        $produces = $+;
      } elsif (/\@typehint\(([^\)]+)\)/i) {
        $typehint = $+;
    
      # Look for a method definition (all on one line)
      } elsif (/\w+\s+\w+\(.*{/i) {
        $open_brackets = 1;
    
        # Skip over the bracketed method definition
        while ($open_brackets) {
          $found_method = 1;
          if (/{/) {
            $open_brackets++;
          } elsif (/{/) {
            $open_brackets--;
          }
        }
      }
    
      # If we just finished passing over an annotated method, output what we
      # found
      if ($found_method and  $found_endpoint) {
        print "\npath = " . $path;
        print "\nconsumes = " . $consumes;
        print "\nproduces = " . $produces;
        print "\ntypehint = " . $typehint;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-19
      • 2014-07-26
      • 2014-12-17
      • 2014-01-29
      • 2010-11-25
      • 1970-01-01
      • 2012-10-26
      • 2020-02-02
      • 1970-01-01
      相关资源
      最近更新 更多