Java tutorial
/******************************************************************************* * (c) Copyright 2017 EntIT Software LLC, a Micro Focus company * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to * whom the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. ******************************************************************************/ package com.fortify.processrunner.processor; import java.util.Collection; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.fortify.processrunner.cli.CLIOptionDefinition; import com.fortify.processrunner.cli.CLIOptionDefinitions; import com.fortify.processrunner.cli.ICLIOptionDefinitionProvider; import com.fortify.processrunner.context.Context; /** * <p>This abstract {@link IProcessor} implementation allows subclasses * to implement only specific processing phases by overriding the * {@link #preProcess(Context)}, {@link #process(Context)} and/or * {@link #postProcess(Context)} methods respectively. A default * implementation for each of these methods is provided that does * nothing.</p> * * <p>Advantages of extending this class instead of implementing the * {@link IProcessor} interface directly:</p> * <ul> * <li>No need to manually determine the current processing phase</li> * <li>Easy to provide functionality only for relevant processing phases</li> * <li>Provides detailed logging</li> * <li>Provides diagnostic {@link #toString()} method</li> * </ul> * * @author Ruud Senden */ public abstract class AbstractProcessor implements IProcessor { private static final Log LOG = LogFactory.getLog(AbstractProcessor.class); /** * Add {@link CLIOptionDefinition} instances to the provided * {@link CLIOptionDefinition} {@link Collection} that describe * the context properties supported/required by the current * {@link ICLIOptionDefinitionProvider} implementation. By * default, this method does not add any context properties. */ public void addCLIOptionDefinitions(CLIOptionDefinitions cliOptionDefinitions) { } /** * Process the given {@link Phase} with the given {@link Context}. * This will log the current {@link Phase}, {@link IProcessor} and * {@link Context} at trace level on entry and exit, and depending * on the given {@link Phase} invoke either the * {@link #preProcess(Context)}, {@link #process(Context)} * or {@link #postProcess(Context)} method (via the private * {@link #_process(Phase, Context)} method). */ public final boolean process(Phase phase, Context context) { if (LOG.isTraceEnabled()) { LOG.trace("[Process][ENTER] Phase: " + phase + "\nProcessor: " + this + "\nContext: " + context); } boolean result = _process(phase, context); if (LOG.isTraceEnabled()) { LOG.trace("[Process][EXIT] Phase: " + phase + "\nProcessor: " + this + "\nContext: " + context + "\nResult: " + result); } return result; } /** * Depending on the given {@link Phase}, this method will * invoke either the {@link #preProcess(Context)}, * {@link #process(Context)} or {@link #postProcess(Context)} * method. * @param phase * @param context * @return */ private boolean _process(Phase phase, Context context) { switch (phase) { case PRE_PROCESS: return preProcess(context); case PROCESS: return process(context); case POST_PROCESS: return postProcess(context); } throw new RuntimeException("Unsupported phase: " + phase); } /** * Pre-process the given {@link Context}. By default this * method does nothing and simply returns true. * @param context * @return */ protected boolean preProcess(Context context) { return true; } /** * Process the given {@link Context}. By default this * method does nothing and simply returns true. * @param context * @return */ protected boolean process(Context context) { return true; } /** * Post-process the given {@link Context}. By default this * method does nothing and simply returns true. * @param context * @return */ protected boolean postProcess(Context context) { return true; } /** * This {@link #toString()} implementation uses * {@link ReflectionToStringBuilder} to generate a string * representation of this {@link IProcessor} implementation * showing all instance field values for diagnostic * information. */ @Override public String toString() { return new ReflectionToStringBuilder(this).toString(); } }