package ca.uhn.fhir.util.jar; /* * #%L * HAPI FHIR - Core Library * %% * Copyright (C) 2014 - 2017 University Health Network * %% * 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. * #L% */ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.jar.Attributes; import java.util.jar.Manifest; import ca.uhn.fhir.util.XmlUtil; public class DependencyLogImpl implements IDependencyLog { private static final Attributes.Name BUNDLE_SYMBOLIC_NAME = new Attributes.Name("Bundle-SymbolicName"); private static final Attributes.Name BUNDLE_VENDOR = new Attributes.Name("Bundle-Vendor"); private static final Attributes.Name BUNDLE_VERSION = new Attributes.Name("Bundle-Version"); private static final Attributes.Name IMPLEMENTATION_TITLE = new Attributes.Name("Implementation-Title"); private static final Attributes.Name IMPLEMENTATION_VENDOR = new Attributes.Name("Implementation-Vendor"); private static final Attributes.Name IMPLEMENTATION_VERSION = new Attributes.Name("Implementation-Version"); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class); @Override public void logStaxImplementation(Class<?> theClass) { try { URL rootUrl = getRootUrlForClass(theClass); if (rootUrl == null) { ourLog.info("Unable to determine location of StAX implementation containing class"); } else { Manifest manifest; URL metaInfUrl = new URL(rootUrl, "META-INF/MANIFEST.MF"); InputStream is = metaInfUrl.openStream(); try { manifest = new Manifest(is); } finally { is.close(); } Attributes attrs = manifest.getMainAttributes(); String title = attrs.getValue(IMPLEMENTATION_TITLE); String symbolicName = attrs.getValue(BUNDLE_SYMBOLIC_NAME); if (symbolicName != null) { int i = symbolicName.indexOf(';'); if (i != -1) { symbolicName = symbolicName.substring(0, i); } } String vendor = attrs.getValue(IMPLEMENTATION_VENDOR); if (vendor == null) { vendor = attrs.getValue(BUNDLE_VENDOR); } String version = attrs.getValue(IMPLEMENTATION_VERSION); if (version == null) { version = attrs.getValue(BUNDLE_VERSION); } if (ourLog.isDebugEnabled()) { ourLog.debug("FHIR XML procesing will use StAX implementation at {}\n Title: {}\n Symbolic name: {}\n Vendor: {}\n Version: {}", new Object[] { rootUrl, title, symbolicName, vendor, version } ); } else { ourLog.info("FHIR XML procesing will use StAX implementation '{}' version '{}'", title, version); } } } catch (Throwable e) { ourLog.info("Unable to determine StAX implementation: " + e.getMessage()); } } private static URL getRootUrlForClass(Class<?> cls) { ClassLoader classLoader = cls.getClassLoader(); String resource = cls.getName().replace('.', '/') + ".class"; if (classLoader == null) { // A null class loader means the bootstrap class loader. In this case we use the // system class loader. This is safe since we can assume that the system class // loader uses parent first as delegation policy. classLoader = ClassLoader.getSystemClassLoader(); } URL url = classLoader.getResource(resource); if (url == null) { return null; } String file = url.getFile(); if (file.endsWith(resource)) { try { return new URL(url.getProtocol(), url.getHost(), url.getPort(), file.substring(0, file.length() - resource.length())); } catch (MalformedURLException ex) { return null; } } return null; } }