Maven plugin for preprocessing JavaScriptXXX annotations preprocess
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 24 Nov 2013 15:39:55 +0100
branchpreprocess
changeset 33172dda6af599b
parent 330 e4b3840d4084
child 332 386429032402
Maven plugin for preprocessing JavaScriptXXX annotations
boot/src/main/java/org/apidesign/html/boot/impl/FnUtils.java
html4j-maven-plugin/pom.xml
html4j-maven-plugin/src/main/java/org/apidesign/html/mojo/ProcessJsAnnotationsMojo.java
html4j-maven-plugin/src/test/java/org/apidesign/html/mojo/GenerateBodyTest.java
pom.xml
     1.1 --- a/boot/src/main/java/org/apidesign/html/boot/impl/FnUtils.java	Fri Nov 22 10:49:23 2013 +0100
     1.2 +++ b/boot/src/main/java/org/apidesign/html/boot/impl/FnUtils.java	Sun Nov 24 15:39:55 2013 +0100
     1.3 @@ -29,6 +29,7 @@
     1.4  import java.util.Collections;
     1.5  import java.util.Enumeration;
     1.6  import java.util.List;
     1.7 +import java.util.Map;
     1.8  import java.util.concurrent.Callable;
     1.9  import org.apidesign.html.boot.spi.Fn;
    1.10  import org.objectweb.asm.AnnotationVisitor;
    1.11 @@ -52,6 +53,19 @@
    1.12      private FnUtils() {
    1.13      }
    1.14      
    1.15 +    /** Seeks for {@link JavaScriptBody} and {@link JavaScriptResource} annotations
    1.16 +     * in the bytecode and converts them into real code. Used by Maven plugin
    1.17 +     * postprocessing classes.
    1.18 +     * 
    1.19 +     * @param bytecode the original bytecode with javascript specific annotations
    1.20 +     * @param resources the resources to load
    1.21 +     * @return the transformed bytecode
    1.22 +     * @since 0.7
    1.23 +     */
    1.24 +    public static byte[] transform(byte[] bytecode, Map<String,InputStream> resources) {
    1.25 +        return transform(null, bytecode);
    1.26 +    }
    1.27 +    
    1.28      public static boolean isJavaScriptCapable(ClassLoader l) {
    1.29          if (l instanceof JsClassLoader) {
    1.30              return true;
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/html4j-maven-plugin/pom.xml	Sun Nov 24 15:39:55 2013 +0100
     2.3 @@ -0,0 +1,101 @@
     2.4 +<?xml version="1.0"?>
     2.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
     2.6 +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     2.7 +  <modelVersion>4.0.0</modelVersion>
     2.8 +  <parent>
     2.9 +    <groupId>org.apidesign</groupId>
    2.10 +    <artifactId>html</artifactId>
    2.11 +    <version>0.7-SNAPSHOT</version>
    2.12 +  </parent>
    2.13 +  <packaging>maven-plugin</packaging>
    2.14 +  <groupId>org.apidesign.html</groupId>
    2.15 +  <artifactId>html4j-maven-plugin</artifactId>
    2.16 +  <version>0.7-SNAPSHOT</version>
    2.17 +  <name>html4j-maven-plugin</name>
    2.18 +  <url>http://maven.apache.org</url>
    2.19 +  <properties>
    2.20 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    2.21 +  </properties>
    2.22 +  <build>
    2.23 +      <plugins>
    2.24 +          <plugin>
    2.25 +              <groupId>org.apache.maven.plugins</groupId>
    2.26 +              <artifactId>maven-plugin-plugin</artifactId>
    2.27 +              <version>3.1</version>
    2.28 +              <configuration>
    2.29 +                  <extractors>
    2.30 +                      <extractor>java-annotations</extractor>
    2.31 +                  </extractors>
    2.32 +                  <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
    2.33 +              </configuration>
    2.34 +              <executions>
    2.35 +                  <execution>
    2.36 +                      <id>mojo-descriptor</id>
    2.37 +                      <phase>process-classes</phase>
    2.38 +                      <goals>
    2.39 +                          <goal>descriptor</goal>
    2.40 +                      </goals>
    2.41 +                  </execution>
    2.42 +              </executions>
    2.43 +          </plugin>
    2.44 +          <plugin>
    2.45 +              <groupId>org.apache.maven.plugins</groupId>
    2.46 +              <artifactId>maven-compiler-plugin</artifactId>
    2.47 +              <version>2.3.2</version>
    2.48 +              <configuration>
    2.49 +                  <source>1.6</source>
    2.50 +                  <target>1.6</target>
    2.51 +              </configuration>
    2.52 +          </plugin>
    2.53 +          <plugin>
    2.54 +              <groupId>org.apidesign.html</groupId>
    2.55 +              <artifactId>html4j-maven-plugin</artifactId>
    2.56 +              <version>${project.version}</version>
    2.57 +              <executions>
    2.58 +                  <execution>
    2.59 +                      <goals>
    2.60 +                          <goal>process-js-annotations</goal>
    2.61 +                      </goals>
    2.62 +                      <phase>process-test-classes</phase>
    2.63 +                      <configuration>
    2.64 +                          <classes>${project.build.directory}/test-classes</classes>
    2.65 +                      </configuration>
    2.66 +                  </execution>
    2.67 +              </executions>
    2.68 +          </plugin>
    2.69 +      </plugins>
    2.70 +  </build>
    2.71 +      
    2.72 +  <dependencies>
    2.73 +      <dependency>
    2.74 +          <groupId>org.apache.maven</groupId>
    2.75 +          <artifactId>maven-plugin-api</artifactId>
    2.76 +          <version>3.0.4</version>
    2.77 +          <type>jar</type>
    2.78 +      </dependency>
    2.79 +      <dependency>
    2.80 +          <groupId>org.apache.maven.plugin-tools</groupId>
    2.81 +          <artifactId>maven-plugin-annotations</artifactId>
    2.82 +          <version>3.0</version>
    2.83 +          <type>jar</type>
    2.84 +      </dependency>
    2.85 +      <dependency>
    2.86 +          <groupId>org.apache.maven</groupId>
    2.87 +          <artifactId>maven-core</artifactId>
    2.88 +          <version>3.0.2</version>
    2.89 +          <type>jar</type>
    2.90 +      </dependency>
    2.91 +    <dependency>
    2.92 +      <groupId>org.apidesign.html</groupId>
    2.93 +      <artifactId>net.java.html.boot</artifactId>
    2.94 +      <version>${project.version}</version>
    2.95 +      <type>jar</type>
    2.96 +    </dependency>
    2.97 +    <dependency>
    2.98 +      <groupId>org.testng</groupId>
    2.99 +      <artifactId>testng</artifactId>
   2.100 +      <scope>test</scope>
   2.101 +      <type>jar</type>
   2.102 +    </dependency>
   2.103 +  </dependencies>
   2.104 +</project>
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/html4j-maven-plugin/src/main/java/org/apidesign/html/mojo/ProcessJsAnnotationsMojo.java	Sun Nov 24 15:39:55 2013 +0100
     3.3 @@ -0,0 +1,103 @@
     3.4 +/**
     3.5 + * HTML via Java(tm) Language Bindings
     3.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     3.7 + *
     3.8 + * This program is free software: you can redistribute it and/or modify
     3.9 + * it under the terms of the GNU General Public License as published by
    3.10 + * the Free Software Foundation, version 2 of the License.
    3.11 + *
    3.12 + * This program is distributed in the hope that it will be useful,
    3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.15 + * GNU General Public License for more details. apidesign.org
    3.16 + * designates this particular file as subject to the
    3.17 + * "Classpath" exception as provided by apidesign.org
    3.18 + * in the License file that accompanied this code.
    3.19 + *
    3.20 + * You should have received a copy of the GNU General Public License
    3.21 + * along with this program. Look for COPYING file in the top folder.
    3.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
    3.23 + */
    3.24 +package org.apidesign.html.mojo;
    3.25 +
    3.26 +import java.io.File;
    3.27 +import java.io.FileInputStream;
    3.28 +import java.io.FileOutputStream;
    3.29 +import java.io.IOException;
    3.30 +import org.apache.maven.plugin.AbstractMojo;
    3.31 +import org.apache.maven.plugin.MojoExecutionException;
    3.32 +import org.apache.maven.plugin.MojoFailureException;
    3.33 +import org.apache.maven.plugins.annotations.LifecyclePhase;
    3.34 +import org.apache.maven.plugins.annotations.Mojo;
    3.35 +import org.apache.maven.plugins.annotations.Parameter;
    3.36 +import org.apache.maven.plugins.annotations.ResolutionScope;
    3.37 +import org.apache.maven.project.MavenProject;
    3.38 +import org.apidesign.html.boot.impl.FnUtils;
    3.39 +
    3.40 +@Mojo(
    3.41 +    name="process-js-annotations",
    3.42 +    requiresDependencyResolution = ResolutionScope.RUNTIME,
    3.43 +    defaultPhase= LifecyclePhase.PROCESS_CLASSES
    3.44 +)
    3.45 +public final class ProcessJsAnnotationsMojo extends AbstractMojo {
    3.46 +    @Parameter(defaultValue = "${project}")
    3.47 +    private MavenProject prj;
    3.48 +    
    3.49 +    @Parameter(defaultValue = "${project.build.directory}/classes")
    3.50 +    private File classes;
    3.51 +
    3.52 +    public ProcessJsAnnotationsMojo() {
    3.53 +    }
    3.54 +
    3.55 +    @Override
    3.56 +    public void execute() throws MojoExecutionException, MojoFailureException {
    3.57 +        try {
    3.58 +            processClasess(classes);
    3.59 +        } catch (IOException ex) {
    3.60 +            throw new MojoExecutionException("Problem converting JavaScriptXXX annotations", ex);
    3.61 +        }
    3.62 +    }
    3.63 +    
    3.64 +    private void processClasess(File f) throws IOException, MojoExecutionException {
    3.65 +        if (f.isDirectory()) {
    3.66 +            File[] arr = f.listFiles();
    3.67 +            if (arr != null) {
    3.68 +                for (File file : arr) {
    3.69 +                    processClasess(file);
    3.70 +                }
    3.71 +            }
    3.72 +            return;
    3.73 +        }
    3.74 +        if (!f.exists()) {
    3.75 +            throw new MojoExecutionException("Does not exist: " + f);
    3.76 +        }
    3.77 +        
    3.78 +        if (!f.getName().endsWith(".class")) {
    3.79 +            return;
    3.80 +        }
    3.81 +        
    3.82 +        byte[] arr = new byte[(int)f.length()];
    3.83 +        FileInputStream is = new FileInputStream(f);
    3.84 +        try {
    3.85 +            int off = 0;
    3.86 +            while (off< arr.length) {
    3.87 +                int read = is.read(arr, off, arr.length - off);
    3.88 +                if (read == -1) {
    3.89 +                    break;
    3.90 +                }
    3.91 +                off += read;
    3.92 +            }
    3.93 +        } finally {
    3.94 +            is.close();
    3.95 +        }
    3.96 +        
    3.97 +        byte[] newArr = FnUtils.transform(arr, null);
    3.98 +        if (newArr == null || newArr == arr) {
    3.99 +            return;
   3.100 +        }
   3.101 +        
   3.102 +        FileOutputStream os = new FileOutputStream(f);
   3.103 +        os.write(newArr);
   3.104 +        os.close();
   3.105 +    }
   3.106 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/html4j-maven-plugin/src/test/java/org/apidesign/html/mojo/GenerateBodyTest.java	Sun Nov 24 15:39:55 2013 +0100
     4.3 @@ -0,0 +1,65 @@
     4.4 +/**
     4.5 + * HTML via Java(tm) Language Bindings
     4.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4.7 + *
     4.8 + * This program is free software: you can redistribute it and/or modify
     4.9 + * it under the terms of the GNU General Public License as published by
    4.10 + * the Free Software Foundation, version 2 of the License.
    4.11 + *
    4.12 + * This program is distributed in the hope that it will be useful,
    4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.15 + * GNU General Public License for more details. apidesign.org
    4.16 + * designates this particular file as subject to the
    4.17 + * "Classpath" exception as provided by apidesign.org
    4.18 + * in the License file that accompanied this code.
    4.19 + *
    4.20 + * You should have received a copy of the GNU General Public License
    4.21 + * along with this program. Look for COPYING file in the top folder.
    4.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
    4.23 + */
    4.24 +package org.apidesign.html.mojo;
    4.25 +
    4.26 +import java.io.Closeable;
    4.27 +import java.io.IOException;
    4.28 +import java.io.Reader;
    4.29 +import java.net.URL;
    4.30 +import net.java.html.js.JavaScriptBody;
    4.31 +import org.apidesign.html.boot.spi.Fn;
    4.32 +import static org.testng.Assert.*;
    4.33 +import org.testng.annotations.Test;
    4.34 +
    4.35 +public class GenerateBodyTest implements Fn.Presenter {
    4.36 +    @JavaScriptBody(args = {}, body = "return true;")
    4.37 +    public static native boolean generateMe();
    4.38 +    
    4.39 +    @Test public void generateMeReturnsTrue() throws IOException {
    4.40 +        Closeable c = Fn.activate(this);
    4.41 +        try {
    4.42 +            assertTrue(generateMe(), "Body has been generated");
    4.43 +        } finally {
    4.44 +            c.close();
    4.45 +        }
    4.46 +    }
    4.47 +        
    4.48 +    @Override
    4.49 +    public Fn defineFn(String code, String... names) {
    4.50 +        return new Fn(this) {
    4.51 +            @Override
    4.52 +            public Object invoke(Object thiz, Object... args) throws Exception {
    4.53 +                return Boolean.TRUE;
    4.54 +            }
    4.55 +        };
    4.56 +    }
    4.57 +
    4.58 +    @Override
    4.59 +    public void displayPage(URL page, Runnable onPageLoad) {
    4.60 +        throw new IllegalStateException();
    4.61 +    }
    4.62 +
    4.63 +    @Override
    4.64 +    public void loadScript(Reader code) throws Exception {
    4.65 +        throw new Exception();
    4.66 +    }
    4.67 +        
    4.68 +}
     5.1 --- a/pom.xml	Fri Nov 22 10:49:23 2013 +0100
     5.2 +++ b/pom.xml	Sun Nov 24 15:39:55 2013 +0100
     5.3 @@ -29,6 +29,7 @@
     5.4      <module>boot-fx</module>
     5.5      <module>geo</module>
     5.6      <module>ko-ws-tyrus</module>
     5.7 +    <module>html4j-maven-plugin</module>
     5.8    </modules>
     5.9    <licenses>
    5.10        <license>