NIHVIVO-2811 Changing the approach to FileSet-based ResourceCollection. Is it a problem that it won't copy empty directories?

This commit is contained in:
j2blake 2011-09-09 22:11:39 +00:00
parent 19dfde675c
commit 38a5269521
15 changed files with 164 additions and 289 deletions

View file

@ -1,125 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.utilities.anttasks;
import java.io.File;
import java.io.FileFilter;
import java.util.Iterator;
import java.util.List;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.DataType;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileResource;
/**
* Include all files that are in the primary directory, but do not have matching
* files in the blocking directory.
*/
public abstract class AbstractDirResourceCollection extends DataType implements
ResourceCollection {
protected List<FileResource> files = null;
protected File primaryDir;
@Override
public boolean isFilesystemOnly() {
return true;
}
/**
* Insure that the list has been filled and return an iterator to the list.
*/
@Override
public Iterator<? extends Resource> iterator() {
fillFilesList();
return files.iterator();
}
/**
* Insure that the list has been filled and return the size of the list.
*/
@Override
public int size() {
fillFilesList();
return files.size();
}
public void setPrimary(File primaryDir) {
this.primaryDir = primaryDir;
}
protected abstract void fillFilesList();
/**
* The directory path must be provided, and unless the optional flag is set,
* must point to an existing, readable directory.
*/
protected void confirmValidDirectory(File dir, String label,
boolean optional) {
if (dir == null) {
throw new BuildException(label + " directory not specified.");
}
if (!dir.exists()) {
if (optional) {
return;
} else {
throw new BuildException(label + " directory '" + dir.getPath()
+ "' does not exist.");
}
}
if (!dir.isDirectory()) {
throw new BuildException(label + " directory '" + dir.getPath()
+ "' is not a directory.");
}
if (!dir.canRead()) {
throw new BuildException(label + " directory '" + dir.getPath()
+ "' is not readable.");
}
}
protected void includeAllFiles(File primary) {
for (File file : primary.listFiles(new NonDirectoryFilter())) {
files.add(buildResource(file));
}
for (File primarySubDir : primary.listFiles(new DirectoryFilter())) {
includeAllFiles(primarySubDir);
}
}
/**
* All file resources are based on the original primary directory.
*/
protected FileResource buildResource(File file) {
String primaryBasePath = primaryDir.getAbsolutePath();
String filePath = file.getAbsolutePath();
if (!filePath.startsWith(primaryBasePath)) {
throw new IllegalStateException("File is not a descendant "
+ "of the primary directory: file='" + file
+ "', primary='" + primaryDir + "'");
}
String pathPart = filePath.substring(primaryBasePath.length());
if (pathPart.startsWith(File.separator)) {
pathPart = pathPart.substring(1);
}
// System.out.println("Resource: b='" + primaryDir + "', name='" +
// pathPart + "'");
return new FileResource(primaryDir, pathPart);
}
public class DirectoryFilter implements FileFilter {
@Override
public boolean accept(File file) {
return file.isDirectory();
}
}
public class NonDirectoryFilter implements FileFilter {
@Override
public boolean accept(File file) {
return !file.isDirectory();
}
}
}

View file

@ -0,0 +1,72 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.utilities.anttasks;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileResource;
/**
* A base class for our custom-made FileSet extensions.
*/
public abstract class AbstractWrappedFileSet implements ResourceCollection {
protected List<FileResource> files;
private Project p;
private File dir;
private FileSet fileSet;
public void setProject(Project p) {
this.p = p;
}
public void setDir(File dir) {
this.dir = dir;
}
@Override
public Object clone() {
throw new BuildException(this.getClass().getSimpleName()
+ " does not support cloning.");
}
@Override
public boolean isFilesystemOnly() {
return true;
}
@Override
public Iterator<? extends Resource> iterator() {
fillFileList();
return files.iterator();
}
@Override
public int size() {
fillFileList();
return files.size();
}
protected abstract void fillFileList();
protected FileSet getInternalFileSet() {
if (fileSet != null) {
return fileSet;
}
fileSet = new FileSet();
fileSet.setProject(p);
fileSet.setDir(dir);
return fileSet;
}
}

View file

