View Javadoc
1   package ca.uhn.fhir.util.jar;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 - 2018 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import java.io.InputStream;
24  import java.net.MalformedURLException;
25  import java.net.URL;
26  import java.util.jar.Attributes;
27  import java.util.jar.Manifest;
28  
29  import ca.uhn.fhir.util.XmlUtil;
30  
31  public class DependencyLogImpl implements IDependencyLog {
32  	private static final Attributes.Name BUNDLE_SYMBOLIC_NAME = new Attributes.Name("Bundle-SymbolicName");
33  	private static final Attributes.Name BUNDLE_VENDOR = new Attributes.Name("Bundle-Vendor");
34  	private static final Attributes.Name BUNDLE_VERSION = new Attributes.Name("Bundle-Version");
35  	private static final Attributes.Name IMPLEMENTATION_TITLE = new Attributes.Name("Implementation-Title");
36  	private static final Attributes.Name IMPLEMENTATION_VENDOR = new Attributes.Name("Implementation-Vendor");
37  	private static final Attributes.Name IMPLEMENTATION_VERSION = new Attributes.Name("Implementation-Version");
38  	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class);
39  	
40  	@Override
41  	public void logStaxImplementation(Class<?> theClass) {
42  		try {
43  			URL rootUrl = getRootUrlForClass(theClass);
44  			if (rootUrl == null) {
45  				ourLog.info("Unable to determine location of StAX implementation containing class");
46  			} else {
47  				Manifest manifest;
48  				URL metaInfUrl = new URL(rootUrl, "META-INF/MANIFEST.MF");
49  				InputStream is = metaInfUrl.openStream();
50  				try {
51  					manifest = new Manifest(is);
52  				} finally {
53  					is.close();
54  				}
55  				Attributes attrs = manifest.getMainAttributes();
56  				String title = attrs.getValue(IMPLEMENTATION_TITLE);
57  				String symbolicName = attrs.getValue(BUNDLE_SYMBOLIC_NAME);
58  				if (symbolicName != null) {
59  					int i = symbolicName.indexOf(';');
60  					if (i != -1) {
61  						symbolicName = symbolicName.substring(0, i);
62  					}
63  				}
64  				String vendor = attrs.getValue(IMPLEMENTATION_VENDOR);
65  				if (vendor == null) {
66  					vendor = attrs.getValue(BUNDLE_VENDOR);
67  				}
68  				String version = attrs.getValue(IMPLEMENTATION_VERSION);
69  				if (version == null) {
70  					version = attrs.getValue(BUNDLE_VERSION);
71  				}
72  				if (ourLog.isDebugEnabled()) {
73  					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 } );
74  				} else {
75  					ourLog.info("FHIR XML procesing will use StAX implementation '{}' version '{}'", title, version);
76  				}
77  			}
78  		} catch (Throwable e) {
79  			ourLog.info("Unable to determine StAX implementation: " + e.getMessage());
80  		}
81  	}
82  	
83  	private static URL getRootUrlForClass(Class<?> cls) {
84  		ClassLoader classLoader = cls.getClassLoader();
85  		String resource = cls.getName().replace('.', '/') + ".class";
86  		if (classLoader == null) {
87  			// A null class loader means the bootstrap class loader. In this case we use the
88  			// system class loader. This is safe since we can assume that the system class
89  			// loader uses parent first as delegation policy.
90  			classLoader = ClassLoader.getSystemClassLoader();
91  		}
92  		URL url = classLoader.getResource(resource);
93  		if (url == null) {
94  			return null;
95  		}
96  		String file = url.getFile();
97  		if (file.endsWith(resource)) {
98  			try {
99  				return new URL(url.getProtocol(), url.getHost(), url.getPort(), file.substring(0, file.length() - resource.length()));
100 			} catch (MalformedURLException ex) {
101 				return null;
102 			}
103 		}
104 		return null;
105 	}
106 }