001package org.unix4j.unix.xargs;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.List;
006
007import org.unix4j.variable.Arg;
008import org.unix4j.variable.VariableResolver;
009
010class DefaultItemStorage implements ItemStorage, VariableResolver {
011        
012        private final XargsLineProcessor processor;
013//      private final VariableContext variables;
014        
015        private final long maxLines;
016        private final int maxArgs;
017        private final boolean isNoRunIfEmpty;
018
019        private int lineCount;
020        private final List<String> items = new ArrayList<String>();
021        private int runCountForLine = 0;
022        private int runCountOverall = 0;
023        
024        public DefaultItemStorage(XargsLineProcessor processor) {
025                this.processor = processor;
026                final XargsArguments args = processor.getArguments();
027                this.maxLines = args.isMaxLinesSet() ? args.getMaxLines() : 1; 
028                this.maxArgs = args.isMaxArgsSet() ? args.getMaxArgs() : Integer.MAX_VALUE;
029                this.isNoRunIfEmpty = args.isNoRunIfEmpty();
030        }
031
032        @Override
033        public void storeItem(String item) {
034                items.add(item);
035                if (items.size() >= maxArgs) {
036                        invokeCommandAndClearAllItems();
037                }
038        }
039
040        @Override
041        public void incrementLineCount() {
042                lineCount++;
043                if ((lineCount % maxLines) == 0 && (runCountForLine == 0 || !items.isEmpty())) {
044                        invokeCommandAndClearAllItems();
045                        runCountForLine = 0;
046                }
047        }
048        
049        protected void flush() {
050                if ((lineCount % maxLines) != 0 && (runCountForLine == 0 || !items.isEmpty())) {
051                        invokeCommandAndClearAllItems();
052                }
053                if (runCountOverall == 0 && !isNoRunIfEmpty) {
054                        invokeCommandAndClearAllItems();
055                }
056                lineCount = 0;
057                runCountForLine = 0;
058                runCountOverall = 0;
059        }
060        
061        private void invokeCommandAndClearAllItems() {
062                processor.invoke();
063                runCountForLine++;
064                runCountOverall++;
065                items.clear();
066        }
067        
068        @Override
069        public Object getValue(String name) {
070                //(a) is variable a reference to all items?
071                if (Arg.$all.equals(name)) {
072                        return Collections.unmodifiableList(items);
073                }
074                //(b) is variable a reference to one specific item?
075                final int index = Arg.argIndex(name);
076                if (index >= 0) {
077                        return index < items.size() ? items.get(index) : null;
078                }
079                //(c) is variable a reference to all items from a given index?
080                final int from = Arg.argsFromIndex(name);
081                if (from >= 0) {
082                        if (from < items.size()) {
083                                return Collections.unmodifiableList(from == 0 ? items : items.subList(from, items.size()));
084                        }
085                        return Collections.EMPTY_LIST;
086                }
087                //no, not a variable that we know
088                return null;
089        }
090        
091}