diff --git a/engine/src/core/com/jme3/asset/AssetInfo.java b/engine/src/core/com/jme3/asset/AssetInfo.java index 786b9fafd..42ee822d3 100644 --- a/engine/src/core/com/jme3/asset/AssetInfo.java +++ b/engine/src/core/com/jme3/asset/AssetInfo.java @@ -66,6 +66,10 @@ public abstract class AssetInfo { /** * Implementations of this method should return an {@link InputStream} * allowing access to the data represented by the {@link AssetKey}. + *

+ * Each invocation of this method should return a new stream to the + * asset data, starting at the beginning of the file. + * * @return The asset data. */ public abstract InputStream openStream(); diff --git a/engine/src/desktop/com/jme3/asset/plugins/ClasspathLocator.java b/engine/src/desktop/com/jme3/asset/plugins/ClasspathLocator.java index 299ec70e1..d4c84e479 100644 --- a/engine/src/desktop/com/jme3/asset/plugins/ClasspathLocator.java +++ b/engine/src/desktop/com/jme3/asset/plugins/ClasspathLocator.java @@ -32,14 +32,17 @@ package com.jme3.asset.plugins; -import com.jme3.asset.*; +import com.jme3.asset.AssetInfo; +import com.jme3.asset.AssetKey; +import com.jme3.asset.AssetLoadException; +import com.jme3.asset.AssetLocator; +import com.jme3.asset.AssetManager; +import com.jme3.asset.AssetNotFoundException; import com.jme3.system.JmeSystem; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.net.URISyntaxException; import java.net.URL; -import java.net.URLConnection; import java.util.logging.Logger; /** @@ -51,25 +54,6 @@ public class ClasspathLocator implements AssetLocator { private static final Logger logger = Logger.getLogger(ClasspathLocator.class.getName()); private String root = ""; - private static class ClasspathAssetInfo extends AssetInfo { - - private URLConnection conn; - - public ClasspathAssetInfo(AssetManager manager, AssetKey key, URLConnection conn){ - super(manager, key); - this.conn = conn; - } - - @Override - public InputStream openStream() { - try{ - return conn.getInputStream(); - }catch (IOException ex){ - return null; // failure.. - } - } - } - public ClasspathLocator(){ } @@ -127,10 +111,11 @@ public class ClasspathLocator implements AssetLocator { } try{ - URLConnection conn = url.openConnection(); - conn.setUseCaches(false); - return new ClasspathAssetInfo(manager, key, conn); + return UrlAssetInfo.create(manager, key, url); }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 read URL " + url, ex); } } diff --git a/engine/src/desktop/com/jme3/asset/plugins/UrlAssetInfo.java b/engine/src/desktop/com/jme3/asset/plugins/UrlAssetInfo.java new file mode 100644 index 000000000..a9494a27f --- /dev/null +++ b/engine/src/desktop/com/jme3/asset/plugins/UrlAssetInfo.java @@ -0,0 +1,66 @@ +package com.jme3.asset.plugins; + +import com.jme3.asset.AssetInfo; +import com.jme3.asset.AssetKey; +import com.jme3.asset.AssetLoadException; +import com.jme3.asset.AssetManager; +import com.jme3.asset.AssetNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; + +/** + * Handles loading of assets from a URL + * + * @author Kirill Vainer + */ +public class UrlAssetInfo extends AssetInfo { + + private URL url; + private InputStream in; + + public static UrlAssetInfo create(AssetManager assetManager, AssetKey key, URL url) throws IOException { + // Check if URL can be reached. This will throw + // IOException which calling code will handle. + URLConnection conn = url.openConnection(); + conn.setUseCaches(false); + InputStream in = conn.getInputStream(); + + // For some reason url cannot be reached? + if (in == null){ + return null; + }else{ + return new UrlAssetInfo(assetManager, key, url, in); + } + } + + private UrlAssetInfo(AssetManager assetManager, AssetKey key, URL url, InputStream in) throws IOException { + super(assetManager, key); + this.url = url; + this.in = in; + } + + public boolean hasInitialConnection(){ + return in != null; + } + + @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 { + URLConnection conn = url.openConnection(); + conn.setUseCaches(false); + return conn.getInputStream(); + } catch (IOException ex) { + throw new AssetLoadException("Failed to read URL " + url, ex); + } + } + } +} diff --git a/engine/src/desktop/com/jme3/asset/plugins/UrlLocator.java b/engine/src/desktop/com/jme3/asset/plugins/UrlLocator.java index 1ff1c54e1..691fa2b32 100644 --- a/engine/src/desktop/com/jme3/asset/plugins/UrlLocator.java +++ b/engine/src/desktop/com/jme3/asset/plugins/UrlLocator.java @@ -53,21 +53,6 @@ public class UrlLocator implements AssetLocator { private static final Logger logger = Logger.getLogger(UrlLocator.class.getName()); private URL root; - private static class UrlAssetInfo extends AssetInfo { - - private InputStream in; - - public UrlAssetInfo(AssetManager manager, AssetKey key, InputStream in){ - super(manager, key); - this.in = in; - } - - @Override - public InputStream openStream() { - return in; - } - } - public void setRootPath(String rootPath) { try { this.root = new URL(rootPath); @@ -78,22 +63,9 @@ public class UrlLocator implements AssetLocator { public AssetInfo locate(AssetManager manager, AssetKey key) { String name = key.getName(); - try{ URL url = new URL(root, name); - URLConnection conn = url.openConnection(); - conn.setUseCaches(false); - conn.setDoOutput(false); - InputStream in; - try { - in = conn.getInputStream(); - if (in == null) - return null; - } catch (FileNotFoundException ex){ - return null; - } - - return new UrlAssetInfo(manager, key, in); + return UrlAssetInfo.create(manager, key, url); }catch (IOException ex){ logger.log(Level.WARNING, "Error while locating " + name, ex); return null;