package com.ibm.nmon.parser.gc.state; import com.ibm.nmon.parser.gc.GCParserContext; /** * State responsible for parsing <code><con></code> elements. These elements need special * handling because they can be nested. This implementation only cares about actual garbage * collection events. */ final class ConcurrentGCCycle extends Java6GCCycle { // track nested element depth so actions are only taken at the top level (i.e. 0) private int depth = 0; // has garbage collection actually started? private boolean collectionStarted = false; ConcurrentGCCycle() { super("con", "con_mark"); } @Override protected GCState onStartCycle(GCParserContext context, String elementName, String unparsedAttributes) { ++depth; // only process 'collection' events, otherwise skip if ("collection".equals(context.getAttribute("event"))) { calculateTime(context); collectionStarted = true; error = false; } else { // once collection starts, inner <con> elements are valid error = !collectionStarted; } return this; } public GCState endElement(GCParserContext context, String elementName) { if (elementName.equals(transitionElement)) { --depth; if (depth == 0) { // outermost </con> // save data if an actual collection // otherwise ignore if (collectionStarted) { if (!error) { calculateTotalSizes(context); context.saveRecord(); } collectionStarted = false; } beforeGC = true; error = false; return Java6GC.INSTANCE; } } // either nested </con> or some other element, continue processing return this; } @Override public void reset() { super.reset(); depth = 0; } }