📄 standardpluginclassloader.java
字号:
/*****************************************************************************
* Java Plug-in Framework (JPF)
* Copyright (C) 2004-2007 Dmitry Olshansky
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
package org.java.plugin.standard;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.java.plugin.PathResolver;
import org.java.plugin.PluginClassLoader;
import org.java.plugin.PluginManager;
import org.java.plugin.registry.Library;
import org.java.plugin.registry.PluginDescriptor;
import org.java.plugin.registry.PluginPrerequisite;
import org.java.plugin.registry.PluginRegistry;
import org.java.plugin.util.IoUtil;
/**
* Standard implementation of plug-in class loader.
* @version $Id: StandardPluginClassLoader.java,v 1.22 2007/01/05 13:32:09 ddimon Exp $
*/
public class StandardPluginClassLoader extends PluginClassLoader {
static Log log = LogFactory.getLog(StandardPluginClassLoader.class);
private static File libCacheFolder;
private static boolean libCacheFolderInitialized = false;
private static URL getClassBaseUrl(final Class cls) {
ProtectionDomain pd = cls.getProtectionDomain();
if (pd != null) {
CodeSource cs = pd.getCodeSource();
if (cs != null) {
return cs.getLocation();
}
}
return null;
}
private static URL[] getUrls(final PluginManager manager,
final PluginDescriptor descr) {
List result = new LinkedList();
for (Iterator it = descr.getLibraries().iterator(); it.hasNext();) {
Library lib = (Library) it.next();
if (!lib.isCodeLibrary()) {
continue;
}
result.add(manager.getPathResolver().resolvePath(lib,
lib.getPath()));
}
if (log.isDebugEnabled()) {
StringBuffer buf = new StringBuffer();
buf.append("Code URL's populated for plug-in " //$NON-NLS-1$
+ descr + ":\r\n"); //$NON-NLS-1$
for (Iterator it = result.iterator(); it.hasNext();) {
buf.append("\t"); //$NON-NLS-1$
buf.append(it.next());
buf.append("\r\n"); //$NON-NLS-1$
}
log.debug(buf.toString());
}
return (URL[]) result.toArray(new URL[result.size()]);
}
private static URL[] getUrls(final PluginManager manager,
final PluginDescriptor descr, final URL[] existingUrls) {
List urls = Arrays.asList(existingUrls);
List result = new LinkedList();
for (Iterator it = descr.getLibraries().iterator(); it.hasNext();) {
Library lib = (Library) it.next();
if (!lib.isCodeLibrary()) {
continue;
}
URL url = manager.getPathResolver().resolvePath(lib, lib.getPath());
if (!urls.contains(url)) {
result.add(url);
}
}
return (URL[]) result.toArray(new URL[result.size()]);
}
private static File getLibCacheFolder() {
if (libCacheFolder != null) {
return libCacheFolderInitialized ? libCacheFolder : null;
}
synchronized (StandardPluginClassLoader.class) {
libCacheFolder = new File(System.getProperty("java.io.tmpdir"), //$NON-NLS-1$
System.currentTimeMillis() + ".jpf-lib-cache"); //$NON-NLS-1$
log.debug("libraries cache folder is " + libCacheFolder); //$NON-NLS-1$
File lockFile = new File(libCacheFolder, "lock"); //$NON-NLS-1$
if (lockFile.exists()) {
log.error("can't initialize libraries cache folder " //$NON-NLS-1$
+ libCacheFolder + " as lock file indicates that it" //$NON-NLS-1$
+ " is owned by another JPF instance"); //$NON-NLS-1$
return null;
}
if (libCacheFolder.exists()) {
// clean up folder
IoUtil.emptyFolder(libCacheFolder);
} else {
libCacheFolder.mkdirs();
}
try {
if (!lockFile.createNewFile()) {
log.error("can\'t create lock file in JPF libraries cache" //$NON-NLS-1$
+ " folder " + libCacheFolder); //$NON-NLS-1$
return null;
}
} catch (IOException ioe) {
log.error("can\'t create lock file in JPF libraries cache" //$NON-NLS-1$
+ " folder " + libCacheFolder, ioe); //$NON-NLS-1$
return null;
}
lockFile.deleteOnExit();
libCacheFolder.deleteOnExit();
libCacheFolderInitialized = true;
}
return libCacheFolder;
}
private PluginDescriptor[] publicImports;
private PluginDescriptor[] privateImports;
private PluginDescriptor[] reverseLookups;
private PluginResourceLoader resourceLoader;
private Map resourceFilters; // <lib URL, ResourceFilter>
private Map libraryCache; // <lib URL, File>
private boolean probeParentLoaderLast;
/**
* Creates class instance configured to load classes and resources for
* given plug-in.
* @param aManager plug-in manager instance
* @param descr plug-in descriptor
* @param parent parent class loader, usually this is JPF "host"
* application class loader
*/
public StandardPluginClassLoader(final PluginManager aManager,
final PluginDescriptor descr, final ClassLoader parent) {
super(aManager, descr, getUrls(aManager, descr), parent);
collectImports();
resourceLoader = PluginResourceLoader.get(aManager, descr);
collectFilters();
libraryCache = new HashMap();
}
protected void collectImports() {
// collect imported plug-ins (exclude duplicates)
Map publicImportsMap = new HashMap(); //<plug-in ID, PluginDescriptor>
Map privateImportsMap = new HashMap(); //<plug-in ID, PluginDescriptor>
PluginRegistry registry = getPluginDescriptor().getRegistry();
for (Iterator it = getPluginDescriptor().getPrerequisites().iterator();
it.hasNext();) {
PluginPrerequisite pre = (PluginPrerequisite) it.next();
if (!pre.matches()) {
continue;
}
PluginDescriptor preDescr =
registry.getPluginDescriptor(pre.getPluginId());
if (pre.isExported()) {
publicImportsMap.put(preDescr.getId(), preDescr);
} else {
privateImportsMap.put(preDescr.getId(), preDescr);
}
}
publicImports = (PluginDescriptor[]) publicImportsMap.values().toArray(
new PluginDescriptor[publicImportsMap.size()]);
privateImports =
(PluginDescriptor[]) privateImportsMap.values().toArray(
new PluginDescriptor[privateImportsMap.size()]);
// collect reverse look up plug-ins (exclude duplicates)
Map reverseLookupsMap = new HashMap(); //<plug-in ID, PluginDescriptor>
for (Iterator it = registry.getPluginDescriptors().iterator();
it.hasNext();) {
PluginDescriptor descr = (PluginDescriptor) it.next();
if (descr.equals(getPluginDescriptor())
|| publicImportsMap.containsKey(descr.getId())
|| privateImportsMap.containsKey(descr.getId())) {
continue;
}
for (Iterator it2 = descr.getPrerequisites().iterator();
it2.hasNext();) {
PluginPrerequisite pre = (PluginPrerequisite) it2.next();
if (!pre.getPluginId().equals(getPluginDescriptor().getId())
|| !pre.isReverseLookup()) {
continue;
}
if (!pre.matches()) {
continue;
}
reverseLookupsMap.put(descr.getId(), descr);
break;
}
}
reverseLookups =
(PluginDescriptor[]) reverseLookupsMap.values().toArray(
new PluginDescriptor[reverseLookupsMap.size()]);
}
protected void collectFilters() {
if (resourceFilters == null) {
resourceFilters = new HashMap();
} else {
resourceFilters.clear();
}
for (Iterator it = getPluginDescriptor().getLibraries().iterator();
it.hasNext();) {
Library lib = (Library) it.next();
resourceFilters.put(
getPluginManager().getPathResolver().resolvePath(lib,
lib.getPath()).toExternalForm(),
new ResourceFilter(lib));
}
}
/**
* @see org.java.plugin.PluginClassLoader#pluginsSetChanged()
*/
protected void pluginsSetChanged() {
URL[] newUrls = getUrls(getPluginManager(), getPluginDescriptor(),
getURLs());
for (int i = 0; i < newUrls.length; i++) {
addURL(newUrls[i]);
}
if (log.isDebugEnabled()) {
StringBuffer buf = new StringBuffer();
buf.append("New code URL's populated for plug-in " //$NON-NLS-1$
+ getPluginDescriptor() + ":\r\n"); //$NON-NLS-1$
for (int i = 0; i < newUrls.length; i++) {
buf.append("\t"); //$NON-NLS-1$
buf.append(newUrls[i]);
buf.append("\r\n"); //$NON-NLS-1$
}
log.debug(buf.toString());
}
collectImports();
// repopulate resource URLs
resourceLoader =
PluginResourceLoader.get(getPluginManager(), getPluginDescriptor());
collectFilters();
for (Iterator it = libraryCache.entrySet().iterator(); it.hasNext();) {
if (((Map.Entry) it.next()).getValue() == null) {
it.remove();
}
}
}
/**
* @see org.java.plugin.PluginClassLoader#dispose()
*/
protected void dispose() {
for (Iterator it = libraryCache.values().iterator(); it.hasNext();) {
((File) it.next()).delete();
}
libraryCache.clear();
resourceFilters.clear();
privateImports = null;
publicImports = null;
resourceLoader = null;
}
protected void setProbeParentLoaderLast(final boolean value) {
probeParentLoaderLast = value;
}
/**
* @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
*/
protected Class loadClass(final String name, final boolean resolve)
throws ClassNotFoundException {
/*log.debug("loadClass(String, boolean): name=" + name + ", this="
+ this);*/
Class result;
if (probeParentLoaderLast) {
try {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -