package com.ftloverdrive.io; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.badlogic.gdx.assets.loaders.FileHandleResolver; import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver; import com.badlogic.gdx.assets.loaders.resolvers.ExternalFileHandleResolver; import com.badlogic.gdx.files.FileHandle; /** * A resolver for multiple locations, delegating to resolvers based on URI. * * When resolving a string that is not a URI, a list of default resolvers * are tried until one works. * * An AssetManager constructed without an explicit resolver will only have * an InternalFileHandleResolver. * * Internal: Path relative to the asset directory on Android and to the * application's root directory on the desktop. On the desktop, if the file * is not found, then the classpath is checked. Internal files are always * readonly. * * External: Path relative to the root of the SD card on Android and to the * home directory of the current user on the desktop. * * @see com.badlogic.gdx.assets.AssetManager * @see com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver * @see com.badlogic.gdx.assets.loaders.resolvers.ExternalFileHandleResolver * @see com.badlogic.gdx.Files.FileType#External * @see com.badlogic.gdx.Files.FileType#Internal */ public class URIFileHandleResolver implements FileHandleResolver { protected List<FileHandleResolver> defaultMap = new ArrayList<FileHandleResolver>(2); protected Map<String,FileHandleResolver> handlerMap = new HashMap<String,FileHandleResolver>(3); protected Map<String,Boolean> stripURIMap = new HashMap<String,Boolean>(3); protected Pattern uriPtn; public URIFileHandleResolver() { this.uriPtn = Pattern.compile( "^([a-zA-z_-]+:)//" ); } /** * Sets a resolver to handle a given scheme. * * @param scheme example: "http:" * @param r the resolver, or null to skip * @param stripURIPrefix removes "abc://" if r won't understand URIs */ public void setResolver( String scheme, FileHandleResolver r, boolean stripURIPrefix ) { handlerMap.put( scheme, r ); stripURIMap.put( scheme, new Boolean(stripURIPrefix) ); } /** * Adds a resolver to use when the string to resolve isn't a URI. * These will be tried, in the order added, until one returns a * non-null FileHandle that exists. */ public void addDefaultResolver( FileHandleResolver r ) { defaultMap.add( r ); } @Override public FileHandle resolve( String s ) { Matcher m = uriPtn.matcher( s ); if ( m.find() ) { String scheme = m.group(1); FileHandleResolver r = handlerMap.get( scheme ); if ( r != null ) { if ( Boolean.TRUE.equals( stripURIMap.get( scheme ) ) ) { s = m.replaceAll( "" ); } return r.resolve( s ); } // It was a URI, but no resolvers were relevant. return null; } else { // The string was not a URI. FileHandle result; for ( FileHandleResolver r : defaultMap ) { result = r.resolve( s ); if ( result != null && result.exists() ) { return result; } } // None of those worked either. return null; } } }