001    /* JAPI - (Yet another (hopefully) useful) Java API
002     *
003     * Copyright (C) 2004-2006 Christian Hujer
004     *
005     * This program is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU General Public License as
007     * published by the Free Software Foundation; either version 2 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful, but
011     * WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     * General Public License for more details.
014     *
015     * You should have received a copy of the GNU General Public License
016     * along with this program; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018     * 02111-1307, USA.
019     */
020    
021    package net.sf.japi.io;
022    
023    import java.io.FileInputStream;
024    import java.io.FileNotFoundException;
025    import java.io.IOException;
026    import java.io.InputStream;
027    import java.io.SequenceInputStream;
028    import java.util.ArrayList;
029    import java.util.Enumeration;
030    import java.util.List;
031    import java.util.NoSuchElementException;
032    import net.sf.japi.util.ThrowableHandler;
033    
034    /** Implementation of {@link Enumeration} for ARGV.
035     * Used by {@link ARGVInputStream} and {@link ARGVReader}.
036     * This class looks as if it could instead be an Iterator, but it is intended for use with {@link SequenceInputStream}.
037     * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a>
038     * @see ARGVInputStream
039     * @see ARGVReader
040     */
041    public class ARGVEnumeration implements Enumeration<InputStream> {
042    
043        /** Command line arguments. */
044        private final String[] args;
045    
046        /** Index. */
047        private int index;
048    
049        /** Current InputStream. */
050        private InputStream currentStream;
051    
052        /** Next InputStream. */
053        private InputStream nextStream;
054    
055        /** Current filename. */
056        private String currentFilename;
057    
058        /** Next filename. */
059        private String nextFilename;
060    
061        /** ThrowableHandlers. */
062        private final List<ThrowableHandler<? super FileNotFoundException>> handlers = new ArrayList<ThrowableHandler<? super FileNotFoundException>>();
063    
064        /** Create an ARGVEnumeration.
065         * @param args Command line arguments or some other String array containing 0 or more file names.
066         */
067        public ARGVEnumeration(final String... args) {
068            this.args = args.clone();
069            if (args.length == 0) {
070                nextStream = System.in;
071            } else {
072                nextStream();
073            }
074        }
075    
076        /** Switch to the next stream. */
077        private void nextStream() {
078            if (currentStream != null) {
079                try {
080                    currentStream.close();
081                } catch (final IOException e) {
082                    /* ignore. */
083                }
084            }
085            currentStream = nextStream;
086            currentFilename = nextFilename;
087            nextStream = null;
088            while (index < args.length && nextStream == null) {
089                try {
090                    nextStream = new FileInputStream(nextFilename = args[index++]);
091                } catch (final FileNotFoundException e) {
092                    log(e);
093                }
094            }
095        }
096    
097        /** Log an exception.
098         * Currently does nothing but tell the registered exception handlers to handle the exception.
099         * @param e Exception to log
100         */
101        protected void log(final FileNotFoundException e) {
102            for (final ThrowableHandler<? super FileNotFoundException> handler : handlers) {
103                handler.handleThrowable(e);
104            }
105        }
106    
107        /** Create an ARGVEnumeration.
108         * @param handler ThrowableHandler to add
109         * @param args Command line arguments or some other String array containing 0 or more file names.
110         */
111        public ARGVEnumeration(final ThrowableHandler<? super FileNotFoundException> handler, final String... args) {
112            addThrowableHandler(handler);
113            this.args = args.clone();
114            if (args.length == 0) {
115                nextStream = System.in;
116            } else {
117                nextStream();
118            }
119        }
120    
121        /** Register an exception handler.
122         * @param handler New ThrowableHandler
123         */
124        public void addThrowableHandler(final ThrowableHandler<? super FileNotFoundException> handler) {
125            handlers.add(handler);
126        }
127    
128        /** Get the name of the current file. */
129        public String getCurrentFilename() {
130            return currentFilename;
131        }
132    
133        /** @see Enumeration */
134        public boolean hasMoreElements() {
135            return nextStream != null;
136        }
137    
138        /** @see Enumeration
139         * Elements returned are InputStreams.
140         */
141        public InputStream nextElement() {
142            if (hasMoreElements()) {
143                nextStream();
144                return currentStream;
145            } else {
146                throw new NoSuchElementException();
147            }
148        }
149    
150        /** Unregister an exception handler.
151         * @param handler ThrowableHandler to be removed
152         */
153        public void removeThrowableHandler(final ThrowableHandler<? super FileNotFoundException> handler) {
154            handlers.remove(handler);
155        }
156    
157    } // class ARGVEnumeration