?? repositoryclassloader.java
字號(hào):
// create new array and copy old and new contents ClassPathEntry[] newList = new ClassPathEntry[list.length+1]; System.arraycopy(list, 0, newList, 0, list.length); newList[list.length] = newEntry; return newList; } //---------- Object overwrite --------------------------------------------- /** * Returns a string representation of this instance. */ public String toString() { StringBuffer buf = new StringBuffer(getClass().getName()); if (isDestroyed()) { buf.append(" - destroyed"); } else { buf.append(": parent: { "); buf.append(getParent()); buf.append(" }, user: "); buf.append(session.getUserID()); } return buf.toString(); } //---------- internal ------------------------------------------------------ /** * Builds the repository list from the list of path patterns and appends * the path entries from any added handles. This method may be used multiple * times, each time replacing the currently defined repository list. * * @throws NullPointerException If this class loader has already been * destroyed. */ protected synchronized void buildRepository() { // build new repository List handles; try { handles = getHandles().getExpandedPaths(); } catch (RepositoryException re) { log.error("Cannot expand handle list", re); return; } List newRepository = new ArrayList(handles.size()); // build repository from path patterns for (int i=0; i < handles.size(); i++) { String entry = (String) handles.get(i); ClassPathEntry cp = null; // try to find repository based on this path if (getRepository() != null) { for (int j=0; j < repository.length; j++) { ClassPathEntry tmp = repository[i]; if (tmp.getPath().equals(entry)) { cp = tmp; break; } } } // not found, creating new one if (cp == null) { cp = ClassPathEntry.getInstance(session, entry); } if (cp != null) { log.debug("Adding path {}", entry); newRepository.add(cp); } else { log.debug("Cannot get a ClassPathEntry for {}", entry); } } // replace old repository with new one ClassPathEntry[] newClassPath = new ClassPathEntry[newRepository.size()]; newRepository.toArray(newClassPath); setRepository(newClassPath); // clear un-found resource cache cleanCache(); } /** * Tries to find the class in the class path from within a * <code>PrivilegedAction</code>. Throws <code>ClassNotFoundException</code> * if no class can be found for the name. * * @param name the name of the class * * @return the resulting class * * @throws ClassNotFoundException if the class could not be found * @throws NullPointerException If this class loader has already been * destroyed. */ private Class findClassPrivileged(String name) throws ClassNotFoundException { // prepare the name of the class final String path = name.replace('.', '/').concat(".class"); log.debug("findClassPrivileged: Try to find path {} for class {}", path, name); ClassLoaderResource res = findClassLoaderResource(path); if (res != null) { // try defining the class, error aborts try { log.debug( "findClassPrivileged: Loading class from {}, created {}", res, new Date(res.getLastModificationTime())); Class c = defineClass(name, res); if (c == null) { log.warn("defineClass returned null for class {}", name); throw new ClassNotFoundException(name); } return c; } catch (IOException ioe) { log.debug("defineClass failed", ioe); throw new ClassNotFoundException(name, ioe); } catch (Throwable t) { log.debug("defineClass failed", t); throw new ClassNotFoundException(name, t); } } throw new ClassNotFoundException(name); } /** * Returns a {@link ClassLoaderResource} for the given <code>name</code> or * <code>null</code> if not existing. If the resource has already been * loaded earlier, the cached instance is returned. If the resource has * not been found in an earlier call to this method, <code>null</code> is * returned. Otherwise the resource is looked up in the class path. If * found, the resource is cached and returned. If not found, the * {@link #NOT_FOUND_RESOURCE} is cached for the name and <code>null</code> * is returned. * * @param name The name of the resource to return. * * @return The named <code>ClassLoaderResource</code> if found or * <code>null</code> if not found. * * @throws NullPointerException If this class loader has already been * destroyed. */ /* package */ ClassLoaderResource findClassLoaderResource(String name) { // check for cached resources first ClassLoaderResource res = (ClassLoaderResource) cache.get(name); if (res == NOT_FOUND_RESOURCE) { log.debug("Resource '{}' known to not exist in class path", name); return null; } else if (res != null) { return res; } // walk the repository list and try to find the resource for (int i = 0; i < repository.length; i++) { final ClassPathEntry cp = repository[i]; log.debug("Checking {}", cp); res = cp.getResource(name); if (res != null) { log.debug("Found resource in {}, created ", res, new Date( res.getLastModificationTime())); cache.put(name, res); return res; } } log.debug("No classpath entry contains {}", name); cache.put(name, NOT_FOUND_RESOURCE); return null; } /** * Defines a class getting the bytes for the class from the resource * * @param name The fully qualified class name * @param res The resource to obtain the class bytes from * * @throws RepositoryException If a problem occurrs getting at the data. * @throws IOException If a problem occurrs reading the class bytes from * the resource. * @throws ClassFormatError If the class bytes read from the resource are * not a valid class. */ private Class defineClass(String name, ClassLoaderResource res) throws IOException, RepositoryException { log.debug("defineClass({}, {})", name, res); Class clazz = res.getLoadedClass(); if (clazz == null) { /** * This following code for packages is duplicate from URLClassLoader * because it is private there. I would like to not be forced to * do this, but I still have to find a way ... -fmeschbe */ // package support int i = name.lastIndexOf('.'); if (i != -1) { String pkgname = name.substring(0, i); // Check if package already loaded. Package pkg = getPackage(pkgname); URL url = res.getCodeSourceURL(); Manifest man = res.getManifest(); if (pkg != null) { // Package found, so check package sealing. boolean ok; if (pkg.isSealed()) { // Verify that code source URL is the same. ok = pkg.isSealed(url); } else { // Make sure we are not attempting to seal the package // at this code source URL. ok = (man == null) || !isSealed(pkgname, man); } if (!ok) { throw new SecurityException("sealing violation"); } } else { if (man != null) { definePackage(pkgname, man, url); } else { definePackage(pkgname, null, null, null, null, null, null, null); } } } byte[] data = res.getBytes(); clazz = defineClass(name, data, 0, data.length); res.setLoadedClass(clazz); } return clazz; } /** * Returns true if the specified package name is sealed according to the * given manifest * <p> * This code is duplicate from <code>URLClassLoader.isSealed</code> because * the latter has private access and we need the method here. */ private boolean isSealed(String name, Manifest man) { String path = name.replace('.', '/').concat("/"); Attributes attr = man.getAttributes(path); String sealed = null; if (attr != null) { sealed = attr.getValue(Attributes.Name.SEALED); } if (sealed == null) { if ((attr = man.getMainAttributes()) != null) { sealed = attr.getValue(Attributes.Name.SEALED); } } return "true".equalsIgnoreCase(sealed); } /** * Returns <code>true</code> if the <code>url</code> is a <code>JCR</code> * URL. * * @param url The URL to check whether it is a valid <code>JCR</code> URL. * * @return <code>true</code> if <code>url</code> is a valid <code>JCR</code> * URL. * * @throws NullPointerException if <code>url</code> is <code>null</code>. */ private boolean checkURL(URL url) { return URLFactory.REPOSITORY_SCHEME.equalsIgnoreCase(url.getProtocol()); }}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -