Skip to content

Commit

Permalink
Bug 1237 - Clarify IOUtil.getResource(..) for better efficiency, i.e.…
Browse files Browse the repository at this point in the history
… allow caller to skip relative futile lookup

IOUtil.getResource(..) and IOUtil.ClassResources, needs more clarity.

ClassLoader shall be passed explicitly next to the optional
relative context Class instance.

This allows better efficiency, i.e. caller can pass ClassLoader
but skip a possible relative lookup, if not existing.
  • Loading branch information
sgothel committed Oct 3, 2015
1 parent a1009b4 commit d78bb1b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 28 deletions.
86 changes: 63 additions & 23 deletions src/java/com/jogamp/common/util/IOUtil.java
Expand Up @@ -432,7 +432,7 @@ public static String getDirname(String fname) throws URISyntaxException {

/***
*
* RESOURCE LOCATION STUFF
* RESOURCE LOCATION HELPER
*
*/

Expand All @@ -441,7 +441,10 @@ public static String getDirname(String fname) throws URISyntaxException {
* to be {@link #resolve(int) resolved} at a later time.
*/
public static class ClassResources {
/** Class instance used to {@link #resolve(int)} the {@link #resourcePaths}. */
/** Optional {@link ClassLoader} used to {@link #resolve(int)} {@link #resourcePaths}. */
public final ClassLoader classLoader;

/** Optional class instance used to {@link #resolve(int)} relative {@link #resourcePaths}. */
public final Class<?> contextCL;

/** Resource paths, see {@link #resolve(int)}. */
Expand All @@ -453,23 +456,34 @@ public static class ClassResources {
/**
* @param contextCL class instance to {@link #resolve(int)} {@link #resourcePaths}.
* @param resourcePaths array of strings denominating multiple resource paths. None shall be null.
* @deprecated Use {@link #IOUtil(String[], ClassLoader, Class)} for clarity!
*/
public ClassResources(final Class<?> contextCL, final String[] resourcePaths) {
this(resourcePaths, contextCL.getClassLoader(), contextCL);
}
/**
* @param resourcePaths multiple relative or absolute resource locations
* @param classLoader optional {@link ClassLoader}, see {@link IOUtil#getResource(String, ClassLoader, Class)}
* @param relContext optional relative context, see {@link IOUtil#getResource(String, ClassLoader, Class)}
*/
public ClassResources(final String[] resourcePaths, final ClassLoader classLoader, final Class<?> relContext) {
for(int i=resourcePaths.length-1; i>=0; i--) {
if( null == resourcePaths[i] ) {
throw new IllegalArgumentException("resourcePath["+i+"] is null");
}
}
this.contextCL = contextCL;
this.classLoader = classLoader;
this.contextCL = relContext;
this.resourcePaths = resourcePaths;
}

/**
* Resolving one of the {@link #resourcePaths} indexed by <code>uriIndex</code> using {@link #contextCL} and {@link IOUtil#getResource(Class, String)}.
* Resolving one of the {@link #resourcePaths} indexed by <code>uriIndex</code> using
* {@link #classLoader}, {@link #contextCL} through {@link IOUtil#getResource(String, ClassLoader, Class)}.
* @throws ArrayIndexOutOfBoundsException if <code>uriIndex</code> is < 0 or >= {@link #resourceCount()}.
*/
public URLConnection resolve(final int uriIndex) throws ArrayIndexOutOfBoundsException {
return getResource(contextCL, resourcePaths[uriIndex]);
return getResource(resourcePaths[uriIndex], classLoader, contextCL);
}
}

Expand All @@ -478,40 +492,69 @@ public URLConnection resolve(final int uriIndex) throws ArrayIndexOutOfBoundsExc
* <ul>
* <li><i>relative</i>: <code>context</code>'s package name-path plus <code>resourcePath</code> via <code>context</code>'s ClassLoader.
* This allows locations relative to JAR- and other URLs.
* The <code>resourcePath</code> may start with <code>../</code> to navigate to parent folder.</li>
* <li><i>absolute</i>: <code>context</code>'s ClassLoader and the <code>resourcePath</code> as is (filesystem)</li>
* The <code>resourcePath</code> may start with <code>../</code> to navigate to parent folder.
* This attempt is skipped if {@code context} is {@code null}.</li>
* <li><i>absolute</i>: <code>resourcePath</code> as is via <code>context</code>'s ClassLoader.
* In case {@code context} is {@code null}, this class {@link ClassLoader} is being used.</li>
* </ul>
*
* <p>
* Returns the resolved and open URLConnection or null if not found.
* </p>
*
* @see #getResource(String, ClassLoader)
* @see ClassLoader#getResource(String)
* @see ClassLoader#getSystemResource(String)
* @deprecated Use {@link IOUtil#getResource(String, ClassLoader, Class)} for clarity!
*/
public static URLConnection getResource(final Class<?> context, final String resourcePath) {
final ClassLoader contextCL = null != context ? context.getClassLoader() : IOUtil.class.getClassLoader();
return getResource(resourcePath, contextCL, context);
}

/**
* Locating a resource using {@link #getResource(String, ClassLoader)}:
* <ul>
* <li><i>relative</i>: <code>relContext</code>'s package name-path plus <code>resourcePath</code> via <code>classLoader</code>.
* This allows locations relative to JAR- and other URLs.
* The <code>resourcePath</code> may start with <code>../</code> to navigate to parent folder.
* This attempt is skipped if {@code relContext} is {@code null}.</li>
* <li><i>absolute</i>: <code>resourcePath</code> as is via <code>classLoader</code>.
* </ul>
* <p>
* Returns the resolved and open URLConnection or null if not found.
* </p>
*
* @param resourcePath the resource path to locate relative or absolute
* @param classLoader the optional {@link ClassLoader}, recommended
* @param relContext relative context, i.e. position, of the {@code resourcePath},
* to perform the relative lookup, if not {@code null}.
* @see #getResource(String, ClassLoader)
* @see ClassLoader#getResource(String)
* @see ClassLoader#getSystemResource(String)
*/
public static URLConnection getResource(final String resourcePath, final ClassLoader classLoader, final Class<?> relContext) {
if(null == resourcePath) {
return null;
}
final ClassLoader contextCL = (null!=context)?context.getClassLoader():IOUtil.class.getClassLoader();
URLConnection conn = null;
if(null != context) {
if(null != relContext) {
// scoping the path within the class's package
final String className = context.getName().replace('.', '/');
final String className = relContext.getName().replace('.', '/');
final int lastSlash = className.lastIndexOf('/');
if (lastSlash >= 0) {
final String pkgName = className.substring(0, lastSlash + 1);
conn = getResource(pkgName + resourcePath, contextCL);
conn = getResource(pkgName + resourcePath, classLoader);
if(DEBUG) {
System.err.println("IOUtil: found <"+resourcePath+"> within class package <"+pkgName+"> of given class <"+context.getName()+">: "+(null!=conn));
System.err.println("IOUtil: found <"+resourcePath+"> within class package <"+pkgName+"> of given class <"+relContext.getName()+">: "+(null!=conn));
}
}
} else if(DEBUG) {
System.err.println("IOUtil: null context");
} else {
if(DEBUG) {
System.err.println("IOUtil: null context");
}
}
if(null == conn) {
conn = getResource(resourcePath, contextCL);
conn = getResource(resourcePath, classLoader);
if(DEBUG) {
System.err.println("IOUtil: found <"+resourcePath+"> by classloader: "+(null!=conn));
}
Expand Down Expand Up @@ -542,8 +585,7 @@ public static URLConnection getResource(final String resourcePath, final ClassLo
return AssetURLContext.createURL(resourcePath, cl).openConnection();
} catch (final IOException ioe) {
if(DEBUG) {
System.err.println("IOUtil: Caught Exception:");
ioe.printStackTrace();
ExceptionUtils.dumpThrowable("IOUtil", ioe);
}
return null;
}
Expand All @@ -552,8 +594,7 @@ public static URLConnection getResource(final String resourcePath, final ClassLo
return AssetURLContext.resolve(resourcePath, cl);
} catch (final IOException ioe) {
if(DEBUG) {
System.err.println("IOUtil: Caught Exception:");
ioe.printStackTrace();
ExceptionUtils.dumpThrowable("IOUtil", ioe);
}
}
}
Expand Down Expand Up @@ -666,8 +707,7 @@ public static URLConnection openURL(final URL url, final String dbgmsg) {
return c;
} catch (final IOException ioe) {
if(DEBUG) {
System.err.println("IOUtil: urlExists("+url+") ["+dbgmsg+"] - false - "+ioe.getClass().getSimpleName()+": "+ioe.getMessage());
ioe.printStackTrace();
ExceptionUtils.dumpThrowable("IOUtil: urlExists("+url+") ["+dbgmsg+"] - false -", ioe);
}
}
} else if(DEBUG) {
Expand Down Expand Up @@ -707,7 +747,7 @@ private static String[] getExeTestCommandArgs(final String scriptFile) {
}

private static final byte[] readCode(final String fname) throws IOException {
final URLConnection con = IOUtil.getResource(IOUtil.class, fname);
final URLConnection con = IOUtil.getResource(fname, IOUtil.class.getClassLoader(), IOUtil.class);
final InputStream in = con.getInputStream();
byte[] output = null;
try {
Expand Down
Expand Up @@ -38,7 +38,7 @@ public void assetUnregisteredIOUtilGetResourceAbs_RT() throws IOException {

@Test
public void assetUnregisteredIOUtilGetResourceRel0_RT() throws IOException, URISyntaxException {
final URLConnection urlConn0 = IOUtil.getResource(this.getClass(), test_asset_test2_rel.get());
final URLConnection urlConn0 = IOUtil.getResource(test_asset_test2_rel.get(), this.getClass().getClassLoader(), this.getClass());
testAssetConnection(urlConn0, test_asset_test2_entry);

final Uri uri1 = Uri.valueOf(urlConn0.getURL()).getRelativeOf(test_asset_test3_rel);
Expand Down
8 changes: 4 additions & 4 deletions src/junit/com/jogamp/common/util/TestIOUtil01.java
Expand Up @@ -79,7 +79,7 @@ public static void cleanup() {

@Test
public void testCopyStream01Array() throws IOException {
final URLConnection urlConn = IOUtil.getResource(this.getClass(), tfilename);
final URLConnection urlConn = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(urlConn);
final BufferedInputStream bis = new BufferedInputStream( urlConn.getInputStream() );
final byte[] bb;
Expand All @@ -95,7 +95,7 @@ public void testCopyStream01Array() throws IOException {

@Test
public void testCopyStream02Buffer() throws IOException {
final URLConnection urlConn = IOUtil.getResource(this.getClass(), tfilename);
final URLConnection urlConn = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(urlConn);
final BufferedInputStream bis = new BufferedInputStream( urlConn.getInputStream() );
final ByteBuffer bb;
Expand All @@ -113,14 +113,14 @@ public void testCopyStream02Buffer() throws IOException {
@Test
public void testCopyStream03Buffer() throws IOException {
final String tfilename2 = "./test2.bin" ;
final URLConnection urlConn1 = IOUtil.getResource(this.getClass(), tfilename);
final URLConnection urlConn1 = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(urlConn1);

final File file2 = new File(tfilename2);
file2.deleteOnExit();
try {
IOUtil.copyURLConn2File(urlConn1, file2);
final URLConnection urlConn2 = IOUtil.getResource(this.getClass(), tfilename2);
final URLConnection urlConn2 = IOUtil.getResource(tfilename2, this.getClass().getClassLoader(), this.getClass());
Assert.assertNotNull(urlConn2);

final BufferedInputStream bis = new BufferedInputStream( urlConn2.getInputStream() );
Expand Down

0 comments on commit d78bb1b

Please sign in to comment.