@ -0,0 +1,57 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.utilities.anttasks;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.resources.FileResource;
/**
* TODO
*/
public class DirDifferenceFileSet extends AbstractWrappedFileSet {
private Path blockingPath;
@SuppressWarnings("hiding")
public void addConfiguredPath(Path blockingPath) {
this.blockingPath = blockingPath;
}
@Override
protected void fillFileList() {
if (files != null) {
return;
}
FileSet fs = getInternalFileSet();
@SuppressWarnings("unchecked")
Iterator<FileResource> iter = fs.iterator();
files = new ArrayList<FileResource>();
while (iter.hasNext()) {
FileResource fr = iter.next();
if (!isBlocked(fr)) {
files.add(fr);
}
}
}
/**
* Check to see whether this same file exists in any of the blocking
* directories.
*/
private boolean isBlocked(FileResource fr) {
for (String blockingDir : blockingPath.list()) {
File f = new File(blockingDir + File.separator + fr.getName());
if (f.exists()) {
return true;
}
}
return false;
}
}

View file

@ -1,92 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.utilities.anttasks;
import java.io.File;
import java.util.ArrayList;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileResource;
/**
* Include all files that are in the primary directory, but do not have matching
* files in the blocking directory.
*/
public class DirDifferenceResourceCollection extends
AbstractDirResourceCollection implements ResourceCollection {
private File blockingDir;
private boolean blockingOptional;
public void setBlocking(File blockingDir) {
this.blockingDir = blockingDir;
}
public void setBlockingOptional(boolean blockingOptional) {
this.blockingOptional = blockingOptional;
}
/**
* If the list hasn't already been filled, fill it with all files in the
* primary directory that are not blocked by files with the same path under
* the blocking directory.
*/
@Override
protected void fillFilesList() {
if (files != null) {
return;
}
confirmValidDirectory(primaryDir, "Primary", false);
confirmValidDirectory(blockingDir, "Blocking", blockingOptional);
files = new ArrayList<FileResource>();
includeUnblockedFiles(primaryDir, blockingDir);
}
/**
* Include any file from the primary directory that does not match a file in
* the blocking directory.
*
* Include all files from any subdirectory that has no matching subdirectory
* in the blocking directory.
*
* Include all unblocked files from any subdirectory that has a matching
* subdirectory in the blocking directory.
*
* NOTE: if a file is matched by a subdirectory, the file is blocked. If a
* subdirectory is matched by a file, an exception is thrown.
*/
private void includeUnblockedFiles(File primary, File blocking) {
for (File file : primary.listFiles(new NonDirectoryFilter())) {
if (!isBlocked(file, blocking)) {
files.add(buildResource(file));
}
}
for (File primarySubDir : primary.listFiles(new DirectoryFilter())) {
File blockingSubDir = findMatchingDir(primarySubDir, blocking);
if (blockingSubDir == null) {
includeAllFiles(primarySubDir);
} else {
includeUnblockedFiles(primarySubDir, blockingSubDir);
}
}
}
private boolean isBlocked(File file, File blocking) {
return new File(blocking, file.getName()).exists();
}
private File findMatchingDir(File primary, File blockingParent) {
File dir = new File(blockingParent, primary.getName());
if (!dir.exists()) {
return null;
}
if (!dir.isDirectory()) {
throw new BuildException("Directory '" + primary
+ "' is blocked by a non-directory '" + dir.getPath() + "'");
}
return dir;
}
}

View file

@ -1,35 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.utilities.anttasks;
import java.util.ArrayList;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileResource;
/**
* If the primary directory exists, include all files that are descendent from
* it. Otherwise, don't complain but act as a collection of zero files.
*/
public class OptionalDirResourceCollection extends
AbstractDirResourceCollection implements ResourceCollection {
/**
* If the list hasn't already been filled, fill it with all files in the
* primary directory that are not blocked by files with the same path under
* the blocking directory.
*/
@Override
protected void fillFilesList() {
if (files != null) {
return;
}
files = new ArrayList<FileResource>();
confirmValidDirectory(primaryDir, "The", true);
if (primaryDir.exists()) {
includeAllFiles(primaryDir);
}
}
}

View file

