<commit_before>/*
 * Copyright 2008-2017 by <NAME>
 *
 *     This file is part of Java Melody.
 *
 * Licensed 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.
 */
package net.bull.javamelody.internal.model;

import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.management.Attribute;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;

import net.bull.javamelody.internal.common.LOG;
import net.bull.javamelody.internal.model.MBeanNode.MBeanAttribute;

/**
 * Objet récupérant une instance de {@link MBeanServer} lors de sa construction
 * et permettant de récupérer différentes données sur les MBeans.
 * @author <NAME>
 */
public final class MBeans {
	/**
	 * Separator between mbeans attributes in the External API.
	 */
	public static final char ATTRIBUTES_SEPARATOR = '|';

	private static final String JAVA_LANG_MBEAN_DESCRIPTION = "Information on the management interface of the MBean";
	private static final Comparator<MBeanNode> NODE_COMPARATOR = new Comparator<MBeanNode>() {
		@Override
		public int compare(MBeanNode o1, MBeanNode o2) {
			return o1.getName() != null ? o1.getName().compareTo(o2.getName()) : 0;
		}
	};
	private static final Comparator<MBeanAttribute> ATTRIBUTE_COMPARATOR = new Comparator<MBeanAttribute>() {
		@Override
		public int compare(MBeanAttribute o1, MBeanAttribute o2) {
			return o1.getName().compareTo(o2.getName());
		}
	};
	private final MBeanServer mbeanServer;

	MBeans() {
		this(getPlatformMBeanServer());
	}

	private MBeans(MBeanServer mbeanServer) {
		super();
		this.mbeanServer = mbeanServer;
	}

	Object getAttribute(ObjectName name, String attribute) throws JMException {
		return mbeanServer.getAttribute(name, attribute);
	}

	public static List<MBeanNode> getAllMBeanNodes() throws JMException {
		initJRockitMBeansIfNeeded();

		final List<MBeanNode> result = new ArrayList<MBeanNode>();
		final MBeanServer platformMBeanServer = getPlatformMBeanServer();
		final MBeanNode platformNode = new MBeanNode("");
		// MBeans pour la plateforme
		final MBeans platformMBeans = new MBeans();
		platformNode.getChildren().addAll(platformMBeans.getMBeanNodes());
		result.add(platformNode);

		// pour JBoss 5.0.x, les MBeans de JBoss sont dans un autre MBeanServer
		for (final MBeanServer mbeanServer : getMBeanServers()) {
			if (!mbeanServer.equals(platformMBeanServer)) {
				final MBeanNode node = new MBeanNode(mbeanServer.getDefaultDomain());
				final MBeans mbeans = new MBeans(mbeanServer);
				node.getChildren().addAll(mbeans.getMBeanNodes());
				result.add(node);
			}
		}
		return result;
	}

	private static void initJRockitMBeansIfNeeded() {
		// si jrockit, on initialise les MBeans spécifiques jrockit lors de la première demande
		if (System.getProperty("java.vendor").contains("BEA")) {
			try {
				// initialisation des MBeans jrockit comme indiqué dans http://blogs.oracle.com/hirt/jrockit/
				try {
					getPlatformMBeanServer().getMBeanInfo(
							new ObjectName("bea.jrockit.management:type=JRockitConsole"));
				} catch (final InstanceNotFoundException e1) {
					getPlatformMBeanServer().createMBean("bea.jrockit.management.JRockitConsole",
							null);
					LOG.debug("JRockit MBeans initialized");
				}
			} catch (final JMException e) {
				throw new IllegalStateException(e);
			}
		}
	}

