/******************************************************************************* * Copyright (c) 2004,2009 Red Hat, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Keith Seitz <keiths@redhat.com> - initial API and implementation * Kent Sebastian <ksebasti@redhat.com> *******************************************************************************/ package org.eclipse.linuxtools.internal.oprofile.core.opxml.info; import java.util.ArrayList; import org.eclipse.linuxtools.internal.oprofile.core.daemon.OpEvent; import org.eclipse.linuxtools.internal.oprofile.core.daemon.OpUnitMask; import org.eclipse.linuxtools.internal.oprofile.core.opxml.OprofileSAXHandler; import org.eclipse.linuxtools.internal.oprofile.core.opxml.XMLProcessor; import org.xml.sax.Attributes; /** * XML handler class for opxml's "event-list". * @see org.eclipse.linuxtools.internal.oprofile.core.opxml.OpxmlRunner */ public class EventListProcessor extends XMLProcessor { // The current event being constructed private OpEvent currentEvent; private int counter; private ArrayList<OpEvent> currentEventList; // An XML processor for reading the unit mask information for an event private UnitMaskProcessor umProcessor; // XML elements recognized by this processor private static final String EVENT_TAG = "event"; //$NON-NLS-1$ private static final String UNIT_MASK_TAG = "unit-mask"; //$NON-NLS-1$ private static final String NAME_TAG = "name"; //$NON-NLS-1$ private static final String VALUE_TAG = "value"; //$NON-NLS-1$ private static final String DESCRIPTION_TAG = "description"; //$NON-NLS-1$ private static final String MASK_TAG = "mask"; //$NON-NLS-1$ private static final String MINIMUM_COUNT_TAG = "minimum"; //$NON-NLS-1$ private static final String ATTR_EVENT_LIST_COUNTER = "counter"; //$NON-NLS-1$ // This is a special processor which is used to deal with a single mask value private static class MaskProcessor extends XMLProcessor { private OpUnitMask.MaskInfo info; @Override public void reset(Object callData) { info = new OpUnitMask.MaskInfo(); } @Override public void endElement(String name, Object callData) { if (name.equals(VALUE_TAG)) { // Set mask's value info.value = Integer.parseInt(characters); } else if (name.equals(DESCRIPTION_TAG)) { info.description = characters; } else if (name.equals(MASK_TAG)) { // Pop and pass mask tag to previous processor (UnitMaskProcessor) OprofileSAXHandler.getInstance(callData).pop(MASK_TAG); } } /** * Returns the information that has been collected about a mask. * @return the mask information */ public OpUnitMask.MaskInfo getResult() { return info; } } // This is a special processor to handle unit mask information private class UnitMaskProcessor extends XMLProcessor { // An ArrayList to hold all the valid masks for a unit mask. private ArrayList<OpUnitMask.MaskInfo> masks; // The unit mask being constructed private OpUnitMask unitMask; // An XML processor for each individual mask value. private MaskProcessor maskProcessor; // XML elements recognized by this processor private static final String MASK_TYPE_TAG = "type"; //$NON-NLS-1$ private static final String MASK_DEFAULT_TAG = "default"; //$NON-NLS-1$ private static final String MASK_TYPE_BITMASK = "bitmask"; //$NON-NLS-1$ private static final String MASK_TYPE_MANDATORY = "mandatory"; //$NON-NLS-1$ private static final String MASK_TYPE_EXCLUSIVE = "exclusive"; //$NON-NLS-1$ /** * Constructor for UnitMaskProcessor. Initializes internal state. */ public UnitMaskProcessor() { super(); maskProcessor = new MaskProcessor(); masks = new ArrayList<>(); } @Override public void reset(Object callData) { unitMask = new OpUnitMask(); masks.clear(); } @Override public void startElement(String name, Attributes attrs, Object callData) { if (name.equals(MASK_TAG)) { // Tell SAX handler to use the mask processor OprofileSAXHandler.getInstance(callData).push(maskProcessor); } else { super.startElement(name, attrs, callData); } } @Override public void endElement(String name, Object callData) { if (name.equals(MASK_TYPE_TAG)) { // Set the mask type unitMask.setType(getTypeFromString(characters)); } else if (name.equals(MASK_DEFAULT_TAG)) { // Set the default mask unitMask.setDefault(Integer.parseInt(characters)); } else if (name.equals(MASK_TAG)) { // Add this mask description to the list of all masks masks.add(maskProcessor.getResult()); } else if (name.equals(UNIT_MASK_TAG)) { // All done. Add the known masks to the unit mask OpUnitMask.MaskInfo[] descs = new OpUnitMask.MaskInfo[masks.size()]; masks.toArray(descs); unitMask.setMaskDescriptions(descs); // Pop this processor and pass _UNIT_MASK_TAG to previoius processor OprofileSAXHandler.getInstance(callData).pop(UNIT_MASK_TAG); } } /** * Returns the constructed unit mask. * @return the unit mask */ public OpUnitMask getResult() { return unitMask; } // Converts a string representing a mask type into an integer private int getTypeFromString(String string) { if (string.equals(MASK_TYPE_MANDATORY)) { return OpUnitMask.MANDATORY; } else if (string.equals(MASK_TYPE_BITMASK)) { return OpUnitMask.BITMASK; } else if (string.equals(MASK_TYPE_EXCLUSIVE)) { return OpUnitMask.EXCLUSIVE; } return -1; } } /** * Constructor for EventListProcessor. Initializes internal state. */ public EventListProcessor() { super(); umProcessor = new UnitMaskProcessor(); } @Override public void reset(Object callData) { currentEventList = new ArrayList<>(); } @Override public void startElement(String name, Attributes attrs, Object callData) { if (name.equals(EVENT_TAG)) { // new event currentEvent = new OpEvent(); } else if (name.equals(UNIT_MASK_TAG)) { // Tell the SAX handler to use the unit mask processor OprofileSAXHandler.getInstance(callData).push(umProcessor); } else if (name.equals(OpInfoProcessor.EVENT_LIST_TAG)) { // Our start tag: grab the counter number from the attributes counter = Integer.parseInt(attrs.getValue(ATTR_EVENT_LIST_COUNTER)); } else { super.startElement(name, attrs, callData); } } @Override public void endElement(String name, Object callData) { if (name.equals(EVENT_TAG)) { // Finished constructing an event. Add it to the list. currentEventList.add(currentEvent); } else if (name.equals(UNIT_MASK_TAG)) { // Set the event's unit mask currentEvent.setUnitMask(umProcessor.getResult()); } else if (name.equals(NAME_TAG)) { // Set event's name currentEvent.setText(characters); } else if (name.equals(DESCRIPTION_TAG)) { // Set event's description currentEvent.setTextDescription(characters); } else if (name.equals(MINIMUM_COUNT_TAG)) { // Set event's minimum count currentEvent.setMinCount(Integer.parseInt(characters)); } else if (name.equals(OpInfoProcessor.EVENT_LIST_TAG)) { OprofileSAXHandler.getInstance(callData).pop(name); } } public int getCounterNum() { return counter; } public OpEvent[] getEvents() { OpEvent[] events = new OpEvent[currentEventList.size()]; currentEventList.toArray(events); return events; } }