| @@ -16,7 +16,7 @@ Fixed bugs: | |||
| Other changes: | |||
| -------------- | |||
| * New file selectors <executable> and <symlink> | |||
| * New file selectors <executable>, <symlink> and <ownedBy>. | |||
| Changes from Ant 1.9.6 TO Ant 1.9.7 | |||
| =================================== | |||
| @@ -96,6 +96,8 @@ | |||
| Select files if they are executable.</li> | |||
| <li><a href="#symlink"><code><symlink></code></a> - | |||
| Select files if they are symlink.</li> | |||
| <li><a href="#ownedBy"><code><ownedBy></code></a> - | |||
| Select files if they are owned by a given user.</li> | |||
| </ul> | |||
| <h4><a name="containsselect">Contains Selector</a></h4> | |||
| @@ -1041,6 +1043,29 @@ | |||
| <p><em>Since Ant 1.10.0</em></p> | |||
| <h4><a name="ownedBy">OwnedBy Selector</a></h4> | |||
| <p>The <code><ownedBy></code> selector selects only files | |||
| that are owned by the given user. Ant only invokes | |||
| <code>java.nio.file.Files#getOwner</code> so if a file system | |||
| doesn't support the operation this selector will not select | |||
| the file.</p> | |||
| <p><em>Since Ant 1.10.0</em></p> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">owner</td> | |||
| <td valign="top">Username of the expected owner</td> | |||
| <td valign="top" align="center">yes</td> | |||
| </tr> | |||
| </table> | |||
| <h4><a name="scriptselector">Script Selector</a></h4> | |||
| <p> | |||
| @@ -43,6 +43,7 @@ import org.apache.tools.ant.types.selectors.MajoritySelector; | |||
| import org.apache.tools.ant.types.selectors.NoneSelector; | |||
| import org.apache.tools.ant.types.selectors.NotSelector; | |||
| import org.apache.tools.ant.types.selectors.OrSelector; | |||
| import org.apache.tools.ant.types.selectors.OwnedBySelector; | |||
| import org.apache.tools.ant.types.selectors.PresentSelector; | |||
| import org.apache.tools.ant.types.selectors.ReadableSelector; | |||
| import org.apache.tools.ant.types.selectors.SelectSelector; | |||
| @@ -799,14 +800,27 @@ public abstract class AbstractFileSet extends DataType | |||
| appendSelector(w); | |||
| } | |||
| /** | |||
| * @since 1.10.0 | |||
| */ | |||
| public void addExecutable(ExecutableSelector e) { | |||
| appendSelector(e); | |||
| } | |||
| /** | |||
| * @since 1.10.0 | |||
| */ | |||
| public void addSymlink(SymlinkSelector e) { | |||
| appendSelector(e); | |||
| } | |||
| /** | |||
| * @since 1.10.0 | |||
| */ | |||
| public void addOwnedBy(OwnedBySelector o) { | |||
| appendSelector(o); | |||
| } | |||
| /** | |||
| * Add an arbitrary selector. | |||
| * @param selector the <code>FileSelector</code> to add. | |||
| @@ -312,14 +312,27 @@ public abstract class AbstractSelectorContainer extends DataType | |||
| appendSelector(w); | |||
| } | |||
| /** | |||
| * @since 1.10.0 | |||
| */ | |||
| public void addExecutable(ExecutableSelector e) { | |||
| appendSelector(e); | |||
| } | |||
| /** | |||
| * @since 1.10.0 | |||
| */ | |||
| public void addSymlink(SymlinkSelector e) { | |||
| appendSelector(e); | |||
| } | |||
| /** | |||
| * @since 1.10.0 | |||
| */ | |||
| public void addOwnedBy(OwnedBySelector o) { | |||
| appendSelector(o); | |||
| } | |||
| /** | |||
| * add an arbitrary selector | |||
| * @param selector the selector to add | |||
| @@ -315,14 +315,27 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
| appendSelector(w); | |||
| } | |||
| /** | |||
| * @since 1.10.0 | |||
| */ | |||
| public void addExecutable(ExecutableSelector e) { | |||
| appendSelector(e); | |||
| } | |||
| /** | |||
| * @since 1.10.0 | |||
| */ | |||
| public void addSymlink(SymlinkSelector e) { | |||
| appendSelector(e); | |||
| } | |||
| /** | |||
| * @since 1.10.0 | |||
| */ | |||
| public void addOwnedBy(OwnedBySelector o) { | |||
| appendSelector(o); | |||
| } | |||
| /** | |||
| * add an arbitrary selector | |||
| * @param selector the selector to add | |||
| @@ -0,0 +1,78 @@ | |||
| /* | |||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||
| * contributor license agreements. See the NOTICE file distributed with | |||
| * this work for additional information regarding copyright ownership. | |||
| * The ASF licenses this file to You 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.nio.file.Files; | |||
| import java.nio.file.attribute.UserPrincipal; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.types.Resource; | |||
| import org.apache.tools.ant.types.resources.FileProvider; | |||
| import org.apache.tools.ant.types.resources.selectors.ResourceSelector; | |||
| /** | |||
| * A selector that selects files based on their owner. | |||
| * | |||
| * <p>Owner is defined in terms of {@link | |||
| * java.nio.file.Files#getOwner}, this means the selector will accept | |||
| * any file that exists and is owned by the given user. If the {@code | |||
| * getOwner} method throws an {@code UnsupportedOperattionException} | |||
| * the file in question is not included.</p> | |||
| * | |||
| * @since Ant 1.10.0 | |||
| */ | |||
| public class OwnedBySelector implements FileSelector, ResourceSelector { | |||
| private String owner; | |||
| /** | |||
| * Sets the User-Name to look for. | |||
| * @param the user name | |||
| */ | |||
| public void setOwner(String owner) { | |||
| this.owner = owner; | |||
| } | |||
| @Override | |||
| public boolean isSelected(File basedir, String filename, File file) { | |||
| if (owner == null) { | |||
| throw new BuildException("the owner attribute is required"); | |||
| } | |||
| if (file != null) { | |||
| try { | |||
| UserPrincipal user = Files.getOwner(file.toPath()); | |||
| return user != null && owner.equals(user.getName()); | |||
| } catch (UnsupportedOperationException | IOException ex) { | |||
| // => not the expected owner | |||
| } | |||
| } | |||
| return false; | |||
| } | |||
| @Override | |||
| public boolean isSelected(Resource r) { | |||
| FileProvider fp = r.as(FileProvider.class); | |||
| if (fp != null) { | |||
| return isSelected(null, null, fp.getFile()); | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| @@ -0,0 +1,65 @@ | |||
| <?xml version="1.0"?> | |||
| <!-- | |||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||
| contributor license agreements. See the NOTICE file distributed with | |||
| this work for additional information regarding copyright ownership. | |||
| The ASF licenses this file to You 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. | |||
| --> | |||
| <project xmlns:au="antlib:org.apache.ant.antunit" default="antunit"> | |||
| <import file="../../antunit-base.xml" /> | |||
| <property name="file" value="testfile"/> | |||
| <target name="createTestdir"> | |||
| <mkdir dir="${output}"/> | |||
| <touch file="${output}/${file}"/> | |||
| </target> | |||
| <target name="testRequiresOwner" depends="createTestdir"> | |||
| <au:expectfailure expectedMessage="the owner attribute is required"> | |||
| <au:assertTrue> | |||
| <isfileselected file="${output}/${file}"> | |||
| <ownedBy/> | |||
| </isfileselected> | |||
| </au:assertTrue> | |||
| </au:expectfailure> | |||
| </target> | |||
| <!-- not sure whether this works on Windows, Jenkins will tell us --> | |||
| <target name="testOwnedBy" depends="createTestdir"> | |||
| <au:assertTrue> | |||
| <resourcecount when="equal" count="1"> | |||
| <fileset dir="${output}"> | |||
| <ownedBy owner="${user.name}"/> | |||
| </fileset> | |||
| </resourcecount> | |||
| </au:assertTrue> | |||
| <au:assertTrue> | |||
| <resourcecount when="equal" count="0"> | |||
| <fileset dir="${output}" excludes="${file}"> | |||
| <ownedBy owner="${user.name}"/> | |||
| </fileset> | |||
| </resourcecount> | |||
| </au:assertTrue> | |||
| </target> | |||
| <target name="testAsTrueConditions" depends="createTestdir"> | |||
| <au:assertTrue> | |||
| <isfileselected file="${output}/${file}"> | |||
| <ownedBy owner="${user.name}"/> | |||
| </isfileselected> | |||
| </au:assertTrue> | |||
| </target> | |||
| </project> | |||