1 /* 2 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package anttasks; 27 28 import genstubs.GenStubs; 29 30 import java.io.*; 31 import java.util.*; 32 33 import org.apache.tools.ant.BuildException; 34 import org.apache.tools.ant.DirectoryScanner; 35 import org.apache.tools.ant.taskdefs.MatchingTask; 36 import org.apache.tools.ant.types.Path; 37 import org.apache.tools.ant.types.Reference; 38 39 /** 40 * Files are specified with an implicit fileset, using srcdir as a base directory. 41 * The set of files to be included is specified with an includes attribute or 42 * nested <includes> set. However, unlike a normal fileset, an empty includes attribute 43 * means "no files" instead of "all files". The Ant task also accepts "fork=true" and 44 * classpath attribute or nested <classpath> element to run GenStubs in a separate VM 45 * with the specified path. This is likely necessary if a JDK 7 parser is required to read the 46 * JDK 7 input files. 47 */ 48 public class GenStubsTask extends MatchingTask { 49 private File srcDir; 50 private File destDir; 51 private boolean fork; 52 private Path classpath; 53 private String includes; 54 55 public void setSrcDir(File dir) { 56 this.srcDir = dir; 57 } 58 59 public void setDestDir(File dir) { 60 this.destDir = dir; 61 } 62 63 public void setFork(boolean v) { 64 this.fork = v; 65 } 66 67 public void setClasspath(Path cp) { 68 if (classpath == null) 69 classpath = cp; 70 else 71 classpath.append(cp); 72 } 73 74 public Path createClasspath() { 75 if (classpath == null) { 76 classpath = new Path(getProject()); 77 } 78 return classpath.createPath(); 79 } 80 81 public void setClasspathRef(Reference r) { 82 createClasspath().setRefid(r); 83 } 84 85 public void setIncludes(String includes) { 86 super.setIncludes(includes); 87 this.includes = includes; 88 } 89 90 @Override 91 public void execute() { 92 if (includes != null && includes.trim().isEmpty()) 93 return; 94 95 DirectoryScanner s = getDirectoryScanner(srcDir); 96 String[] files = s.getIncludedFiles(); 97 // System.err.println("Ant.execute: srcDir " + srcDir); 98 // System.err.println("Ant.execute: destDir " + destDir); 99 // System.err.println("Ant.execute: files " + Arrays.asList(files)); 100 101 files = filter(srcDir, destDir, files); 102 if (files.length == 0) 103 return; 104 System.out.println("Generating " + files.length + " stub files to " + destDir); 105 106 List<String> classNames = new ArrayList<String>(); 107 for (String file: files) { 108 classNames.add(file.replaceAll(".java$", "").replace('/', '.')); 109 } 110 111 if (!fork) { 112 GenStubs m = new GenStubs(); 113 boolean ok = m.run(srcDir.getPath(), destDir, classNames); 114 if (!ok) 115 throw new BuildException("genstubs failed"); 116 } else { 117 List<String> cmd = new ArrayList<String>(); 118 String java_home = System.getProperty("java.home"); 119 cmd.add(new File(new File(java_home, "bin"), "java").getPath()); 120 if (classpath != null) 121 cmd.add("-Xbootclasspath/p:" + classpath); 122 cmd.add(GenStubs.class.getName()); 123 cmd.add("-sourcepath"); 124 cmd.add(srcDir.getPath()); 125 cmd.add("-s"); 126 cmd.add(destDir.getPath()); 127 cmd.addAll(classNames); 128 //System.err.println("GenStubs exec " + cmd); 129 ProcessBuilder pb = new ProcessBuilder(cmd); 130 pb.redirectErrorStream(true); 131 try { 132 Process p = pb.start(); 133 BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); 134 try { 135 String line; 136 while ((line = in.readLine()) != null) 137 System.out.println(line); 138 } finally { 139 in.close(); 140 } 141 int rc = p.waitFor(); 142 if (rc != 0) 143 throw new BuildException("genstubs failed"); 144 } catch (IOException e) { 145 throw new BuildException("genstubs failed", e); 146 } catch (InterruptedException e) { 147 throw new BuildException("genstubs failed", e); 148 } 149 } 150 } 151 152 String[] filter(File srcDir, File destDir, String[] files) { 153 List<String> results = new ArrayList<String>(); 154 for (String f: files) { 155 long srcTime = new File(srcDir, f).lastModified(); 156 long destTime = new File(destDir, f).lastModified(); 157 if (srcTime > destTime) 158 results.add(f); 159 } 160 return results.toArray(new String[results.size()]); 161 } 162 }