2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
20 package org
.apache
.thrift
.maven
;
22 import com
.google
.common
.collect
.ImmutableList
;
23 import com
.google
.common
.collect
.ImmutableSet
;
24 import org
.codehaus
.plexus
.util
.cli
.CommandLineException
;
25 import org
.codehaus
.plexus
.util
.cli
.CommandLineUtils
;
26 import org
.codehaus
.plexus
.util
.cli
.Commandline
;
28 import java
.util
.List
;
30 import static com
.google
.common
.base
.Preconditions
.checkArgument
;
31 import static com
.google
.common
.base
.Preconditions
.checkNotNull
;
32 import static com
.google
.common
.base
.Preconditions
.checkState
;
33 import static com
.google
.common
.collect
.Lists
.newLinkedList
;
34 import static com
.google
.common
.collect
.Sets
.newHashSet
;
37 * This class represents an invokable configuration of the {@code thrift}
38 * compiler. The actual executable is invoked using the plexus
39 * {@link Commandline}.
41 * This class currently only supports generating java source files.
45 final static String GENERATED_JAVA
= "gen-java";
47 private final String executable
;
48 private final String generator
;
49 private final ImmutableSet
<File
> thriftPathElements
;
50 private final ImmutableSet
<File
> thriftFiles
;
51 private final File javaOutputDirectory
;
52 private final CommandLineUtils
.StringStreamConsumer output
;
53 private final CommandLineUtils
.StringStreamConsumer error
;
56 * Constructs a new instance. This should only be used by the {@link Builder}.
58 * @param executable The path to the {@code thrift} executable.
59 * @param generator The value for the {@code --gen} option.
60 * @param thriftPath The directories in which to search for imports.
61 * @param thriftFiles The thrift source files to compile.
62 * @param javaOutputDirectory The directory into which the java source files
65 private Thrift(String executable
, String generator
, ImmutableSet
<File
> thriftPath
,
66 ImmutableSet
<File
> thriftFiles
, File javaOutputDirectory
) {
67 this.executable
= checkNotNull(executable
, "executable");
68 this.generator
= checkNotNull(generator
, "generator");
69 this.thriftPathElements
= checkNotNull(thriftPath
, "thriftPath");
70 this.thriftFiles
= checkNotNull(thriftFiles
, "thriftFiles");
71 this.javaOutputDirectory
= checkNotNull(javaOutputDirectory
, "javaOutputDirectory");
72 this.error
= new CommandLineUtils
.StringStreamConsumer();
73 this.output
= new CommandLineUtils
.StringStreamConsumer();
77 * Invokes the {@code thrift} compiler using the configuration specified at
80 * @return The exit status of {@code thrift}.
81 * @throws CommandLineException
83 public int compile() throws CommandLineException
{
85 for (File thriftFile
: thriftFiles
) {
86 Commandline cl
= new Commandline();
87 cl
.setExecutable(executable
);
88 cl
.addArguments(buildThriftCommand(thriftFile
).toArray(new String
[]{}));
89 final int result
= CommandLineUtils
.executeCommandLine(cl
, null, output
, error
);
96 // result will always be 0 here.
101 * Creates the command line arguments.
103 * This method has been made visible for testing only.
106 * @return A list consisting of the executable followed by any arguments.
108 ImmutableList
<String
> buildThriftCommand(final File thriftFile
) {
109 final List
<String
> command
= newLinkedList();
110 // add the executable
111 for (File thriftPathElement
: thriftPathElements
) {
113 command
.add(thriftPathElement
.toString());
116 command
.add(javaOutputDirectory
.toString());
117 command
.add("--gen");
118 command
.add(generator
);
119 command
.add(thriftFile
.toString());
120 return ImmutableList
.copyOf(command
);
126 public String
getOutput() {
127 return output
.getOutput();
133 public String
getError() {
134 return error
.getOutput();
138 * This class builds {@link Thrift} instances.
140 static final class Builder
{
141 private final String executable
;
142 private final File javaOutputDirectory
;
143 private Set
<File
> thriftPathElements
;
144 private Set
<File
> thriftFiles
;
145 private String generator
;
148 * Constructs a new builder. The two parameters are present as they are
149 * required for all {@link Thrift} instances.
151 * @param executable The path to the {@code thrift} executable.
152 * @param javaOutputDirectory The directory into which the java source files
154 * @throws NullPointerException If either of the arguments are {@code null}.
155 * @throws IllegalArgumentException If the {@code javaOutputDirectory} is
158 public Builder(String executable
, File javaOutputDirectory
) {
159 this.executable
= checkNotNull(executable
, "executable");
160 this.javaOutputDirectory
= checkNotNull(javaOutputDirectory
);
161 checkArgument(javaOutputDirectory
.isDirectory());
162 this.thriftFiles
= newHashSet();
163 this.thriftPathElements
= newHashSet();
167 * Adds a thrift file to be compiled. Thrift files must be on the thriftpath
168 * and this method will fail if a thrift file is added without first adding a
169 * parent directory to the thriftpath.
172 * @return The builder.
173 * @throws IllegalStateException If a thrift file is added without first
174 * adding a parent directory to the thriftpath.
175 * @throws NullPointerException If {@code thriftFile} is {@code null}.
177 public Builder
addThriftFile(File thriftFile
) {
178 checkNotNull(thriftFile
);
179 checkArgument(thriftFile
.isFile());
180 checkArgument(thriftFile
.getName().endsWith(".thrift"));
181 checkThriftFileIsInThriftPath(thriftFile
);
182 thriftFiles
.add(thriftFile
);
187 * Adds the option string for the Thrift executable's {@code --gen} parameter.
190 * @return The builder
191 * @throws NullPointerException If {@code generator} is {@code null}.
193 public Builder
setGenerator(String generator
) {
194 checkNotNull(generator
);
195 this.generator
= generator
;
199 private void checkThriftFileIsInThriftPath(File thriftFile
) {
200 assert thriftFile
.isFile();
201 checkState(checkThriftFileIsInThriftPathHelper(thriftFile
.getParentFile()));
204 private boolean checkThriftFileIsInThriftPathHelper(File directory
) {
205 assert directory
.isDirectory();
206 if (thriftPathElements
.contains(directory
)) {
209 final File parentDirectory
= directory
.getParentFile();
210 return (parentDirectory
== null) ?
false
211 : checkThriftFileIsInThriftPathHelper(parentDirectory
);
216 * @see #addThriftFile(File)
218 public Builder
addThriftFiles(Iterable
<File
> thriftFiles
) {
219 for (File thriftFile
: thriftFiles
) {
220 addThriftFile(thriftFile
);
226 * Adds the {@code thriftPathElement} to the thriftPath.
228 * @param thriftPathElement A directory to be searched for imported thrift message
229 * buffer definitions.
230 * @return The builder.
231 * @throws NullPointerException If {@code thriftPathElement} is {@code null}.
232 * @throws IllegalArgumentException If {@code thriftPathElement} is not a
235 public Builder
addThriftPathElement(File thriftPathElement
) {
236 checkNotNull(thriftPathElement
);
237 checkArgument(thriftPathElement
.isDirectory());
238 thriftPathElements
.add(thriftPathElement
);
243 * @see #addThriftPathElement(File)
245 public Builder
addThriftPathElements(Iterable
<File
> thriftPathElements
) {
246 for (File thriftPathElement
: thriftPathElements
) {
247 addThriftPathElement(thriftPathElement
);
253 * @return A configured {@link Thrift} instance.
254 * @throws IllegalStateException If no thrift files have been added.
256 public Thrift
build() {
257 checkState(!thriftFiles
.isEmpty());
258 return new Thrift(executable
, generator
, ImmutableSet
.copyOf(thriftPathElements
),
259 ImmutableSet
.copyOf(thriftFiles
), javaOutputDirectory
);