/* * Copyright 2006-2012 The Scriptella Project Team. * * 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 scriptella.driver.text; import scriptella.core.EtlCancelledException; import scriptella.expression.PropertiesSubstitutor; import scriptella.spi.AbstractConnection; import scriptella.spi.ParametersCallback; import scriptella.util.IOUtils; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Closeable; import java.io.Flushable; import java.io.IOException; import java.io.Reader; import java.io.Writer; /** * Writes a text content to the output and performs properties expansion. * <p>This class is a simplified template engine similar to Velocity, * but of course less powerful. Nevertheless this executor * is generally faster than external template engines and does not require any additional libraries. * <p><u>Example:</u></p> * <b>Script:</b> * <code><pre> * $rownum;$name;$surname;${email.trim().replaceAll('@','_at_')} * </pre></code> * <b>Parameters:</b> * <table border=1> * <tr> * <th>rownum</th> * <th>name</th> * <th>surname</th> * <th>email</th> * </tr> * <tr> * <td>1</td> * <td>John</td> * <td>G</td> * <td> john@nosuchhost.com</td> * </tr> * </table> * <b>Result:</b> * <code><pre> * 1;John;G;john_at_nosuchhost.com * </pre></code> * * @author Fyodor Kupolov * @version 1.0 * @see PropertiesSubstitutor */ public class TextScriptExecutor implements Closeable, Flushable { private BufferedWriter out; private PropertiesSubstitutor ps; private TextConnectionParameters textParams; /** * Creates an executor. * * @param out writer for output. * @param textParams text connection parameters. */ public TextScriptExecutor(Writer out, TextConnectionParameters textParams) { ps = new PropertiesSubstitutor(); this.out = IOUtils.asBuffered(out); this.textParams = textParams; } /** * Parses a script from read, expands properties and produces the output. * * @param reader script content. * @param pc parameters for substitution. * @param counter statements counter. */ public void execute(Reader reader, ParametersCallback pc, AbstractConnection.StatementCounter counter) { ps.setParameters(textParams.getPropertyFormatter().format(pc)); BufferedReader r = IOUtils.asBuffered(reader); final boolean trimLines = textParams.isTrimLines(); try { for (String line; (line = r.readLine()) != null;) { EtlCancelledException.checkEtlCancelled(); if (trimLines) { line = line.trim(); } //If trimming is disabled (keeping format) or if line is not empty if (!trimLines || line.length() > 0) { try { out.write(ps.substitute(line)); out.write(textParams.getEol()); counter.statements++; } catch (IOException e) { throw new TextProviderException("Failed writing to a text file", e); } } } } catch (IOException e) { throw new TextProviderException("Failed reading a script file", e); } } public void flush() throws IOException { out.flush(); } public void close() throws IOException { IOUtils.closeSilently(out); out = null; ps = null; } }