/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.component.workflow.execution.api; import java.util.regex.Pattern; import de.rcenvironment.core.component.execution.api.ConsoleRow; import de.rcenvironment.core.component.execution.api.ConsoleRow.Type; /** * Acceptance filter for {@link ConsoleRow}s. Use {@link #accept(ConsoleRow)} to apply the filter criteria. This class is mutable; use the * {@link #clone()} method to create independent copies. * * @author Robert Mischke */ public class ConsoleRowFilter implements Cloneable { // workflow filter value; null disables filtering private String workflow; // component filter value; null disables filtering private String component; // include workflow events of type "component finish"? private boolean includeLifecycleEvents; // include "meta info" type rows? private boolean includeComponentLog; // include "stdout" type rows? private boolean includeStdout; // include "stderr" type rows? private boolean includeStderr; // regular expression representing the text filter; null disables filtering private Pattern searchTermPattern; /** * Constructs a default filter that accepts all row types and leaves all other filter values at "null". */ public ConsoleRowFilter() { includeLifecycleEvents = true; includeComponentLog = true; includeStderr = true; includeStdout = true; } /** * Set the workflow filter value; null disables filtering. * * @param workflow The workflow to set. */ public void setWorkflow(String workflow) { this.workflow = workflow; } /** * Set the component filter value; null disables filtering. * * @param component The component to set. */ public void setComponent(String component) { this.component = component; } /** * Set whether "meta info" type lines should be included. * * @param includeMeta The includeMeta to set. */ public void setIncludeMetaInfo(boolean includeMeta) { this.includeComponentLog = includeMeta; } /** * Set whether "life cycle" type lines should be included. * * @param includeLifecycle The includeLifecycle to set. */ public void setIncludeLifecylceEvents(boolean includeLifecycle) { this.includeLifecycleEvents = includeLifecycle; } /** * Set whether "stdout" type lines should be included. * * @param includeStdout The includeStdout to set. */ public void setIncludeStdout(boolean includeStdout) { this.includeStdout = includeStdout; } /** * Set whether "stderr" type lines should be included. * * @param includeStderr The includeStderr to set. */ public void setIncludeStderr(boolean includeStderr) { this.includeStderr = includeStderr; } /** * Set the search term filter; null or an empty string disables filtering. * * @param searchTerm The searchTerm to set. */ public void setSearchTerm(String searchTerm) { if (searchTerm == null || searchTerm.length() == 0) { searchTermPattern = null; return; } // escape all regexp-relevant characters searchTerm = searchTerm.replaceAll("(\\(|\\)|\\[|\\]|\\.|\\*|\\\\|\\^|\\$|\\||\\?|\\+|\\{|\\})", "\\\\$1"); // compile the sanitized string to a case-insensitive regexp searchTermPattern = Pattern.compile(searchTerm, Pattern.CASE_INSENSITIVE); } /** * @param row the {@link ConsoleRow} to decide on * @return true if the {@link ConsoleRow} matches this filter */ public boolean accept(ConsoleRow row) { // Note that this method is slightly awkward due to the Checkstyle rule of max. 3 returns. boolean accept; // check type switch (row.getType()) { case TOOL_OUT: accept = includeStdout; break; case TOOL_ERROR: accept = includeStderr; break; case COMPONENT_INFO: case COMPONENT_WARN: case COMPONENT_ERROR: case WORKFLOW_ERROR: accept = includeComponentLog; break; case LIFE_CYCLE_EVENT: // TODO not an elegant solution; improve? - misc_ro if (row.getPayload().startsWith(ConsoleRow.WorkflowLifecyleEventType.NEW_STATE.name())) { return false; } else if (row.getPayload().startsWith(ConsoleRow.WorkflowLifecyleEventType.COMPONENT_TERMINATED.name())) { accept = includeLifecycleEvents; } else { accept = false; } break; default: accept = false; } // check workflow if (accept && workflow != null && !workflow.equals(row.getWorkflowName())) { // workflow filter is set but did not match accept = false; } if (row.getType() == Type.WORKFLOW_ERROR) { if (accept && (component != null && !component.isEmpty())) { accept = false; } } else { // check component if (accept && component != null && !component.equals(row.getComponentName())) { // component filter is set but did not match accept = false; } } // check search pattern if set if (accept && searchTermPattern != null) { if (!searchTermPattern.matcher(row.getPayload()).find()) { // does not contain search term accept = false; } } return accept; } @Override public ConsoleRowFilter clone() { ConsoleRowFilter clone = new ConsoleRowFilter(); clone.component = component; clone.workflow = workflow; clone.includeComponentLog = includeComponentLog; clone.includeLifecycleEvents = includeLifecycleEvents; clone.includeStderr = includeStderr; clone.includeStdout = includeStdout; // Pattern is immutable, so this is safe clone.searchTermPattern = searchTermPattern; return clone; } }