aboutsummaryrefslogtreecommitdiff
path: root/engine/src/android/com/jme3/asset/plugins/AndroidLocator.java
blob: 01b1cab9e1387f1c0c9d52be172af2907a2b9ab6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.jme3.asset.plugins;

import com.jme3.asset.*;
import com.jme3.system.android.JmeAndroidSystem;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Level;
import java.util.logging.Logger;

public class AndroidLocator implements AssetLocator {

    private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName());
    
    private android.content.res.AssetManager androidManager;
    private String rootPath = "";

    private class AndroidAssetInfo extends AssetInfo {

        private InputStream in;
        private final String assetPath;

        public AndroidAssetInfo(com.jme3.asset.AssetManager assetManager, AssetKey<?> key, String assetPath, InputStream in) {
            super(assetManager, key);
            this.assetPath = assetPath;
            this.in = in;
        }
        
        @Override
        public InputStream openStream() {
            if (in != null){
                // Reuse the already existing stream (only once)
                InputStream in2 = in;
                in = null;
                return in2;
            }else{
                // Create a new stream for subsequent invocations.
                try {
                    return androidManager.open(assetPath);
                } catch (IOException ex) {
                    throw new AssetLoadException("Failed to open asset " + assetPath, ex);
                }
            }
        }
    }

    private AndroidAssetInfo create(AssetManager assetManager, AssetKey key, String assetPath) throws IOException {
        try {
            InputStream in = androidManager.open(assetPath);
            if (in == null){
                return null;
            }else{
                return new AndroidAssetInfo(assetManager, key, assetPath, in);
            }
        } catch (IOException ex) {
            // XXX: Prefer to show warning here?
            // Should only surpress exceptions for "file missing" type errors.
            return null;
        }
    }
    
    public AndroidLocator() {
        androidManager = JmeAndroidSystem.getResources().getAssets();
    }

    public void setRootPath(String rootPath) {
        this.rootPath = rootPath;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public AssetInfo locate(com.jme3.asset.AssetManager manager, AssetKey key) {
        String assetPath = rootPath + key.getName();
        // Fix path issues
        if (assetPath.startsWith("/")) {
            // Remove leading /
            assetPath = assetPath.substring(1);
        }
        assetPath = assetPath.replace("//", "/");
        try {
            return create(manager, key, assetPath);
        }catch (IOException ex){
            // This is different handling than URL locator
            // since classpath locating would return null at the getResource() 
            // call, otherwise there's a more critical error...
            throw new AssetLoadException("Failed to open asset " + assetPath, ex);
        }
    }
}