/******************************************************************************* * Copyright (c) 2010, 2017 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: * Red Hat - initial API and implementation *******************************************************************************/ package org.eclipse.linuxtools.internal.oprofile.core.opxml.checkevent; import java.util.TreeSet; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.eclipse.linuxtools.internal.oprofile.core.opxml.AbstractDataAdapter; import org.eclipse.linuxtools.internal.oprofile.core.opxml.EventIdCache; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * This class takes the XML that is output from various checks for and uses that * data to modify it into the format expected by the SAX parser. */ public class CheckEventAdapter extends AbstractDataAdapter { public static final String CHECK_EVENTS = "check-events"; //$NON-NLS-1$ public static final String RESULT = "result"; //$NON-NLS-1$ public static final String UNIT_MASKS = "unit_masks"; //$NON-NLS-1$ public static final String UNIT_MASK = "unit_mask"; //$NON-NLS-1$ public static final String MASK = "mask"; //$NON-NLS-1$ private Element event; // the element corresponding to the event id private String eventName; // the id corresponding to the event private String unitMask; // the unit mask for the event private Document resultDoc; // the document to hold the generated xml private String returnCode; // the return code to be used in the generated xml public CheckEventAdapter(String ctr, String event, String umask) { eventName = event; unitMask = umask; this.event = EventIdCache.getInstance().getElementWithName(eventName); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder; try { builder = factory.newDocumentBuilder(); resultDoc = builder.newDocument(); } catch (ParserConfigurationException e1) { e1.printStackTrace(); } } @Override public void process() { setReturnCode(); createXML(); } private void setReturnCode() { if (!isValidUnitMask()) { returnCode = "invalid-um"; //$NON-NLS-1$ return; } returnCode = "ok"; //$NON-NLS-1$ } /** * Check if the unit mask being used is acceptable for this event * * @return true if the unit mask is recognized by the event and false otherwise. */ private boolean isValidUnitMask() { TreeSet<Integer> bitMaskSet = new TreeSet<>(); Element unitMasksTag = (Element) event.getElementsByTagName(UNIT_MASKS).item(0); if (unitMasksTag == null) { return true; } NodeList unitMasksList = unitMasksTag.getElementsByTagName(UNIT_MASK); // type:exclusive unit mask support for (int i = 0; i < unitMasksList.getLength(); i++) { Element unitMaskElem = (Element) unitMasksList.item(i); String val = unitMaskElem.getAttribute(MASK); if (val.equals(unitMask)) { return true; } bitMaskSet.add(Integer.parseInt(val)); } // type:bitmask unit mask support String unitMaskType = EventIdCache.getInstance().getUnitMaskType(eventName); if ("bitmask".equals(unitMaskType)) { //$NON-NLS-1$ int tmpVal = Integer.parseInt(unitMask); int count = 0; while (tmpVal != 0) { if (tmpVal % 2 != 0 && !bitMaskSet.contains((int) Math.pow(2, count))) { return false; } tmpVal = tmpVal / 2; count++; } return true; } return false; } private void createXML() { Element resultRoot = resultDoc.createElement(CHECK_EVENTS); Element resultTag = resultDoc.createElement(RESULT); resultTag.setTextContent(returnCode); resultRoot.appendChild(resultTag); resultDoc.appendChild(resultRoot); } @Override public Document getDocument() { return resultDoc; } }