public static JarEntryName get(StringSequence spec, int beginIndex) { if (spec.length() <= beginIndex) { return EMPTY_JAR_ENTRY_NAME; } return new JarEntryName(spec.subSequence(beginIndex)); }
@Override protected URLConnection openConnection(URL url) throws IOException { if (this.jarFile != null && isUrlInJarFile(url, this.jarFile)) { return JarURLConnection.get(url, this.jarFile); } try { return JarURLConnection.get(url, getRootJarFileFromUrl(url)); } catch (Exception ex) { return openFallbackConnection(url, ex); } }
JarEntry(JarFile jarFile, CentralDirectoryFileHeader header, AsciiBytes nameAlias) { super((nameAlias != null) ? nameAlias.toString() : header.getName().toString()); this.name = (nameAlias != null) ? nameAlias : header.getName(); this.jarFile = jarFile; this.localHeaderOffset = header.getLocalHeaderOffset(); setCompressedSize(header.getCompressedSize()); setMethod(header.getMethod()); setCrc(header.getCrc()); setComment(header.getComment().toString()); setSize(header.getSize()); setTime(header.getTime()); setExtra(header.getExtra()); }
private JarFile createJarFileFromDirectoryEntry(JarEntry entry) throws IOException { AsciiBytes name = entry.getAsciiBytesName(); JarEntryFilter filter = (candidate) -> { if (candidate.startsWith(name) && !candidate.equals(name)) { return candidate.substring(name.length()); } return null; }; return new JarFile(this.rootFile, this.pathFromRoot + "!/" + entry.getName().substring(0, name.length() - 1), this.data, filter, JarFileType.NESTED_DIRECTORY, this.manifestSupplier); }
private StringSequence decode(StringSequence source) { if (source.isEmpty() || (source.indexOf('%') < 0)) { return source; } ByteArrayOutputStream bos = new ByteArrayOutputStream(source.length()); write(source.toString(), bos); // AsciiBytes is what is used to store the JarEntries so make it symmetric return new StringSequence(AsciiBytes.toString(bos.toByteArray())); }
private void parseEntries(CentralDirectoryEndRecord endRecord, RandomAccessData centralDirectoryData) throws IOException { byte[] bytes = centralDirectoryData.read(0, centralDirectoryData.getSize()); CentralDirectoryFileHeader fileHeader = new CentralDirectoryFileHeader(); int dataOffset = 0; for (int i = 0; i < endRecord.getNumberOfRecords(); i++) { fileHeader.load(bytes, dataOffset, null, 0, null); visitFileHeader(dataOffset, fileHeader); dataOffset += CENTRAL_DIRECTORY_HEADER_BASE_SIZE + fileHeader.getName().length() + fileHeader.getComment().length() + fileHeader.getExtra().length; } }
private JarFile createJarFileFromFileEntry(JarEntry entry) throws IOException { if (entry.getMethod() != ZipEntry.STORED) { throw new IllegalStateException("Unable to open nested entry '" + entry.getName() + "'. It has been compressed and nested " + "jar files must be stored without compression. Please check the " + "mechanism used to create your executable jar file"); } RandomAccessData entryData = this.entries.getEntryData(entry.getName()); return new JarFile(this.rootFile, this.pathFromRoot + "!/" + entry.getName(), entryData, JarFileType.NESTED_JAR); }
@Override public void connect() throws IOException { if (this.jarFile == null) { throw FILE_NOT_FOUND_EXCEPTION; } if (!this.jarEntryName.isEmpty() && this.jarEntry == null) { this.jarEntry = this.jarFile.getJarEntry(getEntryName()); if (this.jarEntry == null) { throwFileNotFound(this.jarEntryName, this.jarFile); } } this.connected = true; }
private <T extends FileHeader> T getEntry(int hashCode, CharSequence name, char suffix, Class<T> type, boolean cacheEntry, AsciiBytes nameAlias) { int index = getFirstIndex(hashCode); while (index >= 0 && index < this.size && this.hashCodes[index] == hashCode) { T entry = getEntry(index, type, cacheEntry, nameAlias); if (entry.hasName((nameAlias != null) ? nameAlias.toString() : name, suffix)) { return entry; } index++; } return null; }
@Override public long getContentLengthLong() { if (this.jarFile == null) { return -1; } try { if (this.jarEntryName.isEmpty()) { return this.jarFile.size(); } JarEntry entry = getJarEntry(); return (entry != null) ? (int) entry.getSize() : -1; } catch (IOException ex) { return -1; } }
public InputStream getInputStream(FileHeader entry) throws IOException { if (entry == null) { return null; } InputStream inputStream = getEntryData(entry).getInputStream(); if (entry.getMethod() == ZipEntry.DEFLATED) { inputStream = new ZipInflaterInputStream(inputStream, (int) entry.getSize()); } return inputStream; }
private RandomAccessData getEntryData(FileHeader entry) throws IOException { // aspectjrt-1.7.4.jar has a different ext bytes length in the // local directory to the central directory. We need to re-read // here to skip them RandomAccessData data = this.jarFile.getData(); byte[] localHeader = data.read(entry.getLocalHeaderOffset(), LOCAL_FILE_HEADER_SIZE); long nameLength = Bytes.littleEndianValue(localHeader, 26, 2); long extraLength = Bytes.littleEndianValue(localHeader, 28, 2); return data.getSubsection(entry.getLocalHeaderOffset() + LOCAL_FILE_HEADER_SIZE + nameLength + extraLength, entry.getCompressedSize()); }
@Override public void visitFileHeader(CentralDirectoryFileHeader fileHeader, int dataOffset) { AsciiBytes name = fileHeader.getName(); if (name.startsWith(META_INF) && name.endsWith(SIGNATURE_FILE_EXTENSION)) { JarFile.this.signed = true; } }
@Override public long getLastModified() { if (this.jarFile == null || this.jarEntryName.isEmpty()) { return 0; } try { JarEntry entry = getJarEntry(); return (entry != null) ? entry.getTime() : 0; } catch (IOException ex) { return 0; } }
private JarFile createJarFileFromEntry(JarEntry entry) throws IOException { if (entry.isDirectory()) { return createJarFileFromDirectoryEntry(entry); } return createJarFileFromFileEntry(entry); }
@Override public void visitFileHeader(CentralDirectoryFileHeader fileHeader, int dataOffset) { AsciiBytes name = applyFilter(fileHeader.getName()); if (name != null) { add(name, dataOffset); } }
private <T extends FileHeader> T doGetEntry(CharSequence name, Class<T> type, boolean cacheEntry, AsciiBytes nameAlias) { int hashCode = AsciiBytes.hashCode(name); T entry = getEntry(hashCode, name, NO_SUFFIX, type, cacheEntry, nameAlias); if (entry == null) { hashCode = AsciiBytes.hashCode(hashCode, SLASH); entry = getEntry(hashCode, name, SLASH, type, cacheEntry, nameAlias); } return entry; }
public long getTime() { long datetime = Bytes.littleEndianValue(this.header, this.headerOffset + 12, 4); return decodeMsDosFormatDateTime(datetime); }