	private List<MBeanNode> getMBeanNodes() throws JMException {
		final List<MBeanNode> result = new ArrayList<MBeanNode>();
		final Set<ObjectName> names = mbeanServer.queryNames(null, null);
		for (final ObjectName name : names) {
			final String domain = name.getDomain();
			if ("jboss.deployment".equals(domain)) {
				// la partie "jboss.deployment" dans JBoss (5.0.x) est plutôt inutile et trop lourde
				continue;
			}
			MBeanNode domainNode = getMBeanNodeFromList(result, domain);
			if (domainNode == null) {
				domainNode = new MBeanNode(domain);
				result.add(domainNode);
			}
			final String keyPropertyListString = name.getKeyPropertyListString();
			final String firstPropertyValue;
			final int indexOf = keyPropertyListString.indexOf('=');
			if (indexOf == -1) {
				// n'arrive probablement pas, mais au cas où
				firstPropertyValue = null;
			} else {
				firstPropertyValue = name
						.getKeyProperty(keyPropertyListString.substring(0, indexOf));
			}
			MBeanNode firstPropertyNode = getMBeanNodeFromList(domainNode.getChildren(),
					firstPropertyValue);
			if (firstPropertyNode == null) {
				firstPropertyNode = new MBeanNode(firstPropertyValue);
				domainNode.getChildren().add(firstPropertyNode);
			}
			final MBeanNode mbean = getMBeanNode(name);
			firstPropertyNode.getChildren().add(mbean);
		}
		sortMBeanNodes(result);
		return result;
	}

	private void sortMBeanNodes(List<MBeanNode> nodes) {
		if (nodes.size() > 1) {
			Collections.sort(nodes, NODE_COMPARATOR);
		}

		for (final MBeanNode node : nodes) {
			final List<MBeanNode> children = node.getChildren();
			if (children != null) {
				sortMBeanNodes(children);
			}
			final List<MBeanAttribute> attributes = node.getAttributes();
			if (attributes != null && attributes.size() > 1) {
				Collections.sort(attributes, ATTRIBUTE_COMPARATOR);
			}
		}
	}
<commit_msg>#757 workaround jboss / wildfly bug in MBeans tree<commit_after>/*
 * Copyright 2008-2017 by <NAME>
 *
 *     This file is part of Java Melody.
 *
 * Licensed 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.
 */
package net.bull.javamelody.internal.model;

import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.management.Attribute;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;

import net.bull.javamelody.internal.common.LOG;
import net.bull.javamelody.internal.model.MBeanNode.MBeanAttribute;

/**
 * Objet récupérant une instance de {@link MBeanServer} lors de sa construction
 * et permettant de récupérer différentes données sur les MBeans.
 * @author <NAME>
 */
public final class MBeans {
	/**
	 * Separator between mbeans attributes in the External API.
	 */
	public static final char ATTRIBUTES_SEPARATOR = '|';

	private static final String JAVA_LANG_MBEAN_DESCRIPTION = "Information on the management interface of the MBean";
	private static final Comparator<MBeanNode> NODE_COMPARATOR = new Comparator<MBeanNode>() {
		@Override
		public int compare(MBeanNode o1, MBeanNode o2) {
			return o1.getName() != null ? o1.getName().compareTo(o2.getName()) : 0;
		}
	};
	private static final Comparator<MBeanAttribute> ATTRIBUTE_COMPARATOR = new Comparator<MBeanAttribute>() {
		@Override
		public int compare(MBeanAttribute o1, MBeanAttribute o2) {
			return o1.getName().compareTo(o2.getName());
		}
	};
	private final MBeanServer mbeanServer;

	MBeans() {
		this(getPlatformMBeanServer());
	}

	private MBeans(MBeanServer mbeanServer) {
		super();
		this.mbeanServer = mbeanServer;
	}

	Object getAttribute(ObjectName name, String attribute) throws JMException {
		return mbeanServer.getAttribute(name, attribute);
	}

