/portal-impl/src/com/liferay/portal/security/pacl/PACLClassUtil.java

https://github.com/lululiferay/liferay-portal · Java · 300 lines · 188 code · 77 blank · 35 comment · 44 complexity · bcbea79d2631d97b351df48a42a717c4 MD5 · raw file

  1. /**
  2. * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
  3. *
  4. * This library is free software; you can redistribute it and/or modify it under
  5. * the terms of the GNU Lesser General Public License as published by the Free
  6. * Software Foundation; either version 2.1 of the License, or (at your option)
  7. * any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  12. * details.
  13. */
  14. package com.liferay.portal.security.pacl;
  15. import com.liferay.portal.kernel.log.Log;
  16. import com.liferay.portal.kernel.log.LogFactoryUtil;
  17. import com.liferay.portal.kernel.util.AggregateClassLoader;
  18. import com.liferay.portal.kernel.util.ProxyUtil;
  19. import com.liferay.portal.kernel.util.ServerDetector;
  20. import com.liferay.portal.kernel.util.StringPool;
  21. import com.liferay.portal.kernel.util.StringUtil;
  22. import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
  23. import com.liferay.portal.spring.util.FilterClassLoader;
  24. import java.net.URL;
  25. import sun.reflect.Reflection;
  26. /**
  27. * @author Brian Wing Shun Chan
  28. */
  29. public class PACLClassUtil {
  30. public static ClassLoader getCallerClassLoader(Class<?> callerClass) {
  31. boolean enabled = PortalSecurityManagerThreadLocal.isEnabled();
  32. try {
  33. PortalSecurityManagerThreadLocal.setEnabled(false);
  34. return _instance._getCallerClassLoader(callerClass);
  35. }
  36. finally {
  37. PortalSecurityManagerThreadLocal.setEnabled(enabled);
  38. }
  39. }
  40. public static String getClassLocation(Class<?> clazz) {
  41. boolean enabled = PortalSecurityManagerThreadLocal.isEnabled();
  42. try {
  43. PortalSecurityManagerThreadLocal.setEnabled(false);
  44. ClassLoader classLoader = clazz.getClassLoader();
  45. if (classLoader == null) {
  46. return StringPool.BLANK;
  47. }
  48. String className = clazz.getName();
  49. String name = StringUtil.replace(
  50. className, StringPool.PERIOD, StringPool.SLASH);
  51. name += ".class";
  52. URL url = classLoader.getResource(name);
  53. return url.toString();
  54. }
  55. finally {
  56. PortalSecurityManagerThreadLocal.setEnabled(enabled);
  57. }
  58. }
  59. public static PACLPolicy getPACLPolicy(boolean deep, boolean debug) {
  60. PACLPolicy paclPolicy =
  61. PortalSecurityManagerThreadLocal.getPACLPolicy();
  62. if (paclPolicy != null) {
  63. return paclPolicy;
  64. }
  65. return getPACLPolicyByReflection(deep, debug);
  66. }
  67. public static PACLPolicy getPACLPolicyByReflection(
  68. boolean deep, boolean debug) {
  69. boolean enabled = PortalSecurityManagerThreadLocal.isEnabled();
  70. try {
  71. PortalSecurityManagerThreadLocal.setEnabled(false);
  72. return _instance._getPACLPolicyByReflection(deep, debug);
  73. }
  74. finally {
  75. PortalSecurityManagerThreadLocal.setEnabled(enabled);
  76. }
  77. }
  78. private PACLClassUtil() {
  79. _systemClassLoader = ClassLoader.getSystemClassLoader();
  80. _portalClassLoader = PACLAdvice.class.getClassLoader();
  81. _commonClassLoader = _portalClassLoader.getParent();
  82. }
  83. private ClassLoader _getCallerClassLoader(Class<?> callerClass) {
  84. ClassLoader callerClassLoader = callerClass.getClassLoader();
  85. if (callerClassLoader == null) {
  86. return null;
  87. }
  88. Class<?> callerClassLoaderClass = callerClassLoader.getClass();
  89. String callerClassLoaderClassName = callerClassLoaderClass.getName();
  90. if (callerClassLoader instanceof FilterClassLoader) {
  91. callerClassLoader = callerClassLoader.getParent();
  92. if (callerClassLoader instanceof AggregateClassLoader) {
  93. callerClassLoader = callerClassLoader.getParent();
  94. }
  95. }
  96. if (callerClassLoaderClassName.equals(_ClASS_NAME_JASPER_LOADER)) {
  97. callerClassLoader = callerClassLoader.getParent();
  98. }
  99. else if (ServerDetector.isResin()) {
  100. if (callerClassLoaderClassName.equals(
  101. _ClASS_NAME_DYNAMIC_CLASS_LOADER)) {
  102. callerClassLoader = callerClassLoader.getParent();
  103. }
  104. }
  105. else if (ServerDetector.isWebLogic()) {
  106. if (callerClassLoaderClassName.equals(
  107. _CLASS_NAME_JSP_CLASS_LOADER)) {
  108. // weblogic.servlet.jsp.TagFileClassLoader
  109. callerClassLoader = callerClassLoader.getParent();
  110. // weblogic.utils.classloaders.ChangeAwareClassLoader
  111. callerClassLoader = callerClassLoader.getParent();
  112. }
  113. }
  114. else if (ServerDetector.isWebSphere()) {
  115. if (callerClassLoaderClassName.equals(
  116. _CLASS_NAME_JSP_EXTENSION_CLASS_LOADER)) {
  117. callerClassLoader = callerClassLoader.getParent();
  118. }
  119. }
  120. return callerClassLoader;
  121. }
  122. private PACLPolicy _getPACLPolicyByReflection(boolean deep, boolean debug) {
  123. PACLPolicy paclPolicy = null;
  124. boolean initialPortalClassLoaderPhase = true;
  125. // int i = 0 always returns sun.reflect.Reflection
  126. for (int i = 1;; i++) {
  127. Class<?> callerClass = Reflection.getCallerClass(i);
  128. if (callerClass == null) {
  129. break;
  130. }
  131. if (debug) {
  132. _log.debug(
  133. "Frame " + i + " has caller class " +
  134. callerClass.getName());
  135. }
  136. if (ProxyUtil.isProxyClass(callerClass)) {
  137. if (debug) {
  138. _log.debug("Skipping frame because it is proxy class");
  139. }
  140. continue;
  141. }
  142. ClassLoader callerClassLoader = _getCallerClassLoader(callerClass);
  143. if (callerClassLoader == null) {
  144. continue;
  145. }
  146. /*if (debug) {
  147. StringBundler sb = new StringBundler(10);
  148. sb.append("Frame ");
  149. sb.append(i);
  150. sb.append(" ");
  151. sb.append(callerClass);
  152. sb.append(" ");
  153. sb.append(callerClassLoader);
  154. sb.append(" ");
  155. sb.append(callerClassLoader.getClass());
  156. sb.append(" ");
  157. sb.append(PACLPolicyManager.getPACLPolicy(callerClassLoader));
  158. System.out.println(sb.toString());
  159. }*/
  160. if (!initialPortalClassLoaderPhase &&
  161. (callerClassLoader == _portalClassLoader)) {
  162. PACLPolicy defaultPACLPolicy =
  163. PACLPolicyManager.getDefaultPACLPolicy();
  164. if (paclPolicy == null) {
  165. if (debug) {
  166. _log.debug(
  167. "Possibly return default PACL policy " +
  168. defaultPACLPolicy);
  169. }
  170. paclPolicy = defaultPACLPolicy;
  171. }
  172. if (!deep) {
  173. break;
  174. }
  175. continue;
  176. }
  177. if (initialPortalClassLoaderPhase &&
  178. (callerClassLoader != _portalClassLoader)) {
  179. initialPortalClassLoaderPhase = false;
  180. }
  181. if ((callerClassLoader == _commonClassLoader) ||
  182. (callerClassLoader == _portalClassLoader) ||
  183. (callerClassLoader == _systemClassLoader)) {
  184. continue;
  185. }
  186. if (debug) {
  187. _log.debug(
  188. "Lookup PACL policy for caller class loader " +
  189. callerClassLoader);
  190. }
  191. PACLPolicy callerPACLPolicy = PACLPolicyManager.getPACLPolicy(
  192. callerClassLoader);
  193. if (callerPACLPolicy != null) {
  194. paclPolicy = callerPACLPolicy;
  195. if (debug) {
  196. _log.debug("Possibly return PACL policy " + paclPolicy);
  197. }
  198. if (!deep) {
  199. break;
  200. }
  201. }
  202. }
  203. if (debug) {
  204. _log.debug("Returning PACL policy " + paclPolicy);
  205. }
  206. return paclPolicy;
  207. }
  208. private static final String _ClASS_NAME_DYNAMIC_CLASS_LOADER =
  209. "com.caucho.loader.DynamicClassLoader";
  210. private static final String _ClASS_NAME_JASPER_LOADER =
  211. "org.apache.jasper.servlet.JasperLoader";
  212. private static final String _CLASS_NAME_JSP_CLASS_LOADER =
  213. "weblogic.servlet.jsp.JspClassLoader";
  214. private static final String _CLASS_NAME_JSP_EXTENSION_CLASS_LOADER =
  215. "com.ibm.ws.jsp.webcontainerext.JSPExtensionClassLoader";
  216. private static Log _log = LogFactoryUtil.getLog(PACLClassUtil.class);
  217. private static PACLClassUtil _instance = new PACLClassUtil();
  218. private ClassLoader _commonClassLoader;
  219. private ClassLoader _portalClassLoader;
  220. private ClassLoader _systemClassLoader;
  221. }