diff options
Diffstat (limited to 'branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android')
5 files changed, 421 insertions, 0 deletions
diff --git a/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/ContextRegistry.java b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/ContextRegistry.java new file mode 100644 index 0000000000..312c0059db --- /dev/null +++ b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/ContextRegistry.java @@ -0,0 +1,55 @@ +package org.apache.tuscany.sca.android;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+
+import android.content.Context;
+
+public class ContextRegistry {
+
+ private static Hashtable<String, HashSet<Context>> contexts = new Hashtable<String, HashSet<Context>>();
+
+ public static void registerContext(Context context) {
+ String packageName = context.getPackageName();
+ HashSet<Context> packContexts = contexts.get(packageName);
+
+ if (packContexts == null) {
+ packContexts = new HashSet<Context>();
+ contexts.put(packageName, packContexts);
+
+ }
+
+ packContexts.add(context);
+
+ }
+
+ public static void unregisterContext(Context context) {
+ String packageName = context.getPackageName();
+ HashSet<Context> packContexts = contexts.get(packageName);
+
+ if (packContexts != null) {
+ packContexts.remove(context);
+
+ if (packContexts.isEmpty()) {
+ contexts.remove(packageName);
+ }
+
+ }
+
+ }
+
+ public static Context[] getContexts(String packageName) {
+ HashSet<Context> packageContexts = contexts.get(packageName);
+
+ if (packageContexts == null) {
+ return new Context[0];
+ }
+
+ Context[] ret = new Context[packageContexts.size()];
+ packageContexts.toArray(ret);
+
+ return ret;
+
+ }
+
+}
diff --git a/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexResource.java b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexResource.java new file mode 100644 index 0000000000..fb9029547f --- /dev/null +++ b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexResource.java @@ -0,0 +1,190 @@ +package org.apache.tuscany.sca.android;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+
+import android.content.Context;
+
+public class DexResource {
+
+ private URL url;
+
+ private String folder;
+
+ private String file;
+
+ public DexResource(URL url) {
+ String protocol = url.getProtocol();
+
+ if (!"dex".equals(protocol)) {
+ throw new IllegalArgumentException("The URL protocol should be \"dex\"");
+ }
+
+ String host = url.getHost();
+
+ if ("".equals(host)) {
+ throw new IllegalArgumentException("The host should not be empty!");
+ }
+
+ String path = url.getPath();
+ file = getFile(path);
+ folder = getFolder(path);
+
+ if (file != null && file.indexOf('/') != -1) {
+ throw new IllegalArgumentException("The dex URL format should be: dex:/<package>/[<folder>]/[<file>] only");
+ }
+
+ this.url = url;
+
+ }
+
+ public static String getFolder(String path) {
+ String file = path.trim();
+
+ int firstSlashIndex = file.indexOf('/');
+
+ if ("".equals(file) || "/".equals(file) || firstSlashIndex == -1 || firstSlashIndex >= file.length() - 1) {
+ return null;
+ }
+
+ int secondSlashIndex = file.indexOf("/", firstSlashIndex + 1);
+
+ if (secondSlashIndex == -1 || secondSlashIndex >= file.length() - 1 || firstSlashIndex == secondSlashIndex - 1) {
+ return null;
+ }
+
+ return file.substring(firstSlashIndex + 1, secondSlashIndex);
+
+ }
+
+ public static String getFile(String path) {
+ String file = path.trim();
+
+ int firstSlashIndex = file.indexOf('/');
+
+ if ("".equals(file) || "/".equals(file) || firstSlashIndex == -1 || firstSlashIndex >= file.length() - 1) {
+ return null;
+ }
+
+ int secondSlashIndex = file.indexOf("/", firstSlashIndex + 1);
+
+ if (secondSlashIndex == -1 || secondSlashIndex >= file.length() - 1 || firstSlashIndex == secondSlashIndex - 1) {
+ return null;
+ }
+
+ return file.substring(secondSlashIndex + 1);
+
+ }
+
+ public String getFolderName() {
+ return folder;
+ }
+
+ public Context getContext() {
+ Context[] contexts = ContextRegistry.getContexts(url.getHost());
+
+ if (contexts.length == 0) {
+ return null;
+ }
+
+ return contexts[0];
+
+ }
+
+ public String getFileName() {
+ return file;
+ }
+
+ public boolean isPackage() {
+ return folder == null;
+ }
+
+ public boolean isFolder() {
+ return file == null && folder != null;
+ }
+
+ public boolean isFile() {
+ return file != null;
+ }
+
+ public String getPackageName() {
+ return url.getHost();
+ }
+
+ public URI[] getContentFiles() throws IOException {
+
+ if (isFile()) {
+ throw new UnsupportedOperationException("Not supported when the resource is a file!");
+ }
+
+ String packageName = url.getHost();
+
+ Context[] contexts = ContextRegistry.getContexts(packageName);
+
+ if (contexts.length == 0) {
+ throw new IOException("Android context not found!");
+ }
+
+ Context context = contexts[0];
+
+ ArrayList<URI> files = new ArrayList<URI>();
+ StringBuffer className = new StringBuffer(packageName).append(".R");
+
+ if (isPackage()) {
+ ClassLoader classLoader = context.getClass().getClassLoader();
+
+ try {
+
+ for (String folderName : new String[] {"raw", "xml"}) {
+ Class clazz = classLoader.loadClass(className.toString() + '$' + folderName);
+ folderName = '/' + folderName + '/';
+ Field[] fields = clazz.getFields();
+
+ for (Field field : fields) {
+ try {
+ files.add(new URI("dex://" + packageName + folderName + field.getName()));
+ } catch (URISyntaxException e) {}
+ }
+
+ }
+
+ } catch (ClassNotFoundException e) {}
+
+ } else {
+
+ try {
+ className.append('$').append(folder);
+ Class clazz = getClass().getClassLoader().loadClass(className.toString());
+ String folderName = '/' + clazz.getSimpleName() + '/';
+ Field[] fields = clazz.getFields();
+
+ for (Field field : fields) {
+ try {
+ files.add(new URI("dex://" + packageName + folderName + field.getName()));
+ } catch (URISyntaxException e) {}
+ }
+
+ } catch (ClassNotFoundException e) {
+ throw new IOException("Resource not found!");
+ }
+
+ }
+
+
+
+ URI[] ret = new URI[files.size()];
+ files.toArray(ret);
+
+ return ret;
+
+ }
+
+ public URL getURL() {
+ return url;
+ }
+
+}
diff --git a/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLConnection.java b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLConnection.java new file mode 100644 index 0000000000..af0e93b043 --- /dev/null +++ b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLConnection.java @@ -0,0 +1,128 @@ +package org.apache.tuscany.sca.android;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.UnknownServiceException;
+
+import android.content.Context;
+
+public class DexURLConnection extends URLConnection {
+
+ private InputStream input;
+
+ protected DexURLConnection(URL url) {
+ super(url);
+ setAllowUserInteraction(false);
+ setUseCaches(false);
+ setDefaultUseCaches(false);
+ setConnectTimeout(0);
+ setReadTimeout(0);
+ setDoInput(true);
+ setDoOutput(false);
+
+ }
+
+ public InputStream getInputStream() throws IOException {
+
+ if (input == null) {
+ connect();
+ }
+
+ return input;
+
+ }
+
+ private String guessContentTypeFromInput() {
+
+ if (!connected) {
+
+ try {
+ connect();
+ } catch (IOException e) {
+ return null;
+ }
+
+ }
+
+ try {
+ return guessContentTypeFromStream(input);
+ } catch (IOException e) {
+ return null;
+ }
+
+ }
+
+ @Override
+ public String getContentType() {
+
+ if (DexResource.getFolder(url.getPath()) == null || DexResource.getFile(url.getPath()) == null) {
+ return "application/x-dex";
+ }
+
+ return guessContentTypeFromInput();
+
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ throw new UnknownServiceException("Output not supported!");
+ }
+
+ public void connect() throws IOException {
+
+ if (!connected) {
+ String host = url.getHost();
+ Context[] contexts = ContextRegistry.getContexts(host);
+
+ if (contexts.length == 0) {
+ throw new IOException("Android context not found!");
+ }
+
+ Context context = contexts[0];
+
+ if ("".equals(host)) {
+ throw new IOException("not valid host name: \"\"");
+ }
+
+ String path = url.getPath();
+ String file = DexResource.getFile(path);
+ String folder = DexResource.getFolder(path);
+
+ if (file == null) {
+ return;
+ }
+
+ file = file.replace('.', '_');
+
+ try {
+
+ StringBuffer sb = new StringBuffer(context.getPackageName());
+ sb.append('.').append('R').append('$').append(folder);
+
+ Class clazz = getClass().getClassLoader().loadClass(sb.toString());
+ Field field = clazz.getDeclaredField(file);
+
+ int id = field.getInt(null);
+ input = context.getResources().openRawResource(id);
+ connected = true;
+
+ } catch (ClassNotFoundException e) {
+ throw new IOException(e.getMessage());
+ } catch (SecurityException e) {
+ throw new IOException(e.getMessage());
+ } catch (NoSuchFieldException e) {
+ throw new IOException(e.getMessage());
+ } catch (IllegalArgumentException e) {
+ throw new IOException(e.getMessage());
+ } catch (IllegalAccessException e) {
+ throw new IOException(e.getMessage());
+ }
+
+ }
+
+ }
+
+}
diff --git a/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandler.java b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandler.java new file mode 100644 index 0000000000..a5c1507e0d --- /dev/null +++ b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandler.java @@ -0,0 +1,15 @@ +package org.apache.tuscany.sca.android;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+public class DexURLStreamHandler extends URLStreamHandler {
+
+ @Override
+ protected URLConnection openConnection(URL url) throws IOException {
+ return new DexURLConnection(url);
+ }
+
+}
diff --git a/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandlerFactory.java b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandlerFactory.java new file mode 100644 index 0000000000..5bb53dcd2e --- /dev/null +++ b/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandlerFactory.java @@ -0,0 +1,33 @@ +package org.apache.tuscany.sca.android;
+
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+public class DexURLStreamHandlerFactory implements URLStreamHandlerFactory {
+
+ private static DexURLStreamHandlerFactory instance;
+
+ public static DexURLStreamHandlerFactory getInstance() {
+
+ if (instance == null) {
+ instance = new DexURLStreamHandlerFactory();
+ }
+
+ return instance;
+
+ }
+
+ public DexURLStreamHandlerFactory() {}
+
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ URLStreamHandler urlStreamHandler = null;
+
+ if ("dex".equals(protocol)) {
+ urlStreamHandler = new DexURLStreamHandler();
+ }
+
+ return urlStreamHandler;
+
+ }
+
+}
|