/* ************************************************************************
#
# DivConq
#
# http://divconq.com/
#
# Copyright:
# Copyright 2014 eTimeline, LLC. All rights reserved.
#
# License:
# See the license.txt file in the project's top-level directory for details.
#
# Authors:
# * Andy White
#
************************************************************************ */
package divconq.filestore.zip;
public class ArchiveScanner { /* extends RecordStruct implements IFileStoreScanner {
protected ArchiveDriver driver = null;
protected volatile int totalFolders = 0;
protected volatile int totalFiles = 0;
protected volatile int matchedFiles = 0;
public ArchiveScanner() {
this.setType(Hub.instance.getSchema().getType("dciArchiveScanner"));
}
public ArchiveScanner(ArchiveDriver driver) {
this();
this.driver = driver;
}
@Override
public void scan(FuncCallback<RecordStruct> callback) {
// TODO support offset/max and paging
ListStruct res = new ListStruct();
Iterable<Struct> files = this.getItems();
// collect all for now...
if (files != null)
for (Struct file : files)
res.addItem(file);
callback.setResult(
new RecordStruct(
new FieldStruct("Total", res.getSize()),
new FieldStruct("Offset", 0),
new FieldStruct("Matches", res)
)
);
callback.completed();
}
@Override
public IAsyncIterable<Struct> getItemsAsync() {
this.totalFolders = 0;
this.totalFiles = 0;
this.matchedFiles = 0;
if (this.driver == null)
return null;
String cwd = this.driver.getFieldAsString("RootFolder");
Boolean recursive = this.getFieldAsBoolean("Recursive");
ListStruct match = this.getFieldAsList("MatchFiles");
List<String> wildcards = new ArrayList<String>();
if (match != null)
for (Struct s : match.getItems())
wildcards.add(((StringStruct)s).getValue());
return new Matches(cwd, recursive, wildcards);
}
public class Matches implements IAsyncIterable<Struct>, IAsyncIterator<Struct> {
protected ArchiveInputStream zin = null; // TODO how/when does this close?
protected ArchiveEntry next = null;
protected String cwd = null;
protected boolean recursive = false;
protected List<String> wildcards = null;
public Matches(String cwd, boolean recursive, List<String> wildcards) {
this.cwd = cwd;
this.recursive = recursive;
this.wildcards = wildcards;
}
@Override
public IAsyncIterator<Struct> iterator() {
return this;
}
public void init(final OperationCallback callback) {
if (this.zin != null) {
callback.completed();
return;
}
ArchiveScanner.this.driver.archive.getInputStream(new FuncCallback<InputStream>() {
@Override
public void callback() {
Matches.this.zin = new ZipArchiveInputStream(this.getResult()); // TODO not just ZIP
callback.completed();
}
});
}
@Override
public void hasNext(final FuncCallback<Boolean> callback) {
this.init(new OperationCallback() {
@Override
public void callback() {
callback.setResult(false);
try {
Matches.this.next = Matches.this.zin.getNextEntry();
String wd = Matches.this.cwd + "/";
boolean fnd = false;
while (Matches.this.next != null) {
if (Matches.this.next.isDirectory())
ArchiveScanner.this.totalFolders++;
else {
ArchiveScanner.this.totalFiles++;
String ename = Matches.this.next.getName();
// TODO respect recursive flag
if (ename.startsWith(wd)) {
int pos = ename.lastIndexOf('/');
if (pos != -1)
ename = ename.substring(pos + 1);
for (String wc : Matches.this.wildcards)
if (FilenameUtils.wildcardMatch(ename, wc)) {
fnd = true;
ArchiveScanner.this.matchedFiles++;
break;
}
if (fnd)
break;
}
}
Matches.this.next = Matches.this.zin.getNextEntry();
}
if (Matches.this.next == null)
Matches.this.zin.close();
else
callback.setResult(true);
}
catch (IOException x) {
// TODO log
}
callback.completed();
}
});
}
@Override
public void next(final FuncCallback<Struct> callback) {
this.init(new OperationCallback() {
@Override
public void callback() {
callback.setResult(new ArchiveFile(ArchiveScanner.this.driver, Matches.this.next));
callback.completed();
}
});
}
}
@Override
public FuncResult<Struct> getOrAllocateField(String name) {
if ("TotalFolders".equals(name)) {
FuncResult<Struct> res = new FuncResult<Struct>();
res.setResult(new IntegerStruct(this.totalFolders));
return res;
}
if ("TotalFiles".equals(name)) {
FuncResult<Struct> res = new FuncResult<Struct>();
res.setResult(new IntegerStruct(this.totalFiles));
return res;
}
if ("MatchFiles".equals(name)) {
FuncResult<Struct> res = new FuncResult<Struct>();
res.setResult(new IntegerStruct(this.matchedFiles));
return res;
}
return super.getOrAllocateField(name);
}
@Override
protected void doCopy(Struct n) {
super.doCopy(n);
ArchiveScanner nn = (ArchiveScanner)n;
nn.driver = this.driver;
}
@Override
public Struct deepCopy() {
ArchiveScanner cp = new ArchiveScanner();
this.doCopy(cp);
return cp;
}
@Override
public void dispose() {
// TODO support this!!!
super.dispose();
}
@Override
public void operation(StackEntry stack, XElement code) {
super.operation(stack, code);
}
*/
}