	public static List<MBeanNode> getAllMBeanNodes() throws JMException {
		initJRockitMBeansIfNeeded();

		final List<MBeanNode> result = new ArrayList<MBeanNode>();
		final MBeanServer platformMBeanServer = getPlatformMBeanServer();
		final MBeanNode platformNode = new MBeanNode("");
		// MBeans pour la plateforme
		final MBeans platformMBeans = new MBeans();
		platformNode.getChildren().addAll(platformMBeans.getMBeanNodes());
		result.add(platformNode);

		// pour JBoss 5.0.x, les MBeans de JBoss sont dans un autre MBeanServer
		for (final MBeanServer mbeanServer : getMBeanServers()) {
			if (!mbeanServer.equals(platformMBeanServer)) {
				final MBeanNode node = new MBeanNode(mbeanServer.getDefaultDomain());
				final MBeans mbeans = new MBeans(mbeanServer);
				node.getChildren().addAll(mbeans.getMBeanNodes());
				result.add(node);
			}
		}
		return result;
	}

	private static void initJRockitMBeansIfNeeded() {
		// si jrockit, on initialise les MBeans spécifiques jrockit lors de la première demande
		if (System.getProperty("java.vendor").contains("BEA")) {
			try {
				// initialisation des MBeans jrockit comme indiqué dans http://blogs.oracle.com/hirt/jrockit/
				try {
					getPlatformMBeanServer().getMBeanInfo(
							new ObjectName("bea.jrockit.management:type=JRockitConsole"));
				} catch (final InstanceNotFoundException e1) {
					getPlatformMBeanServer().createMBean("bea.jrockit.management.JRockitConsole",
							null);
					LOG.debug("JRockit MBeans initialized");
				}
			} catch (final JMException e) {
				throw new IllegalStateException(e);
			}
		}
	}

	private List<MBeanNode> getMBeanNodes() throws JMException {
		final List<MBeanNode> result = new ArrayList<MBeanNode>();
		final Set<ObjectName> names = mbeanServer.queryNames(null, null);
		for (final ObjectName name : names) {
			final String domain = name.getDomain();
			if ("jboss.deployment".equals(domain)) {
				// la partie "jboss.deployment" dans JBoss (5.0.x) est plutôt inutile et trop lourde
				continue;
			}
			MBeanNode domainNode = getMBeanNodeFromList(result, domain);
			if (domainNode == null) {
				domainNode = new MBeanNode(domain);
				result.add(domainNode);
			}
			final String keyPropertyListString = name.getKeyPropertyListString();
			final String firstPropertyValue;
			final int indexOf = keyPropertyListString.indexOf('=');
			if (indexOf == -1) {
				// n'arrive probablement pas, mais au cas où
				firstPropertyValue = null;
			} else {
				firstPropertyValue = name
						.getKeyProperty(keyPropertyListString.substring(0, indexOf));
			}
			MBeanNode firstPropertyNode = getMBeanNodeFromList(domainNode.getChildren(),
					firstPropertyValue);
			if (firstPropertyNode == null) {
				firstPropertyNode = new MBeanNode(firstPropertyValue);
				domainNode.getChildren().add(firstPropertyNode);
			}
			try {
				final MBeanNode mbean = getMBeanNode(name);
				firstPropertyNode.getChildren().add(mbean);
			} catch (final IllegalStateException e) {
				// for JBoss EAP 6 (#757)
				continue;
			}
		}
		sortMBeanNodes(result);
		return result;
	}

	private void sortMBeanNodes(List<MBeanNode> nodes) {
		if (nodes.size() > 1) {
			Collections.sort(nodes, NODE_COMPARATOR);
		}

		for (final MBeanNode node : nodes) {
			final List<MBeanNode> children = node.getChildren();
			if (children != null) {
				sortMBeanNodes(children);
			}
			final List<MBeanAttribute> attributes = node.getAttributes();
			if (attributes != null && attributes.size() > 1) {
				Collections.sort(attributes, ATTRIBUTE_COMPARATOR);
			}
		}
	}

{'fraction_non_alphanumeric': 0.10249880630272162, 'fraction_numerical': 0.005491007480502945, 'mean_word_length': 4.4853775643823655, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4266785', 'n_tokens_mistral': 4300, 'n_tokens_neox': 3838, 'n_words': 994}