java/ch/wlkl/wsh/Dir.java

package ch.wlkl.wsh;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * The {@link ch.wlkl.wsh.Read} interface to a filesystem directory.
 * 
 * @author walter keller
 *
 */
public class Dir extends Top implements Read<String> {
    
    final static Option resetAA = new Option("d", "l");
    final static Option openAA = new Option("", "rd", "l");
    private String [] args = null;
    private int argIx = -9;
    private int lev = -9;
    private boolean dirs = false;
    private final ArrayList<File []> files = new ArrayList<File []> ();
    private final ArrayList<Integer> indexes = new ArrayList<Integer> ();

    public Dir(String... a) {
        reset(a);
    }
    
    public void reset(Object... a) {
        String [] s = new String[a.length];
        for (int ix = 0; ix < a.length; ix++)
            s[ix] = (String) a[ix];
        reset(s);
    } 
    
    public void reset(String... a) {
        close();
        args = a;
    }
    public void open(String a) {
        String [] ana = new String [2];
        close();
        if (openAA.analyze(a, ana))
            analyzeOpt(ana);
        argIx = -1;
        next();
    }

    private void analyzeOpt(String [] ana) {
        if (ana[0].indexOf('d') >= 0)
            dirs = true;
        if (ana[0].indexOf('l') >= 0)
            lev = Option.intOpt(ana);                
        
    }
    
    private boolean next() {
        String [] ana = new String [2];
        if (! files.isEmpty())
            fail("next but files not empty");
        if (args == null || argIx == -9) 
            return false;
        while (++argIx < args.length) {
            if (resetAA.analyze(args[argIx], ana)) {
                analyzeOpt(ana);
            } else if ( ana[1] != null) {
                File [] f0 = {new File(ana[1])};
                files.add(f0);
                indexes.add(-1);
                return true;
            } 
        }
        return false;
    }

    public void close() {
        argIx = -99;
        lev = -1;
        dirs = false;
        files.clear();
        indexes.clear();
    }
    
    public String read() {
        while (true) {
            int top = files.size() - 1;
            if (top < 0) {
                if (! next())
                    return null;
            } else {
                int ix = indexes.get(top) + 1;
                if (ix >= files.get(top).length) {
                    files.remove(top);
                    indexes.remove(top);
                } else {
                    File dir = files.get(top)[ix];
                    indexes.set(top, ix);
                    if (top != lev && dir.isDirectory()) {
                                            /* as of 2017, on linux mint, listFile does not sort files, as specified */
                                                File [] fls = dir.listFiles();
                                                Arrays.sort(fls);
                        files.add(fls);
                        indexes.add(-1);                        
                    }
                    if (dirs || dir.isFile())
                        return dir.getPath();
                }
            }            
        }
    }
}