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; 26 27 import java.nio.ByteBuffer; 28 import java.nio.ByteOrder; 29 import java.util.Collection; 30 import java.util.Collections; 31 import java.util.HashSet; 32 import java.util.LinkedHashMap; 33 import java.util.Map; 34 import java.util.Objects; 35 import java.util.Set; 36 37 /** 38 * Pool of resources. This class contain the content of a jimage file in the 39 * matter of Resource. 40 */ 41 public class ResourcePoolImpl implements ResourcePool { 42 43 private final Map<String, Resource> resources = new LinkedHashMap<>(); 44 45 private final ByteOrder order; 46 private boolean isReadOnly; 47 48 public ResourcePoolImpl(ByteOrder order) { 49 Objects.requireNonNull(order); 50 this.order = order; 51 } 52 53 /** 54 * Make this Resources instance read-only. No resource can be added. 55 */ 56 public void setReadOnly() { 57 isReadOnly = true; 58 } 59 60 /** 61 * Read only state. 62 * 63 * @return true if readonly false otherwise. 64 */ 65 @Override 66 public boolean isReadOnly() { 67 return isReadOnly; 68 } 69 70 /** 71 * The byte order 72 * 73 * @return 74 */ 75 @Override 76 public ByteOrder getByteOrder() { 77 return order; 78 } 79 80 /** 81 * Add a resource. 82 * 83 * @param resource The Resource to add. 84 * @throws java.lang.Exception If the pool is read only. 85 */ 86 @Override 87 public void addResource(Resource resource) throws Exception { 88 if (isReadOnly()) { 89 throw new Exception("pool is readonly"); 90 } 91 Objects.requireNonNull(resource); 92 if (resources.get(resource.getPath()) != null) { 93 throw new Exception("Resource" + resource.getPath() + 94 " already present"); 95 } 96 resources.put(resource.getPath(), resource); 97 } 98 99 /** 100 * Check if a resource is contained in the pool. 101 * 102 * @param res The resource to check. 103 * @return true if res is contained, false otherwise. 104 */ 105 @Override 106 public boolean contains(Resource res) { 107 Objects.requireNonNull(res); 108 try { 109 getResource(res.getPath()); 110 return true; 111 } catch (Exception ex) { 112 return false; 113 } 114 } 115 116 /** 117 * Get all resources contained in this pool instance. 118 * 119 * @return The collection of resources; 120 */ 121 @Override 122 public Collection<Resource> getResources() { 123 return Collections.unmodifiableCollection(resources.values()); 124 } 125 126 /** 127 * Get the resource for the passed path. 128 * 129 * @param path A resource path 130 * @return A Resource instance or null if the resource is not found 131 */ 132 @Override 133 public Resource getResource(String path) { 134 Objects.requireNonNull(path); 135 return resources.get(path); 136 } 137 138 /** 139 * The Image modules. It is computed based on the resources contained by 140 * this ResourcePool instance. 141 * 142 * @return The Image Modules. 143 */ 144 @Override 145 public Map<String, Set<String>> getModulePackages() { 146 Map<String, Set<String>> moduleToPackage = new LinkedHashMap<>(); 147 retrieveModulesPackages(moduleToPackage); 148 return moduleToPackage; 149 } 150 151 /** 152 * Check if this pool contains some resources. 153 * 154 * @return True if contains some resources. 155 */ 156 @Override 157 public boolean isEmpty() { 158 return resources.isEmpty(); 159 } 160 161 /** 162 * Visit the resources contained in this ResourcePool. 163 * 164 * @param visitor The visitor 165 * @param strings 166 * @throws Exception 167 */ 168 @Override 169 public void visit(Visitor visitor, ResourcePool output, StringTable strings) 170 throws Exception { 171 for (Resource resource : getResources()) { 172 Resource res = visitor.visit(resource, order, strings); 173 if (res != null) { 174 output.addResource(res); 175 } 176 } 177 } 178 179 @Override 180 public void addTransformedResource(Resource original, ByteBuffer transformed) 181 throws Exception { 182 if (isReadOnly()) { 183 throw new Exception("Pool is readonly"); 184 } 185 Objects.requireNonNull(original); 186 Objects.requireNonNull(transformed); 187 if (resources.get(original.getPath()) != null) { 188 throw new Exception("Resource already present"); 189 } 190 Resource res = new Resource(original.getPath(), transformed); 191 addResource(res); 192 } 193 194 private void retrieveModulesPackages(Map<String, Set<String>> moduleToPackage) { 195 for (Resource res : resources.values()) { 196 Set<String> pkgs = moduleToPackage.get(res.getModule()); 197 if (pkgs == null) { 198 pkgs = new HashSet<>(); 199 moduleToPackage.put(res.getModule(), pkgs); 200 } 201 // Module metadata only contains packages with resource files 202 if (ImageFileCreator.isResourcePackage(res.getPath())) { 203 String[] split = ImageFileCreator.splitPath(res.getPath()); 204 String pkg = split[1]; 205 if (pkg != null && !pkg.isEmpty()) { 206 pkgs.add(pkg); 207 } 208 } 209 } 210 } 211 }