package org.basex.io;
import static org.basex.core.Text.*;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.util.regex.Pattern;
import org.basex.core.BaseXException;
import org.basex.core.Prop;
import org.basex.io.in.BufferInput;
import org.basex.util.Util;
import org.basex.util.list.ByteList;
import org.xml.sax.InputSource;
/**
* {@link IO} reference, representing a URL.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public final class IOUrl extends IO {
/**
* Constructor.
* @param u url
*/
public IOUrl(final String u) {
super(u);
}
@Override
public byte[] read() throws IOException {
final ByteList bl = new ByteList();
final BufferedInputStream bis = new BufferedInputStream(inputStream());
try {
for(int b; (b = bis.read()) != -1;) bl.add(b);
} finally {
try { bis.close(); } catch(final IOException ex) { }
}
return bl.toArray();
}
@Override
public InputSource inputSource() {
return new InputSource(path);
}
@Override
public BufferInput buffer() throws IOException {
return new BufferInput(inputStream());
}
/**
* Returns the input stream.
* @return input stream
* @throws IOException I/O exception
*/
private InputStream inputStream() throws IOException {
final URL url = new URL(path);
try {
return url.openStream();
} catch(final RuntimeException ex) {
// catch unexpected runtime exceptions
Util.debug(ex);
throw new BaseXException(NOT_PARSED_X, path);
}
}
@Override
public long length() {
return 0;
}
@Override
public IO merge(final String f) {
final IO io = IO.get(f);
if(!(io instanceof IOFile)) return io;
final String p = path;
return IO.get((p.endsWith("/") ? p : p.replace("^(.*/).*", "$1")) + f);
}
/** Pattern for duplicate slashes. */
private static final Pattern DUPLSLASH = Pattern.compile("//+");
/** Pattern for leading slash in Windows paths. */
private static final Pattern LEADSLASH = Pattern.compile("^/([A-Za-z]:)");
/**
* Creates a file path from the specified URL.
* @param url url to be converted
* @return file path
*/
public static String file(final String url) {
String file = url;
try {
if(file.indexOf('%') != -1) file = URLDecoder.decode(file, Prop.ENCODING);
} catch(final Exception ex) { /* ignored. */ }
// remove file scheme
if(file.startsWith(FILEPREF)) file = file.substring(FILEPREF.length());
// remove duplicate slashes and leading slash in Windows paths
if(file.contains("//")) file = DUPLSLASH.matcher(file).replaceAll("/");
return LEADSLASH.matcher(file).replaceFirst("$1");
}
}