@@ -16,7 +16,7 @@ Fixed bugs: | |||||
Other changes: | 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 | Changes from Ant 1.9.6 TO Ant 1.9.7 | ||||
=================================== | =================================== | ||||
@@ -96,6 +96,8 @@ | |||||
Select files if they are executable.</li> | Select files if they are executable.</li> | ||||
<li><a href="#symlink"><code><symlink></code></a> - | <li><a href="#symlink"><code><symlink></code></a> - | ||||
Select files if they are symlink.</li> | 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> | </ul> | ||||
<h4><a name="containsselect">Contains Selector</a></h4> | <h4><a name="containsselect">Contains Selector</a></h4> | ||||
@@ -1041,6 +1043,29 @@ | |||||
<p><em>Since Ant 1.10.0</em></p> | <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> | <h4><a name="scriptselector">Script Selector</a></h4> | ||||
<p> | <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.NoneSelector; | ||||
import org.apache.tools.ant.types.selectors.NotSelector; | import org.apache.tools.ant.types.selectors.NotSelector; | ||||
import org.apache.tools.ant.types.selectors.OrSelector; | 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.PresentSelector; | ||||
import org.apache.tools.ant.types.selectors.ReadableSelector; | import org.apache.tools.ant.types.selectors.ReadableSelector; | ||||
import org.apache.tools.ant.types.selectors.SelectSelector; | import org.apache.tools.ant.types.selectors.SelectSelector; | ||||
@@ -799,14 +800,27 @@ public abstract class AbstractFileSet extends DataType | |||||
appendSelector(w); | appendSelector(w); | ||||
} | } | ||||
/** | |||||
* @since 1.10.0 | |||||
*/ | |||||
public void addExecutable(ExecutableSelector e) { | public void addExecutable(ExecutableSelector e) { | ||||
appendSelector(e); | appendSelector(e); | ||||
} | } | ||||
/** | |||||
* @since 1.10.0 | |||||
*/ | |||||
public void addSymlink(SymlinkSelector e) { | public void addSymlink(SymlinkSelector e) { | ||||
appendSelector(e); | appendSelector(e); | ||||
} | } | ||||
/** | |||||
* @since 1.10.0 | |||||
*/ | |||||
public void addOwnedBy(OwnedBySelector o) { | |||||
appendSelector(o); | |||||
} | |||||
/** | /** | ||||
* Add an arbitrary selector. | * Add an arbitrary selector. | ||||
* @param selector the <code>FileSelector</code> to add. | * @param selector the <code>FileSelector</code> to add. | ||||
@@ -312,14 +312,27 @@ public abstract class AbstractSelectorContainer extends DataType | |||||
appendSelector(w); | appendSelector(w); | ||||
} | } | ||||
/** | |||||
* @since 1.10.0 | |||||
*/ | |||||
public void addExecutable(ExecutableSelector e) { | public void addExecutable(ExecutableSelector e) { | ||||
appendSelector(e); | appendSelector(e); | ||||
} | } | ||||
/** | |||||
* @since 1.10.0 | |||||
*/ | |||||
public void addSymlink(SymlinkSelector e) { | public void addSymlink(SymlinkSelector e) { | ||||
appendSelector(e); | appendSelector(e); | ||||
} | } | ||||
/** | |||||
* @since 1.10.0 | |||||
*/ | |||||
public void addOwnedBy(OwnedBySelector o) { | |||||
appendSelector(o); | |||||
} | |||||
/** | /** | ||||
* add an arbitrary selector | * add an arbitrary selector | ||||
* @param selector the selector to add | * @param selector the selector to add | ||||
@@ -315,14 +315,27 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||||
appendSelector(w); | appendSelector(w); | ||||
} | } | ||||
/** | |||||
* @since 1.10.0 | |||||
*/ | |||||
public void addExecutable(ExecutableSelector e) { | public void addExecutable(ExecutableSelector e) { | ||||
appendSelector(e); | appendSelector(e); | ||||
} | } | ||||
/** | |||||
* @since 1.10.0 | |||||
*/ | |||||
public void addSymlink(SymlinkSelector e) { | public void addSymlink(SymlinkSelector e) { | ||||
appendSelector(e); | appendSelector(e); | ||||
} | } | ||||
/** | |||||
* @since 1.10.0 | |||||
*/ | |||||
public void addOwnedBy(OwnedBySelector o) { | |||||
appendSelector(o); | |||||
} | |||||
/** | /** | ||||
* add an arbitrary selector | * add an arbitrary selector | ||||
* @param selector the selector to add | * @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> |