001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.object.config;
005:
006: import com.tc.object.bytecode.ByteCodeUtil;
007:
008: import java.net.URL;
009: import java.util.HashMap;
010: import java.util.Iterator;
011: import java.util.Map;
012:
013: public class ClassReplacementMappingImpl implements
014: ClassReplacementMapping {
015: private Map classNamesMapping = new HashMap();
016: private Map classnameResourceMapping = new HashMap();
017:
018: private Map classNamesSlashesReverseMapping = new HashMap();
019: private Map asmTypesReverseMapping = new HashMap();
020:
021: public synchronized String addMapping(
022: final String originalClassName,
023: final String replacementClassName,
024: final URL replacementResource) {
025: if (null == originalClassName
026: || 0 == originalClassName.length()
027: || null == replacementClassName
028: || 0 == replacementClassName.length()) {
029: return null;
030: }
031:
032: if (classNamesMapping.containsKey(originalClassName)) {
033: return null;
034: }
035:
036: String previous = (String) classNamesMapping.put(
037: originalClassName, replacementClassName);
038: if (replacementResource != null) {
039: classnameResourceMapping.put(replacementClassName,
040: replacementResource);
041: }
042:
043: String originalClassNameSlashes = originalClassName.replace(
044: '.', '/');
045: String replacementClassNameSlashes = replacementClassName
046: .replace('.', '/');
047: classNamesSlashesReverseMapping.put(
048: replacementClassNameSlashes, originalClassNameSlashes);
049: asmTypesReverseMapping.put(
050: ensureAsmType(replacementClassNameSlashes),
051: ensureAsmType(originalClassNameSlashes));
052:
053: return previous;
054: }
055:
056: public URL getReplacementResource(final String replacementClassName) {
057: return getReplacementResource(replacementClassName, null);
058: }
059:
060: public URL getReplacementResource(
061: final String replacementClassName,
062: final ClassLoader defaultClassLoader) {
063: if (null == replacementClassName) {
064: return null;
065: }
066: URL resource = (URL) classnameResourceMapping
067: .get(replacementClassName);
068: if (null == resource && defaultClassLoader != null) {
069: resource = defaultClassLoader.getResource(ByteCodeUtil
070: .classNameToFileName(replacementClassName));
071: }
072: return resource;
073: }
074:
075: public boolean hasReplacement(String originalClassName) {
076: return classNamesMapping.containsKey(originalClassName);
077: }
078:
079: private String ensureAsmType(String classNameSlashes) {
080: if (null == classNameSlashes || 0 == classNameSlashes.length()) {
081: return classNameSlashes;
082: }
083:
084: if (classNameSlashes.charAt(0) != 'L'
085: && classNameSlashes
086: .charAt(classNameSlashes.length() - 1) != ';') {
087: classNameSlashes = 'L' + classNameSlashes + ';';
088: }
089: return classNameSlashes;
090: }
091:
092: public synchronized String getReplacementClassName(String original) {
093: return (String) classNamesMapping.get(original);
094: }
095:
096: public synchronized String getOriginalClassNameSlashes(
097: String replacement) {
098: String original = (String) classNamesSlashesReverseMapping
099: .get(replacement);
100: if (null == original) {
101: original = replacement;
102: }
103: return original;
104: }
105:
106: public synchronized String getOriginalAsmType(String replacement) {
107: String original = (String) asmTypesReverseMapping
108: .get(replacement);
109: if (null == original) {
110: original = replacement;
111: }
112: return original;
113: }
114:
115: public synchronized String ensureOriginalAsmTypes(String s) {
116: if (s != null) {
117: Iterator it = asmTypesReverseMapping.entrySet().iterator();
118: Map.Entry entry;
119: String original;
120: String replacement;
121: while (it.hasNext()) {
122: entry = (Map.Entry) it.next();
123: original = (String) entry.getKey();
124: replacement = (String) entry.getValue();
125:
126: if (s.indexOf(original) != -1) {
127: s = s.replaceAll(original, replacement);
128: }
129: }
130: }
131: return s;
132: }
133: }
|