
patterntesting.runtime.jmx.Info Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of patterntesting-rt Show documentation
Show all versions of patterntesting-rt Show documentation
PatternTesting Runtime (patterntesting-rt) is the runtime component for
the PatternTesting framework. It provides the annotations and base classes
for the PatternTesting testing framework (e.g. patterntesting-check,
patterntesting-concurrent or patterntesting-exception) but can be also
used standalone for classpath monitoring or profiling.
It uses AOP and AspectJ to perform this feat.
/*
* Copyright (c) 2013 by Oli B.
*
* 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 orimplied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* (c)reated 06.04.2014 by Oli B. ([email protected])
*/
package patterntesting.runtime.jmx;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Map.Entry;
import java.util.jar.*;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.*;
import patterntesting.runtime.NullConstants;
import patterntesting.runtime.io.Resource;
import patterntesting.runtime.monitor.ClasspathMonitor;
/**
* This Info bean is registered as MBean and provides some information about
* PatternTesting. Since 1.6 it can be now subclassed and provides information
* from the Manifest file.
*
* @author oliver ([email protected])
* @since 1.4 (06.04.2014)
*/
public class Info implements InfoMBean {
private static final Logger LOG = LogManager.getLogger(Info.class);
private static final String MANIFEST_URI = "Manifest-URI";
private final Properties properties;
private final Manifest manifest;
/** Info about PatternTesting itself. */
public static final Info PATTERNTESTING = new Info();
static {
MBeanHelper.registerMBean("patterntesting.runtime:name=Info", Info.PATTERNTESTING);
}
/**
* Instantiates a new info.
*/
public Info() {
this(Info.class);
}
/**
* Instantiates a new builds the info.
*
* @param clazz
* die Klasse, von der ich die Build-Infos will.
*/
public Info(final Class> clazz) {
this.properties = loadProperties(clazz);
this.manifest = getManifest(clazz);
}
private static Properties loadProperties(final Class> clazz) {
Properties properties = new Properties();
InputStream istream = clazz.getResourceAsStream("info.properties");
try {
if (istream == null) {
throw new IOException("no info.properties found for " + clazz);
}
LOG.debug("Read info.properties for {}.", clazz);
properties.load(istream);
} catch (IOException ioe) {
LOG.warn("Cannot read info.properties for {}:", clazz, ioe);
properties.put("project.version", clazz.getPackage().getImplementationVersion());
} finally {
IOUtils.closeQuietly(istream);
}
return properties;
}
private static Manifest getManifest(final Class> clazz) {
ClasspathMonitor cpmon = ClasspathMonitor.getInstance();
String clazzURI = cpmon.whichClassPath(clazz).toString();
ClassLoader classLoader = clazz.getClassLoader();
if (classLoader == null) {
LOG.warn("Will return emtpy MANIFEST because got no classloader for {}.", clazz);
return new Manifest();
}
try {
Enumeration resources = classLoader.getResources("META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
URI uri = resources.nextElement().toURI();
String path = uri.toString();
if (path.startsWith(clazzURI)) {
return getManifest(uri);
}
LOG.trace("{} does not match {} for {}.", uri, clazzURI, clazz);
}
} catch (IOException| URISyntaxException ex) {
LOG.warn("Cannot read MANIFEST for {}:", clazz, ex);
}
LOG.error("No MANIFEST for {} found, will use first one as fallback.", clazz);
return getFirstManifest(clazz);
}
private static Manifest getFirstManifest(final Class> clazz) {
try {
URI uri = clazz.getClassLoader().getResource("META-INF/MANIFEST.MF").toURI();
LOG.trace("Found {} as first MANIFEST of {}.", uri, clazz);
return getManifest(uri);
} catch (IOException | URISyntaxException ex) {
LOG.warn("Will return empty MANIFEST because cannot read first one for {}:", clazz, ex);
}
return new Manifest();
}
private static Manifest getManifest(final URI uri) throws IOException {
String content = IOUtils.toString(uri, StandardCharsets.UTF_8);
InputStream istream = new ByteArrayInputStream(content.getBytes("UTF8"));
try {
Manifest manifest = new Manifest(istream);
manifest.read(istream);
manifest.getMainAttributes().putValue(MANIFEST_URI, uri.toString());
return manifest;
} finally {
istream.close();
}
}
/**
* Gets the manifest.
*
* @return the manifest
* @since 1.6
*/
public Manifest getManifest() {
return this.manifest;
}
/**
* Gets the manifest uri.
*
* @return the manifest uri
* @since 1.6
*/
@Override
public URI getManifestURI() {
return URI.create(this.manifest.getMainAttributes().getValue(MANIFEST_URI));
}
/**
* Gets the properties.
*
* @return the properties
* @since 1.6
*/
public Properties getProperties() {
return this.properties;
}
/**
* Gets the properties, but sorted and as map.
*
* @return the infos
* @see Info#getProperties()
*/
@SuppressWarnings("unchecked")
public SortedMap getInfos() {
SortedMap, ?> sortedProps = new TreeMap<>(this.properties);
SortedMap infos = (SortedMap) sortedProps;
addAttributesTo(infos, this.manifest.getMainAttributes());
return infos;
}
private static void addAttributesTo(final SortedMap infos, final Attributes attributes) {
for (Entry
© 2015 - 2025 Weber Informatics LLC | Privacy Policy