ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/webresources/JarWarResourceSet.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/webresources/JarWarResourceSet.java
Status
scanned
Type
file
Name
JarWarResourceSet.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
11355 (11.1 KB)
MD5
dfc33cfff3ec193aa6125d49c144c83a
SHA1
05512362620df49da9674802a1c6859e555df7b3
SHA256
80ff7255059baf2f913299a12afa672b9fba49adfbedf91550bc722d362a7f04
SHA512

      
    
SHA1_git
634922e58fb0c1e00925a0c40e20c8f68f5eaf4a
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
JarWarResourceSet.java | 11.1 KB |

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.catalina.webresources; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarInputStream; import java.util.jar.Manifest; import java.util.zip.ZipFile; import org.apache.catalina.LifecycleException; import org.apache.catalina.WebResource; import org.apache.catalina.WebResourceRoot; import org.apache.tomcat.util.buf.UriUtil; /** * Represents a {@link org.apache.catalina.WebResourceSet} based on a JAR file that is nested inside a packed WAR file. * This is only intended for internal use within Tomcat and therefore cannot be created via configuration. */ public class JarWarResourceSet extends AbstractArchiveResourceSet { private final String archivePath; /** * Creates a new {@link org.apache.catalina.WebResourceSet} based on a JAR file that is nested inside a WAR. * * @param root The {@link WebResourceRoot} this new {@link org.apache.catalina.WebResourceSet} will be added * to. * @param webAppMount The path within the web application at which this {@link org.apache.catalina.WebResourceSet} * will be mounted. * @param base The absolute path to the WAR file on the file system in which the JAR is located. * @param archivePath The path within the WAR file where the JAR file is located. * @param internalPath The path within this new {@link org.apache.catalina.WebResourceSet} where resources will be * served from. E.g. for a resource JAR, this would be "META-INF/resources" * * @throws IllegalArgumentException if the webAppMount or internalPath is not valid (valid paths must start with * '/') */ public JarWarResourceSet(WebResourceRoot root, String webAppMount, String base, String archivePath, String internalPath) throws IllegalArgumentException { setRoot(root); setWebAppMount(webAppMount); setBase(base); this.archivePath = archivePath; setInternalPath(internalPath); if (getRoot().getState().isAvailable()) { try { start(); } catch (LifecycleException e) { throw new IllegalStateException(e); } } } @Override protected WebResource createArchiveResource(JarEntry jarEntry, String webAppPath, Manifest manifest) { return new JarWarResource(this, webAppPath, getBaseUrlString(), jarEntry, archivePath); } /** * {@inheritDoc} * <p> * JarWar can't optimise for a single resource so the Map is always returned. */ @Override protected Map<String,JarEntry> getArchiveEntries(boolean single) { synchronized (archiveLock) { if (archiveEntries == null) { JarFile warFile = null; InputStream jarFileIs = null; archiveEntries = new HashMap<>(); boolean multiRelease = false; try { warFile = openJarFile(); JarEntry jarFileInWar = warFile.getJarEntry(archivePath); jarFileIs = warFile.getInputStream(jarFileInWar); try (TomcatJarInputStream jarIs = new TomcatJarInputStream(jarFileIs)) { JarEntry entry = jarIs.getNextJarEntry(); while (entry != null) { archiveEntries.put(entry.getName(), entry); entry = jarIs.getNextJarEntry(); } Manifest m = jarIs.getManifest(); setManifest(m); if (m != null) { String value = m.getMainAttributes().getValue("Multi-Release"); if (value != null) { multiRelease = Boolean.parseBoolean(value); } } // Hack to work-around JarInputStream swallowing these // entries. TomcatJarInputStream is used above which // extends JarInputStream and the method that creates // the entries over-ridden so we can a) tell if the // entries are present and b) cache them so we can // access them here. entry = jarIs.getMetaInfEntry(); if (entry != null) { archiveEntries.put(entry.getName(), entry); } entry = jarIs.getManifestEntry(); if (entry != null) { archiveEntries.put(entry.getName(), entry); } } if (multiRelease) { processArchivesEntriesForMultiRelease(); } } catch (IOException ioe) { // Should never happen archiveEntries = null; throw new IllegalStateException(ioe); } finally { if (warFile != null) { closeJarFile(); } if (jarFileIs != null) { try { jarFileIs.close(); } catch (IOException ignore) { // Ignore } } } } WebResourceRoot root = getRoot(); if (root.getArchiveIndexStrategyEnum().getUsesBloom()) { jarContents = new JarContents(archiveEntries.values()); retainBloomFilterForArchives = root.getArchiveIndexStrategyEnum().getRetain(); } return archiveEntries; } } /** * {@inheritDoc} * <p> * JarWar needs to generate jarContents for the inner JAR, not the outer WAR. */ @Override protected JarFile openJarFile() throws IOException { synchronized (archiveLock) { if (archive == null) { archive = new JarFile(new File(getBase()), true, ZipFile.OPEN_READ, Runtime.version()); // Don't populate JarContents here. Populate at the end of getArchiveEntries() } archiveUseCount++; return archive; } } protected void processArchivesEntriesForMultiRelease() { int targetVersion = Runtime.version().feature(); Map<String,VersionedJarEntry> versionedEntries = new HashMap<>(); Iterator<Entry<String,JarEntry>> iter = archiveEntries.entrySet().iterator(); while (iter.hasNext()) { Entry<String,JarEntry> entry = iter.next(); String name = entry.getKey(); if (name.startsWith("META-INF/versions/")) { // Remove the multi-release version iter.remove(); // Get the base name and version for this versioned entry int i = name.indexOf('/', 18); if (i > 0) { String baseName = name.substring(i + 1); int version = Integer.parseInt(name.substring(18, i)); // Ignore any entries targeting for a later version than // the target for this runtime if (version <= targetVersion) { VersionedJarEntry versionedJarEntry = versionedEntries.get(baseName); if (versionedJarEntry == null) { // No versioned entry found for this name. Create // one. versionedEntries.put(baseName, new VersionedJarEntry(version, entry.getValue())); } else { // Ignore any entry for which we have already found // a later version if (version > versionedJarEntry.version()) { // Replace the entry targeted at an earlier // version versionedEntries.put(baseName, new VersionedJarEntry(version, entry.getValue())); } } } } } } for (Entry<String,VersionedJarEntry> versionedJarEntry : versionedEntries.entrySet()) { archiveEntries.put(versionedJarEntry.getKey(), versionedJarEntry.getValue().jarEntry()); } } /** * {@inheritDoc} * <p> * Should never be called since {@link #getArchiveEntries(boolean)} always returns a Map. */ @Override protected JarEntry getArchiveEntry(String pathInArchive) { throw new IllegalStateException(sm.getString("jarWarResourceSet.codingError")); } @Override protected boolean isMultiRelease() { // This always returns false otherwise the superclass will call // #getArchiveEntry(String) return false; } // -------------------------------------------------------- Lifecycle methods @Override protected void initInternal() throws LifecycleException { try (JarFile warFile = new JarFile(getBase())) { JarEntry jarFileInWar = warFile.getJarEntry(archivePath); InputStream jarFileIs = warFile.getInputStream(jarFileInWar); try (JarInputStream jarIs = new JarInputStream(jarFileIs)) { setManifest(jarIs.getManifest()); } } catch (IOException ioe) { throw new IllegalArgumentException(ioe); } try { setBaseUrl(UriUtil.buildJarSafeUrl(new File(getBase()))); } catch (IOException ioe) { throw new IllegalArgumentException(ioe); } } private record VersionedJarEntry(int version, JarEntry jarEntry) { } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
12.47
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9