001    /*
002     * Copyright 1999-2001,2004 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */ 
016    
017    package org.apache.commons.workflow.io;
018    
019    import java.io.BufferedInputStream;
020    import java.io.FileInputStream;
021    import java.io.InputStreamReader;
022    import java.io.IOException;
023    import org.apache.commons.workflow.Context;
024    import org.apache.commons.workflow.StepException;
025    import org.apache.commons.workflow.base.BaseStep;
026    
027    
028    /**
029     * <p>Read the contents of the specified file from the filesystem, and
030     * push the contents as a String object onto the evaluation stack.</p>
031     *
032     * <p>Supported Attributes:</p>
033     * <ul>
034     * <li><strong>encoding</strong> - Character encoding in which to interpret
035     *     the characters in the specified file, or omitted for the platform
036     *     default encoding.</li>
037     * <li><strong>file</strong> - Relative or absolute operating system pathname
038     *     whose contents are to be read.</li>
039     * </ul>
040     *
041     * <strong>DESIGN QUESTION - What about binary content?</strong>
042     *
043     * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
044     * @author Craig R. McClanahan
045     */
046    
047    public class ReadStep extends BaseStep {
048    
049    
050        // ----------------------------------------------------------= Constructors
051    
052    
053        /**
054         * Construct a default instance of this Step.
055         */
056        public ReadStep() {
057    
058            super();
059    
060        }
061    
062    
063        /**
064         * Construct an instance of this Step with the specified identifier.
065         *
066         * @param id Step identifier
067         */
068        public ReadStep(String id) {
069    
070            super();
071            setId(id);
072    
073        }
074    
075    
076        /**
077         * Construct a fully configured instance of this Step.
078         *
079         * @param id Step identifier
080         * @param encoding Character encoding to use
081         * @param file Relative or absolute pathname
082         */
083        public ReadStep(String id, String encoding, String file) {
084    
085            super();
086            setId(id);
087            setEncoding(encoding);
088            setFile(file);
089    
090        }
091    
092    
093        // ------------------------------------------------------------- Properties
094    
095    
096        /**
097         * The character encoding used to interpret the contents of this file.
098         */
099        protected String encoding = null;
100    
101        public String getEncoding() {
102            return (this.encoding);
103        }
104    
105        public void setEncoding(String encoding) {
106            this.encoding = encoding;
107        }
108    
109    
110        /**
111         * The relative or absolute pathname of the operating system file.
112         */
113        protected String file = null;
114    
115        public String getFile() {
116            return (this.file);
117        }
118    
119        public void setFile(String file) {
120            this.file = file;
121        }
122    
123    
124        // --------------------------------------------------------- Public Methods
125    
126    
127        /**
128         * Perform the executable actions related to this Step, in the context of
129         * the specified Context.
130         *
131         * @param context The Context that is tracking our execution state
132         *
133         * @exception StepException if a processing error has occurred
134         */
135        public void execute(Context context) throws StepException {
136    
137            // Define variables we will need later
138            FileInputStream fis = null;
139            BufferedInputStream bis = null;
140            InputStreamReader isr = null;
141            StringBuffer sb = new StringBuffer();
142            StepException se = null;
143    
144            try {
145    
146                // Construct a suitable InputStreamReader
147                fis = new FileInputStream(file);
148                bis = new BufferedInputStream(fis, 2048);
149                if (encoding == null)
150                    isr = new InputStreamReader(bis);
151                else
152                    isr = new InputStreamReader(bis, encoding);
153    
154                // Copy all characters from this file
155                while (true) {
156                    int ch = isr.read();
157                    if (ch < 0)
158                        break;
159                    sb.append((char) ch);
160                }
161    
162                // Close the input file
163                isr.close();
164                isr = null;
165                bis = null;
166                fis = null;
167    
168            } catch (IOException e) {
169    
170                se = new StepException("IOException processing '" + file + "'",
171                                       e, this);
172    
173            } finally {
174    
175                if (isr != null) {
176                    try {
177                        isr.close();
178                    } catch (Throwable t) {
179                        ;
180                    }
181                } else if (bis != null) {
182                    try {
183                        bis.close();
184                    } catch (Throwable t) {
185                        ;
186                    }
187                } else if (fis != null) {
188                    try {
189                        fis.close();
190                    } catch (Throwable t) {
191                        ;
192                    }
193                }
194    
195            }
196    
197            // Push results or throw exception as appropriate
198            if (se != null)
199                throw se;
200            context.push(sb.toString());
201    
202        }
203    
204    
205    }