org.microemu.microedition.ImplFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of microemulator Show documentation
Show all versions of microemulator Show documentation
MicroEmulator one jar assembly for distribution.
The newest version!
/**
* MicroEmulator
* Copyright (C) 2006-2007 Bartek Teodorczyk
* Copyright (C) 2006-2007 Vlad Skarzhevskyy
*
* It is licensed under the following two licenses as alternatives:
* 1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
* 2. Apache License (the "AL") Version 2.0
*
* You may not use this file except in compliance with at least one of
* the above two licenses.
*
* You may obtain a copy of the LGPL at
* http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
*
* You may obtain a copy of the AL 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 LGPL or the AL for the specific language governing permissions and
* limitations.
*
* @version $Id: ImplFactory.java 1683 2008-04-09 20:59:35Z vlads $
*/
package org.microemu.microedition;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.Map;
import org.microemu.microedition.io.ConnectorDelegate;
/**
* This class allows to unbind implemenation with CLDC or MIDP declarations.
*
* @author vlads
*
*/
public class ImplFactory {
public static final String DEFAULT = "org.microemu.default";
private static final String INTERFACE_NAME_SUFIX = "Delegate";
private static final String IMPLEMENTATION_NAME_SUFIX = "Impl";
private Map implementations = new HashMap();
private Map implementationsGCF = new HashMap();
/* The context to be used when loading classes and resources */
private AccessControlContext acc;
/**
* Allow default initialization. In Secure environment instance() should be
* called initialy from secure contex.
*/
private static class SingletonHolder {
private static ImplFactory instance = new ImplFactory();
}
private ImplFactory() {
acc = AccessController.getContext();
}
public static ImplFactory instance() {
return SingletonHolder.instance;
}
public static void register(Class delegate, Class implementationClass) {
instance().implementations.put(delegate, implementationClass);
}
public static void register(Class delegate, Object implementationInstance) {
instance().implementations.put(delegate, implementationInstance);
}
public static void unregister(Class delegate, Class implementation) {
// TODO implement
}
/**
*
* Register Generic Connection Framework scheme implementation.
*
* @param implementation
* instance of ConnectorDelegate
* @param scheme
*/
public static void registerGCF(String scheme, Object implementation) {
if (!ConnectorDelegate.class.isAssignableFrom(implementation.getClass())) {
throw new IllegalArgumentException();
}
if (scheme == null) {
scheme = DEFAULT;
}
Object impl = instance().implementationsGCF.get(scheme);
if (impl instanceof ImplementationUnloadable) {
((ImplementationUnloadable) impl).unregisterImplementation();
}
instance().implementationsGCF.put(scheme, implementation);
}
public static void unregistedGCF(String scheme, Object implementation) {
if (!ConnectorDelegate.class.isAssignableFrom(implementation.getClass())) {
throw new IllegalArgumentException();
}
if (scheme == null) {
scheme = DEFAULT;
}
Object impl = instance().implementationsGCF.get(scheme);
if (impl == implementation) {
instance().implementationsGCF.remove(scheme);
}
}
private Object getDefaultImplementation(Class delegateInterface) {
try {
String name = delegateInterface.getName();
if (name.endsWith(INTERFACE_NAME_SUFIX)) {
name = name.substring(0, name.length() - INTERFACE_NAME_SUFIX.length());
}
final String implClassName = name + IMPLEMENTATION_NAME_SUFIX;
return AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class implClass = ImplFactory.class.getClassLoader().loadClass(implClassName);
try {
implClass.getConstructor(null);
} catch (NoSuchMethodException e) {
throw new InstantiationException("No default constructor in class " + implClassName);
}
return implClass.newInstance();
}
}, acc);
} catch (Throwable e) {
throw new RuntimeException("Unable create " + delegateInterface.getName() + " implementation", e);
}
}
private Object implementationNewInstance(final Class implClass) {
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
return implClass.newInstance();
}
}, acc);
} catch (Throwable e) {
throw new RuntimeException("Unable create " + implClass.getName() + " implementation", e);
}
}
/**
*
* @param name
* The URL for the connection.
* @return UTL scheme
*/
public static String getCGFScheme(String name) {
return name.substring(0, name.indexOf(':'));
}
/**
*
* @param name
* The URL for the connection.
* @return
*/
public static ConnectorDelegate getCGFImplementation(String name) {
String scheme = getCGFScheme(name);
ConnectorDelegate impl = (ConnectorDelegate) instance().implementationsGCF.get(scheme);
if (impl != null) {
return impl;
}
impl = (ConnectorDelegate) instance().implementationsGCF.get(DEFAULT);
if (impl != null) {
return impl;
}
return (ConnectorDelegate) instance().getDefaultImplementation(ConnectorDelegate.class);
}
// public static Implementation getImplementation(Class origClass, Object[]
// constructorArgs) {
// //TO-DO constructorArgs
// return getImplementation(origClass);
// }
public static Implementation getImplementation(Class origClass, Class delegateInterface) {
// if called from implementation constructor return null to avoid
// recurive calls!
// TODO can be done using thread stack analyse or ThreadLocal
Object impl = instance().implementations.get(delegateInterface);
// debugClassLoader(Implementation.class);
// debugClassLoader(origClass);
// debugClassLoader(delegateInterface);
// debugClassLoader(o);
if (impl != null) {
if (impl instanceof Class) {
return (Implementation) instance().implementationNewInstance((Class) impl);
} else {
return (Implementation) impl;
}
}
return (Implementation) instance().getDefaultImplementation(delegateInterface);
}
// private static void debugClassLoader(Object obj) {
// if (obj == null) {
// System.out.print("no class");
// return;
// }
// Class klass;
// if (obj instanceof Class) {
// klass = (Class)obj;
// System.out.print("class ");
// } else {
// klass = obj.getClass();
// System.out.print("instance ");
// }
// System.out.print(klass.getName() + " loaded by ");
// if (klass.getClassLoader() != null) {
// System.out.print(klass.getClassLoader().hashCode());
// } else {
// System.out.print("system");
// }
// System.out.println();
// }
}