001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.utils; 014 015import static org.apache.juneau.internal.IOUtils.*; 016 017import java.io.*; 018import java.net.*; 019import java.util.*; 020import java.util.jar.*; 021 022import org.apache.juneau.*; 023import org.apache.juneau.internal.*; 024 025/** 026 * Utility class for working with Jar manifest files. 027 * 028 * <p> 029 * Copies the contents of a {@link Manifest} into an {@link ObjectMap} so that the various convenience methods on that 030 * class can be used to retrieve values. 031 */ 032public class ManifestFile extends ObjectMap { 033 034 private static final long serialVersionUID = 1L; 035 036 /** 037 * Create an instance of this class from a manifest file on the file system. 038 * 039 * @param f The manifest file. 040 * @throws IOException If a problem occurred while trying to read the manifest file. 041 */ 042 public ManifestFile(File f) throws IOException { 043 Manifest mf = new Manifest(); 044 try (FileInputStream fis = new FileInputStream(f)) { 045 mf.read(fis); 046 load(mf); 047 } catch (IOException e) { 048 throw new IOException("Problem detected in MANIFEST.MF. Contents below:\n" + read(f), e); 049 } 050 } 051 052 /** 053 * Create an instance of this class from a {@link Manifest} object. 054 * 055 * @param f The manifest to read from. 056 */ 057 public ManifestFile(Manifest f) { 058 load(f); 059 } 060 061 /** 062 * Finds and loads the manifest file of the jar file that the specified class is contained within. 063 * 064 * @param c The class to get the manifest file of. 065 * @throws IOException If a problem occurred while trying to read the manifest file. 066 */ 067 public ManifestFile(Class<?> c) throws IOException { 068 String className = c.getSimpleName() + ".class"; 069 String classPath = c.getResource(className).toString(); 070 if (! classPath.startsWith("jar")) { 071 return; 072 } 073 String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF"; 074 try { 075 Manifest mf = new Manifest(new URL(manifestPath).openStream()); 076 load(mf); 077 } catch (MalformedURLException e) { 078 throw new IOException(e); 079 } catch (IOException e) { 080 e.printStackTrace(); 081 } 082 } 083 084 /** 085 * Create an instance of this class loaded from the contents of a reader. 086 * 087 * <p> 088 * Note that the input must end in a newline to pick up the last line! 089 * 090 * @param r The manifest file contents. 091 * @throws IOException If a problem occurred while trying to read the manifest file. 092 */ 093 public ManifestFile(Reader r) throws IOException { 094 load(new Manifest(IOUtils.toInputStream(r))); 095 } 096 097 /** 098 * Create an instance of this class loaded from the contents of an input stream. 099 * 100 * <p> 101 * Note that the input must end in a newline to pick up the last line! 102 * 103 * @param is The manifest file contents. 104 * @throws IOException If a problem occurred while trying to read the manifest file. 105 */ 106 public ManifestFile(InputStream is) throws IOException { 107 load(new Manifest(is)); 108 } 109 110 private void load(Manifest mf) { 111 for (Map.Entry<Object,Object> e : mf.getMainAttributes().entrySet()) 112 put(e.getKey().toString(), e.getValue().toString()); 113 } 114 115 @Override /* Object */ 116 public String toString() { 117 StringBuilder sb = new StringBuilder(); 118 for (Map.Entry<String,Object> e : entrySet()) 119 sb.append(e.getKey()).append(": ").append(e.getValue()); 120 return sb.toString(); 121 } 122}