jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModulePoolImpl.java
changeset 39934 9c84ee88dd3a
parent 39933 c0dd0f198453
parent 39922 e613affb88d1
child 39935 6016bd47edc9
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModulePoolImpl.java	Thu Jul 28 09:29:36 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,436 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink.internal;
-
-import java.lang.module.ModuleDescriptor;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Stream;
-import jdk.internal.jimage.decompressor.CompressedResourceHeader;
-import jdk.tools.jlink.plugin.ModulePool;
-import jdk.tools.jlink.plugin.LinkModule;
-import jdk.tools.jlink.plugin.ModuleEntry;
-import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
-
-/**
- * Pool of module data.
- */
-public class ModulePoolImpl implements ModulePool {
-
-    private class ModuleImpl implements LinkModule {
-
-        final Map<String, ModuleEntry> moduleContent = new LinkedHashMap<>();
-        private ModuleDescriptor descriptor;
-        final String name;
-
-        private ModuleImpl(String name) {
-            this.name = name;
-        }
-
-        @Override
-        public String getName() {
-            return name;
-        }
-
-        @Override
-        public Optional<ModuleEntry> findEntry(String path) {
-            if (!path.startsWith("/")) {
-                path = "/" + path;
-            }
-            if (!path.startsWith("/" + name)) {
-                path = "/" + name + path;
-            }
-            return Optional.ofNullable(moduleContent.get(path));
-        }
-
-        @Override
-        public ModuleDescriptor getDescriptor() {
-            if (descriptor == null) {
-                String p = "/" + name + "/module-info.class";
-                Optional<ModuleEntry> content = findEntry(p);
-                if (!content.isPresent()) {
-                    throw new PluginException("No module-info for " + name
-                            + " module");
-                }
-                ByteBuffer bb = ByteBuffer.wrap(content.get().getBytes());
-                descriptor = ModuleDescriptor.read(bb);
-            }
-            return descriptor;
-        }
-
-        @Override
-        public void add(ModuleEntry data) {
-            if (isReadOnly()) {
-                throw new PluginException("ModulePool is readonly");
-            }
-            Objects.requireNonNull(data);
-            if (!data.getModule().equals(name)) {
-                throw new PluginException("Can't add resource " + data.getPath()
-                        + " to module " + name);
-            }
-            ModulePoolImpl.this.add(data);
-        }
-
-        @Override
-        public Set<String> getAllPackages() {
-            Set<String> pkgs = new HashSet<>();
-            moduleContent.values().stream().filter(m -> m.getType().
-                    equals(ModuleEntry.Type.CLASS_OR_RESOURCE)).forEach(res -> {
-                // Module metadata only contains packages with .class files
-                if (ImageFileCreator.isClassPackage(res.getPath())) {
-                    String[] split = ImageFileCreator.splitPath(res.getPath());
-                    String pkg = split[1];
-                    if (pkg != null && !pkg.isEmpty()) {
-                        pkgs.add(pkg);
-                    }
-                }
-            });
-            return pkgs;
-        }
-
-        @Override
-        public String toString() {
-            return getName();
-        }
-
-        @Override
-        public Stream<? extends ModuleEntry> entries() {
-            return moduleContent.values().stream();
-        }
-
-        @Override
-        public int getEntryCount() {
-            return moduleContent.values().size();
-        }
-    }
-
-    private final Map<String, ModuleEntry> resources = new LinkedHashMap<>();
-    private final Map<String, ModuleImpl> modules = new LinkedHashMap<>();
-    private final ModuleImpl fileCopierModule = new ModuleImpl(FileCopierPlugin.FAKE_MODULE);
-    private Map<String, String> releaseProps = new HashMap<>();
-
-    private final ByteOrder order;
-
-    private boolean isReadOnly;
-    private final StringTable table;
-
-    public ModulePoolImpl() {
-        this(ByteOrder.nativeOrder());
-    }
-
-    public ModulePoolImpl(ByteOrder order) {
-        this(order, new StringTable() {
-
-            @Override
-            public int addString(String str) {
-                return -1;
-            }
-
-            @Override
-            public String getString(int id) {
-                return null;
-            }
-        });
-    }
-
-    public ModulePoolImpl(ByteOrder order, StringTable table) {
-        this.order = Objects.requireNonNull(order);
-        this.table = Objects.requireNonNull(table);
-    }
-
-    /**
-     * Add a ModuleEntry.
-     *
-     * @param data The ModuleEntry to add.
-     */
-    @Override
-    public void add(ModuleEntry data) {
-        if (isReadOnly()) {
-            throw new PluginException("ModulePool is readonly");
-        }
-        Objects.requireNonNull(data);
-        if (resources.get(data.getPath()) != null) {
-            throw new PluginException("Resource " + data.getPath()
-                    + " already present");
-        }
-        String modulename = data.getModule();
-        ModuleImpl m = modules.get(modulename);
-        // ## TODO: FileCopierPlugin should not add content to a module
-        // FAKE_MODULE is not really a module to be added in the image
-        if (FileCopierPlugin.FAKE_MODULE.equals(modulename)) {
-            m = fileCopierModule;
-        }
-        if (m == null) {
-            m = new ModuleImpl(modulename);
-            modules.put(modulename, m);
-        }
-        resources.put(data.getPath(), data);
-        m.moduleContent.put(data.getPath(), data);
-    }
-
-    /**
-     * Retrieves the module for the provided name.
-     *
-     * @param name The module name
-     * @return the module of matching name, if found
-     */
-    @Override
-    public Optional<LinkModule> findModule(String name) {
-        Objects.requireNonNull(name);
-        return Optional.ofNullable(modules.get(name));
-    }
-
-    /**
-     * The stream of modules contained in this ModulePool.
-     *
-     * @return The stream of modules.
-     */
-    @Override
-    public Stream<? extends LinkModule> modules() {
-        return modules.values().stream();
-    }
-
-    /**
-     * Return the number of LinkModule count in this ModulePool.
-     *
-     * @return the module count.
-     */
-    @Override
-    public int getModuleCount() {
-        return modules.size();
-    }
-
-    /**
-     * Get all ModuleEntry contained in this ModulePool instance.
-     *
-     * @return The stream of LinkModuleEntries.
-     */
-    @Override
-    public Stream<? extends ModuleEntry> entries() {
-        return resources.values().stream();
-    }
-
-    /**
-     * Return the number of ModuleEntry count in this ModulePool.
-     *
-     * @return the entry count.
-     */
-    @Override
-    public int getEntryCount() {
-        return resources.values().size();
-    }
-
-    /**
-     * Get the ModuleEntry for the passed path.
-     *
-     * @param path A data path
-     * @return A ModuleEntry instance or null if the data is not found
-     */
-    @Override
-    public Optional<ModuleEntry> findEntry(String path) {
-        Objects.requireNonNull(path);
-        return Optional.ofNullable(resources.get(path));
-    }
-
-    /**
-     * Get the ModuleEntry for the passed path restricted to supplied context.
-     *
-     * @param path A data path
-     * @param context A context of the search
-     * @return A ModuleEntry instance or null if the data is not found
-     */
-    @Override
-    public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context) {
-        Objects.requireNonNull(path);
-        Objects.requireNonNull(context);
-        LinkModule module = modules.get(context.getModule());
-        Objects.requireNonNull(module);
-        Optional<ModuleEntry> entry = module.findEntry(path);
-        // Navigating other modules via requires and exports is problematic
-        // since we cannot construct the runtime model of loaders and layers.
-        return entry;
-     }
-
-    /**
-     * Check if the ModulePool contains the given ModuleEntry.
-     *
-     * @param data The module data to check existence for.
-     * @return The module data or null if not found.
-     */
-    @Override
-    public boolean contains(ModuleEntry data) {
-        Objects.requireNonNull(data);
-        return findEntry(data.getPath()).isPresent();
-    }
-
-    /**
-     * Check if the ModulePool contains some content at all.
-     *
-     * @return True, no content, false otherwise.
-     */
-    @Override
-    public boolean isEmpty() {
-        return resources.isEmpty();
-    }
-
-    /**
-     * Visit each ModuleEntry in this ModulePool to transform it and
-     * copy the transformed ModuleEntry to the output ModulePool.
-     *
-     * @param transform The function called for each ModuleEntry found in
-     * the ModulePool. The transform function should return a
-     * ModuleEntry instance which will be added to the output or it should
-     * return null if the passed ModuleEntry is to be ignored for the
-     * output.
-     *
-     * @param output The ModulePool to be filled with Visitor returned
-     * ModuleEntry.
-     */
-    @Override
-    public void transformAndCopy(Function<ModuleEntry, ModuleEntry> transform,
-            ModulePool output) {
-        entries().forEach(resource -> {
-            ModuleEntry res = transform.apply(resource);
-            if (res != null) {
-                output.add(res);
-            }
-        });
-    }
-
-    /**
-     * The ByteOrder currently in use when generating the jimage file.
-     *
-     * @return The ByteOrder.
-     */
-    @Override
-    public ByteOrder getByteOrder() {
-        return order;
-    }
-
-    @Override
-    public Map<String, String> getReleaseProperties() {
-        return isReadOnly()? Collections.unmodifiableMap(releaseProps) : releaseProps;
-    }
-
-    public StringTable getStringTable() {
-        return table;
-    }
-
-    /**
-     * Make this Resources instance read-only. No resource can be added.
-     */
-    public void setReadOnly() {
-        isReadOnly = true;
-    }
-
-    /**
-     * Read only state.
-     *
-     * @return true if readonly false otherwise.
-     */
-    @Override
-    public boolean isReadOnly() {
-        return isReadOnly;
-    }
-
-    /**
-     * A resource that has been compressed.
-     */
-    public static final class CompressedModuleData extends ByteArrayModuleEntry {
-
-        final long uncompressed_size;
-
-        private CompressedModuleData(String module, String path,
-                byte[] content, long uncompressed_size) {
-            super(module, path, ModuleEntry.Type.CLASS_OR_RESOURCE, content);
-            this.uncompressed_size = uncompressed_size;
-        }
-
-        public long getUncompressedSize() {
-            return uncompressed_size;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof CompressedModuleData)) {
-                return false;
-            }
-            CompressedModuleData f = (CompressedModuleData) other;
-            return f.getPath().equals(getPath());
-        }
-
-        @Override
-        public int hashCode() {
-            return super.hashCode();
-        }
-    }
-
-    public static CompressedModuleData newCompressedResource(ModuleEntry original,
-            ByteBuffer compressed,
-            String plugin, String pluginConfig, StringTable strings,
-            ByteOrder order) {
-        Objects.requireNonNull(original);
-        Objects.requireNonNull(compressed);
-        Objects.requireNonNull(plugin);
-
-        boolean isTerminal = !(original instanceof CompressedModuleData);
-        long uncompressed_size = original.getLength();
-        if (original instanceof CompressedModuleData) {
-            CompressedModuleData comp = (CompressedModuleData) original;
-            uncompressed_size = comp.getUncompressedSize();
-        }
-        int nameOffset = strings.addString(plugin);
-        int configOffset = -1;
-        if (pluginConfig != null) {
-            configOffset = strings.addString(plugin);
-        }
-        CompressedResourceHeader rh
-                = new CompressedResourceHeader(compressed.limit(), original.getLength(),
-                        nameOffset, configOffset, isTerminal);
-        // Merge header with content;
-        byte[] h = rh.getBytes(order);
-        ByteBuffer bb = ByteBuffer.allocate(compressed.limit() + h.length);
-        bb.order(order);
-        bb.put(h);
-        bb.put(compressed);
-        byte[] contentWithHeader = bb.array();
-
-        CompressedModuleData compressedResource
-                = new CompressedModuleData(original.getModule(), original.getPath(),
-                        contentWithHeader, uncompressed_size);
-        return compressedResource;
-    }
-
-}