blob: ddab1379920b8647676f77e9565c2ce60491694c [file] [log] [blame]
/*
* 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
* @version $Revision$ $Date$
* @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) {
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);
}
}
}