GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
AssetURLContext.java
Go to the documentation of this file.
1package com.jogamp.common.net;
2
3import java.io.File;
4import java.io.FileNotFoundException;
5import java.io.IOException;
6import java.net.MalformedURLException;
7import java.net.URISyntaxException;
8import java.net.URL;
9import java.net.URLConnection;
10import java.net.URLStreamHandler;
11
12import com.jogamp.common.os.AndroidVersion;
13import com.jogamp.common.util.IOUtil;
14
15/**
16 * See {@link PiggybackURLConnection} for description and examples.
17 */
18public abstract class AssetURLContext implements PiggybackURLContext {
19 private static final boolean DEBUG = IOUtil.DEBUG;
20
21 /** The <i>asset URL</i> protocol name <code>asset</code> */
22 public static final String asset_protocol = "asset";
23
24 /** The <i>asset URL</i> protocol prefix <code>asset:</code> */
25 public static final String asset_protocol_prefix = "asset:";
26
27 /**
28 * The <i>optional</i> <i>asset</i> folder name with ending slash <code>assets/</code>.
29 * <p>
30 * Note that the <i>asset</i> folder is not used on all platforms using the <i>asset</i> protocol
31 * and you should not rely on it, use {@link AssetURLConnection#getEntryName()}.
32 * </p>
33 **/
34 public static final String assets_folder = "assets/";
35
36 public static AssetURLContext create(final ClassLoader cl) {
37 return new AssetURLContext() {
38 @Override
39 public ClassLoader getClassLoader() {
40 return cl;
41 }
42 };
43 }
44
45 public static AssetURLStreamHandler createHandler(final ClassLoader cl) {
46 return new AssetURLStreamHandler(create(cl));
47 }
48
49 /**
50 * Create an <i>asset</i> URL, suitable even w/o the registered <i>asset</i> URLStreamHandler.
51 * <p>
52 * This is equivalent with:
53 * <pre>
54 * return new URL(null, path.startsWith("asset:") ? path : "asset:" + path, new AssetURLStreamHandler(cl));
55 * </pre>
56 * </p>
57 * @param path resource path, with or w/o <code>asset:</code> prefix
58 * @param cl the ClassLoader used to resolve the location, see {@link #getClassLoader()}.
59 * @return
60 * @throws MalformedURLException
61 */
62 public static URL createURL(final String path, final ClassLoader cl) throws MalformedURLException {
63 return new URL(null, path.startsWith(asset_protocol_prefix) ? path : asset_protocol_prefix + path, createHandler(cl));
64 }
65
66 /**
67 * Create an <i>asset</i> URL, suitable only with the registered <i>asset</i> URLStreamHandler.
68 * <p>
69 * This is equivalent with:
70 * <pre>
71 * return new URL(path.startsWith("asset:") ? path : "asset:" + path);
72 * </pre>
73 * </p>
74 * @param path resource path, with or w/o <code>asset:</code> prefix
75 * @return
76 * @throws MalformedURLException
77 */
78 public static URL createURL(final String path) throws MalformedURLException {
79 return new URL(path.startsWith(asset_protocol_prefix) ? path : asset_protocol_prefix + path);
80 }
81
82 /**
83 * Returns the <i>asset</i> handler previously set via {@link #registerHandler(ClassLoader)},
84 * or null if none was set.
85 */
86 public static URLStreamHandler getRegisteredHandler() {
88 return ( null != f ) ? f.getHandler(asset_protocol) : null;
89 }
90
91 /**
92 * Registers the generic URLStreamHandlerFactory via {@link GenericURLStreamHandlerFactory#register()}
93 * and if successful sets the <i>asset</i> <code>handler</code> for the given ClassLoader <code>cl</code>.
94 *
95 * @return true if successful, otherwise false
96 */
97 public static boolean registerHandler(final ClassLoader cl) {
99 if( null != f ) {
101 return true;
102 } else {
103 return false;
104 }
105 }
106
107 /**
108 * Returns an <i>asset</i> aware ClassLoader.
109 * <p>
110 * The ClassLoader is required to find the <i>asset</i> resource
111 * via it's <code>URL findResource(String)</code> implementation.
112 * </p>
113 * <p>
114 * It's <code>URL findResource(String)</code> implementation shall return either
115 * an <i>asset</i> URL <code>asset:sub-protocol</code> or just the sub-protocol URL.
116 * </p>
117 * <p>
118 * For example, on Android, we <i>redirect</i> all <code>path</code> request to <i>assets/</i><code>path</code>.
119 * </p>
120 */
121 public abstract ClassLoader getClassLoader();
122
123 @Override
124 public String getImplementedProtocol() {
125 return asset_protocol;
126 }
127
128 /**
129 * {@inheritDoc}
130 * <p>
131 * This implementation attempts to resolve <code>path</code> in the following order:
132 * <ol>
133 * <li> as a valid URL: <code>new URL(path)</code>, use sub-protocol if <i>asset</i> URL</li>
134 * <li> via ClassLoader: {@link #getClassLoader()}.{@link ClassLoader#getResource(String) getResource(path)}, use sub-protocol if <i>asset</i> URL </li>
135 * <li> as a File: <code>new File(path).toURI().toURL()</code>
136 * </ol>
137 * </p>
138 * <p>
139 * In case of using the ClassLoader (2) <b>and</b> if running on Android,
140 * the {@link #assets_folder} is being prepended to <code>path</code> if missing.
141 * </p>
142 **/
143 @Override
144 public URLConnection resolve(final String path) throws IOException {
145 return resolve(path, getClassLoader());
146 }
147
148 public static URLConnection resolve(String path, final ClassLoader cl) throws IOException {
149 URL url = null;
150 URLConnection conn = null;
151 int type = -1;
152
153 if(DEBUG) {
154 System.err.println("AssetURLContext.resolve: <"+path+">");
155 }
156 try {
157 path = IOUtil.cleanPathString(path);
158 } catch (final URISyntaxException uriEx) {
159 throw new IOException(uriEx);
160 }
161
162 try {
163 // lookup as valid sub-protocol
164 url = new URL(path);
165 conn = open(url);
166 type = null != conn ? 1 : -1;
167 } catch(final MalformedURLException e1) { if(DEBUG) { System.err.println("FAIL(1): "+e1.getMessage()); } }
168
169 if(null == conn && null != cl) {
170 // lookup via ClassLoader .. cleanup leading '/'
171 String cpath = path;
172 while(cpath.startsWith("/")) {
173 cpath = cpath.substring(1);
174 }
176 cpath = cpath.startsWith(assets_folder) ? cpath : assets_folder + cpath;
177 }
178 url = cl.getResource(cpath);
179 conn = open(url);
180 type = null != conn ? 2 : -1;
181 }
182
183 if(null == conn) {
184 // lookup as File
185 try {
186 final File file = new File(path);
187 if(file.exists()) {
188 url = Uri.valueOf(file).toURL();
189 conn = open(url);
190 type = null != conn ? 3 : -1;
191 }
192 } catch (final Throwable e) { if(DEBUG) { System.err.println("FAIL(3): "+e.getMessage()); } }
193 }
194
195 if(DEBUG) {
196 System.err.println("AssetURLContext.resolve: type "+type+": url <"+url+">, conn <"+conn+">, connURL <"+(null!=conn?conn.getURL():null)+">");
197 }
198 if(null == conn) {
199 throw new FileNotFoundException("Could not look-up: "+path+" as URL, w/ ClassLoader or as File");
200 }
201 return conn;
202 }
203
204 private static URLConnection open(final URL url) {
205 if(null==url) {
206 return null;
207 }
208 try {
209 final URLConnection c = url.openConnection();
210 c.connect(); // redundant
211 return c;
212 } catch (final IOException ioe) { if(DEBUG) { System.err.println("FAIL(2): "+ioe.getMessage()); } }
213 return null;
214 }
215
216}
See PiggybackURLConnection for description and examples.
static URLConnection resolve(String path, final ClassLoader cl)
static final String assets_folder
The optional asset folder name with ending slash assets/.
static AssetURLContext create(final ClassLoader cl)
abstract ClassLoader getClassLoader()
Returns an asset aware ClassLoader.
static boolean registerHandler(final ClassLoader cl)
Registers the generic URLStreamHandlerFactory via GenericURLStreamHandlerFactory#register() and if su...
static URLStreamHandler getRegisteredHandler()
Returns the asset handler previously set via registerHandler(ClassLoader), or null if none was set.
static final String asset_protocol_prefix
The asset URL protocol prefix asset:
static URL createURL(final String path)
Create an asset URL, suitable only with the registered asset URLStreamHandler.
static URL createURL(final String path, final ClassLoader cl)
Create an asset URL, suitable even w/o the registered asset URLStreamHandler.
URLConnection resolve(final String path)
Resolving path to a URL sub protocol and return it's open URLConnection.
static AssetURLStreamHandler createHandler(final ClassLoader cl)
static final String asset_protocol
The asset URL protocol name asset
String getImplementedProtocol()
Returns the specific protocol, constant for this implementation.
URLStreamHandler to handle the asset protocol.
synchronized final URLStreamHandler getHandler(final String protocol)
Returns the protocol handler previously set via setHandler(String, URLStreamHandler),...
static synchronized GenericURLStreamHandlerFactory register()
Returns the singleton instance of the registered GenericURLStreamHandlerFactory or null if registrati...
synchronized final URLStreamHandler setHandler(final String protocol, final URLStreamHandler handler)
Sets the handler for protocol.
This class implements an immutable Uri as defined by RFC 2396.
Definition: Uri.java:160
static Uri valueOf(final File file)
Creates a new Uri instance using the given File instance.
Definition: Uri.java:1121
final java.net.URL toURL()
Returns a new URL instance using the encoded input string, new URL(uri.input), i.e.
Definition: Uri.java:1369
static String cleanPathString(String path)
Definition: IOUtil.java:712
static final boolean DEBUG
Definition: IOUtil.java:70
See PiggybackURLConnection for description and examples.