/** * Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org> * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.seedstack.seed.web.internal.scan.tomcat; import com.google.common.collect.AbstractIterator; import org.reflections.vfs.Vfs; import org.seedstack.seed.SeedException; import org.seedstack.seed.web.internal.WebErrorCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URL; import java.util.jar.JarInputStream; import java.util.zip.ZipEntry; /** * VFS directory implementation for JNDI JAR scanning. */ class JndiJarInputDir implements Vfs.Dir { private static final Logger LOGGER = LoggerFactory.getLogger(JndiJarInputDir.class); private final URL url; private JarInputStream jarInputStream; JndiJarInputDir(URL url) { this.url = url; } @Override public String getPath() { return url.getPath(); } @Override public Iterable<Vfs.File> getFiles() { return () -> new AbstractIterator<Vfs.File>() { { try { jarInputStream = new JarInputStream(url.openConnection().getInputStream()); } catch (Exception e) { LOGGER.warn("Unable to open JAR at {}, ignoring it", url.toExternalForm(), e); } } @Override protected Vfs.File computeNext() { if (jarInputStream == null) { return endOfData(); } while (true) { try { ZipEntry entry = jarInputStream.getNextEntry(); if (entry == null) { return endOfData(); } if (!entry.isDirectory()) { return new JndiJarInputFile(entry, jarInputStream); } } catch (IOException e) { throw SeedException.wrap(e, WebErrorCode.UNABLE_TO_SCAN_TOMCAT_JNDI_JAR).put("url", url.toExternalForm()); } } } }; } @Override public void close() { try { jarInputStream.close(); } catch (IOException e) { LOGGER.warn("Unable to close JAR at {}", url.toExternalForm(), e); } } }