All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.bonita.runtime.ClassDataLoader Maven / Gradle / Ivy

/**
 * Copyright (C) 2006  Bull S. A. S.
 * Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation
 * version 2.1 of the License.
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License along with this
 * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA  02110-1301, USA.
 **/
package org.ow2.bonita.runtime;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.ow2.bonita.facade.def.element.ConnectorDefinition;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.util.BonitaRuntimeException;
import org.ow2.bonita.util.ExceptionManager;
import org.ow2.bonita.util.Misc;
import org.ow2.bonita.util.ReflectUtil;


public final class ClassDataLoader {

  private static final Logger LOG = Logger.getLogger(ClassDataLoader.class.getName());

  private static Map processClassLoaders =
    new HashMap();

  private ClassDataLoader() { }

  public static Class< ? > getClass(final ProcessDefinitionUUID processUUID, 
      final String className) throws ClassNotFoundException {
    if (LOG.isLoggable(Level.FINE)) {
      LOG.fine("Looking for class " + className + ", in process : " + processUUID);
    }

    Class< ? > result = null;

    if (processUUID != null) {
      result = lookIntoProcessClassLoader(processUUID, className);
    }
    if (result != null) {
      return result;
    }
    if (LOG.isLoggable(Level.FINE)) {
      LOG.fine("Class " + className + " not found in packageClassLoaders...");
    }
    result = lookIntoCommonClassLoader(className);
    if (result != null) {
      return result;
    }
    if (LOG.isLoggable(Level.FINE)) {
      LOG.fine("Class " + className + " not found in globalClassLoaders...");
    }
    //maybe it is present in the current classLoader ? It may be a class delivered in bonita jar ?
    return load(ClassDataLoader.class.getClassLoader(), className);
  }

  protected static Object getInstance(final ProcessDefinitionUUID packageUUID, final ConnectorDefinition connector) {
    final String className = connector.getClassName();
    try {
      final Class< ? > clazz = getClass(packageUUID, className);
      return getClassInstance(clazz);
    } catch (final ClassNotFoundException e) {
      String message = ExceptionManager.getInstance().getFullMessage("be_CDL_1", className);
      throw new BonitaRuntimeException(message);
    }
  }

  private static Object getClassInstance(final Class< ? > clazz) {
    final Object obj = ReflectUtil.newInstance(clazz);
    if (obj == null) {
      String message = ExceptionManager.getInstance().getFullMessage(
          "be_CDL_2", clazz.getName());
      throw new BonitaRuntimeException(message);
    }
    return obj;
  }

  private static Class< ? > lookIntoProcessClassLoader(final ProcessDefinitionUUID processUUID, final String className) {
    if (!processClassLoaders.containsKey(processUUID)) {
      final ProcessClassLoader bonitaClassLoader = new ProcessClassLoader(processUUID);
      processClassLoaders.put(processUUID, bonitaClassLoader);
    }
    final ClassLoader classLoader = processClassLoaders.get(processUUID);
    try {
      final Class< ? > result = load(classLoader, className);
      if (result != null && result.getClassLoader().equals(classLoader)) {
        return result;
      }
    } catch (final ClassNotFoundException e) {
      return null;
    }
    return null;
  }

  private static Class< ? > lookIntoCommonClassLoader(final String className) {
    try {
      synchronized (CommonClassLoader.LOCK) {
        return load(CommonClassLoader.getCurrent(), className);
      }
    } catch (final ClassNotFoundException e) {
      return null;
    }
  }

  private static Class< ? > load(final ClassLoader classLoader, final String className) throws ClassNotFoundException {
    final Class< ? > clazz = classLoader.loadClass(className);
    if (classLoader instanceof ProcessClassLoader
        && !ProcessClassLoader.class.isAssignableFrom(clazz.getClassLoader().getClass())) {
      //throw new BonitaRuntimeException("Problem while creating a new instance of class : " + className + ", wrong classLoader");
      return null;
    }
    return clazz;
  }

  public static ClassLoader getProcessClassLoader(final ProcessDefinitionUUID processUUID) {
    return processClassLoaders.get(processUUID);
  }

  @SuppressWarnings("unchecked")
  public static  T getInstance(final Class clazz, final ProcessDefinitionUUID processUUID, final ConnectorDefinition connector) {
    Misc.checkArgsNotNull(clazz, connector);
    final Object obj = getInstance(processUUID, connector);
    final String className = connector.getClassName();
    if (obj == null) {
      String message = ExceptionManager.getInstance().getFullMessage("be_CDL_3", className);
      throw new BonitaRuntimeException(message);
    }
    if (obj.getClass().isAssignableFrom(clazz)) {
      String message = ExceptionManager.getInstance().getFullMessage(
          "be_CDL_4", connector, clazz.getName(), obj);
      throw new BonitaRuntimeException(message);
    }
    return (T)obj;
  }

  public static void removeProcessClassLoader(final ProcessDefinitionUUID processUUID) {
    processClassLoaders.remove(processUUID);
  }

  public static void clear() {
    processClassLoaders.clear();
    CommonClassLoader.reset();
  }

  public static CommonClassLoader getCommonClassLoader() {
    return CommonClassLoader.getCurrent();
  }

  public static Map getProcessClassLoaders() {
    return processClassLoaders;
  }

  public static void removeCommonClass(final String className) {
    CommonClassLoader.reset();
  }

}






© 2015 - 2025 Weber Informatics LLC | Privacy Policy