/*
Name:
- DefaultClassLoadStrategy
Description:
-
Requires:
-
Provides:
-
Part of: ProcessPuzzle Framework, Domain and Business Model Ready Architecture. Provides content, workflow and social networking functionality.
http://www.processpuzzle.com
ProcessPuzzle - Content and Workflow Management Integration Business Platform
Author(s):
- Zsolt Zsuffa
Copyright: (C) 2011 This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.processpuzzle.application.configuration.domain;
// ----------------------------------------------------------------------------
/**
* A default implementation of {@link IClassLoadStrategy} that should be
* suitable for a variety of situations. See {@link #getClassLoader} for
* details.
*
* @author (C) <a
* href="http://www.javaworld.com/columns/jw-qna-index.shtml">Vlad
* Roubtsov</a>, 2003
*/
public class DefaultClassLoadStrategy implements IClassLoadStrategy {
// public: ................................................................
// inherit javadoc
public ClassLoader getClassLoader(final ClassLoadContext ctx) {
if (ctx == null) throw new IllegalArgumentException("null input: ctx");
final ClassLoader callerLoader = ctx.getCallerClass().getClassLoader();
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
ClassLoader result;
// if 'callerLoader' and 'contextLoader' are in a parent-child
// relationship, always choose the child:
if (isChild(contextLoader, callerLoader)) result = callerLoader;
else if (isChild(callerLoader, contextLoader)) result = contextLoader;
else {
// this else branch could be merged into the previous one,
// but I show it here to emphasize the ambiguous case:
result = contextLoader;
}
final ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
// precaution for when deployed as a bootstrap or extension class:
if (isChild(result, systemLoader)) result = systemLoader;
return result;
}
// protected: .............................................................
// package: ...............................................................
// private: ...............................................................
/**
* Returns 'true' if 'loader2' is a delegation child of 'loader1' [or if
* 'loader1'=='loader2']. Of course, this works only for classloaders that
* set their parent pointers correctly. 'null' is interpreted as the
* primordial loader [i.e., everybody's parent].
*/
private static boolean isChild(final ClassLoader loader1, ClassLoader loader2) {
if (loader1 == loader2) return true;
if (loader2 == null) return false;
if (loader1 == null) return true;
for (; loader2 != null; loader2 = loader2.getParent()) {
if (loader2 == loader1) return true;
}
return false;
}
}