package com.jogamp.common.net;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import com.jogamp.common.os.AndroidVersion;
import com.jogamp.common.util.IOUtil;
/**
* See {@link PiggybackURLConnection} for description and examples.
*/
public abstract class AssetURLContext implements PiggybackURLContext {
private static final boolean DEBUG = IOUtil.DEBUG;
/** The asset URL protocol name asset
*/
public static final String asset_protocol = "asset";
/** The asset URL protocol prefix asset:
*/
public static final String asset_protocol_prefix = "asset:";
/**
* The optional asset folder name with ending slash assets/
.
*
* Note that the asset folder is not used on all platforms using the asset protocol * and you should not rely on it, use {@link AssetURLConnection#getEntryName()}. *
**/ public static final String assets_folder = "assets/"; public static AssetURLContext create(final ClassLoader cl) { return new AssetURLContext() { @Override public ClassLoader getClassLoader() { return cl; } }; } public static AssetURLStreamHandler createHandler(final ClassLoader cl) { return new AssetURLStreamHandler(create(cl)); } /** * Create an asset URL, suitable even w/o the registered asset URLStreamHandler. ** This is equivalent with: *
* return new URL(null, path.startsWith("asset:") ? path : "asset:" + path, new AssetURLStreamHandler(cl)); ** * @param path resource path, with or w/o
asset:
prefix
* @param cl the ClassLoader used to resolve the location, see {@link #getClassLoader()}.
* @return
* @throws MalformedURLException
*/
public static URL createURL(final String path, final ClassLoader cl) throws MalformedURLException {
return new URL(null, path.startsWith(asset_protocol_prefix) ? path : asset_protocol_prefix + path, createHandler(cl));
}
/**
* Create an asset URL, suitable only with the registered asset URLStreamHandler.
* * This is equivalent with: *
* return new URL(path.startsWith("asset:") ? path : "asset:" + path); ** * @param path resource path, with or w/o
asset:
prefix
* @return
* @throws MalformedURLException
*/
public static URL createURL(final String path) throws MalformedURLException {
return new URL(path.startsWith(asset_protocol_prefix) ? path : asset_protocol_prefix + path);
}
/**
* Returns the asset handler previously set via {@link #registerHandler(ClassLoader)},
* or null if none was set.
*/
public static URLStreamHandler getRegisteredHandler() {
final GenericURLStreamHandlerFactory f = GenericURLStreamHandlerFactory.register();
return ( null != f ) ? f.getHandler(asset_protocol) : null;
}
/**
* Registers the generic URLStreamHandlerFactory via {@link GenericURLStreamHandlerFactory#register()}
* and if successful sets the asset handler
for the given ClassLoader cl
.
*
* @return true if successful, otherwise false
*/
public static boolean registerHandler(final ClassLoader cl) {
final GenericURLStreamHandlerFactory f = GenericURLStreamHandlerFactory.register();
if( null != f ) {
f.setHandler(asset_protocol, createHandler(cl));
return true;
} else {
return false;
}
}
/**
* Returns an asset aware ClassLoader.
*
* The ClassLoader is required to find the asset resource
* via it's URL findResource(String)
implementation.
*
* It's URL findResource(String)
implementation shall return either
* an asset URL asset:sub-protocol
or just the sub-protocol URL.
*
* For example, on Android, we redirect all path
request to assets/path
.
*
* This implementation attempts to resolve path
in the following order:
*
new URL(path)
, use sub-protocol if asset URLnew File(path).toURI().toURL()
*
* In case of using the ClassLoader (2) and if running on Android,
* the {@link #assets_folder} is being prepended to path
if missing.
*