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

org.microbean.helm.chart.URLChartLoader Maven / Gradle / Ivy

The newest version!
/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
 *
 * Copyright © 2017-2018 microBean.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package org.microbean.helm.chart;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.util.IdentityHashMap;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Objects;

import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;

import hapi.chart.ChartOuterClass.Chart; // for javadoc only

import org.kamranzafar.jtar.TarInputStream;

/**
 * A {@link StreamOrientedChartLoader StreamOrientedChartLoader<URL>} that creates
 * {@link Chart} instances from {@link URL} instances.
 *
 * 

Thread Safety

* *

This class is safe for concurrent use by multiple threads.

* * @author Laird Nelson * * @see #toNamedInputStreamEntries(URL) * * @see StreamOrientedChartLoader */ public class URLChartLoader extends StreamOrientedChartLoader { /** * Resources to be closed by the {@link #close()} method. * *

This field is never {@code null}.

*/ private final IdentityHashMap closeables; /* * Constructors. */ /** * Creates a new {@link URLChartLoader}. */ public URLChartLoader() { super(); this.closeables = new IdentityHashMap<>(); } /* * Instance methods. */ /** * Converts the supplied {@link URL} into an {@link Iterable} of * {@link Entry} instances, each of which consists of an {@link * InputStream} representing a resource within a Helm chart together * with its (relative to the chart) name. * *

This method never returns {@code null}.

* *

Overrides of this method are not permitted to return {@code * null}. * * @param url the {@link URL} to dereference; must be non-{@code * null} or an effectively empty {@link Iterable} will be returned * * @return a non-{@code null} {@link Iterable} of {@link Entry} * instances representing named {@link InputStream}s * * @exception IOException if there is a problem reading from the * supplied {@link URL} */ @Override protected Iterable> toNamedInputStreamEntries(final URL url) throws IOException { Objects.requireNonNull(url); final String scheme = url.getProtocol(); Path path = null; if ("file".equals(scheme)) { URI uri = null; try { uri = url.toURI(); } catch (final URISyntaxException wrapMe) { throw new IllegalArgumentException(wrapMe.getMessage(), wrapMe); } assert uri != null; try { path = Paths.get(uri); } catch (final IllegalArgumentException notAFile) { path = null; } } final Iterable> returnValue; if (path == null || !Files.isDirectory(path)) { final String urlString = url.toString(); assert urlString != null; if (urlString.endsWith(".zip") || urlString.endsWith(".jar")) { final ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(this.openStream(url))); this.closeables.put(zipInputStream, null); final ZipInputStreamChartLoader loader = new ZipInputStreamChartLoader(); this.closeables.put(loader, null); returnValue = loader.toNamedInputStreamEntries(zipInputStream); } else { final TarInputStream tarInputStream = new TarInputStream(new GZIPInputStream(new BufferedInputStream(this.openStream(url)))); this.closeables.put(tarInputStream, null); final TapeArchiveChartLoader loader = new TapeArchiveChartLoader(); this.closeables.put(loader, null); returnValue = loader.toNamedInputStreamEntries(tarInputStream); } } else { final DirectoryChartLoader loader = new DirectoryChartLoader(); this.closeables.put(loader, null); returnValue = loader.toNamedInputStreamEntries(path); } return returnValue; } /** * Returns an {@link InputStream} corresponding to the supplied * {@link URL}. * *

This method may return {@code null}.

* *

Overrides of this method are permitted to return {@code * null}.

* * @param url the {@link URL} whose affiliated {@link InputStream} * should be returned; may be {@code null} in which case {@code * null} will be returned * * @return an {@link InputStream} appropriate for the supplied * {@link URL}, or {@code null} * * @exception IOException if an error occurs while connecting to the * supplied {@link URL} */ protected InputStream openStream(final URL url) throws IOException { InputStream returnValue = null; if (url != null) { final URLConnection urlConnection = url.openConnection(); assert urlConnection != null; urlConnection.setRequestProperty("User-Agent", "microbean-helm"); returnValue = urlConnection.getInputStream(); } return returnValue; } /** * Closes resources opened by this {@link URLChartLoader}'s {@link * #toNamedInputStreamEntries(URL)} method. * * @exception IOException if a subclass has overridden this method * and an error occurs */ @Override public void close() throws IOException { if (!this.closeables.isEmpty()) { final Collection keys = this.closeables.keySet(); if (keys != null && !keys.isEmpty()) { final Iterator iterator = keys.iterator(); if (iterator != null) { while (iterator.hasNext()) { final AutoCloseable closeable = iterator.next(); if (closeable != null) { try { closeable.close(); } catch (final IOException | RuntimeException throwMe) { throw throwMe; } catch (final Exception willNeverHappen) { throw new AssertionError(willNeverHappen); } } iterator.remove(); } } } } assert this.closeables.isEmpty(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy