001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.instrument.classloading;
018:
019: import java.io.IOException;
020: import java.io.InputStream;
021: import java.net.URL;
022: import java.util.Enumeration;
023: import java.util.HashMap;
024: import java.util.Map;
025:
026: import org.springframework.util.Assert;
027:
028: /**
029: * Subclass of ShadowingClassLoader that overrides attempts to
030: * locate certain files.
031: *
032: * @author Rod Johnson
033: * @author Adrian Colyer
034: * @since 2.0
035: */
036: public class ResourceOverridingShadowingClassLoader extends
037: ShadowingClassLoader {
038:
039: private static final Enumeration<URL> EMPTY_URL_ENUMERATION = new Enumeration<URL>() {
040: public boolean hasMoreElements() {
041: return false;
042: }
043:
044: public URL nextElement() {
045: throw new UnsupportedOperationException(
046: "Should not be called. I am empty.");
047: }
048: };
049:
050: /**
051: * Key is asked for value: value is actual value
052: */
053: private Map<String, String> overrides = new HashMap<String, String>();
054:
055: /**
056: * Create a new ResourceOverridingShadowingClassLoader,
057: * decorating the given ClassLoader.
058: * @param enclosingClassLoader the ClassLoader to decorate
059: */
060: public ResourceOverridingShadowingClassLoader(
061: ClassLoader enclosingClassLoader) {
062: super (enclosingClassLoader);
063: }
064:
065: /**
066: * Return the resource (if any) at the new path
067: * on an attempt to locate a resource at the old path.
068: * @param oldPath the path requested
069: * @param newPath the actual path to be looked up
070: */
071: public void override(String oldPath, String newPath) {
072: this .overrides.put(oldPath, newPath);
073: }
074:
075: /**
076: * Ensure that a resource with the given path is not found.
077: * @param oldPath the path of the resource to hide even if
078: * it exists in the parent ClassLoader
079: */
080: public void suppress(String oldPath) {
081: this .overrides.put(oldPath, null);
082: }
083:
084: /**
085: * Copy all overrides from the given ClassLoader.
086: * @param other the other ClassLoader to copy from
087: */
088: public void copyOverrides(
089: ResourceOverridingShadowingClassLoader other) {
090: Assert.notNull(other, "Other ClassLoader must not be null");
091: this .overrides.putAll(other.overrides);
092: }
093:
094: @Override
095: public URL getResource(String requestedPath) {
096: if (this .overrides.containsKey(requestedPath)) {
097: String overriddenPath = this .overrides.get(requestedPath);
098: return (overriddenPath != null ? super
099: .getResource(overriddenPath) : null);
100: } else {
101: return super .getResource(requestedPath);
102: }
103: }
104:
105: @Override
106: public InputStream getResourceAsStream(String requestedPath) {
107: if (this .overrides.containsKey(requestedPath)) {
108: String overriddenPath = this .overrides.get(requestedPath);
109: return (overriddenPath != null ? super
110: .getResourceAsStream(overriddenPath) : null);
111: } else {
112: return super .getResourceAsStream(requestedPath);
113: }
114: }
115:
116: @Override
117: public Enumeration<URL> getResources(String requestedPath)
118: throws IOException {
119: if (this .overrides.containsKey(requestedPath)) {
120: String overriddenLocation = this.overrides
121: .get(requestedPath);
122: return (overriddenLocation != null ? super
123: .getResources(overriddenLocation)
124: : EMPTY_URL_ENUMERATION);
125: } else {
126: return super.getResources(requestedPath);
127: }
128: }
129:
130: }
|