Commit 1612a692 authored by Nils Christian Ehmke's avatar Nils Christian Ehmke

Added JavaDoc and comments

parent 851a88ad
......@@ -13,6 +13,11 @@ import kieker.diagnosis.service.traces.TracesFilter;
import kieker.diagnosis.service.traces.TracesService;
import kieker.diagnosis.ui.main.MainController;
/**
* The controller of the traces tab.
*
* @author Nils Christian Ehmke
*/
@Singleton
class TracesController extends ControllerBase<TracesViewModel> {
......@@ -29,18 +34,23 @@ class TracesController extends ControllerBase<TracesViewModel> {
getViewModel( ).updatePresentationFilter( new TracesFilter( ) );
}
/**
* This action is performed when settings or data are changed and the view has to be refreshed. The actual refresh is only performed when
* {@link #performRefresh()} is called. This method prepares only the refresh.
*/
public void performPrepareRefresh( ) {
// Find the trace roots to display
final TracesService tracesService = getService( TracesService.class );
ivTraceRoots = tracesService.searchTraces( new TracesFilter( ) );
ivTotalTraces = tracesService.countTraces( );
// Get the duration suffix
final SettingsService settingsService = getService( SettingsService.class );
ivDurationSuffix = settingsService.getCurrentDurationSuffix( );
}
/**
* This action is performed, when a refresh of the view is required
* This action is performed, when a refresh of the view is required. The preparation of the refresh is performed in {@link #performPrepareRefresh()}.
*/
public void performRefresh( ) {
// Reset the filter
......@@ -56,13 +66,16 @@ class TracesController extends ControllerBase<TracesViewModel> {
}
/**
* This action is performed, when the selection of the table changes
* This action is performed, when the selection of the table changes.
*/
public void performSelectionChange( ) {
final MethodCall methodCall = getViewModel( ).getSelected( );
getViewModel( ).updatePresentationDetails( methodCall );
}
/**
* This action is performed, when the user wants to perform a search.
*/
public void performSearch( ) {
try {
// Get the filter input from the user
......@@ -71,7 +84,6 @@ class TracesController extends ControllerBase<TracesViewModel> {
// Find the trace roots to display
final TracesService tracesService = getService( TracesService.class );
final List<MethodCall> traceRoots = tracesService.searchTraces( filter );
final int totalTraces = tracesService.countTraces( );
// Update the view
......@@ -83,6 +95,14 @@ class TracesController extends ControllerBase<TracesViewModel> {
}
/**
* This action is performed, when someone requested a jump into the traces tab. The real action is determined based on the type of the parameter. If the
* parameter is a {@link TracesFilter}, the filter is simply applied. If the parameter is a {@link MethodCall}, the trace for the method call is shown and
* the view tries to navigate directly to the method call. If the method call is not visible, the trace is still shown.
*
* @param aParameter
* The parameter.
*/
public void performSetParameter( final Object aParameter ) {
if ( aParameter instanceof MethodCall ) {
final MethodCall methodCall = (MethodCall) aParameter;
......@@ -105,8 +125,12 @@ class TracesController extends ControllerBase<TracesViewModel> {
}
}
/**
* This action is performed, when the user wants to save the current filter as a filter favorite.
*/
public void performSaveAsFavorite( ) {
try {
// We simply save the filter's content and delegate to the main controller.
final TracesFilter filter = getViewModel( ).savePresentationFilter( );
getController( MainController.class ).performSaveAsFavorite( TracesView.class, filter );
} catch ( final BusinessException ex ) {
......
......@@ -32,6 +32,11 @@ import kieker.diagnosis.ui.traces.components.MethodCellValueFactory;
import kieker.diagnosis.ui.traces.components.StyledRow;
import kieker.diagnosis.ui.traces.components.TimestampCellValueFactory;
/**
* The view of the traces tab.
*
* @author Nils Christian Ehmke
*/
@Singleton
public class TracesView extends ViewBase<TracesController> {
......
......@@ -27,6 +27,11 @@ import kieker.diagnosis.ui.traces.aggregator.TraceDepthAggregator;
import kieker.diagnosis.ui.traces.aggregator.TraceSizeAggregator;
import kieker.diagnosis.ui.traces.components.MethodCallTreeItem;
/**
* The view model of the traces tab.
*
* @author Nils Christian Ehmke
*/
@Singleton
class TracesViewModel extends ViewModelBase<TracesView> {
......
......@@ -7,12 +7,33 @@ import java.util.stream.Collectors;
import kieker.diagnosis.service.data.MethodCall;
/**
* Implementation of this class are responsible for aggregating method calls in a trace by various parameters.
*
* @author Nils Christian Ehmke
*/
public abstract class Aggregator {
private final ResourceBundle ivResourceBundle = ResourceBundle.getBundle( Aggregator.class.getName( ) );
/**
* Aggregates the given list of method calls. This means that the resulting list should contain real method calls and (aggregated) pseudo method calls.
*
* @param aCalls
* The method calls to aggregate.
*
* @return The aggregated list.
*/
public abstract List<MethodCall> aggregate( List<MethodCall> aCalls );
/**
* This is a helper method to aggregate a list of method calls into a single pseudo method call.
*
* @param aList
* The methods to be aggregated.
*
* @return A single pseudo method call.
*/
protected final MethodCall aggregateToSingleCall( final List<MethodCall> aList ) {
final double percent = aList.parallelStream( ).map( MethodCall::getPercent ).collect( Collectors.summingDouble( Float::doubleValue ) );
final long duration = aList.parallelStream( ).map( MethodCall::getDuration ).collect( Collectors.summingLong( Long::longValue ) );
......
......@@ -4,6 +4,11 @@ import java.util.Comparator;
import kieker.diagnosis.service.data.MethodCall;
/**
* This aggregator aggregates method calls by duration. That means that method calls in a trace with lower duration are aggregated into a single method call.
*
* @author Nils Christian Ehmke
*/
public final class DurationAggregator extends PropertyAggregator {
public DurationAggregator( final int aMaxCalls ) {
......
......@@ -4,6 +4,11 @@ import java.util.List;
import kieker.diagnosis.service.data.MethodCall;
/**
* This aggregator is a pseudo aggregator which does not do anything. It is basically the identity function on method call aggregation.
*
* @author Nils Christian Ehmke
*/
public final class IdentityAggregator extends Aggregator {
@Override
......
......@@ -16,16 +16,20 @@ public abstract class PropertyAggregator extends Aggregator {
}
@Override
public List<MethodCall> aggregate( final List<MethodCall> aCalls ) {
public final List<MethodCall> aggregate( final List<MethodCall> aCalls ) {
final List<MethodCall> accepted = new ArrayList<>( );
// Sort the methods by the comparator of the concrete implementation
final Iterator<MethodCall> iterator = aCalls.stream( ).sorted( getComparator( ) ).iterator( );
// Get the first n method calls (where n is the maximal numbers of allowed method calls)
int maxCalls = ivMaxCalls;
while ( maxCalls > 0 && iterator.hasNext( ) ) {
accepted.add( iterator.next( ) );
maxCalls--;
}
// The remaining method calls - if there are any - have to be aggregated.
final List<MethodCall> toBeAggregated = new ArrayList<>( );
while ( iterator.hasNext( ) ) {
toBeAggregated.add( iterator.next( ) );
......@@ -35,7 +39,7 @@ public abstract class PropertyAggregator extends Aggregator {
final MethodCall methodCall = aggregateToSingleCall( toBeAggregated );
accepted.add( methodCall );
} else {
// if the list is empty or contains only a single method call, we do not want to aggregate
// If the list is empty or contains only a single method call, we do not want to aggregate
accepted.addAll( toBeAggregated );
}
......
......@@ -5,6 +5,11 @@ import java.util.List;
import kieker.diagnosis.service.data.MethodCall;
/**
* This aggregator aggregates method calls by a given threshold. That means that method calls below this threshold are aggregated into a single method call.
*
* @author Nils Christian Ehmke
*/
public final class ThresholdAggregator extends Aggregator {
private final float ivThreshold;
......@@ -18,6 +23,7 @@ public final class ThresholdAggregator extends Aggregator {
final List<MethodCall> underThreshold = new ArrayList<>( );
final List<MethodCall> overThreshold = new ArrayList<>( );
// Separate the method calls with the threshold.
for ( final MethodCall call : calls ) {
if ( call.getPercent( ) < ivThreshold ) {
underThreshold.add( call );
......@@ -27,10 +33,11 @@ public final class ThresholdAggregator extends Aggregator {
}
if ( underThreshold.size( ) > 1 ) {
// If there are multiple method calls below the threshold, we want to aggregate them
final MethodCall methodCall = aggregateToSingleCall( underThreshold );
overThreshold.add( methodCall );
} else {
// if the list is empty or contains only a single method call, we do not want to aggregate
// If the list is empty or contains only a single method call, we do not want to aggregate
overThreshold.addAll( underThreshold );
}
......
......@@ -4,6 +4,12 @@ import java.util.Comparator;
import kieker.diagnosis.service.data.MethodCall;
/**
* This aggregator aggregates method calls by trace depth. That means that method calls in a trace with lower trace depth are aggregated into a single method
* call.
*
* @author Nils Christian Ehmke
*/
public final class TraceDepthAggregator extends PropertyAggregator {
public TraceDepthAggregator( final int aMaxCalls ) {
......
......@@ -4,6 +4,12 @@ import java.util.Comparator;
import kieker.diagnosis.service.data.MethodCall;
/**
* This aggregator aggregates method calls by trace size. That means that method calls in a trace with lower trace size are aggregated into a single method
* call.
*
* @author Nils Christian Ehmke
*/
public final class TraceSizeAggregator extends PropertyAggregator {
public TraceSizeAggregator( final int aMaxCalls ) {
......
......@@ -12,6 +12,12 @@ import kieker.diagnosis.service.data.MethodCall;
import kieker.diagnosis.service.settings.ClassAppearance;
import kieker.diagnosis.service.settings.properties.ClassAppearanceProperty;
/**
* This is a cell factory for a tree table which shows the class of a method call in the configured manner. It has to be in the CDI context, as it has to have
* access to the application properties.
*
* @author Nils Christian Ehmke
*/
@Singleton
public class ClassCellValueFactory implements Callback<CellDataFeatures<MethodCall, String>, ObservableValue<String>> {
......
......@@ -13,6 +13,12 @@ import kieker.diagnosis.architecture.service.properties.PropertiesService;
import kieker.diagnosis.service.data.MethodCall;
import kieker.diagnosis.service.settings.properties.TimeUnitProperty;
/**
* This is a cell factory for a tree table which shows the duration of a method call in the configured manner. It has to be in the CDI context, as it has to
* have access to the application properties.
*
* @author Nils Christian Ehmke
*/
@Singleton
public class DurationCellValueFactory implements Callback<CellDataFeatures<MethodCall, Long>, ObservableValue<Long>> {
......
......@@ -10,6 +10,12 @@ import kieker.diagnosis.architecture.common.ClassUtil;
import kieker.diagnosis.service.data.MethodCall;
import kieker.diagnosis.ui.traces.aggregator.Aggregator;
/**
* This is an item for a tree table, which contains a method call. The children are loaded in a lazy way. The item enriches and aggregates the children based on
* the current application settings.
*
* @author Nils Christian Ehmke
*/
public final class MethodCallTreeItem extends TreeItem<MethodCall> {
private final ResourceBundle ivResourceBundle = ResourceBundle.getBundle( ClassUtil.getRealName( getClass( ) ) );
......@@ -18,6 +24,16 @@ public final class MethodCallTreeItem extends TreeItem<MethodCall> {
private final boolean ivShowUnmonitoredTime;
private final Aggregator ivAggregator;
/**
* Creates a new tree item.
*
* @param aMethodCall
* The method call to be contained in the new item.
* @param aShowUnmonitoredTime
* Determines whether the node should show the unmonitored time.
* @param aAggregator
* The aggregator which is used to aggregate the children of the node.
*/
public MethodCallTreeItem( final MethodCall aMethodCall, final boolean aShowUnmonitoredTime, final Aggregator aAggregator ) {
super( aMethodCall );
......@@ -27,6 +43,7 @@ public final class MethodCallTreeItem extends TreeItem<MethodCall> {
@Override
public final ObservableList<TreeItem<MethodCall>> getChildren( ) {
// Initialize the children in a lazy way.
if ( !ivChildrenInitialized ) {
ivChildrenInitialized = true;
initializeChildren( );
......@@ -43,8 +60,10 @@ public final class MethodCallTreeItem extends TreeItem<MethodCall> {
private void initializeChildren( ) {
final List<TreeItem<MethodCall>> result = new ArrayList<>( );
// Aggregate the method calls if necessary
final List<MethodCall> children = ivAggregator.aggregate( getValue( ).getChildren( ) );
// Show the unmonitored time if necessary
if ( ivShowUnmonitoredTime ) {
// Calculate the unmonitored time
float percent = 0.0f;
......@@ -69,6 +88,7 @@ public final class MethodCallTreeItem extends TreeItem<MethodCall> {
result.add( new MethodCallTreeItem( methodCall, false, ivAggregator ) );
}
// Now convert the children into items
for ( final MethodCall child : children ) {
result.add( new MethodCallTreeItem( child, ivShowUnmonitoredTime, ivAggregator ) );
}
......
......@@ -12,6 +12,12 @@ import kieker.diagnosis.service.data.MethodCall;
import kieker.diagnosis.service.settings.MethodAppearance;
import kieker.diagnosis.service.settings.properties.MethodAppearanceProperty;
/**
* This is a cell factory for a tree table which shows the method of a method call in the configured manner. It has to be in the CDI context, as it has to have
* access to the application properties.
*
* @author Nils Christian Ehmke
*/
@Singleton
public class MethodCellValueFactory implements Callback<CellDataFeatures<MethodCall, String>, ObservableValue<String>> {
......
......@@ -3,12 +3,18 @@ package kieker.diagnosis.ui.traces.components;
import javafx.scene.control.TreeTableRow;
import kieker.diagnosis.service.data.MethodCall;
/**
* This is a row for a tree table which is aware of a method call being failed. If the method call has an exception, it is styled accordingly.
*
* @author Nils Christian Ehmke
*/
public final class StyledRow extends TreeTableRow<MethodCall> {
@Override
protected void updateItem( final MethodCall aItem, final boolean aEmpty ) {
super.updateItem( aItem, aEmpty );
// Remove a potential style class from an earlier run
getStyleClass( ).remove( "failed" );
if ( aItem != null && aItem.getException( ) != null ) {
......
......@@ -12,6 +12,12 @@ import kieker.diagnosis.service.data.MethodCall;
import kieker.diagnosis.service.settings.TimestampAppearance;
import kieker.diagnosis.service.settings.properties.TimestampProperty;
/**
* This is a cell factory for a tree table which shows the timestamp of a method call in the configured manner. It has to be in the CDI context, as it has to
* have access to the application properties.
*
* @author Nils Christian Ehmke
*/
@Singleton
public class TimestampCellValueFactory implements Callback<CellDataFeatures<MethodCall, String>, ObservableValue<String>> {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment