jaroslav@331
|
1 |
/**
|
jaroslav@421
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
jaroslav@331
|
3 |
*
|
jaroslav@551
|
4 |
* Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
|
jaroslav@331
|
5 |
*
|
jaroslav@421
|
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates.
|
jaroslav@421
|
7 |
* Other names may be trademarks of their respective owners.
|
jaroslav@331
|
8 |
*
|
jaroslav@421
|
9 |
* The contents of this file are subject to the terms of either the GNU
|
jaroslav@421
|
10 |
* General Public License Version 2 only ("GPL") or the Common
|
jaroslav@421
|
11 |
* Development and Distribution License("CDDL") (collectively, the
|
jaroslav@421
|
12 |
* "License"). You may not use this file except in compliance with the
|
jaroslav@421
|
13 |
* License. You can obtain a copy of the License at
|
jaroslav@421
|
14 |
* http://www.netbeans.org/cddl-gplv2.html
|
jaroslav@421
|
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
|
jaroslav@421
|
16 |
* specific language governing permissions and limitations under the
|
jaroslav@421
|
17 |
* License. When distributing the software, include this License Header
|
jaroslav@421
|
18 |
* Notice in each file and include the License file at
|
jaroslav@421
|
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
|
jaroslav@421
|
20 |
* particular file as subject to the "Classpath" exception as provided
|
jaroslav@421
|
21 |
* by Oracle in the GPL Version 2 section of the License file that
|
jaroslav@421
|
22 |
* accompanied this code. If applicable, add the following below the
|
jaroslav@421
|
23 |
* License Header, with the fields enclosed by brackets [] replaced by
|
jaroslav@421
|
24 |
* your own identifying information:
|
jaroslav@421
|
25 |
* "Portions Copyrighted [year] [name of copyright owner]"
|
jaroslav@421
|
26 |
*
|
jaroslav@421
|
27 |
* Contributor(s):
|
jaroslav@421
|
28 |
*
|
jaroslav@421
|
29 |
* The Original Software is NetBeans. The Initial Developer of the Original
|
jaroslav@551
|
30 |
* Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
|
jaroslav@421
|
31 |
*
|
jaroslav@421
|
32 |
* If you wish your version of this file to be governed by only the CDDL
|
jaroslav@421
|
33 |
* or only the GPL Version 2, indicate your decision by adding
|
jaroslav@421
|
34 |
* "[Contributor] elects to include this software in this distribution
|
jaroslav@421
|
35 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a
|
jaroslav@421
|
36 |
* single choice of license, a recipient has the option to distribute
|
jaroslav@421
|
37 |
* your version of this file under either the CDDL, the GPL Version 2 or
|
jaroslav@421
|
38 |
* to extend the choice of license to its licensees as provided above.
|
jaroslav@421
|
39 |
* However, if you add GPL Version 2 code and therefore, elected the GPL
|
jaroslav@421
|
40 |
* Version 2 license, then the option applies only if the new code is
|
jaroslav@421
|
41 |
* made subject to such option by the copyright holder.
|
jaroslav@331
|
42 |
*/
|
jaroslav@536
|
43 |
package org.netbeans.html.mojo;
|
jaroslav@331
|
44 |
|
jaroslav@486
|
45 |
import java.io.BufferedReader;
|
jaroslav@331
|
46 |
import java.io.File;
|
jaroslav@331
|
47 |
import java.io.FileInputStream;
|
jaroslav@334
|
48 |
import java.io.FileNotFoundException;
|
jaroslav@331
|
49 |
import java.io.FileOutputStream;
|
jaroslav@486
|
50 |
import java.io.FileReader;
|
jaroslav@486
|
51 |
import java.io.FileWriter;
|
jaroslav@331
|
52 |
import java.io.IOException;
|
jaroslav@334
|
53 |
import java.io.InputStream;
|
jaroslav@486
|
54 |
import java.lang.reflect.Method;
|
jaroslav@351
|
55 |
import java.net.MalformedURLException;
|
jaroslav@351
|
56 |
import java.net.URL;
|
jaroslav@351
|
57 |
import java.net.URLClassLoader;
|
jaroslav@351
|
58 |
import java.util.ArrayList;
|
jaroslav@351
|
59 |
import java.util.List;
|
jaroslav@334
|
60 |
import org.apache.maven.artifact.Artifact;
|
jaroslav@331
|
61 |
import org.apache.maven.plugin.AbstractMojo;
|
jaroslav@331
|
62 |
import org.apache.maven.plugin.MojoExecutionException;
|
jaroslav@331
|
63 |
import org.apache.maven.plugin.MojoFailureException;
|
jaroslav@486
|
64 |
import org.apache.maven.plugins.annotations.Component;
|
jaroslav@331
|
65 |
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
jaroslav@331
|
66 |
import org.apache.maven.plugins.annotations.Mojo;
|
jaroslav@331
|
67 |
import org.apache.maven.plugins.annotations.Parameter;
|
jaroslav@331
|
68 |
import org.apache.maven.plugins.annotations.ResolutionScope;
|
jaroslav@331
|
69 |
import org.apache.maven.project.MavenProject;
|
jaroslav@489
|
70 |
import org.objectweb.asm.ClassReader;
|
jaroslav@331
|
71 |
|
jaroslav@331
|
72 |
@Mojo(
|
jaroslav@331
|
73 |
name="process-js-annotations",
|
jaroslav@486
|
74 |
requiresDependencyResolution = ResolutionScope.COMPILE,
|
jaroslav@331
|
75 |
defaultPhase= LifecyclePhase.PROCESS_CLASSES
|
jaroslav@331
|
76 |
)
|
jaroslav@331
|
77 |
public final class ProcessJsAnnotationsMojo extends AbstractMojo {
|
jaroslav@486
|
78 |
@Component
|
jaroslav@331
|
79 |
private MavenProject prj;
|
jaroslav@331
|
80 |
|
jaroslav@331
|
81 |
@Parameter(defaultValue = "${project.build.directory}/classes")
|
jaroslav@331
|
82 |
private File classes;
|
jaroslav@334
|
83 |
|
jaroslav@331
|
84 |
public ProcessJsAnnotationsMojo() {
|
jaroslav@331
|
85 |
}
|
jaroslav@331
|
86 |
|
jaroslav@331
|
87 |
@Override
|
jaroslav@331
|
88 |
public void execute() throws MojoExecutionException, MojoFailureException {
|
jaroslav@486
|
89 |
List<URL> arr = new ArrayList<URL>();
|
jaroslav@489
|
90 |
boolean foundAsm = false;
|
jaroslav@486
|
91 |
for (Artifact a : prj.getArtifacts()) {
|
jaroslav@486
|
92 |
final File f = a.getFile();
|
jaroslav@486
|
93 |
if (f != null) {
|
jaroslav@489
|
94 |
if (a.getArtifactId().equals("asm")) {
|
jaroslav@489
|
95 |
foundAsm = true;
|
jaroslav@489
|
96 |
}
|
jaroslav@486
|
97 |
try {
|
jaroslav@486
|
98 |
arr.add(f.toURI().toURL());
|
jaroslav@486
|
99 |
} catch (MalformedURLException ex) {
|
jaroslav@486
|
100 |
throw new IllegalStateException(ex);
|
jaroslav@486
|
101 |
}
|
jaroslav@486
|
102 |
}
|
jaroslav@486
|
103 |
}
|
jaroslav@489
|
104 |
if (!foundAsm) {
|
jaroslav@489
|
105 |
URL loc = ClassReader.class.getProtectionDomain().getCodeSource().getLocation();
|
jaroslav@489
|
106 |
arr.add(loc);
|
jaroslav@489
|
107 |
}
|
jaroslav@486
|
108 |
URLClassLoader l = new URLClassLoader(arr.toArray(new URL[arr.size()]));
|
jaroslav@331
|
109 |
try {
|
jaroslav@509
|
110 |
File master = new File(new File(classes, "META-INF"), "net.java.html.js.classes");
|
jaroslav@509
|
111 |
processClasses(l, master, classes);
|
jaroslav@331
|
112 |
} catch (IOException ex) {
|
jaroslav@331
|
113 |
throw new MojoExecutionException("Problem converting JavaScriptXXX annotations", ex);
|
jaroslav@331
|
114 |
}
|
jaroslav@486
|
115 |
}
|
jaroslav@486
|
116 |
|
jaroslav@509
|
117 |
private void processClasses(ClassLoader l, File master, File f) throws IOException, MojoExecutionException {
|
jaroslav@486
|
118 |
if (!f.exists()) {
|
jaroslav@486
|
119 |
return;
|
jaroslav@486
|
120 |
}
|
jaroslav@486
|
121 |
if (f.isDirectory()) {
|
jaroslav@486
|
122 |
boolean classes = new File(f, "net.java.html.js.classes").exists();
|
jaroslav@486
|
123 |
File[] arr = f.listFiles();
|
jaroslav@486
|
124 |
if (arr != null) {
|
jaroslav@486
|
125 |
for (File file : arr) {
|
jaroslav@486
|
126 |
if (classes || file.isDirectory()) {
|
jaroslav@509
|
127 |
processClasses(l, master, file);
|
jaroslav@351
|
128 |
}
|
jaroslav@351
|
129 |
}
|
jaroslav@351
|
130 |
}
|
jaroslav@331
|
131 |
return;
|
jaroslav@331
|
132 |
}
|
jaroslav@331
|
133 |
|
jaroslav@331
|
134 |
if (!f.getName().endsWith(".class")) {
|
jaroslav@331
|
135 |
return;
|
jaroslav@331
|
136 |
}
|
jaroslav@331
|
137 |
|
jaroslav@331
|
138 |
byte[] arr = new byte[(int)f.length()];
|
jaroslav@331
|
139 |
FileInputStream is = new FileInputStream(f);
|
jaroslav@331
|
140 |
try {
|
jaroslav@334
|
141 |
readArr(arr, is);
|
jaroslav@331
|
142 |
} finally {
|
jaroslav@331
|
143 |
is.close();
|
jaroslav@331
|
144 |
}
|
jaroslav@486
|
145 |
|
jaroslav@486
|
146 |
byte[] newArr = null;
|
jaroslav@486
|
147 |
try {
|
jaroslav@486
|
148 |
Class<?> fnUtils = l.loadClass("org.netbeans.html.boot.impl.FnUtils");
|
jaroslav@486
|
149 |
Method transform = fnUtils.getMethod("transform", byte[].class, ClassLoader.class);
|
jaroslav@486
|
150 |
|
jaroslav@486
|
151 |
newArr = (byte[]) transform.invoke(null, arr, l);
|
jaroslav@486
|
152 |
if (newArr == null || newArr == arr) {
|
jaroslav@486
|
153 |
return;
|
jaroslav@486
|
154 |
}
|
jaroslav@486
|
155 |
filterClass(new File(f.getParentFile(), "net.java.html.js.classes"), f.getName());
|
jaroslav@509
|
156 |
filterClass(master, f.getName());
|
jaroslav@486
|
157 |
} catch (Exception ex) {
|
jaroslav@486
|
158 |
throw new MojoExecutionException("Can't process " + f, ex);
|
jaroslav@331
|
159 |
}
|
jaroslav@334
|
160 |
getLog().info("Processing " + f);
|
jaroslav@334
|
161 |
writeArr(f, newArr);
|
jaroslav@334
|
162 |
}
|
jaroslav@334
|
163 |
|
jaroslav@334
|
164 |
private void writeArr(File f, byte[] newArr) throws IOException, FileNotFoundException {
|
jaroslav@334
|
165 |
FileOutputStream os = new FileOutputStream(f);
|
jaroslav@334
|
166 |
try {
|
jaroslav@334
|
167 |
os.write(newArr);
|
jaroslav@334
|
168 |
} finally {
|
jaroslav@334
|
169 |
os.close();
|
jaroslav@334
|
170 |
}
|
jaroslav@334
|
171 |
}
|
jaroslav@334
|
172 |
|
jaroslav@334
|
173 |
private static void readArr(byte[] arr, InputStream is) throws IOException {
|
jaroslav@334
|
174 |
int off = 0;
|
jaroslav@334
|
175 |
while (off< arr.length) {
|
jaroslav@334
|
176 |
int read = is.read(arr, off, arr.length - off);
|
jaroslav@334
|
177 |
if (read == -1) {
|
jaroslav@334
|
178 |
break;
|
jaroslav@334
|
179 |
}
|
jaroslav@334
|
180 |
off += read;
|
jaroslav@334
|
181 |
}
|
jaroslav@334
|
182 |
}
|
jaroslav@334
|
183 |
|
jaroslav@486
|
184 |
private static void filterClass(File f, String className) throws IOException {
|
jaroslav@486
|
185 |
if (!f.exists()) {
|
jaroslav@486
|
186 |
return;
|
jaroslav@486
|
187 |
}
|
jaroslav@486
|
188 |
if (className.endsWith(".class")) {
|
jaroslav@486
|
189 |
className = className.substring(0, className.length() - 6);
|
jaroslav@486
|
190 |
}
|
jaroslav@486
|
191 |
|
jaroslav@486
|
192 |
BufferedReader r = new BufferedReader(new FileReader(f));
|
jaroslav@486
|
193 |
List<String> arr = new ArrayList<String>();
|
jaroslav@486
|
194 |
boolean modified = false;
|
jaroslav@486
|
195 |
for (;;) {
|
jaroslav@486
|
196 |
String line = r.readLine();
|
jaroslav@486
|
197 |
if (line == null) {
|
jaroslav@486
|
198 |
break;
|
jaroslav@486
|
199 |
}
|
jaroslav@486
|
200 |
if (line.endsWith(className)) {
|
jaroslav@486
|
201 |
modified = true;
|
jaroslav@334
|
202 |
continue;
|
jaroslav@334
|
203 |
}
|
jaroslav@486
|
204 |
arr.add(line);
|
jaroslav@486
|
205 |
}
|
jaroslav@486
|
206 |
r.close();
|
jaroslav@486
|
207 |
|
jaroslav@486
|
208 |
if (modified) {
|
jaroslav@486
|
209 |
if (arr.isEmpty()) {
|
jaroslav@486
|
210 |
f.delete();
|
jaroslav@486
|
211 |
} else {
|
jaroslav@486
|
212 |
FileWriter w = new FileWriter(f);
|
jaroslav@486
|
213 |
for (String l : arr) {
|
jaroslav@486
|
214 |
w.write(l);
|
jaroslav@486
|
215 |
w.write("\n");
|
jaroslav@334
|
216 |
}
|
jaroslav@486
|
217 |
w.close();
|
jaroslav@334
|
218 |
}
|
jaroslav@334
|
219 |
}
|
jaroslav@331
|
220 |
}
|
jaroslav@331
|
221 |
}
|