/* * * Copyright 2007-2015 University Of Southern California * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package edu.isi.pegasus.planner.common; import edu.isi.pegasus.common.util.VariableExpander; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; /** * A Reader class that uses BufferedReader to read in from a stream, and * perform variable expansion before returning as part of the read methods * * @author Karan Vahi */ public class VariableExpansionReader extends Reader { private final BufferedReader mReader; /** * the buffer where we read in a line */ private String mBuffer; private int mPosition; private final VariableExpander mVariableExpander; /** * * @param reader * @throws java.io.IOException */ public VariableExpansionReader( Reader reader) throws IOException { mReader = new BufferedReader( reader ); mVariableExpander = new VariableExpander(); setBufferToNextLine(); } /** * Reads characters into a portion of an array. The characters read are * already susbstituted with their variable values. * * This method implements the general contract of the corresponding read * method of the BufferedReader class. As an additional convenience, it * attempts to read as many characters as possible by repeatedly * invoking the readLine method of the underlying BufferedReader and * doing the variable substitution. This iterated read continues until * one of the following conditions becomes true: * * The specified number of characters have been read, The read method of * the underlying reader returns -1, indicating end-of-file. * * If the first read on the underlying stream returns -1 to indicate * end-of-file then this method returns -1. Otherwise this method * returns the number of characters actually read. * * @param cbuf Destination buffer * @param off Offset at which to start storing characters * @param len Maximum number of characters to read * * @return The number of characters read, or -1 if the end of the stream * has been reached. * @throws IOException */ public int read(char[] cbuf, int off, int len) throws IOException { int read = 0; if( mBuffer == null ){ //end of stream reached return -1; } int store = off; while( true ){ int bufferLength = mBuffer.length(); //read characters from the internal buffer to destination buffer while( read < len && ( mPosition < bufferLength ) ){ cbuf[store++] = mBuffer.charAt(mPosition++); read++; } if( mPosition == bufferLength ){ //we have exhausted our current buffer setBufferToNextLine(); } if( read == len || mBuffer == null ){ //break out of outerwhile //we have the number of characters read break; } } /*store = off; for( int i = 0; i < read; i++ ){ System.out.print( cbuf[store++] ); }*/ return read; } @Override public void close() throws IOException { mReader.close(); } private void setBufferToNextLine() throws IOException { mPosition = 0; mBuffer = mReader.readLine(); //System.out.println("Buffer " + mBuffer ); //mCurrentLineNumber = mReader.getLineNumber(); //we don't want expand anything in the comment string //if( mBuffer != null && !mBuffer.startsWith( mCommentPrefix ) ){ mBuffer = mVariableExpander.expand(mBuffer); //System.out.println( mBuffer ); //} //always add \n to ensure consistent semantics for read function //w.r.t Reader class if( mBuffer != null ){ mBuffer = mBuffer + '\n'; } } }