org.jopendocument.util.protocol.jarjar.Handler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jOpenDocument Show documentation
Show all versions of jOpenDocument Show documentation
jOpenDocument is a free library for developers looking to use
Open Document files without OpenOffice.org.
The newest version!
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008-2013 jOpenDocument, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU
* General Public License Version 3 only ("GPL").
* You may not use this file except in compliance with the License.
* You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
* See the License for the specific language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*
*/
package org.jopendocument.util.protocol.jarjar;
/*******************************************************************************
* Copyright (c) 2009 Pavel Savara as part of Robocode project All rights reserved. This program and
* the accompanying materials are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/cpl-v10.html
*
* Contributors: Pavel Savara - JarJarURLStreamHandler is just tweaked version of jar handler from
* OpenJDK, license below
*******************************************************************************/
/*
* Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. DO NOT ALTER OR REMOVE COPYRIGHT
* NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License version 2 only, as published by the Free Software Foundation. Sun
* designates this particular file as subject to the "Classpath" exception as provided by Sun in the
* LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version 2 along with this work;
* if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, CA 95054 USA or visit
* www.sun.com if you need additional information or have any questions.
*/
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
public class Handler extends URLStreamHandler {
protected URLConnection openConnection(URL u) throws IOException {
return new JarJarURLConnection(u);
}
private int indexOfBangSlash(String spec) {
int indexOfBang = spec.length();
while ((indexOfBang = spec.lastIndexOf(JarJarURLConnection.SEPARATOR_CHAR, indexOfBang)) != -1) {
if ((indexOfBang != (spec.length() - 1)) && (spec.charAt(indexOfBang + 1) == '/')) {
return indexOfBang + 1;
} else {
indexOfBang--;
}
}
return -1;
}
@SuppressWarnings( { "deprecation" })
protected void parseURL(URL url, String spec, int start, int limit) {
String file = null;
String ref = null;
// first figure out if there is an anchor
int refPos = spec.indexOf('#', limit);
boolean refOnly = refPos == start;
if (refPos > -1) {
ref = spec.substring(refPos + 1, spec.length());
if (refOnly) {
file = url.getFile();
}
}
// then figure out if the spec is
// 1. absolute (jarjar:)
// 2. relative (i.e. url + foo/bar/baz.ext)
// 3. anchor-only (i.e. url + #foo), which we already did (refOnly)
boolean absoluteSpec = false;
if (spec.length() >= 7) {
absoluteSpec = spec.substring(0, 7).equalsIgnoreCase("jarjar:");
}
spec = spec.substring(start, limit);
if (absoluteSpec) {
file = parseAbsoluteSpec(spec);
} else if (!refOnly) {
file = parseContextSpec(url, spec);
// Canonize the result after the bangslash
int bangSlash = indexOfBangSlash(file);
String toBangSlash = file.substring(0, bangSlash);
String afterBangSlash = file.substring(bangSlash);
file = toBangSlash + afterBangSlash;
}
file = file != null ? "jar:" + file.replaceFirst("\\" + JarJarURLConnection.SEPARATOR, "!/") : null;
setURL(url, "jarjar", "", -1, file, ref);
}
@SuppressWarnings( { "UnusedAssignment", "UnusedDeclaration" })
private String parseAbsoluteSpec(String spec) {
@SuppressWarnings("unused")
URL url = null;
int index = -1;
// check for !/
if ((index = indexOfBangSlash(spec)) == -1) {
throw new IllegalArgumentException("no " + JarJarURLConnection.SEPARATOR + " in spec");
}
// test the inner URL
try {
String innerSpec = spec.substring(0, index - 1);
url = new URL(innerSpec);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("invalid url: " + spec + " (" + e + ")");
}
return spec;
}
private String parseContextSpec(URL url, String spec) {
String ctxFile = url.getFile();
// if the spec begins with /, chop up the jar back !/
if (spec.startsWith("/")) {
int bangSlash = indexOfBangSlash(ctxFile);
if (bangSlash == -1) {
throw new NullPointerException("malformed " + "context url:" + url + ": no " + JarJarURLConnection.SEPARATOR);
}
ctxFile = ctxFile.substring(0, bangSlash);
}
if (!ctxFile.endsWith("/") && (!spec.startsWith("/"))) {
// chop up the last component
int lastSlash = ctxFile.lastIndexOf('/');
if (lastSlash == -1) {
throw new NullPointerException("malformed " + "context url:" + url);
}
ctxFile = ctxFile.substring(0, lastSlash + 1);
}
return (ctxFile + spec);
}
/**
* @author Pavel Savara
*/
static public class JarJarURLConnection extends URLConnection {
private URLConnection connection;
public final static char SEPARATOR_CHAR = '^';
public final static String SEPARATOR = SEPARATOR_CHAR + "/";
public JarJarURLConnection(URL url) throws IOException {
super(url);
final String file = url.getFile();
URL inner = new URL(file);
connection = inner.openConnection();
}
public void connect() throws IOException {
if (!connected) {
connection.connect();
connected = true;
}
}
public InputStream getInputStream() throws IOException {
connect();
return connection.getInputStream();
}
}
}