001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.object.bytecode.hook.impl;
006:
007: import com.tc.text.Banner;
008:
009: import java.io.File;
010: import java.lang.reflect.InvocationTargetException;
011: import java.lang.reflect.Method;
012: import java.net.MalformedURLException;
013: import java.net.URL;
014: import java.net.URLClassLoader;
015: import java.util.ArrayList;
016: import java.util.List;
017:
018: public class SessionsHelper {
019:
020: // For dev/test use only, not intended for customer usage
021: private static final String TC_SESSION_CLASSPATH = "tc.session.classpath";
022:
023: private SessionsHelper() {
024: //
025: }
026:
027: // TODO those classes probably should be exported trough generic classloading mechanism
028: private static String[] getSessionsPaths() {
029: List classPaths = new ArrayList();
030:
031: String tcSessionCP = System.getProperty(TC_SESSION_CLASSPATH);
032: if (tcSessionCP != null) {
033: tcSessionCP = tcSessionCP.replace('\\', '/'); // for windows
034: String[] paths = tcSessionCP.split(File.pathSeparator);
035: for (int i = 0; i < paths.length; i++) {
036: String path = paths[i];
037: if (path.endsWith(".jar")) {
038: classPaths.add(path);
039: } else {
040: if (!path.endsWith("/")) {
041: path += "/";
042: }
043: if (!path.startsWith("/")) {
044: path = "/" + path;
045: }
046: classPaths.add(path);
047: }
048: }
049: } else {
050: File installRoot = ClassProcessorHelper
051: .getTCInstallDir(false);
052: File sessionsLib = new File(installRoot, "lib");
053: File tcSessionLib = new File(sessionsLib, "session");
054: File tcSessionJar = new File(tcSessionLib, "tc-session.jar");
055: if (tcSessionJar.exists() && tcSessionJar.isFile()
056: && tcSessionJar.canRead()) {
057: classPaths.add(tcSessionJar.getAbsolutePath());
058: } else {
059: Banner
060: .errorBanner(tcSessionJar.getAbsolutePath()
061: + " does not exist, or is not an accessible directory");
062: Util.exit();
063: }
064: }
065:
066: return (String[]) classPaths.toArray(new String[classPaths
067: .size()]);
068: }
069:
070: public static void injectClasses(ClassLoader loader) {
071: final String[] sessionsClasspaths = getSessionsPaths();
072: if (!invokeAddURLMethodIfPresent(loader, sessionsClasspaths)) {
073: if (!invokeAddPathsMethodIfPresent(loader,
074: sessionsClasspaths)) {
075: AssertionError ae = new AssertionError(
076: "SessionsHelper.injectClasses() cannot recognize classloader of type: "
077: + loader.getClass().getName());
078: throw ae;
079: }
080: }
081: }
082:
083: private static boolean invokeAddPathsMethodIfPresent(
084: ClassLoader loader, String[] classPaths) {
085: try {
086: Method m = loader.getClass().getDeclaredMethod("addPaths",
087: new Class[] { String[].class });
088: m.setAccessible(true);
089: m.invoke(loader, new Object[] { classPaths });
090: return true;
091: } catch (SecurityException e) {
092: return false;
093: } catch (NoSuchMethodException e) {
094: return false;
095: } catch (IllegalArgumentException e) {
096: return false;
097: } catch (IllegalAccessException e) {
098: return false;
099: } catch (InvocationTargetException e) {
100: return false;
101: }
102: }
103:
104: private static boolean invokeAddURLMethodIfPresent(
105: ClassLoader loader, String[] classPaths) {
106: Method m;
107: try {
108: m = URLClassLoader.class.getDeclaredMethod("addURL",
109: new Class[] { URL.class });
110: m.setAccessible(true);
111: for (int pos = 0; pos < classPaths.length; pos++) {
112: m.invoke(loader, new Object[] { new URL("file", "",
113: classPaths[pos]) });
114: }
115: return true;
116: } catch (SecurityException e) {
117: return false;
118: } catch (NoSuchMethodException e) {
119: return false;
120: } catch (IllegalArgumentException e) {
121: return false;
122: } catch (MalformedURLException e) {
123: return false;
124: } catch (IllegalAccessException e) {
125: return false;
126: } catch (InvocationTargetException e) {
127: return false;
128: }
129: }
130:
131: }
|