159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.asset.plugins;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.*;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.system.android.JmeAndroidSystem;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.InputStream;
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class AndroidLocator implements AssetLocator {
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName());
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private android.content.res.AssetManager androidManager;
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private String rootPath = "";
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private class AndroidAssetInfo extends AssetInfo {
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        private InputStream in;
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        private final String assetPath;
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        public AndroidAssetInfo(com.jme3.asset.AssetManager assetManager, AssetKey<?> key, String assetPath, InputStream in) {
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            super(assetManager, key);
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.assetPath = assetPath;
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.in = in;
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        @Override
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        public InputStream openStream() {
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (in != null){
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Reuse the already existing stream (only once)
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                InputStream in2 = in;
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                in = null;
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return in2;
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }else{
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Create a new stream for subsequent invocations.
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                try {
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return androidManager.open(assetPath);
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } catch (IOException ex) {
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    throw new AssetLoadException("Failed to open asset " + assetPath, ex);
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private AndroidAssetInfo create(AssetManager assetManager, AssetKey key, String assetPath) throws IOException {
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        try {
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            InputStream in = androidManager.open(assetPath);
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (in == null){
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return null;
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }else{
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return new AndroidAssetInfo(assetManager, key, assetPath, in);
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } catch (IOException ex) {
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // XXX: Prefer to show warning here?
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // Should only surpress exceptions for "file missing" type errors.
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AndroidLocator() {
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        androidManager = JmeAndroidSystem.getResources().getAssets();
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setRootPath(String rootPath) {
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.rootPath = rootPath;
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @SuppressWarnings("rawtypes")
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AssetInfo locate(com.jme3.asset.AssetManager manager, AssetKey key) {
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String assetPath = rootPath + key.getName();
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Fix path issues
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (assetPath.startsWith("/")) {
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // Remove leading /
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            assetPath = assetPath.substring(1);
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        assetPath = assetPath.replace("//", "/");
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        try {
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return create(manager, key, assetPath);
80a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        } catch (IOException ex) {
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // This is different handling than URL locator
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // since classpath locating would return null at the getResource()
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // call, otherwise there's a more critical error...
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new AssetLoadException("Failed to open asset " + assetPath, ex);
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
88