Skip to content

Commit

Permalink
Fix issue #35: Allow to ignore empty filesets: <forbiddenapis ignoreE…
Browse files Browse the repository at this point in the history
…mptyFileset="true"/>.

Fix issue #36: Allow signaturesFileList and signaturesFile nested elements to enforce existence (does not work with Filesets).
  • Loading branch information
uschindler committed Sep 14, 2014
1 parent 3ec4c38 commit 67a4d60
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 22 deletions.
51 changes: 39 additions & 12 deletions src/main/java/de/thetaphi/forbiddenapis/AntTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.FileList;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.Resource;
Expand Down Expand Up @@ -55,6 +56,7 @@ public final class AntTask extends Task {
private boolean internalRuntimeForbidden = false;
private boolean restrictClassFilename = true;
private boolean failOnMissingClasses = true;
private boolean ignoreEmptyFileset = false;

@Override
public void execute() throws BuildException {
Expand Down Expand Up @@ -112,12 +114,9 @@ protected void logInfo(String msg) {
}

@SuppressWarnings("unchecked")
Iterator<Resource> iter = (Iterator<Resource>) apiSignatures.iterator();
final Iterator<Resource> iter = (Iterator<Resource>) apiSignatures.iterator();
while (iter.hasNext()) {
final Resource r = iter.next();
if (!r.isExists()) {
throw new BuildException("Signatures file does not exist: " + r);
}
if (r instanceof StringResource) {
final String s = ((StringResource) r).getValue();
if (s != null && s.trim().length() > 0) {
Expand All @@ -142,23 +141,28 @@ protected void logInfo(String msg) {
log("Loading classes to check...", Project.MSG_INFO);
try {
@SuppressWarnings("unchecked")
Iterator<Resource> iter = (Iterator<Resource>) classFiles.iterator();
if (!iter.hasNext()) {
throw new BuildException("There is no <fileset/> given or the fileset does not contain any class files to check.");
}
final Iterator<Resource> iter = (Iterator<Resource>) classFiles.iterator();
boolean foundClass = false;
while (iter.hasNext()) {
final Resource r = iter.next();
final String name = r.getName();
if (restrictClassFilename && name != null && !name.endsWith(".class")) {
continue;
}
if (!r.isExists()) {
throw new BuildException("Class file does not exist: " + r);
}
checker.addClassToCheck(r.getInputStream());
foundClass = true;
}
if (!foundClass) {
if (ignoreEmptyFileset) {
log("There is no <fileset/> or other resource collection given, or the collection does not contain any class files to check.", Project.MSG_WARN);
log("Scanned 0 class files.", Project.MSG_INFO);
return;
} else {
throw new BuildException("There is no <fileset/> or other resource collection given, or the collection does not contain any class files to check.");
}
}
} catch (IOException ioe) {
throw new BuildException("Failed to load one of the given class files:" + ioe);
throw new BuildException("Failed to load one of the given class files: " + ioe);
}

log("Scanning for API signatures and dependencies...", Project.MSG_INFO);
Expand Down Expand Up @@ -202,6 +206,22 @@ public FileSet createSignaturesFileSet() {
return fs;
}

/** List of files with API signatures as <signaturesFileList/> nested element */
public FileList createSignaturesFileList() {
final FileList fl = new FileList();
fl.setProject(getProject());
apiSignatures.add(fl);
return fl;
}

/** Single file with API signatures as <signaturesFile/> nested element */
public FileResource createSignaturesFile() {
final FileResource fr = new FileResource();
fr.setProject(getProject());
apiSignatures.add(fr);
return fr;
}

public BundledSignaturesType createBundledSignatures() {
final BundledSignaturesType s = new BundledSignaturesType();
s.setProject(getProject());
Expand Down Expand Up @@ -278,4 +298,11 @@ public void setRestrictClassFilename(boolean restrictClassFilename) {
this.restrictClassFilename = restrictClassFilename;
}

/** Ignore empty fileset/resource collection and print a warning instead.
* Defaults to {@code false}.
*/
public void setIgnoreEmptyFileSet(boolean ignoreEmptyFileset) {
this.ignoreEmptyFileset = ignoreEmptyFileset;
}

}
2 changes: 1 addition & 1 deletion src/test/antunit/TestClassReferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<target name="testClassReferences">
<au:expectfailure expectedMessage="Check for forbidden API calls failed, see log">
<forbiddenapis>
<fileset file="Java5ClassReferences.class"/>
<file file="Java5ClassReferences.class"/>
java.lang.Integer @ Forbidden class reference!
java.util.List @ Forbidden class reference!
java.util.AbstractCollection @ Forbidden class reference!
Expand Down
8 changes: 1 addition & 7 deletions src/test/antunit/TestCommonsIOSignatures.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,7 @@
<echo message="Testing signatures of version ${commons-io-version}..."/>
<ivy:cachepath organisation="commons-io" module="commons-io" revision="${commons-io-version}"
inline="true" conf="master" type="jar" pathid="commons-io.classpath" log="${ivy.logging}"/>
<forbiddenapis bundledSignatures="${commons-io-signature}">
<classpath>
<path refid="path.run"/>
<path refid="commons-io.classpath"/>
</classpath>
<fileset refid="main.classes"/>
</forbiddenapis>
<forbiddenapis bundledSignatures="${commons-io-signature}" ignoreEmptyFileset="true" classpathref="commons-io.classpath"/>
</target>

</project>
20 changes: 20 additions & 0 deletions src/test/antunit/TestFileSignatures.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,24 @@
<au:assertLogContains level="error" text="java.lang.String#substring(int,int) [You are crazy that you disallow substrings]"/>
</target>

<target name="testFileList">
<au:expectfailure expectedMessage="Check for forbidden API calls failed, see log">
<forbiddenapis classpathref="path.run">
<fileset refid="main.classes"/>
<signaturesFilelist dir="." files="signatures1.txt"/>
</forbiddenapis>
</au:expectfailure>
<au:assertLogContains level="error" text="java.lang.String#substring(int,int) [You are crazy that you disallow substrings]"/>
</target>

<target name="testFileResource">
<au:expectfailure expectedMessage="Check for forbidden API calls failed, see log">
<forbiddenapis classpathref="path.run">
<fileset refid="main.classes"/>
<signaturesFile file="signatures1.txt"/>
</forbiddenapis>
</au:expectfailure>
<au:assertLogContains level="error" text="java.lang.String#substring(int,int) [You are crazy that you disallow substrings]"/>
</target>

</project>
2 changes: 1 addition & 1 deletion src/test/antunit/TestInternalRuntimeCalls.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<target name="testInternalRuntimeForbidden">
<au:expectfailure expectedMessage="Check for forbidden API calls failed, see log">
<forbiddenapis internalRuntimeForbidden="true" failOnMissingClasses="false">
<fileset file="OracleInternalRuntime.class"/>
<file file="OracleInternalRuntime.class"/>
</forbiddenapis>
</au:expectfailure>
<au:assertLogContains level="error" text="sun.misc.BASE64Encoder [non-public internal runtime class]"/>
Expand Down
2 changes: 1 addition & 1 deletion src/test/antunit/TestJava8.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<target name="testDefaultMethodAndClosures">
<au:expectfailure expectedMessage="Check for forbidden API calls failed, see log">
<forbiddenapis failOnMissingClasses="false">
<fileset file="Java8Closures.class"/>
<file file="Java8Closures.class"/>
java.io.Closeable @ Police alarm!
java.lang.StringBuilder @ Police alarm!
java.lang.Integer#compareTo(java.lang.Integer) @ Closure alarm!
Expand Down

0 comments on commit 67a4d60

Please sign in to comment.