package org.ebayopensource.turmeric.runtime.common.registration; //import java.io.BufferedWriter; //import java.io.FileWriter; //import java.io.IOException; import java.util.Hashtable; import java.util.logging.Level; import java.util.logging.Logger; import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceException; import org.ebayopensource.turmeric.runtime.common.impl.utils.LogManager; import org.ebayopensource.turmeric.runtime.sif.impl.internal.config.ClientConfigHolder; import org.ebayopensource.turmeric.runtime.sif.impl.internal.config.ClientConfigManager; //import org.osgi.framework.BundleContext; /** * The one which holds all the registry entries meaning the client configs and * service metadata. * * @author agrinenko * */ public class ClassLoaderRegistry { private static final Logger s_logger = LogManager.getInstance(ClassLoaderRegistry.class); private static ClassLoaderRegistry REGISTRY = new ClassLoaderRegistry(); private static Hashtable<String, ClassLoader> RESOURCES_CLASS_LOADERS = new Hashtable<String, ClassLoader>(); private static Hashtable<String, ClassLoader> CLASSES_CLASS_LOADERS = new Hashtable<String, ClassLoader>(); // private BufferedWriter out; public void writeToOut(String str) { // try { // out.write(str); out.flush(); // } catch (Exception e){ // e.printStackTrace(); // } if (s_logger.isLoggable(Level.INFO)) { s_logger.log(Level.INFO, str); } } private ClassLoaderRegistry() { } public static ClassLoaderRegistry instanceOf() { // if (REGISTRY == null) { // synchronized (ClassLoaderRegistry.class) { // if (REGISTRY == null) { // REGISTRY = new ClassLoaderRegistry(); //// try { //// REGISTRY.out = new BufferedWriter(new FileWriter( //// "ClassLoaderRegistry"+System.currentTimeMillis())); //// } catch (IOException e) {e.printStackTrace();} // } // } // } return REGISTRY; } public ClassLoader getClassLoaderForClass(String fullClassName) { return CLASSES_CLASS_LOADERS.get(fullClassName); } public ClassLoader getClassLoaderForFile(String filePath) { return RESOURCES_CLASS_LOADERS.get(filePath); } /** * A registration of file, to which a relative path should be provided, like * META-INF/soa/services/config/WebUtilityService/SecurityPolicy.xml * Most of the files are supposed to be registered automatically by using * a method registerServiceClient * * @param resourceFilePath * @param classLoader */ public void registerResource(String resourceFilePath, ClassLoader classLoader) { if (!RESOURCES_CLASS_LOADERS.containsKey(resourceFilePath)) { RESOURCES_CLASS_LOADERS.put(resourceFilePath, classLoader); } } /** * A registration of a java package. * Most of the packages are supposed to be registered automatically by using * a method registerServiceClient. * * @param packageName * @param classLoader */ public void registerPackage (String packageName, ClassLoader classLoader) { if (!CLASSES_CLASS_LOADERS.containsKey(packageName)) { CLASSES_CLASS_LOADERS.put(packageName, classLoader); } } /** * A simplified registration of a java package, when the full class name is available. * Most of the packages are supposed to be registered automatically by using * a method registerServiceClient. * * @param fullClassName * @param classLoader */ public void registerPackageForClass (String fullClassName, ClassLoader classLoader) { String packageName = getPackageName(fullClassName); if (!CLASSES_CLASS_LOADERS.containsKey(packageName)) { CLASSES_CLASS_LOADERS.put(packageName, classLoader); } } public int getCount() { return CLASSES_CLASS_LOADERS.size() + RESOURCES_CLASS_LOADERS.size(); } public void unregisterClassLoader(ClassLoader classLoader) throws ServiceException { } /** * Method for the backward compartibility with CodeGen Shared Service classes, * which are using a version of this method without a "useDefaultClientConfig" parameter. */ public void registerServiceClient (String clientName, String environment, String serviceAdminName, Class<?> serviceClass, Class<?> clientClass) throws ServiceException { registerServiceClient(clientName, environment, serviceAdminName, serviceClass, clientClass, false); } /** * This is a main method for an automatic registration of resources (classes and files) * of a SOA Service bundle. Than, SOA Runtime would be able to use them. * The registration assumes, that all request/response classes, interface files * (like TypeMappings.xml and service_metadata.properties) are located either * inside an interface("shared") bundle or in the attached to it (as a fragment) * - client bundle. ClassLoaderRegistry will try to use a ClassLoaderof a provided * "serviceClass" to load all those resources. A file ClientConfig.xml can be loacted * in another bundle, but then one a special constructors of a Shared Service class * should be called, then one which has a "clientClass" parameter. ClassLoaderRegistry * will try to use a ClassLoader of that ClassLoader to load ClientConfig.xml * * If a file path to the ClientConfig.xml of the service looks like * META-INF/soa/client/config/SomeServiceClient/staging/SomeService/ClientConfig.xml * , then those parameter should be passed: * clientName="SomeServiceClient", * environment="staging" * serviceAdminName="SomeService". * If the path to ClientConfig.xml is * META-INF/soa/client/config/SomeService/ClientConfig.xml * , then empty or null value of environment variable should be passed. * * Additional resource can be registered as well, by using direct calls to * methods registerResource, registerPackage and registerPackageForClass. * * @param clientName * @param environment * @param serviceAdminName * @param serviceClass * @param clientClass * @param useDefaultClientConfig * @throws ServiceException */ public void registerServiceClient (String clientName, String environment, String serviceAdminName, Class<?> serviceClass, Class<?> clientClass, boolean useDefaultClientConfig) throws ServiceException { ClassLoader serviceClassLoader = serviceClass.getClassLoader(); ClassLoader clientClassLoader = null; if (clientClass != null) { clientClassLoader = clientClass.getClassLoader(); } else { clientClassLoader = serviceClassLoader; } // Register resources that are from the caller bundle if (environment != null && environment.trim().length() > 0) { registerResource("META-INF/soa/client/config/" + clientName + "/" + environment + "/" + serviceAdminName + "/ClientConfig.xml", clientClassLoader); } else { registerResource("META-INF/soa/client/config/" + clientName + "/ClientConfig.xml", clientClassLoader); } // Register resources that are from service interface bundle registerResource("META-INF/soa/common/config/" + serviceAdminName + "/service_metadata.properties", serviceClassLoader); registerResource("META-INF/soa/common/config/" + serviceAdminName + "/TypeMappings.xml", serviceClassLoader); registerResource("META-INF/soa/services/wsdl/" + serviceAdminName + "/" + serviceAdminName + ".wsdl", serviceClassLoader); ClientConfigHolder config = null; if (environment != null && environment.trim().length() > 0) { config = ClientConfigManager.getInstance() .readClientConfigMap(serviceAdminName, clientName, environment, false, false, useDefaultClientConfig) .get(serviceAdminName); } else { config = ClientConfigManager.getInstance() .readClientConfigMap(serviceAdminName, clientName, null, false, false, useDefaultClientConfig) .get(serviceAdminName); } for(String className : config.getTypeMappings().getJavaTypes()) { registerPackageForClass(className, serviceClassLoader); } String interfaceClass = config.getServiceInterfaceClassName(); registerPackageForClass(interfaceClass, serviceClassLoader); registerPackage(getPackageName(interfaceClass) + ".gen", serviceClassLoader); } public final static String DEFAULT_PACKAGE = "."; //$NON-NLS-1$ public final static String getResourcePackageName(String name) { if (name != null) { /* check for leading slash*/ int begin = ((name.length() > 1) && (name.charAt(0) == '/' || name.charAt(0) == '\\')) ? 1 : 0; int end = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\')); /* index of last slash */ if (end > begin) return name.substring(begin, end).replace('/', '.').replace('\\', '.'); } return DEFAULT_PACKAGE; } public final static String getPackageName(String name) { if (name != null) { int index = name.lastIndexOf('.'); /* find last period in class name */ if (index > 0) return name.substring(0, index); } return DEFAULT_PACKAGE; } }