From 587877fcbd358e233f653e01c4b3ed3354203626 Mon Sep 17 00:00:00 2001 From: lresende Date: Wed, 11 Nov 2009 23:06:30 +0000 Subject: Moving 1.x branches git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835118 13f79535-47bb-0310-9956-ffa450edef68 --- .../tuscany/sca/android/ContextRegistry.java | 55 ++++++ .../apache/tuscany/sca/android/DexResource.java | 190 +++++++++++++++++++++ .../tuscany/sca/android/DexURLConnection.java | 128 ++++++++++++++ .../tuscany/sca/android/DexURLStreamHandler.java | 15 ++ .../sca/android/DexURLStreamHandlerFactory.java | 33 ++++ 5 files changed, 421 insertions(+) create mode 100644 sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/ContextRegistry.java create mode 100644 sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexResource.java create mode 100644 sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLConnection.java create mode 100644 sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandler.java create mode 100644 sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandlerFactory.java (limited to 'sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org') diff --git a/sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/ContextRegistry.java b/sca-java-1.x/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/sca-java-1.x/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> contexts = new Hashtable>(); + + public static void registerContext(Context context) { + String packageName = context.getPackageName(); + HashSet packContexts = contexts.get(packageName); + + if (packContexts == null) { + packContexts = new HashSet(); + contexts.put(packageName, packContexts); + + } + + packContexts.add(context); + + } + + public static void unregisterContext(Context context) { + String packageName = context.getPackageName(); + HashSet packContexts = contexts.get(packageName); + + if (packContexts != null) { + packContexts.remove(context); + + if (packContexts.isEmpty()) { + contexts.remove(packageName); + } + + } + + } + + public static Context[] getContexts(String packageName) { + HashSet 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/sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexResource.java b/sca-java-1.x/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/sca-java-1.x/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://[]/[] 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 files = new ArrayList(); + 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/sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLConnection.java b/sca-java-1.x/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/sca-java-1.x/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/sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandler.java b/sca-java-1.x/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/sca-java-1.x/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/sca-java-1.x/branches/sca-android-r643746/modules/android-jdk-classes/src/org/apache/tuscany/sca/android/DexURLStreamHandlerFactory.java b/sca-java-1.x/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/sca-java-1.x/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; + + } + +} -- cgit v1.2.3