@ -40,10 +40,7 @@
custom Ant types custom Ant types
- - - - - - - - - - - - - - - - - --> - - - - - - - - - - - - - - - - - -->
<typedef name="dirDifference" <typedef name="dirDifference"
classname="edu.cornell.mannlib.vitro.utilities.anttasks.DirDifferenceResourceCollection" classname="edu.cornell.mannlib.vitro.utilities.anttasks.DirDifferenceFileSet"
classpathref="anttasks.classpath" />
<typedef name="optionalDir"
classname="edu.cornell.mannlib.vitro.utilities.anttasks.OptionalDirResourceCollection"
classpathref="anttasks.classpath" /> classpathref="anttasks.classpath" />
<!-- - - - - - - - - - - - - - - - - - <!-- - - - - - - - - - - - - - - - - -
@ -55,55 +52,56 @@
<mkdir dir="${appbase.dir}/src" /> <mkdir dir="${appbase.dir}/src" />
<mkdir dir="${appbase.dir}/test" /> <mkdir dir="${appbase.dir}/test" />
<copy todir="${appbase.dir}/web"> <copy todir="${appbase.dir}/web" includeemptydirs="true">
<dirDifference primary="${inner.basedir}/web" blocking="${product.modifications.dir}" /> <dirDifference dir="${inner.basedir}/web">
<path>
<pathelement location="${product.modifications.dir}" />
</path>
</dirDifference>
</copy> </copy>
<copy todir="${appbase.dir}/web"> <copy todir="${appbase.dir}/web" includeemptydirs="true">
<fileset dir="${product.modifications.dir}" /> <fileset dir="${product.modifications.dir}" />
</copy> </copy>
<copy todir="${appbase.dir}/config"> <copy todir="${appbase.dir}/config" includeemptydirs="true">
<fileset dir="${inner.basedir}/config" /> <fileset dir="${inner.basedir}/config" />
</copy> </copy>
<copy todir="${appbase.dir}/src"> <copy todir="${appbase.dir}/src" includeemptydirs="true">
<dirDifference primary="${inner.basedir}/src" <dirDifference dir="${inner.basedir}/src">
blocking="./src" <path>
blockingOptional="true" /> <pathelement location="./src" />
</path>
</dirDifference>
</copy> </copy>
<copy todir="${appbase.dir}/src"> <copy todir="${appbase.dir}/src" includeemptydirs="true">
<optionalDir primary="./src" /> <fileset dir="./src" erroronmissingdir="false" />
</copy> </copy>
<copy todir="${appbase.dir}/lib"> <copy todir="${appbase.dir}/lib" includeemptydirs="true">
<dirDifference primary="${inner.basedir}/lib" <dirDifference dir="${inner.basedir}/lib">
blocking="./lib" <path>
blockingOptional="true" /> <pathelement location="./lib" />
</path>
</dirDifference>
</copy> </copy>
<copy todir="${appbase.dir}/lib"> <copy todir="${appbase.dir}/lib" includeemptydirs="true">
<optionalDir primary="./lib" /> <fileset dir="./lib" erroronmissingdir="false" />
</copy> </copy>
<copy todir="${appbase.dir}/test"> <copy todir="${appbase.dir}/test" includeemptydirs="true">
<dirDifference primary="${inner.basedir}/test" <dirDifference dir="${inner.basedir}/test">
blocking="./test" <path>
blockingOptional="true" /> <pathelement location="./test" />
</path>
</dirDifference>
</copy> </copy>
<copy todir="${appbase.dir}/test"> <copy todir="${appbase.dir}/test" includeemptydirs="true">
<optionalDir primary="./test" /> <fileset dir="./test" />
</copy> </copy>
<copy todir="${appbase.dir}/test"> <copy todir="${appbase.dir}/themes" includeemptydirs="true">
<dirDifference primary="${inner.basedir}/test" <fileset dir="./themes" erroronmissingdir="false" />
blocking="./test"
blockingOptional="true" />
</copy>
<copy todir="${appbase.dir}/test">
<optionalDir primary="./test" />
</copy>
<copy todir="${appbase.dir}/themes">
<optionalDir primary="./themes" />
</copy> </copy>
<copy tofile="${appbase.dir}/context.xml" file="${inner.basedir}/context.xml" /> <copy tofile="${appbase.dir}/context.xml" file="${inner.basedir}/context.xml" />