blob: 1c47afbff043fa2d9fd922ddad6c7d9fdd1915c9 [file] [log] [blame]
package org.apache.maven.plugin.surefire.booterclient.output;
/*
* 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.
*/
import org.apache.maven.surefire.api.booter.ForkedProcessEventType;
import org.apache.maven.surefire.api.event.AbstractConsoleEvent;
import org.apache.maven.surefire.api.event.AbstractStandardStreamEvent;
import org.apache.maven.surefire.api.event.AbstractTestControlEvent;
import org.apache.maven.surefire.api.event.ConsoleErrorEvent;
import org.apache.maven.surefire.api.event.Event;
import org.apache.maven.surefire.api.event.JvmExitErrorEvent;
import org.apache.maven.surefire.api.event.SystemPropertyEvent;
import org.apache.maven.surefire.api.report.ReportEntry;
import org.apache.maven.surefire.api.report.RunMode;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static java.util.Objects.requireNonNull;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_BYE;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_DEBUG;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_INFO;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_WARNING;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_NEXT_TEST;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDERR;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDERR_NEW_LINE;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDOUT;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDOUT_NEW_LINE;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STOP_ON_NEXT_TEST;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TESTSET_COMPLETED;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TESTSET_STARTING;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_ASSUMPTIONFAILURE;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_ERROR;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_FAILED;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_SKIPPED;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_STARTING;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_SUCCEEDED;
/**
* magic number : run mode : opcode [: opcode specific data]*
*
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
* @since 3.0.0-M4
*/
public final class ForkedProcessEventNotifier
{
private volatile ForkedProcessPropertyEventListener propertyEventListener;
private volatile ForkedProcessStackTraceEventListener consoleErrorEventListener;
private volatile ForkedProcessExitErrorListener exitErrorEventListener;
private final ConcurrentMap<ForkedProcessEventType, ForkedProcessReportEventListener<?>> reportEventListeners =
new ConcurrentHashMap<>();
private final ConcurrentMap<ForkedProcessEventType, ForkedProcessStandardOutErrEventListener>
stdOutErrEventListeners = new ConcurrentHashMap<>();
private final ConcurrentMap<ForkedProcessEventType, ForkedProcessStringEventListener> consoleEventListeners =
new ConcurrentHashMap<>();
private final ConcurrentMap<ForkedProcessEventType, ForkedProcessEventListener> controlEventListeners =
new ConcurrentHashMap<>();
public void setSystemPropertiesListener( ForkedProcessPropertyEventListener listener )
{
propertyEventListener = requireNonNull( listener );
}
public <T extends ReportEntry> void setTestSetStartingListener( ForkedProcessReportEventListener<T> listener )
{
reportEventListeners.put( BOOTERCODE_TESTSET_STARTING, requireNonNull( listener ) );
}
public void setTestSetCompletedListener( ForkedProcessReportEventListener<?> listener )
{
reportEventListeners.put( BOOTERCODE_TESTSET_COMPLETED, requireNonNull( listener ) );
}
public void setTestStartingListener( ForkedProcessReportEventListener<?> listener )
{
reportEventListeners.put( BOOTERCODE_TEST_STARTING, requireNonNull( listener ) );
}
public void setTestSucceededListener( ForkedProcessReportEventListener<?> listener )
{
reportEventListeners.put( BOOTERCODE_TEST_SUCCEEDED, requireNonNull( listener ) );
}
public void setTestFailedListener( ForkedProcessReportEventListener<?> listener )
{
reportEventListeners.put( BOOTERCODE_TEST_FAILED, requireNonNull( listener ) );
}
public void setTestSkippedListener( ForkedProcessReportEventListener<?> listener )
{
reportEventListeners.put( BOOTERCODE_TEST_SKIPPED, requireNonNull( listener ) );
}
public void setTestErrorListener( ForkedProcessReportEventListener<?> listener )
{
reportEventListeners.put( BOOTERCODE_TEST_ERROR, requireNonNull( listener ) );
}
public void setTestAssumptionFailureListener( ForkedProcessReportEventListener<?> listener )
{
reportEventListeners.put( BOOTERCODE_TEST_ASSUMPTIONFAILURE, requireNonNull( listener ) );
}
public void setStdOutListener( ForkedProcessStandardOutErrEventListener listener )
{
stdOutErrEventListeners.put( BOOTERCODE_STDOUT, requireNonNull( listener ) );
stdOutErrEventListeners.put( BOOTERCODE_STDOUT_NEW_LINE, requireNonNull( listener ) );
}
public void setStdErrListener( ForkedProcessStandardOutErrEventListener listener )
{
stdOutErrEventListeners.put( BOOTERCODE_STDERR, requireNonNull( listener ) );
stdOutErrEventListeners.put( BOOTERCODE_STDERR_NEW_LINE, requireNonNull( listener ) );
}
public void setConsoleInfoListener( ForkedProcessStringEventListener listener )
{
consoleEventListeners.put( BOOTERCODE_CONSOLE_INFO, requireNonNull( listener ) );
}
public void setConsoleErrorListener( ForkedProcessStackTraceEventListener listener )
{
consoleErrorEventListener = requireNonNull( listener );
}
public void setConsoleDebugListener( ForkedProcessStringEventListener listener )
{
consoleEventListeners.put( BOOTERCODE_CONSOLE_DEBUG, requireNonNull( listener ) );
}
public void setConsoleWarningListener( ForkedProcessStringEventListener listener )
{
consoleEventListeners.put( BOOTERCODE_CONSOLE_WARNING, requireNonNull( listener ) );
}
public void setByeListener( ForkedProcessEventListener listener )
{
controlEventListeners.put( BOOTERCODE_BYE, requireNonNull( listener ) );
}
public void setStopOnNextTestListener( ForkedProcessEventListener listener )
{
controlEventListeners.put( BOOTERCODE_STOP_ON_NEXT_TEST, requireNonNull( listener ) );
}
public void setAcquireNextTestListener( ForkedProcessEventListener listener )
{
controlEventListeners.put( BOOTERCODE_NEXT_TEST, requireNonNull( listener ) );
}
public void setExitErrorEventListener( ForkedProcessExitErrorListener listener )
{
exitErrorEventListener = requireNonNull( listener );
}
public void notifyEvent( Event event )
{
ForkedProcessEventType eventType = event.getEventType();
if ( event.isControlCategory() )
{
ForkedProcessEventListener listener = controlEventListeners.get( eventType );
if ( listener != null )
{
listener.handle();
}
}
else if ( event.isConsoleErrorCategory() )
{
if ( consoleErrorEventListener != null )
{
consoleErrorEventListener.handle( ( ( ConsoleErrorEvent ) event ).getStackTraceWriter() );
}
}
else if ( event.isConsoleCategory() )
{
ForkedProcessStringEventListener listener = consoleEventListeners.get( eventType );
if ( listener != null )
{
listener.handle( ( (AbstractConsoleEvent) event ).getMessage() );
}
}
else if ( event.isStandardStreamCategory() )
{
boolean newLine = eventType == BOOTERCODE_STDOUT_NEW_LINE || eventType == BOOTERCODE_STDERR_NEW_LINE;
AbstractStandardStreamEvent standardStreamEvent = (AbstractStandardStreamEvent) event;
ForkedProcessStandardOutErrEventListener listener = stdOutErrEventListeners.get( eventType );
if ( listener != null )
{
listener.handle( standardStreamEvent.getRunMode(), standardStreamEvent.getMessage(), newLine );
}
}
else if ( event.isSysPropCategory() )
{
SystemPropertyEvent systemPropertyEvent = (SystemPropertyEvent) event;
RunMode runMode = systemPropertyEvent.getRunMode();
String key = systemPropertyEvent.getKey();
String value = systemPropertyEvent.getValue();
if ( propertyEventListener != null )
{
propertyEventListener.handle( runMode, key, value );
}
}
else if ( event.isTestCategory() )
{
ForkedProcessReportEventListener listener = reportEventListeners.get( eventType );
AbstractTestControlEvent testControlEvent = (AbstractTestControlEvent) event;
RunMode mode = testControlEvent.getRunMode();
ReportEntry reportEntry = testControlEvent.getReportEntry();
if ( listener != null )
{
listener.handle( mode, reportEntry );
}
}
else if ( event.isJvmExitError() )
{
JvmExitErrorEvent jvmExitErrorEvent = (JvmExitErrorEvent) event;
if ( exitErrorEventListener != null )
{
exitErrorEventListener.handle( jvmExitErrorEvent.getStackTraceWriter() );
}
}
else
{
throw new IllegalArgumentException( "Unknown event type " + eventType );
}
}
}