/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.catalina.ant; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.taskdefs.Redirector; import org.apache.tools.ant.types.RedirectorElement; /** * Abstract base class to add output redirection support for Catalina * Ant tasks. These tasks require Ant 1.5 or later. * <br> * <strong>WARNING:</strong> due to depends chain, Ant could call a Task * more than once and this can affect the output redirection when configured. * If you are collecting the output in a property, it will collect the output * of only the first run, since Ant properties are immutable and once created * they cannot be changed. * <br> * If you are collecting output in a file the file will be overwritten with the * output of the last run, unless you set append="true", in which case each run * will append it's output to the file. * * * @author Gabriele Garuglieri * * @since 5.5 */ public abstract class BaseRedirectorHelperTask extends Task { // ------------------------------------------------------------- Properties /** Redirector helper */ protected Redirector redirector = new Redirector(this); //protected Redirector redirector = null; /** Redirector element for this task */ protected RedirectorElement redirectorElement = null; /** The stream for info output */ protected OutputStream redirectOutStream = null; /** The stream for error output */ protected OutputStream redirectErrStream = null; /** The print stream for info output */ PrintStream redirectOutPrintStream = null; /** The print stream for error output */ PrintStream redirectErrPrintStream = null; /** * Whether to fail (with a BuildException) if * ManagerServlet returns an error. The default behavior is * to do so. * <b> * This flag does not control parameters checking. If the task is called * with wrong or invalid parameters, it will throw BuildException * independently from the setting of this flag. */ protected boolean failOnError = true; /** * <code>true</code> true when output redirection is requested for this task . * Default is to log on Ant log. */ protected boolean redirectOutput = false; /** * will be set to <code>true</code> when the configuration of the Redirector is * complete. */ protected boolean redirectorConfigured = false; /** * Flag which indicates that, if redirected, output should also be * always sent to the log. Default is that otput is sent only to * redirected streams. */ protected boolean alwaysLog = false; /** * Whether to fail (with a BuildException) if * ManagerServlet returns an error. The default behavior is * to do so. */ public void setFailonerror(boolean fail) { failOnError = fail; } /** * Returns the value of the failOnError * property. */ public boolean isFailOnError() { return failOnError; } /** * File the output of the task is redirected to. * * @param out name of the output file */ public void setOutput(File out) { redirector.setOutput(out); redirectOutput = true; } /** * File the error output of the task is redirected to. * * @param error name of the error file * */ public void setError(File error) { redirector.setError(error); redirectOutput = true; } /** * Controls whether error output is logged. This is only useful * when output is being redirected and error output is desired in the * Ant log * * @param logError if true the standard error is sent to the Ant log system * and not sent to output stream. */ public void setLogError(boolean logError) { redirector.setLogError(logError); redirectOutput = true; } /** * Property name whose value should be set to the output of * the task. * * @param outputProperty property name * */ public void setOutputproperty(String outputProperty) { redirector.setOutputProperty(outputProperty); redirectOutput = true; } /** * Property name whose value should be set to the error of * the task.. * * @param errorProperty property name * */ public void setErrorProperty(String errorProperty) { redirector.setErrorProperty(errorProperty); redirectOutput = true; } /** * If true, append output to existing file. * * @param append if true, append output to existing file * */ public void setAppend(boolean append) { redirector.setAppend(append); redirectOutput = true; } /** * If true, (error and non-error) output will be redirected * as specified while being sent to Ant's logging mechanism as if no * redirection had taken place. Defaults to false. * <br> * Actually handled internally, with Ant 1.6.3 it will be handled by * the <code>Redirector</code> itself. * @param alwaysLog <code>boolean</code> */ public void setAlwaysLog(boolean alwaysLog) { this.alwaysLog = alwaysLog; //redirector.setAlwaysLog(alwaysLog); redirectOutput = true; } /** * Whether output and error files should be created even when empty. * Defaults to true. * @param createEmptyFiles <CODE>boolean</CODE>. */ public void setCreateEmptyFiles(boolean createEmptyFiles) { redirector.setCreateEmptyFiles(createEmptyFiles); redirectOutput = true; } /** * Add a <CODE>RedirectorElement</CODE> to this task. * @param redirectorElement <CODE>RedirectorElement</CODE>. */ public void addConfiguredRedirector(RedirectorElement redirectorElement) { if (this.redirectorElement != null) { throw new BuildException("Cannot have > 1 nested <redirector>s"); } else { this.redirectorElement = redirectorElement; } } /** * Set up properties on the Redirector from RedirectorElement if present. */ private void configureRedirector() { if (redirectorElement != null) { redirectorElement.configure(redirector); redirectOutput = true; } /* * Due to depends chain, Ant could call the Task more than once, * this is to prevent that we attempt to configure uselessly * more than once the Redirector. */ redirectorConfigured = true; } /** * Set up properties on the Redirector and create output streams. */ protected void openRedirector() { if (! redirectorConfigured) { configureRedirector(); } if (redirectOutput) { redirector.createStreams(); redirectOutStream = redirector.getOutputStream(); redirectOutPrintStream = new PrintStream(redirectOutStream); redirectErrStream = redirector.getErrorStream(); redirectErrPrintStream = new PrintStream(redirectErrStream); } } /** * Ask redirector to close all the streams. It is necessary to call this method * before leaving the Task to have the Streams flush their contents. If you are * collecting output in a property, it will be created only if this method is * called, otherwise you'll find it unset. */ protected void closeRedirector() { try { if (redirectOutput && redirectOutPrintStream != null) { redirector.complete(); } } catch (IOException ioe) { log("Error closing redirector: " + ioe.getMessage(), Project.MSG_ERR); } /* * Due to depends chain, Ant could call the Task more than once, * this is to prevent that we attempt to reuse the previuosly * closed Streams. */ redirectOutStream = null; redirectOutPrintStream = null; redirectErrStream = null; redirectErrPrintStream = null; } /** * Handles output with the INFO priority. * * @param output The output to log. Should not be <code>null</code>. */ protected void handleOutput(String output) { if (redirectOutput) { if (redirectOutPrintStream == null) { openRedirector(); } redirectOutPrintStream.println(output); if (alwaysLog) { log(output, Project.MSG_INFO); } } else { log(output, Project.MSG_INFO); } } /** * Handles output with the INFO priority and flushes the stream. * * @param output The output to log. Should not be <code>null</code>. * */ protected void handleFlush(String output) { handleOutput(output); redirectOutPrintStream.flush(); } /** * Handles error output with the ERR priority. * * @param output The error output to log. Should not be <code>null</code>. */ protected void handleErrorOutput(String output) { if (redirectOutput) { if (redirectErrPrintStream == null) { openRedirector(); } redirectErrPrintStream.println(output); if (alwaysLog) { log(output, Project.MSG_ERR); } } else { log(output, Project.MSG_ERR); } } /** * Handles error output with the ERR priority and flushes the stream. * * @param output The error output to log. Should not be <code>null</code>. * */ protected void handleErrorFlush(String output) { handleErrorOutput(output); redirectErrPrintStream.flush(); } /** * Handles output with ERR priority to error stream and all other * pritorities to output stream. * * @param output The output to log. Should not be <code>null</code>. */ protected void handleOutput(String output, int priority) { if (priority == Project.MSG_ERR) { handleErrorOutput(output); } else { handleOutput(output); } } /** * Handles output with ERR priority to error stream and all other * pritorities to output stream, then flushes the stream. * * @param output The output to log. Should not be <code>null</code>. */ protected void handleFlush(String output, int priority) { if (priority == Project.MSG_ERR) { handleErrorFlush(output); } else { handleFlush(output); } } }