summaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp/common/net/AssetURLConnection.java
blob: f2a5a0166cebc868a0e94af6528336eef9ae7d88 (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
91
92
93
94
95
96
97
98
package com.jogamp.common.net;

import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;

/**
 * See base class {@link PiggybackURLConnection} for motivation.
 * 
 * <p>
 * <i>asset</i> resource location protocol connection.
 * </p>
 * 
 * <p>
 * See {@link AssetURLContext#resolve(String)} how resources are being resolved.
 * </p>
 *
 * <h3>Example:</h3>
 * 
 * Assuming the plain <i>asset entry</i> <b><code>test/lala.txt</code></b> is being resolved by
 * a class <code>test.LaLaTest</code>, ie. using the <i>asset aware</i> ClassLoader,
 * one would use the following <i>asset</i> aware filesystem layout: 
 * 
 * <pre>
 *  test/LaLaTest.class
 *  assets/test/lala.txt
 * </pre>
 * 
 * The above maybe on a plain filesystem, or within a JAR or an APK file, 
 * e.g. <code>jogamp.test.apk</code>.
 * 
 * The above would result in the following possible URLs
 * reflecting the plain and resolved state of the <i>asset URL</i>:  
 * <pre>
 *  0 Entry          test/lala.txt
 *  1 Plain    asset:test/lala.txt
 *  2 Resolved asset:jar:file:/data/app/jogamp.test.apk!/assets/test/lala.txt
 * </pre>
 *
 * <p>
 * The sub protocol URL of the resolved <i>asset</i>  
 * <pre>
 *  3 Sub-URL        jar:file:/data/app/jogamp.test.apk!/assets/test/lala.txt
 * </pre>
 * can be retrieved using {@link #getSubProtocol()}.
 * </p>
 *  
 * In all above cases, the <i>asset entry</i> is <b><code>test/lala.txt</code></b>,
 * which can be retrieved via {@link #getEntryName()}.
 * 
 * <p>
 * <h3>General Implementation Notes:</h3>
 * An <i>asset</i> URL is resolved using {@link AssetURLContext#getClassLoader()}.{@link ClassLoader#getResource(String) getResource(String)},
 * hence the only requirement for an implementation is to have an <i>asset</i> aware ClassLoader
 * as described in  {@link AssetURLContext#getClassLoader()}.
 * </p>
 * <p>
 * <h3>Warning:</h3>
 * Since the <i>asset</i> protocol is currently not being implemented 
 * on all platform with an appropriate ClassLoader, a user shall not create the <i>asset</i> URL manually.<br>
 * </p>
 * 
 * <h3>Android Implementation Notes:</h3>
 * <p>
 * The Android ClassLoader {@link jogamp.android.launcher.AssetDexClassLoader} 
 * resolves the resource as an <i>asset</i> URL in it's {@link ClassLoader#findResource(String)} implementation.</p>
 * <p>
 * Currently we attach our <i>asset</i> {@link java.net.URLStreamHandlerFactory} 
 * to allow {@link java.net.URL} to handle <i>asset</i> URLs via our <i>asset</i> {@link java.net.URLStreamHandler} implementation.
 * </p>
 */
public class AssetURLConnection extends PiggybackURLConnection<AssetURLContext> {
    
    public AssetURLConnection(URL url, AssetURLContext implHelper) {
        super(url, implHelper);
    }
    
    @Override
    public String getEntryName() throws IOException {
        if(!connected) {
            throw new IOException("not connected");
        }
        
        final String urlPath ;
        if(subConn instanceof JarURLConnection) {
            urlPath = ((JarURLConnection)subConn).getEntryName();
        } else {
            urlPath = subConn.getURL().getPath();
        }
        
        if(urlPath.startsWith(AssetURLContext.assets_folder)) {
            return urlPath.substring(AssetURLContext.assets_folder.length());
        } else {
            return urlPath;
        }
    }
    
}