All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.embulk.deps.EmbulkSelfContainedJarFiles Maven / Gradle / Ivy

package org.embulk.deps;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

/**
 * Represents a pre-defined set of self-contained JAR file resources in the Embulk JAR file.
 *
 * 

It is intentionally designed to be a singleton. {@link DependencyClassLoader} is introduced only for dependency * visibility, not for customizability. It should not be customizable so flexibly. */ public final class EmbulkSelfContainedJarFiles { private EmbulkSelfContainedJarFiles() { // No instantiation. } public static final class StaticInitializer { private StaticInitializer() { this.jarFileResources = new HashMap<>(); } public StaticInitializer addJarFileResources(final String category, final Collection resources) { this.jarFileResources.compute(category, (dummy, old) -> { final ArrayList targetList = (old != null) ? old : new ArrayList(); targetList.addAll(resources); return targetList; }); return this; } public StaticInitializer addFromManifest(final Manifest manifest) { final Attributes attributes = manifest.getMainAttributes(); // embulk-core's own self-contained dependencies this.addJarFileResources(CORE, splitAttribute(attributes.getValue("Embulk-Resource-Class-Path"))); // self-contained plugins final List pluginNames = splitAttribute(attributes.getValue("Embulk-Plugins")); for (final String pluginName : pluginNames) { this.addJarFileResources(pluginName, splitAttribute(attributes.getValue("Embulk-Plugin-" + pluginName))); } return this; } public void initialize() { initializeAll(this.jarFileResources); } private final HashMap> jarFileResources; } public static StaticInitializer staticInitializer() { return new StaticInitializer(); } public static boolean has(final String category) { return JAR_RESOURCE_NAMES.containsKey(category); } /** * Returns the JAR manifest of the first JAR resource in the category. * *

This is for self-contained plugins. Plugin's main JAR file (e.g. {@code embulk-input-file.jar}) should be * listed first in the {@code Embulk-Plugin-*} (e.g. {@code Embulk-Plugin-embulk-input-file}) attribute of * Embulk executable's top-level manifest. * *

{@code Embulk-Plugin-embulk-decoder-gzip: /lib/embulk-decoder-gzip.jar /lib/commons-compress-1.10.jar}
*/ public static Manifest getFirstManifest(final String category) { final List jarResourceNames = JAR_RESOURCE_NAMES.get(category); if (jarResourceNames.isEmpty()) { return null; } final String firstJarResourceName = jarResourceNames.get(0); final SelfContainedJarFile selfContainedJarFile = Holder.INSTANCE.get(firstJarResourceName); return selfContainedJarFile.getManifest(); } /** * It must be called initially at once before all other getResource*() methods are called. * * public to be called from org.embulk.cli. Not for plugins. Not guaranteed. */ private static void initializeAll(final HashMap> jarFileResources) { synchronized (JAR_RESOURCE_NAMES) { if (JAR_RESOURCE_NAMES.isEmpty()) { for (final Map.Entry> entry : jarFileResources.entrySet()) { JAR_RESOURCE_NAMES.put(entry.getKey(), entry.getValue()); } } else { throw new LinkageError("Double initialization of self-contained JAR files."); } } } static Resource getSingleResource(final String targetResourceName, final String category) { if (category == null) { throw new NullPointerException("EmbulkSelfContainedJarFiles.getSingleResources received null."); } final List jarResourceNames = JAR_RESOURCE_NAMES.get(category); if (jarResourceNames == null) { throw new IllegalArgumentException( "EmbulkSelfContainedJarFiles.getSingleResources received unexpected category: " + category); } String foundJarResourceName = null; Resource resourceToReturn = null; for (final String jarResourceName : jarResourceNames) { final SelfContainedJarFile selfContainedJarFile = Holder.INSTANCE.get(jarResourceName); final Resource resourceFound = selfContainedJarFile.getResource(targetResourceName); if (resourceFound != null) { if (resourceToReturn != null) { throw new LinkageError(String.format("Duplicated resource: '%s' in '%s' v.s. '%s'", targetResourceName, foundJarResourceName, jarResourceName)); } foundJarResourceName = jarResourceName; resourceToReturn = resourceFound; } } return resourceToReturn; } static Collection getMultipleResources(final String targetResourceName, final String category) { if (category == null) { throw new NullPointerException("EmbulkSelfContainedJarFiles.getMultipleResources received null."); } final List jarResourceNames = JAR_RESOURCE_NAMES.get(category); if (jarResourceNames == null) { throw new IllegalArgumentException( "EmbulkSelfContainedJarFiles.getMultipleResources received unexpected category: " + category); } final ArrayList resourcesToReturn = new ArrayList<>(); for (final String jarResourceName : jarResourceNames) { final SelfContainedJarFile selfContainedJarFile = Holder.INSTANCE.get(jarResourceName); final Resource resourceFound = selfContainedJarFile.getResource(targetResourceName); if (resourceFound != null) { resourcesToReturn.add(resourceFound); } } return resourcesToReturn; } private static class Holder { // Initialization-on-demand holder idiom. static final Map INSTANCE; static { final HashSet allJarResourceNames = new HashSet<>(); for (final Map.Entry> entry : JAR_RESOURCE_NAMES.entrySet()) { for (final String jarResourceName : entry.getValue()) { allJarResourceNames.add(jarResourceName); } } final HashMap instanceBuilt = new HashMap<>(); for (final String jarResourceName : allJarResourceNames) { instanceBuilt.put(jarResourceName, new SelfContainedJarFile(jarResourceName)); } INSTANCE = Collections.unmodifiableMap(instanceBuilt); } } private static List splitAttribute(final String value) { final ArrayList list = new ArrayList<>(); if (value != null) { final StringTokenizer tokenizer = new StringTokenizer(value); while (tokenizer.hasMoreTokens()) { list.add(tokenizer.nextToken()); } } return list; } // Category for embulk-core's own self-contained dependencies. public static final String CORE = "$embulk-deps$"; // Note this is technically mutable -- so that it can be initialized lazily via StaticInitializer. private static final HashMap> JAR_RESOURCE_NAMES = new HashMap<>(); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy