GenStubsTask.java revision 1304:9d47f4850714
1/*
2 * Copyright (c) 2009, 2012, 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
26package anttasks;
27
28import genstubs.GenStubs;
29
30import java.io.*;
31import java.util.*;
32
33import org.apache.tools.ant.BuildException;
34import org.apache.tools.ant.DirectoryScanner;
35import org.apache.tools.ant.taskdefs.MatchingTask;
36import org.apache.tools.ant.types.Path;
37import 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 */
48public 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}
163