You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2008/05/27 00:21:57 UTC
svn commit: r660326 [11/17] - in /harmony/enhanced/microemulator: ./
microemu-android/ microemu-android/src/ microemu-android/src/org/
microemu-android/src/org/microemu/ microemu-android/src/org/microemu/android/
microemu-android/src/org/microemu/andro...
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ChangeCallsMethodVisitor.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ChangeCallsMethodVisitor.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ChangeCallsMethodVisitor.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ChangeCallsMethodVisitor.java Mon May 26 15:20:19 2008
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.classloader;
+
+import java.util.HashMap;
+
+import org.microemu.Injected;
+import org.microemu.app.util.MIDletThread;
+import org.microemu.app.util.MIDletTimer;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodAdapter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * @author vlads
+ *
+ */
+public class ChangeCallsMethodVisitor extends MethodAdapter implements Opcodes {
+
+ private static final String INJECTED_CLASS = codeName(Injected.class);
+
+ static String NEW_SYSTEM_OUT_CLASS = INJECTED_CLASS;
+
+ static String NEW_SYSTEM_PROPERTIES_CLASS = INJECTED_CLASS;
+
+ static String NEW_RESOURCE_LOADER_CLASS = INJECTED_CLASS;
+
+ private HashMap catchInfo;
+
+ private InstrumentationConfig config;
+
+ private static class CatchInformation {
+
+ Label label;
+
+ String type;
+
+ public CatchInformation(String type) {
+ this.label = new Label();
+ this.type = type;
+ }
+ }
+
+ public ChangeCallsMethodVisitor(MethodVisitor mv, InstrumentationConfig config) {
+ super(mv);
+ this.config = config;
+ }
+
+ public static String codeName(Class klass) {
+ return klass.getName().replace('.', '/');
+ }
+
+ public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) {
+ switch (opcode) {
+ case GETSTATIC:
+ if ((name.equals("out")) && (owner.equals("java/lang/System"))) {
+ //System.out.println("owner " + owner + " name " + name + " desc " + desc);
+ // GETSTATIC System.out : PrintStream
+ mv.visitFieldInsn(opcode, NEW_SYSTEM_OUT_CLASS, name, desc);
+ return;
+ }
+ if ((name.equals("err")) && (owner.equals("java/lang/System"))) {
+ //System.out.println("owner " + owner + " name " + name + " desc " + desc);
+ // GETSTATIC System.out : PrintStream
+ mv.visitFieldInsn(opcode, NEW_SYSTEM_OUT_CLASS, name, desc);
+ return;
+ }
+ break;
+
+ }
+ mv.visitFieldInsn(opcode, owner, name, desc);
+ }
+
+ public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+ switch (opcode) {
+ case INVOKESTATIC:
+ //System.out.println("Method owner " + owner + " name " + name + " desc " + desc);
+ if ((name.equals("getProperty")) && (owner.equals("java/lang/System"))) {
+ // INVOKESTATIC
+ // java/lang/System.getProperty(Ljava/lang/String;)Ljava/lang/String;
+ mv.visitMethodInsn(opcode, NEW_SYSTEM_PROPERTIES_CLASS, name, desc);
+ return;
+ }
+ break;
+ case INVOKEVIRTUAL:
+ if ((name.equals("getResourceAsStream")) && (owner.equals("java/lang/Class"))) {
+ // INVOKEVIRTUAL
+ // java/lang/Class.getResourceAsStream(Ljava/lang/String;)Ljava/io/InputStream;
+ // "org/microemu/ResourceLoader", "getResourceAsStream", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/io/InputStream;");
+ mv.visitMethodInsn(INVOKESTATIC, NEW_RESOURCE_LOADER_CLASS, name, "(Ljava/lang/Class;Ljava/lang/String;)Ljava/io/InputStream;");
+ return;
+ } else if ((name.equals("printStackTrace")) && (owner.equals("java/lang/Throwable"))) {
+ // INVOKEVIRTUAL java/lang/Throwable.printStackTrace()V
+ mv.visitMethodInsn(INVOKESTATIC, INJECTED_CLASS, name, "(Ljava/lang/Throwable;)V");
+ return;
+ }
+ break;
+ case INVOKESPECIAL:
+ if ((config.isEnhanceThreadCreation()) && (name.equals("<init>"))) {
+ if (owner.equals("java/util/Timer")) {
+ owner = codeName(MIDletTimer.class);
+ } else if (owner.equals("java/lang/Thread")) {
+ owner = codeName(MIDletThread.class);
+ }
+ }
+ break;
+ }
+
+ mv.visitMethodInsn(opcode, owner, name, desc);
+ }
+
+ public void visitTypeInsn(final int opcode, String desc) {
+ if ((opcode == NEW) && (config.isEnhanceThreadCreation())) {
+ if ("java/util/Timer".equals(desc)) {
+ desc = codeName(MIDletTimer.class);
+ } else if ("java/lang/Thread".equals(desc)) {
+ desc = codeName(MIDletThread.class);
+ }
+ }
+ mv.visitTypeInsn(opcode, desc);
+ }
+
+ public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) {
+ if (config.isEnhanceCatchBlock() && type != null) {
+ if (catchInfo == null) {
+ catchInfo = new HashMap();
+ }
+ CatchInformation newHandler = (CatchInformation)catchInfo.get(handler);
+ if (newHandler == null) {
+ newHandler = new CatchInformation(type);
+ catchInfo.put(handler, newHandler);
+ }
+ mv.visitTryCatchBlock(start, end, newHandler.label, type);
+ } else {
+ mv.visitTryCatchBlock(start, end, handler, type);
+ }
+ }
+
+ //TODO make this work for gMaps case
+ public void visitLabel(Label label) {
+ if (config.isEnhanceCatchBlock() && catchInfo != null) {
+ CatchInformation newHandler = (CatchInformation)catchInfo.get(label);
+ if (newHandler != null) {
+ mv.visitLabel(newHandler.label);
+ // no push, just use current Throwable in stack
+ mv.visitMethodInsn(INVOKESTATIC, INJECTED_CLASS, "handleCatchThrowable", "(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
+ // stack contains Throwable, just verify that it is right type for this handler
+ mv.visitTypeInsn(CHECKCAST, newHandler.type);
+ }
+ }
+ mv.visitLabel(label);
+ }
+
+}
\ No newline at end of file
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ChangeCallsMethodVisitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ClassPreprocessor.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ClassPreprocessor.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ClassPreprocessor.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ClassPreprocessor.java Mon May 26 15:20:19 2008
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.classloader;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.microemu.log.Logger;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+
+/**
+ * @author vlads
+ *
+ */
+public class ClassPreprocessor {
+
+ public static byte[] instrument(final InputStream classInputStream, InstrumentationConfig config) {
+ try {
+ ClassReader cr = new ClassReader(classInputStream);
+ ClassWriter cw = new ClassWriter(0);
+ ClassVisitor cv = new ChangeCallsClassVisitor(cw, config);
+ cr.accept(cv, 0);
+ return cw.toByteArray();
+ } catch (IOException e) {
+ Logger.error("Error loading MIDlet class", e);
+ return null;
+ }
+ }
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ClassPreprocessor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ExtensionsClassLoader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ExtensionsClassLoader.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ExtensionsClassLoader.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ExtensionsClassLoader.java Mon May 26 15:20:19 2008
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.classloader;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.StringTokenizer;
+
+import org.microemu.app.util.IOUtils;
+import org.microemu.log.Logger;
+
+/**
+ *
+ * Class loader for device and other Extensions
+ *
+ * @author vlads
+ *
+ */
+public class ExtensionsClassLoader extends URLClassLoader {
+
+ private final static boolean debug = false;
+
+ /* The context to be used when loading classes and resources */
+ private AccessControlContext acc;
+
+ public ExtensionsClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent);
+ acc = AccessController.getContext();
+ }
+
+ public void addURL(URL url) {
+ super.addURL(url);
+ }
+
+ public void addClasspath(String classpath) {
+ StringTokenizer st = new StringTokenizer(classpath, ";");
+ while (st.hasMoreTokens()) {
+ try {
+ String path = st.nextToken();
+ if (path.startsWith("file:")) {
+ addURL(new URL(path));
+ } else {
+ addURL(new URL(IOUtils.getCanonicalFileURL(new File(path))));
+ }
+ } catch (MalformedURLException e) {
+ throw new Error(e);
+ }
+ }
+ }
+
+
+ /**
+ * Finds the resource with the given name. A resource is some data (images,
+ * audio, text, etc) that can be accessed by class code in a way that is
+ * independent of the location of the code.
+ *
+ * <p>
+ * The name of a resource is a '<tt>/</tt>'-separated path name that
+ * identifies the resource.
+ *
+ * <p>
+ * Search order is reverse to standard implemenation
+ * </p>
+ *
+ * <p>
+ * This method will first use {@link #findResource(String)} to find the
+ * resource. That failing, this method will NOT invoke the parent class
+ * loader.
+ * </p>
+ *
+ * @param name
+ * The resource name
+ *
+ * @return A <tt>URL</tt> object for reading the resource, or
+ * <tt>null</tt> if the resource could not be found or the invoker
+ * doesn't have adequate privileges to get the resource.
+ *
+ */
+ public URL getResource(final String name) {
+ try {
+ URL url = (URL) AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() {
+ return findResource(name);
+ }
+ }, acc);
+ if (url != null) {
+ return url;
+ }
+ } catch (PrivilegedActionException e) {
+ if (debug) {
+ Logger.error("Unable to find resource " + name + " ", e);
+ }
+ }
+ return super.getResource(name);
+ }
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/ExtensionsClassLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/InstrumentationConfig.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/InstrumentationConfig.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/InstrumentationConfig.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/InstrumentationConfig.java Mon May 26 15:20:19 2008
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.classloader;
+
+/**
+ * @author vlads
+ */
+public class InstrumentationConfig {
+
+ private boolean enhanceThreadCreation = false;
+
+ private boolean enhanceCatchBlock = false;
+
+ public boolean isEnhanceCatchBlock() {
+ return this.enhanceCatchBlock;
+ }
+
+ public void setEnhanceCatchBlock(boolean enhanceCatchBlock) {
+ this.enhanceCatchBlock = enhanceCatchBlock;
+ }
+
+ public boolean isEnhanceThreadCreation() {
+ return this.enhanceThreadCreation;
+ }
+
+ public void setEnhanceThreadCreation(boolean enhanceThreadCreation) {
+ this.enhanceThreadCreation = enhanceThreadCreation;
+ }
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/InstrumentationConfig.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoader.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoader.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoader.java Mon May 26 15:20:19 2008
@@ -0,0 +1,411 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.classloader;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.microemu.app.util.IOUtils;
+import org.microemu.log.Logger;
+
+/**
+ * Main features of this class loader Security aware - enables load and run app
+ * in Webstart. Proper class loading order. MIDlet classes loaded first then
+ * system and MicroEmulator classes Proper resource loading order. MIDlet
+ * resources only can be loaded. MIDlet Bytecode preprocessing/instrumentation
+ *
+ * @author vlads
+ *
+ */
+public class MIDletClassLoader extends URLClassLoader {
+
+ // TODO make this configurable
+
+ public static boolean instrumentMIDletClasses = true;
+
+ public static boolean traceClassLoading = false;
+
+ public static boolean traceSystemClassLoading = false;
+
+ public static boolean enhanceCatchBlock = false;
+
+ private final static boolean debug = false;
+
+ private boolean delegatingToParent = false;
+
+ private InstrumentationConfig config;
+
+ private Set noPreporcessingNames;
+
+ /* The context to be used when loading classes and resources */
+ private AccessControlContext acc;
+
+ private static class LoadClassByParentException extends ClassNotFoundException {
+
+ public LoadClassByParentException(String name) {
+ super(name);
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ }
+
+ public MIDletClassLoader(ClassLoader parent) {
+ super(new URL[] {}, parent);
+ noPreporcessingNames = new HashSet();
+ acc = AccessController.getContext();
+ config = new InstrumentationConfig();
+ config.setEnhanceCatchBlock(enhanceCatchBlock);
+ config.setEnhanceThreadCreation(true);
+ }
+
+ // public MIDletClassLoader(URL[] urls, ClassLoader parent) {
+ // super(urls, parent);
+ // noPreporcessingNames = new HashSet();
+ // }
+
+ public void configure(MIDletClassLoaderConfig clConfig) throws MalformedURLException {
+ for (Iterator iter = clConfig.appclasspath.iterator(); iter.hasNext();) {
+ String path = (String) iter.next();
+ StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
+ while (st.hasMoreTokens()) {
+ this.addURL(new URL(IOUtils.getCanonicalFileClassLoaderURL(new File(st.nextToken()))));
+ }
+ }
+ for (Iterator iter = clConfig.appclasses.iterator(); iter.hasNext();) {
+ this.addClassURL((String) iter.next());
+ }
+ this.delegatingToParent = (clConfig.delegationType == MIDletClassLoaderConfig.DELEGATION_DELEGATING);
+ }
+
+ /**
+ * Appends the Class Location URL to the list of URLs to search for classes
+ * and resources.
+ *
+ * @param Class
+ * Name
+ */
+ public void addClassURL(String className) throws MalformedURLException {
+ String resource = getClassResourceName(className);
+ URL url = getParent().getResource(resource);
+ if (url == null) {
+ url = this.getResource(resource);
+ }
+ if (url == null) {
+ throw new MalformedURLException("Unable to find class " + className + " URL");
+ }
+ String path = url.toExternalForm();
+ if (debug) {
+ Logger.debug("addClassURL ", path);
+ }
+ addURL(new URL(path.substring(0, path.length() - resource.length())));
+ }
+
+ static URL getClassURL(ClassLoader parent, String className) throws MalformedURLException {
+ String resource = getClassResourceName(className);
+ URL url = parent.getResource(resource);
+ if (url == null) {
+ throw new MalformedURLException("Unable to find class " + className + " URL");
+ }
+ String path = url.toExternalForm();
+ return new URL(path.substring(0, path.length() - resource.length()));
+ }
+
+ public void addURL(URL url) {
+ if (debug) {
+ Logger.debug("addURL ", url.toString());
+ }
+ super.addURL(url);
+ }
+
+ /**
+ * Loads the class with the specified <a href="#name">binary name</a>.
+ *
+ * <p>
+ * Search order is reverse to standard implemenation
+ * </p>
+ *
+ * This implementation of this method searches for classes in the following
+ * order:
+ *
+ * <p>
+ * <ol>
+ *
+ * <li>
+ * <p>
+ * Invoke {@link #findLoadedClass(String)} to check if the class has already
+ * been loaded.
+ * </p>
+ * </li>
+ *
+ * <li>
+ * <p>
+ * Invoke the {@link #findClass(String)} method to find the class in this
+ * class loader URLs.
+ * </p>
+ * </li>
+ *
+ * <li>
+ * <p>
+ * Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method on the
+ * parent class loader. If the parent is <tt>null</tt> the class loader
+ * built-in to the virtual machine is used, instead.
+ * </p>
+ * </li>
+ *
+ * </ol>
+ *
+ */
+ protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ if (debug) {
+ Logger.debug("loadClass", name);
+ }
+ // First, check if the class has already been loaded
+ Class result = findLoadedClass(name);
+ if (result == null) {
+ try {
+ result = findClass(name);
+ if (debug && (result == null)) {
+ Logger.debug("loadClass not found", name);
+ }
+ } catch (ClassNotFoundException e) {
+
+ if ((e instanceof LoadClassByParentException) || this.delegatingToParent) {
+ if (traceSystemClassLoading) {
+ Logger.info("Load system class", name);
+ }
+ // This will call our findClass again if Class is not found
+ // in parent
+ result = super.loadClass(name, false);
+ if (result == null) {
+ throw new ClassNotFoundException(name);
+ }
+ }
+ }
+ }
+ if (resolve) {
+ resolveClass(result);
+ }
+ return result;
+ }
+
+ /**
+ * Finds the resource with the given name. A resource is some data (images,
+ * audio, text, etc) that can be accessed by class code in a way that is
+ * independent of the location of the code.
+ *
+ * <p>
+ * The name of a resource is a '<tt>/</tt>'-separated path name that
+ * identifies the resource.
+ *
+ * <p>
+ * Search order is reverse to standard implemenation
+ * </p>
+ *
+ * <p>
+ * This method will first use {@link #findResource(String)} to find the
+ * resource. That failing, this method will NOT invoke the parent class
+ * loader if delegatingToParent=false.
+ * </p>
+ *
+ * @param name
+ * The resource name
+ *
+ * @return A <tt>URL</tt> object for reading the resource, or
+ * <tt>null</tt> if the resource could not be found or the invoker
+ * doesn't have adequate privileges to get the resource.
+ *
+ */
+
+ public URL getResource(final String name) {
+ try {
+ return (URL) AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() {
+ URL url = findResource(name);
+ if (delegatingToParent && (getParent() != null)) {
+ url = getParent().getResource(name);
+ }
+ return url;
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ if (debug) {
+ Logger.error("Unable to find resource " + name + " ", e);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Allow access to resources
+ */
+ public InputStream getResourceAsStream(String name) {
+ final URL url = getResource(name);
+ if (url == null) {
+ return null;
+ }
+
+ try {
+ return (InputStream) AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws IOException {
+ return url.openStream();
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ if (debug) {
+ Logger.debug("Unable to find resource for class " + name + " ", e);
+ }
+ return null;
+ }
+
+ }
+
+ public boolean classLoadByParent(String className) {
+ /* This java standard */
+ if (className.startsWith("java.")) {
+ return true;
+ }
+ /*
+ * This is required when Class.forName().newInstance() used to create
+ * instances with inheritance
+ */
+ if (className.startsWith("sun.reflect.")) {
+ return true;
+ }
+ /* No real device allow overloading this package */
+ if (className.startsWith("javax.microedition.")) {
+ return true;
+ }
+ if (className.startsWith("javax.")) {
+ return true;
+ }
+ if (noPreporcessingNames.contains(className)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Special case for classes injected to MIDlet
+ *
+ * @param klass
+ */
+ public void disableClassPreporcessing(Class klass) {
+ disableClassPreporcessing(klass.getName());
+ }
+
+ public void disableClassPreporcessing(String className) {
+ noPreporcessingNames.add(className);
+ }
+
+ public static String getClassResourceName(String className) {
+ return className.replace('.', '/').concat(".class");
+ }
+
+ protected Class findClass(final String name) throws ClassNotFoundException {
+ if (debug) {
+ Logger.debug("findClass", name);
+ }
+ if (classLoadByParent(name)) {
+ throw new LoadClassByParentException(name);
+ }
+ InputStream is;
+ try {
+ is = (InputStream) AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws ClassNotFoundException {
+ return getResourceAsStream(getClassResourceName(name));
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ if (debug) {
+ Logger.debug("Unable to find resource for class " + name + " ", e);
+ }
+ throw new ClassNotFoundException(name, e.getCause());
+ }
+
+ if (is == null) {
+ if (debug) {
+ Logger.debug("Unable to find resource for class", name);
+ }
+ throw new ClassNotFoundException(name);
+ }
+ byte[] byteCode;
+ int byteCodeLength;
+ try {
+ if (traceClassLoading) {
+ Logger.info("Load MIDlet class", name);
+ }
+ if (instrumentMIDletClasses) {
+ byteCode = ClassPreprocessor.instrument(is, config);
+ byteCodeLength = byteCode.length;
+ } else {
+ final int chunkSize = 1024 * 2;
+ // No class or data object must be bigger than 16 Kilobyte
+ final int maxClassSizeSize = 1024 * 16;
+ byteCode = new byte[chunkSize];
+ byteCodeLength = 0;
+ do {
+ int retrived;
+ try {
+ retrived = is.read(byteCode, byteCodeLength, byteCode.length - byteCodeLength);
+ } catch (IOException e) {
+ throw new ClassNotFoundException(name, e);
+ }
+ if (retrived == -1) {
+ break;
+ }
+ if (byteCode.length + chunkSize > maxClassSizeSize) {
+ throw new ClassNotFoundException(name, new ClassFormatError(
+ "Class object is bigger than 16 Kilobyte"));
+ }
+ byteCodeLength += retrived;
+ if (byteCode.length == byteCodeLength) {
+ byte[] newData = new byte[byteCode.length + chunkSize];
+ System.arraycopy(byteCode, 0, newData, 0, byteCode.length);
+ byteCode = newData;
+ } else if (byteCode.length < byteCodeLength) {
+ throw new ClassNotFoundException(name, new ClassFormatError("Internal read error"));
+ }
+ } while (true);
+ }
+ } finally {
+ try {
+ is.close();
+ } catch (IOException ignore) {
+ }
+ }
+ if ((debug) && (instrumentMIDletClasses)) {
+ Logger.debug("instrumented ", name);
+ }
+ return defineClass(name, byteCode, 0, byteCodeLength);
+ }
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoaderConfig.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoaderConfig.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoaderConfig.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoaderConfig.java Mon May 26 15:20:19 2008
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.classloader;
+
+import java.util.List;
+import java.util.Vector;
+
+import org.microemu.app.ConfigurationException;
+
+public class MIDletClassLoaderConfig {
+
+ public static final int DELEGATION_STRICT = 0;
+
+ public static final int DELEGATION_DELEGATING = 1;
+
+ public static final int DELEGATION_SYSTEM = 2;
+
+ int delegationType = DELEGATION_STRICT;
+
+ List appclasses = new Vector();
+
+ List appclasspath = new Vector();
+
+ public void setDelegationType(String delegationType) throws ConfigurationException {
+ if ("strict".equalsIgnoreCase(delegationType)) {
+ this.delegationType = DELEGATION_STRICT;
+ } else if ("delegating".equalsIgnoreCase(delegationType)) {
+ this.delegationType = DELEGATION_DELEGATING;
+ } else if ("system".equalsIgnoreCase(delegationType)) {
+ if ((appclasses.size() != 0) || (appclasspath.size() != 0)) {
+ throw new ConfigurationException("Can't extend system CLASSPATH");
+ }
+ this.delegationType = DELEGATION_SYSTEM;
+ } else {
+ throw new ConfigurationException("Unknown delegationType [" + delegationType + "]");
+ }
+ }
+
+ public boolean isClassLoaderDisabled() {
+ return (this.delegationType == DELEGATION_SYSTEM);
+ }
+
+ public void addAppClassPath(String path) throws ConfigurationException {
+ if (this.delegationType == DELEGATION_SYSTEM) {
+ throw new ConfigurationException("Can't extend system CLASSPATH");
+ }
+ appclasspath.add(path);
+ }
+
+ public void addAppClass(String className) throws ConfigurationException {
+ if (this.delegationType == DELEGATION_SYSTEM) {
+ throw new ConfigurationException("Can't extend system CLASSPATH");
+ }
+ appclasses.add(className);
+ }
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/classloader/MIDletClassLoaderConfig.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/Message.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/Message.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/Message.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/Message.java Mon May 26 15:20:19 2008
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.ui;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.microemu.log.Logger;
+
+/**
+ *
+ * This class is used to Show error message to user
+ *
+ * @author vlads
+ *
+ */
+public class Message {
+
+ public static final int ERROR = 0;
+
+ public static final int INFO = 1;
+
+ public static final int WARN = 2;
+
+ private static List listeners = new Vector();
+
+ static {
+ Logger.addLogOrigin(Message.class);
+ }
+
+ /**
+ * Show Error message to user
+ *
+ * @param title Dialog title
+ * @param text Message
+ */
+ public static void error(String title, String text) {
+ Logger.error("Message: " + title + ": " + text);
+ callListeners(ERROR, title, text, null);
+ }
+
+ /**
+ * Show Error message to user
+ *
+ * @param text Message
+ */
+ public static void error(String text) {
+ Logger.error("Message: Error: " + text);
+ callListeners(ERROR, "Error", text, null);
+ }
+
+ /**
+ * Show Error message to user
+ *
+ * @param title Dialog title
+ * @param text Message
+ */
+ public static void error(String title, String text, Throwable throwable) {
+ Logger.error("Message: " + title + ": " + text, throwable);
+ callListeners(ERROR, title, text, throwable);
+ }
+
+ public static void error(String text, Throwable throwable) {
+ Logger.error("Message: Error : " + text, throwable);
+ callListeners(ERROR, "Error", text, throwable);
+ }
+
+ /**
+ * Show info message to user
+ *
+ * @param text Message
+ */
+ public static void info(String text) {
+ Logger.info("Message: info: " + text);
+ callListeners(INFO, "Info", text, null);
+ }
+
+ /**
+ * Show info message to user
+ *
+ * @param text Message
+ */
+ public static void warn(String text) {
+ Logger.warn("Message: warn: " + text);
+ callListeners(INFO, "Warning", text, null);
+ }
+
+ /**
+ * Here we can butify error message text.
+ * @param throwable
+ * @return
+ */
+ public static String getCauseMessage(Throwable throwable) {
+ if (throwable.getCause() == null) {
+ return throwable.toString();
+ } else {
+ return getCauseMessage(throwable.getCause());
+ }
+ }
+
+ private static void callListeners(int level, String title, String text, Throwable throwable) {
+ for (Iterator iter = listeners.iterator(); iter.hasNext();) {
+ MessageListener a = (MessageListener) iter.next();
+ a.showMessage(level, title, text, throwable);
+ };
+ }
+
+ public static void addListener(MessageListener newListener) {
+ listeners.add(newListener);
+ }
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/Message.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/MessageListener.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/MessageListener.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/MessageListener.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/MessageListener.java Mon May 26 15:20:19 2008
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.ui;
+
+public interface MessageListener {
+
+ public static final int ERROR = 0;
+
+ public static final int INFO = 1;
+
+ public static final int WARN = 2;
+
+ public void showMessage(int level, String title, String text, Throwable throwable);
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/MessageListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/ResponseInterfaceListener.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/ResponseInterfaceListener.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/ResponseInterfaceListener.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/ResponseInterfaceListener.java Mon May 26 15:20:19 2008
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.ui;
+
+
+public interface ResponseInterfaceListener
+{
+
+ void stateChanged(boolean state);
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/ResponseInterfaceListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/StatusBarListener.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/StatusBarListener.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/StatusBarListener.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/StatusBarListener.java Mon May 26 15:20:19 2008
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.ui;
+
+
+public interface StatusBarListener
+{
+
+ void statusBarChanged(String text);
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/ui/StatusBarListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/AppletProducer.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/AppletProducer.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/AppletProducer.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/AppletProducer.java Mon May 26 15:20:19 2008
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URL;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.microemu.app.classloader.ClassPreprocessor;
+import org.microemu.app.classloader.InstrumentationConfig;
+import org.microemu.device.Device;
+import org.microemu.log.Logger;
+
+public class AppletProducer {
+
+ public static void createHtml(File htmlOutputFile, Device device, String className, File midletOutputFile,
+ File appletPackageOutputFile, File deviceOutputFile, String deviceDescriptorLocation) throws IOException {
+ int width = device.getNormalImage().getWidth();
+ int height = device.getNormalImage().getHeight();
+
+ FileWriter writer = null;
+ try {
+ writer = new FileWriter(htmlOutputFile);
+ writer.write("");
+ writer.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n\n");
+ writer.write("<html>\n");
+ writer.write("\t<head>\n");
+ writer.write("\t\t<title>MicroEmulator</title>\n");
+ writer.write("\t</head>\n");
+ writer.write("\t<body>\n");
+ writer.write("\t\t<applet code=\"org.microemu.applet.Main\"\n");
+ writer.write("\t\t\t\twidth=\"" + width + "\" height=\"" + height + "\"\n");
+ writer.write("\t\t\t\tarchive=\"" + appletPackageOutputFile.getName() + ",");
+ if (deviceOutputFile != null) {
+ writer.write(deviceOutputFile.getName() + ",");
+ }
+ writer.write(midletOutputFile.getName() + "\">\n");
+ writer.write("\t\t\t<param name=\"midlet\" value=\"" + className + "\">\n");
+ if (deviceDescriptorLocation != null) {
+ writer.write("\t\t\t<param name=\"device\" value=\"" + deviceDescriptorLocation + "\">\n");
+ }
+ writer.write("\t\t</applet>\n");
+ writer.write("\t</body>\n");
+ writer.write("</html>\n");
+ } finally {
+ IOUtils.closeQuietly(writer);
+ }
+ }
+
+ public static void createMidlet(String midletInput, File midletOutputFile) throws IOException {
+ JarInputStream jis = null;
+ JarInputStream ijis = null;
+ JarOutputStream jos = null;
+ InstrumentationConfig config = new InstrumentationConfig();
+ config.setEnhanceThreadCreation(false);
+ try {
+ jis = new JarInputStream(new URL(midletInput).openStream());
+ Manifest manifest = jis.getManifest();
+ if (manifest == null) {
+ jos = new JarOutputStream(new FileOutputStream(midletOutputFile));
+ } else {
+ jos = new JarOutputStream(new FileOutputStream(midletOutputFile), manifest);
+ }
+
+ byte[] inputBuffer = new byte[1024];
+ JarEntry jarEntry;
+ while ((jarEntry = jis.getNextJarEntry()) != null) {
+ if (jarEntry.isDirectory() == false) {
+ String name = jarEntry.getName();
+ int size = 0;
+ int read;
+ int length = inputBuffer.length;
+ while ((read = jis.read(inputBuffer, size, length)) > 0) {
+ size += read;
+
+ length = 1024;
+ if (size + length > inputBuffer.length) {
+ byte[] newInputBuffer = new byte[size + length];
+ System.arraycopy(inputBuffer, 0, newInputBuffer, 0, inputBuffer.length);
+ inputBuffer = newInputBuffer;
+ }
+ }
+
+ byte[] outputBuffer = inputBuffer;
+ int outputSize = size;
+ if (name.endsWith(".class")) {
+ outputBuffer = ClassPreprocessor.instrument(new ByteArrayInputStream(inputBuffer, 0, size), config);
+ outputSize = outputBuffer.length;
+ }
+ jos.putNextEntry(new JarEntry(name));
+ jos.write(outputBuffer, 0, outputSize);
+ }
+ }
+
+ URL url = AppletProducer.class.getResource("/microemu-injected.jar");
+ if (url != null) {
+ ijis = new JarInputStream(url.openStream());
+ while ((jarEntry = ijis.getNextJarEntry()) != null) {
+ if (jarEntry.getName().equals("org/microemu/Injected.class")) {
+ jos.putNextEntry(new JarEntry(jarEntry.getName()));
+ int read;
+ while ((read = ijis.read(inputBuffer)) > 0) {
+ jos.write(inputBuffer, 0, read);
+ }
+ }
+ }
+ } else {
+ Logger.error("Cannot find microemu-injected.jar resource in classpath");
+ }
+ } finally {
+ IOUtils.closeQuietly(jis);
+ IOUtils.closeQuietly(ijis);
+ IOUtils.closeQuietly(jos);
+ }
+ }
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/AppletProducer.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/BuildVersion.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/BuildVersion.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/BuildVersion.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/BuildVersion.java Mon May 26 15:20:19 2008
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * @author vlads
+ *
+ */
+public class BuildVersion {
+
+ public static String getVersion() {
+ InputStream is = BuildVersion.class.getResourceAsStream("/META-INF/maven/org.microemu/microemu-javase/pom.properties");
+ if (is != null) {
+ Properties projectProperties = new Properties();
+ try {
+ projectProperties.load(is);
+ String version = projectProperties.getProperty("version");
+ if (version != null) {
+ return version;
+ }
+ } catch (IOException ignore) {
+ }
+ }
+ return "n/a";
+ }
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/BuildVersion.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/DeviceEntry.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/DeviceEntry.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/DeviceEntry.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/DeviceEntry.java Mon May 26 15:20:19 2008
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.util;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.microemu.EmulatorContext;
+import org.microemu.app.Common;
+import org.microemu.app.Config;
+import org.microemu.log.Logger;
+
+import com.barteo.emulator.device.Device;
+
+public class DeviceEntry {
+
+ private String name;
+
+ private String fileName;
+
+ private String descriptorLocation;
+
+ private boolean defaultDevice;
+
+ private boolean canRemove;
+
+ /**
+ * @deprecated
+ */
+ private String className;
+
+ /**
+ * @deprecated
+ */
+ private EmulatorContext emulatorContext;
+
+ public DeviceEntry(String name, String fileName, String descriptorLocation, boolean defaultDevice) {
+ this(name, fileName, descriptorLocation, defaultDevice, true);
+ }
+
+ public DeviceEntry(String name, String fileName, String descriptorLocation, boolean defaultDevice, boolean canRemove) {
+ this.name = name;
+ this.fileName = fileName;
+ this.descriptorLocation = descriptorLocation;
+ this.defaultDevice = defaultDevice;
+ this.canRemove = canRemove;
+ }
+
+ /**
+ * @deprecated use new DeviceEntry(String name, String fileName, String descriptorLocation, boolean defaultDevice);
+ */
+ public DeviceEntry(String name, String fileName, boolean defaultDevice, String className,
+ EmulatorContext emulatorContext) {
+ this(name, fileName, null, defaultDevice, true);
+
+ this.className = className;
+ this.emulatorContext = emulatorContext;
+ }
+
+ public boolean canRemove() {
+ return canRemove;
+ }
+
+ public String getDescriptorLocation() {
+ if (descriptorLocation == null) {
+ URL[] urls = new URL[1];
+ try {
+ urls[0] = new File(Config.getConfigPath(), fileName).toURI().toURL();
+ ClassLoader classLoader = Common.createExtensionsClassLoader(urls);
+ Class deviceClass = Class.forName(className, true, classLoader);
+ Device device = (Device) deviceClass.newInstance();
+
+ com.barteo.emulator.EmulatorContext oldContext = new com.barteo.emulator.EmulatorContext(emulatorContext);
+
+ device.init(oldContext);
+ descriptorLocation = device.getDescriptorLocation();
+ } catch (MalformedURLException ex) {
+ Logger.error(ex);
+ } catch (ClassNotFoundException ex) {
+ Logger.error(ex);
+ } catch (InstantiationException ex) {
+ Logger.error(ex);
+ } catch (IllegalAccessException ex) {
+ Logger.error(ex);
+ }
+
+ }
+
+ return descriptorLocation;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ /**
+ * @deprecated
+ */
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isDefaultDevice() {
+ return defaultDevice;
+ }
+
+ public void setDefaultDevice(boolean b) {
+ defaultDevice = b;
+ }
+
+ public boolean equals(DeviceEntry test) {
+ if (test == null) {
+ return false;
+ }
+ if (test.getDescriptorLocation().equals(getDescriptorLocation())) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public String toString() {
+ if (defaultDevice) {
+ return name + " (default)";
+ } else {
+ return name;
+ }
+ }
+
+}
\ No newline at end of file
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/DeviceEntry.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/FileRecordStoreManager.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/FileRecordStoreManager.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/FileRecordStoreManager.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/FileRecordStoreManager.java Mon May 26 15:20:19 2008
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.util;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Hashtable;
+
+import javax.microedition.rms.RecordStore;
+import javax.microedition.rms.RecordStoreException;
+import javax.microedition.rms.RecordStoreNotFoundException;
+import javax.microedition.rms.RecordStoreNotOpenException;
+
+import org.microemu.MicroEmulator;
+import org.microemu.RecordStoreManager;
+import org.microemu.app.Config;
+import org.microemu.log.Logger;
+import org.microemu.util.ExtendedRecordListener;
+import org.microemu.util.RecordStoreImpl;
+
+public class FileRecordStoreManager implements RecordStoreManager {
+
+ private final static String RECORD_STORE_SUFFIX = ".rs";
+
+ private MicroEmulator emulator;
+
+ private Hashtable testOpenRecordStores = new Hashtable();
+
+ private ExtendedRecordListener recordListener = null;
+
+ /* The context to be used when accessing files in Webstart */
+ private AccessControlContext acc;
+
+ private FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ if (name.endsWith(RECORD_STORE_SUFFIX)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+
+ public void init(MicroEmulator emulator) {
+ this.emulator = emulator;
+ this.acc = AccessController.getContext();
+ }
+
+ public String getName() {
+ return "File record store";
+ }
+
+ private File getSuiteFolder() {
+ return new File(Config.getConfigPath(), "suite-" + emulator.getLauncher().getSuiteName());
+ }
+
+ public void deleteRecordStore(final String recordStoreName) throws RecordStoreNotFoundException,
+ RecordStoreException {
+ final File storeFile = new File(getSuiteFolder(), recordStoreName + RECORD_STORE_SUFFIX);
+
+ RecordStoreImpl recordStoreImpl = (RecordStoreImpl) testOpenRecordStores.get(storeFile.getName());
+ if (recordStoreImpl != null && recordStoreImpl.isOpen()) {
+ throw new RecordStoreException();
+ }
+
+ try {
+ recordStoreImpl = loadFromDisk(storeFile);
+ } catch (FileNotFoundException ex) {
+ throw new RecordStoreNotFoundException(recordStoreName);
+ }
+
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ storeFile.delete();
+ fireRecordStoreListener(ExtendedRecordListener.RECORDSTORE_DELETE, recordStoreName);
+ return null;
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ Logger.error("Unable remove file " + storeFile, e);
+ throw new RecordStoreException();
+ }
+ }
+
+ public RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary) throws RecordStoreException {
+ File storeFile = new File(getSuiteFolder(), recordStoreName + RECORD_STORE_SUFFIX);
+
+ RecordStoreImpl recordStoreImpl;
+ try {
+ recordStoreImpl = loadFromDisk(storeFile);
+ } catch (FileNotFoundException e) {
+ if (!createIfNecessary) {
+ throw new RecordStoreNotFoundException(recordStoreName);
+ }
+ recordStoreImpl = new RecordStoreImpl(this, recordStoreName);
+ saveToDisk(storeFile, recordStoreImpl);
+ }
+ recordStoreImpl.setOpen(true);
+ if (recordListener != null) {
+ recordStoreImpl.addRecordListener(recordListener);
+ }
+
+ testOpenRecordStores.put(storeFile.getName(), recordStoreImpl);
+
+ fireRecordStoreListener(ExtendedRecordListener.RECORDSTORE_OPEN, recordStoreName);
+
+ return recordStoreImpl;
+ }
+
+ public String[] listRecordStores() {
+ String[] result;
+ try {
+ result = (String[]) AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() {
+ return getSuiteFolder().list(filter);
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ Logger.error("Unable to acess storeFiles", e);
+ return null;
+ }
+ if (result != null) {
+ if (result.length == 0) {
+ result = null;
+ } else {
+ for (int i = 0; i < result.length; i++) {
+ result[i] = result[i].substring(0, result[i].length() - RECORD_STORE_SUFFIX.length());
+ }
+ }
+ }
+ return result;
+ }
+
+ public void saveChanges(RecordStoreImpl recordStoreImpl) throws RecordStoreNotOpenException, RecordStoreException {
+
+ File storeFile = new File(getSuiteFolder(), recordStoreImpl.getName() + RECORD_STORE_SUFFIX);
+
+ saveToDisk(storeFile, recordStoreImpl);
+ }
+
+ public void init() {
+ }
+
+ public void deleteStores() {
+ String[] stores = listRecordStores();
+ for (int i = 0; i < stores.length; i++) {
+ String store = stores[i];
+ try {
+ deleteRecordStore(store);
+ } catch (RecordStoreException e) {
+ Logger.debug("deleteRecordStore", e);
+ }
+ }
+ }
+
+ private RecordStoreImpl loadFromDisk(final File recordStoreFile) throws FileNotFoundException {
+ try {
+ return (RecordStoreImpl) AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return loadFromDiskSecure(recordStoreFile);
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ if (e.getCause() instanceof FileNotFoundException) {
+ throw (FileNotFoundException) e.getCause();
+ }
+ Logger.error("Unable access file " + recordStoreFile, e);
+ throw new FileNotFoundException();
+ }
+ }
+
+ private RecordStoreImpl loadFromDiskSecure(File recordStoreFile) throws FileNotFoundException {
+ RecordStoreImpl store = null;
+ try {
+ DataInputStream dis = new DataInputStream(new FileInputStream(recordStoreFile));
+ store = new RecordStoreImpl(this, dis);
+ dis.close();
+ } catch (FileNotFoundException e) {
+ throw e;
+ } catch (IOException e) {
+ Logger.error("RecordStore.loadFromDisk: ERROR reading " + recordStoreFile.getName(), e);
+ }
+ return store;
+ }
+
+ private void saveToDisk(final File recordStoreFile, final RecordStoreImpl recordStore) throws RecordStoreException {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws RecordStoreException {
+ saveToDiskSecure(recordStoreFile, recordStore);
+ return null;
+ }
+ }, acc);
+ } catch (PrivilegedActionException e) {
+ if (e.getCause() instanceof RecordStoreException) {
+ throw (RecordStoreException) e.getCause();
+ }
+ Logger.error("Unable access file " + recordStoreFile, e);
+ throw new RecordStoreException();
+ }
+ }
+
+ private void saveToDiskSecure(final File recordStoreFile, final RecordStoreImpl recordStore)
+ throws RecordStoreException {
+ if (!recordStoreFile.getParentFile().exists()) {
+ if (!recordStoreFile.getParentFile().mkdirs()) {
+ throw new RecordStoreException("Unable to create recordStore directory");
+ }
+ }
+ try {
+ DataOutputStream dos = new DataOutputStream(new FileOutputStream(recordStoreFile));
+ recordStore.write(dos);
+ dos.close();
+ } catch (IOException e) {
+ Logger.error("RecordStore.saveToDisk: ERROR writting object to " + recordStoreFile.getName(), e);
+ throw new RecordStoreException(e.getMessage());
+ }
+ }
+
+ public int getSizeAvailable(RecordStoreImpl recordStoreImpl) {
+ // FIXME should return free space on device
+ return 1024 * 1024;
+ }
+
+ public void setRecordListener(ExtendedRecordListener recordListener) {
+ this.recordListener = recordListener;
+ }
+
+ public void fireRecordStoreListener(int type, String recordStoreName) {
+ if (recordListener != null) {
+ recordListener.recordStoreEvent(type, System.currentTimeMillis(), recordStoreName);
+ }
+ }
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/FileRecordStoreManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/IOUtils.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/IOUtils.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/IOUtils.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/IOUtils.java Mon May 26 15:20:19 2008
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * General IO stream manipulation utilities.
+ * Some functions are based on org.apache.commons.io
+ *
+ * <p>
+ * This class provides static utility methods for input/output operations.
+ * <ul>
+ * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
+ * </ul>
+ * <p>
+ */
+
+public class IOUtils {
+
+ /**
+ * Solution for JVM bug
+ * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6351751
+ */
+ public static String getCanonicalFileURL(File file) {
+ String path = file.getAbsoluteFile().getPath();
+ if (File.separatorChar != '/') {
+ path = path.replace(File.separatorChar, '/');
+ }
+ // Not network path
+ if (!path.startsWith("//")) {
+ if (path.startsWith("/")) {
+ path = "//" + path;
+ } else {
+ path = "///" + path;
+ }
+ }
+ return "file:" + path;
+ }
+
+ public static String getCanonicalFileClassLoaderURL(File file) {
+ String url = getCanonicalFileURL(file);
+ if ((file.isDirectory()) && (!url.endsWith("/"))) {
+ url += "/";
+ }
+ return url;
+ }
+
+ public static void copyFile(File src, File dst) throws IOException {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(src);
+ copyToFile(fis, dst);
+ } finally {
+ closeQuietly(fis);
+ }
+ }
+
+ public static void copyToFile(InputStream is, File dst) throws IOException {
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(dst);
+ byte[] buf = new byte[1024];
+ int i = 0;
+ while ((i = is.read(buf)) != -1) {
+ fos.write(buf, 0, i);
+ }
+ } finally {
+ closeQuietly(fos);
+ }
+ }
+
+ /**
+ * Unconditionally close an <code>InputStream</code>.
+ * <p>
+ * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
+ * This is typically used in finally blocks.
+ *
+ * @param input the InputStream to close, may be null or already closed
+ */
+ public static void closeQuietly(InputStream input) {
+ try {
+ if (input != null) {
+ input.close();
+ }
+ } catch (IOException ignore) {
+ // ignore
+ }
+ }
+
+ /**
+ * Unconditionally close an <code>OutputStream</code>.
+ * <p>
+ * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
+ * This is typically used in finally blocks.
+ *
+ * @param output the OutputStream to close, may be null or already closed
+ */
+ public static void closeQuietly(OutputStream output) {
+ try {
+ if (output != null) {
+ output.close();
+ }
+ } catch (IOException ignore) {
+ // ignore
+ }
+ }
+
+ /**
+ * Unconditionally close a <code>Writer</code>.
+ * <p>
+ * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
+ * This is typically used in finally blocks.
+ *
+ * @param output the Writer to close, may be null or already closed
+ */
+ public static void closeQuietly(Writer output) {
+ try {
+ if (output != null) {
+ output.close();
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/IOUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletClassLoader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletClassLoader.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletClassLoader.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletClassLoader.java Mon May 26 15:20:19 2008
@@ -0,0 +1,274 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.NoSuchElementException;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+/**
+ * @deprecated use MIDletClassLoader
+ */
+public class MIDletClassLoader /*extends SystemClassLoader*/ {
+
+// protected Hashtable entries;
+//
+// private ResURLStreamHandler resUrlStreamHandler;
+//
+// public static final boolean debug = false;
+//
+// public MIDletClassLoader(ClassLoader parent) {
+// super(parent);
+// entries = new Hashtable();
+// resUrlStreamHandler = new ResURLStreamHandler(entries);
+// }
+//
+//
+// public void addURL(URL midletSource) throws IOException {
+// String path = midletSource.toExternalForm();
+// if (path.endsWith(".jar")) {
+// addJarURL(midletSource);
+// } else if (path.startsWith("file:")) {
+// addPathURL(midletSource);
+// } else {
+// throw new IOException("URL Type not supported: " + midletSource);
+// }
+// }
+//
+// private void addPathURL(URL url) throws IOException {
+// String path = url.toExternalForm();
+// path = path.substring("file:".length(), path.length());
+// File classesDir = new File(path);
+// if ((!classesDir.exists()) || (!classesDir.isDirectory())) {
+// throw new IOException("URL Type not supported: " + url);
+// }
+// int baseLen = path.length();
+// for (Enumeration en = new DirectoryEnumeration(classesDir); en.hasMoreElements();) {
+// File file = (File) en.nextElement();
+// if (!file.isDirectory()) {
+// String name = file.getAbsolutePath().substring(baseLen);
+// if (!allowEntryName(name)) {
+// continue;
+// }
+// InputStream is = new FileInputStream(file);
+// byte[] tmp = new byte[(int)file.length()];
+// is.read(tmp);
+// if (debug) {
+// System.out.println("add entry: " + name);
+// }
+// entries.put(name, tmp);
+// }
+// }
+// }
+//
+// private class DirectoryEnumeration implements Enumeration {
+//
+// File[] files;
+//
+// int processing;
+//
+// Enumeration child = null;
+//
+// DirectoryEnumeration(File dir) {
+// files = dir.listFiles();
+// if (files == null) {
+// throw new Error(dir.getAbsolutePath() + " path does not denote a directory");
+// }
+// processing = 0;
+// }
+//
+// public boolean hasMoreElements() {
+// return ((child != null) && (child.hasMoreElements())) || (processing < files.length);
+// }
+//
+// public Object nextElement() {
+// if (child != null) {
+// try {
+// return child.nextElement();
+// } catch (NoSuchElementException e) {
+// child = null;
+// }
+// }
+// if (processing >= files.length) {
+// throw new NoSuchElementException();
+// }
+// File next = files[processing++];
+// if (next.isDirectory()) {
+// child = new DirectoryEnumeration(next);
+// }
+// return next;
+// }
+//
+// }
+//
+// private void addJarURL(URL midletSource) throws IOException {
+// byte[] cache = new byte[1024];
+// JarInputStream jis = null;
+// try {
+// URLConnection conn = midletSource.openConnection();
+// jis = new JarInputStream(conn.getInputStream());
+// while (true) {
+// JarEntry entry = jis.getNextJarEntry();
+// if (entry != null) {
+// if (!entry.isDirectory()) {
+// if (!allowEntryName(entry.getName())) {
+// continue;
+// }
+// int offset = 0;
+// int i = 0;
+// while ((i = jis.read(cache, offset, cache.length - offset)) != -1) {
+// offset += i;
+// if (offset >= cache.length) {
+// byte newcache[] = new byte[cache.length + 1024];
+// System.arraycopy(cache, 0, newcache, 0, cache.length);
+// cache = newcache;
+// }
+// }
+// byte[] tmp = new byte[offset];
+// System.arraycopy(cache, 0, tmp, 0, offset);
+// if (debug) {
+// System.out.println("add entry: " + entry.getName());
+// }
+// entries.put(entry.getName(), tmp);
+// }
+// } else {
+// break;
+// }
+// }
+// } finally {
+// if (jis != null) {
+// try {
+// jis.close();
+// } catch (IOException ignore) {
+// }
+// }
+// }
+// }
+//
+// /**
+// * Loads the class with the specified <a href="#name">binary name</a>.
+// * This implementation of this method searches for classes in the
+// * following order:
+// *
+// * <p><ol>
+// *
+// * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
+// * has already been loaded. </p></li>
+// *
+// * <li><p> Invoke the {@link #findClass(String)} method to find the
+// * class in this class loader. </p></li>
+// *
+// * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
+// * on the parent class loader. If the parent is <tt>null</tt> the class
+// * loader built-in to the virtual machine is used, instead. </p></li>
+// *
+// * </ol>
+// *
+// */
+// protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+// // First, check if the class has already been loaded
+// Class result = findLoadedClass(name);
+// if (result == null) {
+// if (hasClassData(name)) {
+// result = findClass(name);
+// } else {
+// result = super.loadClass(name, false);
+// }
+// }
+// if (resolve) {
+// resolveClass(result);
+// }
+// return result;
+// }
+//
+// public Class findClass(String name) throws ClassNotFoundException {
+// Class result = findLoadedClass(name);
+// if (result == null) {
+// byte[] b = loadClassData(name);
+// result = defineClass(name, b, 0, b.length);
+// }
+// return result;
+// }
+//
+// public InputStream getResourceAsStream(String name) {
+// String newname;
+// if (name.startsWith("/")) {
+// newname = name.substring(1);
+// } else {
+// newname = name;
+// }
+// byte[] tmp = (byte[]) entries.get(newname);
+// if (tmp != null) {
+// InputStream is = new ByteArrayInputStream(tmp);
+// return is;
+// }
+//
+// return getClass().getResourceAsStream(name);
+// }
+//
+// private boolean allowEntryName(String name) {
+// return !((name.startsWith("javax/") || name.startsWith("java/")));
+// }
+//
+// private boolean allowClass(String name) {
+// return !((name.startsWith("javax.") || name.startsWith("java.")));
+// }
+//
+// private boolean hasClassData(String name) {
+// if (!allowClass(name)) {
+// return false;
+// }
+// name = name.replace('.', '/') + ".class";
+// return (entries.get(name) != null);
+// }
+//
+// protected byte[] loadClassData(String name) throws ClassNotFoundException {
+// name = name.replace('.', '/') + ".class";
+// byte[] result = (byte[]) entries.get(name);
+// if (result == null) {
+// throw new ClassNotFoundException(name);
+// }
+//
+// return result;
+// }
+//
+// protected URL findResource(String name) {
+// if (entries.containsKey(name)) {
+// try {
+// return new URL(null, "res:" + name, resUrlStreamHandler);
+// } catch (MalformedURLException ex) {
+// ex.printStackTrace();
+// return null;
+// }
+// }
+// return null;
+// }
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletClassLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletOutputStreamRedirector.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletOutputStreamRedirector.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletOutputStreamRedirector.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletOutputStreamRedirector.java Mon May 26 15:20:19 2008
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import org.microemu.log.Logger;
+
+
+/**
+ * @author vlads
+ *
+ * This class allow redirection of stdout and stderr from MIDlet to MicroEmulator logger console
+ *
+ */
+public class MIDletOutputStreamRedirector extends PrintStream {
+
+ public final static PrintStream out = outPrintStream();
+
+ public final static PrintStream err = errPrintStream();
+
+ static {
+ Logger.addLogOrigin(MIDletOutputStreamRedirector.class);
+ Logger.addLogOrigin(OutputStream2Log.class);
+ }
+
+ private static class OutputStream2Log extends OutputStream {
+
+ boolean isErrorStream;
+
+ StringBuffer buffer = new StringBuffer();
+
+ OutputStream2Log(boolean error) {
+ this.isErrorStream = error;
+ }
+
+ public void write(int b) throws IOException {
+ if ((b == '\n') || (b == '\r')) {
+ if (buffer.length() > 0) {
+ if (isErrorStream) {
+ Logger.error(buffer.toString());
+ } else {
+ Logger.info(buffer.toString());
+ }
+ buffer = new StringBuffer();
+ }
+ } else {
+ buffer.append((char) b);
+ }
+ }
+
+ }
+
+ private MIDletOutputStreamRedirector(boolean error) {
+ super(new OutputStream2Log(error));
+ }
+
+ private static PrintStream outPrintStream() {
+ return new MIDletOutputStreamRedirector(false);
+ }
+
+ private static PrintStream errPrintStream() {
+ return new MIDletOutputStreamRedirector(true);
+ }
+
+ //Override methods to be able to get proper stack trace
+
+ public void print(boolean b) {
+ super.print(b);
+ }
+
+ public void print(char c) {
+ super.print(c);
+ }
+
+ public void print(char[] s) {
+ super.print(s);
+ }
+
+ public void print(double d) {
+ super.print(d);
+ }
+
+ public void print(float f) {
+ super.print(f);
+ }
+
+ public void print(int i) {
+ super.print(i);
+ }
+
+ public void print(long l) {
+ super.print(l);
+ }
+
+ public void print(Object obj) {
+ super.print(obj);
+ }
+
+ public void print(String s) {
+ super.print(s);
+ }
+
+ public void println() {
+ super.println();
+ }
+
+ public void println(boolean x) {
+ super.println(x);
+ }
+
+ public void println(char x) {
+ super.println(x);
+ }
+
+ public void println(char[] x) {
+ super.println(x);
+ }
+
+ public void println(double x) {
+ super.println(x);
+ }
+
+ public void println(float x) {
+ super.println(x);
+ }
+
+ public void println(int x) {
+ super.println(x);
+ }
+
+ public void println(long x) {
+ super.println(x);
+ }
+
+ public void println(Object x) {
+ super.println(x);
+ }
+
+ public void println(String x) {
+ super.println(x);
+ }
+
+ public void write(byte[] buf, int off, int len) {
+ super.write(buf, off, len);
+ }
+
+ public void write(int b) {
+ super.write(b);
+ }
+
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletOutputStreamRedirector.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletResourceLoader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletResourceLoader.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletResourceLoader.java (added)
+++ harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletResourceLoader.java Mon May 26 15:20:19 2008
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.microemu.app.util;
+
+import java.io.InputStream;
+
+import org.microemu.Injected;
+import org.microemu.log.Logger;
+import org.microemu.util.ThreadUtils;
+
+/**
+ * @author vlads
+ *
+ * Use MIDletResourceLoader to load resources.
+ * To solve resource resource loading paterns commonly used in MIDlet and not aceptable in Java SE application
+ * when System class is called to load resource
+ *
+ * j2me example:
+ *
+ * String.class.getResourceAsStream(resourceName)
+ *
+ */
+public class MIDletResourceLoader {
+
+ //TODO make this configurable
+
+ public static boolean traceResourceLoading = false;
+
+ /**
+ * @deprecated find better solution to share variable
+ */
+ public static ClassLoader classLoader;
+
+ private static final String FQCN = Injected.class.getName();
+
+ public static InputStream getResourceAsStream(Class origClass, String resourceName) {
+ if (traceResourceLoading) {
+ Logger.debug("Loading MIDlet resource", resourceName);
+ }
+ if (classLoader != origClass.getClassLoader()) {
+ // showWarning
+ String callLocation = ThreadUtils.getCallLocation(FQCN);
+ if (callLocation != null) {
+ Logger.warn("attempt to load resource [" + resourceName + "] using System ClasslLoader from " + callLocation);
+ }
+ }
+ resourceName = resolveName(origClass, resourceName);
+
+ InputStream is = classLoader.getResourceAsStream(resourceName);
+ if (is == null) {
+ Logger.debug("Resource not found ", resourceName);
+ }
+ return is;
+ }
+
+ private static String resolveName(Class origClass, String name) {
+ if (name == null) {
+ return name;
+ }
+ if (!name.startsWith("/")) {
+ while (origClass.isArray()) {
+ origClass = origClass.getComponentType();
+ }
+ String baseName = origClass.getName();
+ int index = baseName.lastIndexOf('.');
+ if (index != -1) {
+ name = baseName.substring(0, index).replace('.', '/') + "/" +name;
+ }
+ } else {
+ name = name.substring(1);
+ }
+ return name;
+ }
+}
Propchange: harmony/enhanced/microemulator/microemu-javase/src/main/java/org/microemu/app/util/MIDletResourceLoader.java
------------------------------------------------------------------------------
svn:eol-style = native