1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package jdk.internal.jimage.decompressor; 26 27 import java.io.ByteArrayInputStream; 28 import java.io.IOException; 29 import java.nio.ByteOrder; 30 import java.util.HashMap; 31 import java.util.Map; 32 import java.util.Objects; 33 import java.util.Properties; 34 import jdk.internal.jimage.decompressor.ResourceDecompressor.StringsProvider; 35 36 /** 37 * Entry point to decompress resources. 38 */ 39 public final class Decompressor { 40 41 private final Map<Integer, ResourceDecompressor> pluginsCache = new HashMap<>(); 42 43 public Decompressor() { 44 } 45 46 /** 47 * Decompress a resource. 48 * @param order Byte order. 49 * @param provider Strings provider 50 * @param content The resource content to uncompress. 51 * @return A fully uncompressed resource. 52 * @throws IOException 53 */ 54 public byte[] decompressResource(ByteOrder order, StringsProvider provider, 55 byte[] content) throws IOException { 56 Objects.requireNonNull(order); 57 Objects.requireNonNull(provider); 58 Objects.requireNonNull(content); 59 CompressedResourceHeader header; 60 do { 61 header = CompressedResourceHeader.readFromResource(order, content); 62 if (header != null) { 63 ResourceDecompressor decompressor = 64 pluginsCache.get(header.getDecompressorNameOffset()); 65 if (decompressor == null) { 66 String pluginName = 67 provider.getString(header.getDecompressorNameOffset()); 68 if (pluginName == null) { 69 throw new IOException("Plugin name not found"); 70 } 71 String storedContent = header.getStoredContent(provider); 72 Properties props = new Properties(); 73 if (storedContent != null) { 74 try (ByteArrayInputStream stream = 75 new ByteArrayInputStream(storedContent.getBytes());) { 76 props.loadFromXML(stream); 77 } 78 } 79 decompressor = ResourceDecompressorRepository. 80 newResourceDecompressor(props, pluginName); 81 if (decompressor == null) { 82 throw new IOException("Plugin not found: " + pluginName); 83 } 84 85 pluginsCache.put(header.getDecompressorNameOffset(), decompressor); 86 } 87 try { 88 content = decompressor.decompress(provider, content, 89 CompressedResourceHeader.getSize(), header.getUncompressedSize()); 90 } catch (Exception ex) { 91 throw new IOException(ex); 92 } 93 } 94 } while (header != null); 95 return content; 96 } 97 }