@@ -26,8 +26,13 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.Stack;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -61,10 +66,8 @@ public class Resources extends DataType implements AppendableResourceCollection
public static final Iterator<Resource> EMPTY_ITERATOR = Collections.emptyIterator();
private class MyCollection extends AbstractCollection<Resource> {
private Collection<Resource> cached;
private volatile Collection<Resource> cached;
MyCollection() {
}
@Override
public int size() {
return getCache().size();
@@ -74,45 +77,41 @@ public class Resources extends DataType implements AppendableResourceCollection
return getCache().iterator();
}
private synchronized Collection<Resource> getCache() {
Collection<Resource> coll = cached;
if (coll == null) {
coll = new ArrayList<>();
new MyIterator().forEachRemaining(coll::add);
if (cache) {
cached = coll;
}
if (cached == null) {
cached = internalResources().collect(Collectors.toList());
}
return coll ;
return cached;
}
private class MyIterator implements Iterator<Resource> {
private Iterator<ResourceCollection> rci = getNested().iterator();
private Iterator<Resource> ri = null;
}
@Override
public boolean hasNext() {
boolean result = ri != null && ri.hasNext();
while (!result && rci.hasNext()) {
ri = rci.next().iterator();
result = ri.hasNext();
}
return result;
}
@Override
public Resource next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return ri.next();
private class MyIterator implements Iterator<Resource> {
private Iterator<ResourceCollection> rci = getNested().iterator();
private Iterator<Resource> ri;
@Override
public boolean hasNext() {
boolean result = ri != null && ri.hasNext();
while (!result && rci.hasNext()) {
ri = rci.next().iterator();
result = ri.hasNext();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
return result;
}
@Override
public Resource next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return ri.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
private List<ResourceCollection> rc;
private Collection<Resource> coll;
private Optional< Collection<Resource>> cacheC oll = Optional.empty() ;
private volatile boolean cache = false;
/**
@@ -156,7 +155,7 @@ public class Resources extends DataType implements AppendableResourceCollection
}
rc.add(c);
invalidateExistingIterators();
coll = null ;
cacheColl = Optional.empty() ;
setChecked(false);
}
@@ -170,7 +169,7 @@ public class Resources extends DataType implements AppendableResourceCollection
return getRef().iterator();
}
validate();
return new FailFast(this, coll.iterator());
return new FailFast(this, cacheC oll.map(Iterable:: iterator).orElseGet (MyIterator::new ));
}
/**
@@ -183,7 +182,7 @@ public class Resources extends DataType implements AppendableResourceCollection
return getRef().size();
}
validate();
return coll.size();
return cacheC oll.isPresent() ? cacheColl.get(). size() : (int) internalResources().count ();
}
/**
@@ -196,8 +195,7 @@ public class Resources extends DataType implements AppendableResourceCollection
return getRef().isFilesystemOnly();
}
validate();
return getNested().stream()
.allMatch(ResourceCollection::isFilesystemOnly);
return getNested().stream().allMatch(ResourceCollection::isFilesystemOnly);
}
/**
@@ -210,11 +208,8 @@ public class Resources extends DataType implements AppendableResourceCollection
return getRef().toString();
}
validate();
if (coll == null || coll.isEmpty()) {
return "";
}
return coll.stream().map(Object::toString)
.collect(Collectors.joining(File.pathSeparator));
final Stream<?> stream = cache ? cacheColl.get().stream() : getNested().stream();
return stream.map(String::valueOf).collect(Collectors.joining(File.pathSeparator));
}
/**
@@ -227,17 +222,13 @@ public class Resources extends DataType implements AppendableResourceCollection
@Override
protected void dieOnCircularReference(Stack<Object> stk, Project p)
throws BuildException {
if (isChecked()) {
return;
}
if (isReference()) {
super.dieOnCircularReference(stk, p);
} else {
for (ResourceCollection resourceCollection : getNested()) {
if (resourceCollection instanceof DataType) {
pushAndInvokeCircularReferenceCheck((DataType) resourceCollection, stk, p);
}
}
return;
}
if (!isChecked()) {
getNested().stream().filter(DataType.class::isInstance).map(DataType.class::cast)
.forEach(dt -> pushAndInvokeCircularReferenceCheck(dt, stk, p));
setChecked(true);
}
}
@@ -259,10 +250,17 @@ public class Resources extends DataType implements AppendableResourceCollection
private synchronized void validate() {
dieOnCircularReference();
coll = (coll == null) ? new MyCollection() : coll;
if (cache && !cacheColl.isPresent()) {
cacheColl = Optional.of(new MyCollection());
}
}
private synchronized List<ResourceCollection> getNested() {
return rc == null ? Collections.emptyList() : rc;
}
private synchronized Stream<Resource> internalResources() {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(new MyIterator(), Spliterator.NONNULL), false);
}
}