private void write(String source, ByteArrayOutputStream outputStream) { int length = source.length(); for (int i = 0; i < length; i++) { int c = source.charAt(i); if (c > 127) { try { String encoded = URLEncoder.encode(String.valueOf((char) c), "UTF-8"); write(encoded, outputStream); } catch (UnsupportedEncodingException ex) { throw new IllegalStateException(ex); } } else { if (c == '%') { if ((i + 2) >= length) { throw new IllegalArgumentException( "Invalid encoded sequence \"" + source.substring(i) + "\""); } c = decodeEscapeSequence(source, i); i += 2; } outputStream.write(c); } } }
static JarURLConnection get(URL url, JarFile jarFile) throws IOException { StringSequence spec = new StringSequence(url.getFile()); int index = indexOfRootSpec(spec, jarFile.getPathFromRoot()); if (index == -1) { return (Boolean.TRUE.equals(useFastExceptions.get()) ? NOT_FOUND_CONNECTION : new JarURLConnection(url, null, EMPTY_JAR_ENTRY_NAME)); } int separator; while ((separator = spec.indexOf(SEPARATOR, index)) > 0) { JarEntryName entryName = JarEntryName.get(spec.subSequence(index, separator)); JarEntry jarEntry = jarFile.getJarEntry(entryName.toCharSequence()); if (jarEntry == null) { return JarURLConnection.notFound(jarFile, entryName); } jarFile = jarFile.getNestedJarFile(jarEntry); index = separator + SEPARATOR.length(); } JarEntryName jarEntryName = JarEntryName.get(spec, index); if (Boolean.TRUE.equals(useFastExceptions.get()) && !jarEntryName.isEmpty() && !jarFile.containsEntry(jarEntryName.toString())) { return NOT_FOUND_CONNECTION; } return new JarURLConnection(url, jarFile, jarEntryName); }
@Override public InputStream getInputStream() throws IOException { if (this.jarFile == null) { throw FILE_NOT_FOUND_EXCEPTION; } if (this.jarEntryName.isEmpty() && this.jarFile.getType() == JarFile.JarFileType.DIRECT) { throw new IOException("no entry name specified"); } connect(); InputStream inputStream = (this.jarEntryName.isEmpty() ? this.jarFile.getData().getInputStream() : this.jarFile.getInputStream(this.jarEntry)); if (inputStream == null) { throwFileNotFound(this.jarEntryName, this.jarFile); } return inputStream; }
@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 static JarEntryName get(StringSequence spec) { return get(spec, 0); }
JarEntryName(StringSequence spec) { this.name = decode(spec); }
@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; } }
@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; }
public String getContentType() { if (this.contentType == null) { this.contentType = deduceContentType(); } return this.contentType; }
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())); }
@Override public String getEntryName() { if (this.jarFile == null) { throw NOT_FOUND_CONNECTION_EXCEPTION; } return this.jarEntryName.toString(); }
@Override public String getContentType() { return (this.jarEntryName != null) ? this.jarEntryName.getContentType() : null; }
public static JarEntryName get(StringSequence spec, int beginIndex) { if (spec.length() <= beginIndex) { return EMPTY_JAR_ENTRY_NAME; } return new JarEntryName(spec.subSequence(beginIndex)); }
@Override public JarEntry getJarEntry() throws IOException { if (this.jarEntryName == null || this.jarEntryName.isEmpty()) { return null; } connect(); return this.jarEntry; }
@Override public Object getContent() throws IOException { connect(); return this.jarEntryName.isEmpty() ? this.jarFile : super.getContent(); }