diff --git a/WHATSNEW b/WHATSNEW index 71f4205a4..f43dede82 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -89,6 +89,9 @@ Other changes: * has a new "force" attribute that, when true, disables checking of target files. +* Added isSigned condition and task, and signedselector selector + Bugzilla report 32126. + Changes from Ant 1.6.2 to current Ant 1.6 CVS version ===================================================== diff --git a/src/main/org/apache/tools/ant/taskdefs/ConditionAndTask.java b/src/main/org/apache/tools/ant/taskdefs/ConditionAndTask.java new file mode 100644 index 000000000..fbc726c72 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/ConditionAndTask.java @@ -0,0 +1,95 @@ +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.tools.ant.taskdefs; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.condition.Condition; + +/** + * Abstract task to allow defintion of a task or a condition. + * It has property and value (for the property) attributes. + * + * @since Ant 1.7 + * + * @ant.task category="control" + */ +public abstract class ConditionAndTask extends Task implements Condition { + + private String property; + private String value = "true"; + + /** + * Set the name of the property which will be set if the particular resource + * is available. + * + * @param property the name of the property to set. + */ + public void setProperty(String property) { + this.property = property; + } + + /** + * Set the value to be given to the property if the desired resource is + * available. + * + * @param value the value to be given. + */ + public void setValue(String value) { + this.value = value; + } + + /** + * This method should be overridden by derived classes. + * It is used by eval() to evaluate the condition. + * @return true if the condition passes, false otherwise. + */ + protected abstract boolean evaluate(); + + /** + * This method evaluates the condition. It calls evaluate in the + * derived class. + * It sets the property if a property is present and if the + * evaluate returns true. + * @return true if the condition passes, false otherwise. + */ + public boolean eval() { + if (evaluate()) { + if (property != null) { + getProject().setNewProperty(property, value); + } + return true; + } else { + return false; + } + } + + /** + * Entry point when operating as a task. + * + * @exception BuildException if the task is not configured correctly. + */ + public void execute() throws BuildException { + if (property == null) { + throw new BuildException("property attribute is required", + getLocation()); + } + eval(); + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/IsSigned.java b/src/main/org/apache/tools/ant/taskdefs/IsSigned.java new file mode 100644 index 000000000..a8b4921d9 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/IsSigned.java @@ -0,0 +1,119 @@ +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.tools.ant.taskdefs; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import java.io.File; +import java.io.IOException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.Enumeration; + +/** + * Checks whether a jarfile is signed: if the name of the + * signature is passed, the file is checked for presence of that + * particular signature; otherwise the file is checked for the + * existence of any signature. + */ +public class IsSigned extends ConditionAndTask { + + private static final String SIG_START = "META-INF/"; + private static final String SIG_END = ".SF"; + + private String name; + private File file; + + /** + * The jarfile that is to be tested for the presence + * of a signature. + * + * @param file jarfile to be tested. + */ + public void setFile(File file) { + this.file = file; + } + + /** + * The signature name to check jarfile for. + * + * @param name signature to look for. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns true if the file exists and is signed with + * the signature specified, or, if name wasn't + * specified, if the file contains a signature. + * @return true if the file is signed. + */ + protected boolean evaluate() { + if (file == null) { + throw new BuildException("The file attribute must be set."); + } + if (file != null && !file.exists()) { + log("The file \"" + file.getAbsolutePath() + + "\" does not exist.", Project.MSG_VERBOSE); + return false; + } + + ZipFile jarFile = null; + try { + jarFile = new ZipFile(file); + if (null == name) { + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + String name = ((ZipEntry) entries.nextElement()).getName(); + if (name.startsWith(SIG_START) && name.endsWith(SIG_END)) { + log("File \"" + file.getAbsolutePath() + + "\" is signed.", Project.MSG_VERBOSE); + return true; + } + } + return false; + } else { + boolean shortSig = jarFile.getEntry(SIG_START + + name.toUpperCase() + + SIG_END) != null; + boolean longSig = jarFile.getEntry(SIG_START + + name.substring(0, 8).toUpperCase() + + SIG_END) != null; + if (shortSig || longSig) { + log("File \"" + file.getAbsolutePath() + + "\" is signed.", Project.MSG_VERBOSE); + return true; + } else { + return false; + } + } + } catch (IOException e) { + log("Got IOException reading file \"" + file.getAbsolutePath() + + "\"" + e, Project.MSG_VERBOSE); + return false; + } finally { + if (jarFile != null) { + try { + jarFile.close(); + } catch (IOException e) { + // Ignored + } + } + } + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties index bde9ce30a..a6bf2ed0c 100644 --- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties +++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties @@ -80,6 +80,7 @@ defaultexcludes=org.apache.tools.ant.taskdefs.DefaultExcludes presetdef=org.apache.tools.ant.taskdefs.PreSetDef macrodef=org.apache.tools.ant.taskdefs.MacroDef nice=org.apache.tools.ant.taskdefs.Nice +issigned=org.apache.tools.ant.taskdefs.IsSigned libraries=org.apache.tools.ant.taskdefs.repository.Libraries # optional tasks diff --git a/src/main/org/apache/tools/ant/types/defaults.properties b/src/main/org/apache/tools/ant/types/defaults.properties index a3309e7a6..1792a716a 100644 --- a/src/main/org/apache/tools/ant/types/defaults.properties +++ b/src/main/org/apache/tools/ant/types/defaults.properties @@ -28,10 +28,11 @@ extensionSet=org.apache.tools.ant.taskdefs.optional.extension.ExtensionSet extension=org.apache.tools.ant.taskdefs.optional.extension.ExtensionAdapter libfileset=org.apache.tools.ant.taskdefs.optional.extension.LibFileSet selector=org.apache.tools.ant.types.selectors.SelectSelector +signedselector=org.apache.tools.ant.types.selectors.SignedSelector zipfileset=org.apache.tools.ant.types.ZipFileSet scriptfilter=org.apache.tools.ant.types.optional.ScriptFilter propertyset=org.apache.tools.ant.types.PropertySet assertions=org.apache.tools.ant.types.Assertions concatfilter=org.apache.tools.ant.filters.ConcatFilter ispingable=org.apache.tools.ant.taskdefs.optional.condition.IsPingable -mavenrepository=org.apache.tools.ant.taskdefs.repository.MavenRepository \ No newline at end of file +mavenrepository=org.apache.tools.ant.taskdefs.optional.repository.MavenRepository diff --git a/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java b/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java new file mode 100644 index 000000000..104c77619 --- /dev/null +++ b/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java @@ -0,0 +1,54 @@ +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.tools.ant.types.selectors; +import java.io.File; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.taskdefs.IsSigned; + +/** + * Selector that chooses files based on whether they are signed or not. + * + * @since 1.7 + */ +public class SignedSelector extends DataType implements FileSelector { + IsSigned isSigned = new IsSigned(); + + /** + * The signature name to check jarfile for. + * + * @param name signature to look for. + */ + public void setName(String name) { + isSigned.setName(name); + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. + * + * @param basedir the base directory the scan is being done from + * @param filename is the name of the file to check + * @param file is a java.io.File object the selector can use + * @return whether the file should be selected or not + */ + public boolean isSelected(File basedir, String filename, File file) { + isSigned.setProject(getProject()); + isSigned.setFile(file); + return isSigned.eval(); + } +}