[CB-3384] Add a length getter for UriResolver. Change from interface -> abstract class.

Thinking here is that we can maintain compatibility going forward with a
base class as opposed to interface by having new methods on it have
default implementations.
(cherry picked from commit 990d91360d)
This commit is contained in:
Andrew Grieve 2013-07-10 15:11:23 -04:00
parent 4be84fbf12
commit 43bf47ea7b
2 changed files with 82 additions and 27 deletions

View File

@ -23,40 +23,47 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import android.net.Uri;
/* /*
* Interface for a class that can resolve URIs. * Interface for a class that can resolve URIs.
* See CordovaUriResolver for an example. * See CordovaUriResolver for an example.
*/ */
public interface UriResolver { public abstract class UriResolver {
/** /**
* Returns the InputStream for the resource. * Returns the InputStream for the resource.
* Throws an exception if it cannot be read. * Throws an exception if it cannot be read.
* Never returns null. * Never returns null.
*/ */
InputStream getInputStream() throws IOException; public abstract InputStream getInputStream() throws IOException;
/**
* Returns the MIME type of the resource.
* Returns null if the MIME type cannot be determined (e.g. content: that doesn't exist).
*/
public abstract String getMimeType();
/** Returns whether the resource is writable. */
public abstract boolean isWritable();
/**
* Returns a File that points to the resource, or null if the resource
* is not on the local file system.
*/
public abstract File getLocalFile();
/** /**
* Returns the OutputStream for the resource. * Returns the OutputStream for the resource.
* Throws an exception if it cannot be written to. * Throws an exception if it cannot be written to.
* Never returns null. * Never returns null.
*/ */
OutputStream getOutputStream() throws IOException; public OutputStream getOutputStream() throws IOException {
throw new IOException("Writing is not suppported");
}
/**
* Returns the MIME type of the resource.
* Returns null if the MIME type cannot be determined (e.g. content: that doesn't exist).
*/
String getMimeType();
/** Returns whether the resource is writable. */
boolean isWritable();
/** /**
* Returns a File that points to the resource, or null if the resource * Returns the length of the input stream, or -1 if it is not computable.
* is not on the local file system.
*/ */
File getLocalFile(); public long computeLength() throws IOException {
return -1;
}
} }

View File

@ -44,19 +44,38 @@ public final class UriResolvers {
private UriResolvers() {} private UriResolvers() {}
private static final class FileUriResolver implements UriResolver { private static long computeSizeFromResolver(UriResolver resolver) throws IOException {
InputStream inputStream = resolver.getInputStream();
if (inputStream instanceof FileInputStream) {
return ((FileInputStream)inputStream).getChannel().size();
}
if (inputStream instanceof ByteArrayInputStream) {
return ((ByteArrayInputStream)inputStream).available();
}
return -1;
}
private static final class FileUriResolver extends UriResolver {
private final File localFile; private final File localFile;
private String mimeType; private String mimeType;
private FileInputStream cachedInputStream;
FileUriResolver(Uri uri) { FileUriResolver(Uri uri) {
localFile = new File(uri.getPath()); localFile = new File(uri.getPath());
} }
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return new FileInputStream(localFile); if (cachedInputStream == null) {
cachedInputStream = new FileInputStream(localFile);
}
return cachedInputStream;
} }
public OutputStream getOutputStream() throws FileNotFoundException { public OutputStream getOutputStream() throws FileNotFoundException {
File parent = localFile.getParentFile();
if (parent != null) {
localFile.getParentFile().mkdirs();
}
return new FileOutputStream(localFile); return new FileOutputStream(localFile);
} }
@ -80,12 +99,17 @@ public final class UriResolvers {
public File getLocalFile() { public File getLocalFile() {
return localFile; return localFile;
} }
public long computeLength() throws IOException {
return localFile.length();
}
} }
private static final class AssetUriResolver implements UriResolver { private static final class AssetUriResolver extends UriResolver {
private final AssetManager assetManager; private final AssetManager assetManager;
private final String assetPath; private final String assetPath;
private String mimeType; private String mimeType;
private InputStream cachedInputStream;
AssetUriResolver(Uri uri, AssetManager assetManager) { AssetUriResolver(Uri uri, AssetManager assetManager) {
this.assetManager = assetManager; this.assetManager = assetManager;
@ -93,7 +117,10 @@ public final class UriResolvers {
} }
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return assetManager.open(assetPath); if (cachedInputStream == null) {
cachedInputStream = assetManager.open(assetPath);
}
return cachedInputStream;
} }
public OutputStream getOutputStream() throws FileNotFoundException { public OutputStream getOutputStream() throws FileNotFoundException {
@ -114,12 +141,17 @@ public final class UriResolvers {
public File getLocalFile() { public File getLocalFile() {
return null; return null;
} }
public long computeLength() throws IOException {
return computeSizeFromResolver(this);
}
} }
private static final class ContentUriResolver implements UriResolver { private static final class ContentUriResolver extends UriResolver {
private final Uri uri; private final Uri uri;
private final ContentResolver contentResolver; private final ContentResolver contentResolver;
private String mimeType; private String mimeType;
private InputStream cachedInputStream;
ContentUriResolver(Uri uri, ContentResolver contentResolver) { ContentUriResolver(Uri uri, ContentResolver contentResolver) {
this.uri = uri; this.uri = uri;
@ -127,7 +159,10 @@ public final class UriResolvers {
} }
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return contentResolver.openInputStream(uri); if (cachedInputStream == null) {
cachedInputStream = contentResolver.openInputStream(uri);
}
return cachedInputStream;
} }
public OutputStream getOutputStream() throws FileNotFoundException { public OutputStream getOutputStream() throws FileNotFoundException {
@ -148,9 +183,13 @@ public final class UriResolvers {
public File getLocalFile() { public File getLocalFile() {
return null; return null;
} }
public long computeLength() throws IOException {
return computeSizeFromResolver(this);
}
} }
private static final class ErrorUriResolver implements UriResolver { private static final class ErrorUriResolver extends UriResolver {
final String errorMsg; final String errorMsg;
ErrorUriResolver(String errorMsg) { ErrorUriResolver(String errorMsg) {
@ -178,7 +217,7 @@ public final class UriResolvers {
} }
} }
private static final class ReadOnlyResolver implements UriResolver { private static final class ReadOnlyResolver extends UriResolver {
private InputStream inputStream; private InputStream inputStream;
private String mimeType; private String mimeType;
@ -206,9 +245,13 @@ public final class UriResolvers {
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return inputStream; return inputStream;
} }
public long computeLength() throws IOException {
return computeSizeFromResolver(this);
}
} }
private static final class ThreadCheckingResolver implements UriResolver { private static final class ThreadCheckingResolver extends UriResolver {
final UriResolver delegate; final UriResolver delegate;
ThreadCheckingResolver(UriResolver delegate) { ThreadCheckingResolver(UriResolver delegate) {
@ -250,6 +293,11 @@ public final class UriResolvers {
checkThread(); checkThread();
return delegate.getInputStream(); return delegate.getInputStream();
} }
public long computeLength() throws IOException {
checkThread();
return delegate.computeLength();
}
} }
public static UriResolver createInline(Uri uri, String response, String mimeType) { public static UriResolver createInline(Uri uri, String response, String mimeType) {
@ -290,4 +338,4 @@ public final class UriResolvers {
} }
return new ThreadCheckingResolver(resolver); return new ThreadCheckingResolver(resolver);
} }
} }