/portal-pacl/src/com/liferay/portal/security/pacl/Reflection.java

https://github.com/aarondelani/liferay-portal · Java · 126 lines · 69 code · 31 blank · 26 comment · 20 complexity · 181f21b4b6c3da5ee1b3c56526f9ed37 MD5 · raw file

  1. /**
  2. * Copyright (c) 2000-2013 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.util.JavaDetector;
  16. import java.lang.reflect.Method;
  17. /**
  18. * <p>
  19. * See http://issues.liferay.com/browse/LPS-38327.
  20. * </p>
  21. *
  22. * @author Raymond Augé
  23. */
  24. public class Reflection extends SecurityManager {
  25. public static Class<?> getCallerClass(int depth) {
  26. return _instance._getCallerClass(depth);
  27. }
  28. public static int getStackIndex(int oracle, int ibm) {
  29. return _instance._getStackIndex(new int[] {oracle}, new int[] {ibm});
  30. }
  31. public static int getStackIndex(int[] oracle, int[] ibm) {
  32. return _instance._getStackIndex(oracle, ibm);
  33. }
  34. private Reflection() {
  35. Method[] methods = sun.reflect.Reflection.class.getMethods();
  36. for (Method method : methods) {
  37. String methodName = method.getName();
  38. if (methodName.equals("isCallerSensitive")) {
  39. _useOldReflection = false;
  40. break;
  41. }
  42. }
  43. }
  44. private Class<?> _getCallerClass(int depth) {
  45. if (_useOldReflection) {
  46. // This operation is faster, so leave it here for legacy versions
  47. return sun.reflect.Reflection.getCallerClass(depth + 2);
  48. }
  49. Class<?>[] callerClasses = getClassContext();
  50. // [0] Reflection._getCallerClass
  51. // [1] Reflection.getCallerClass
  52. return callerClasses[depth + 1];
  53. }
  54. private int _getStackIndex(int[] oracle, int[] ibm) {
  55. if ((oracle.length != ibm.length) && (oracle.length == 0)) {
  56. throw new IllegalArgumentException(
  57. "Both arrays must not be empty and have the same length");
  58. }
  59. int index = 0;
  60. // Case 1: Oracle or IBM (default case)
  61. if (JavaDetector.isIBM()) {
  62. index = ibm[0];
  63. }
  64. else {
  65. index = oracle[0];
  66. }
  67. if (oracle.length == 1) {
  68. return index;
  69. }
  70. // Case 2: JDK7
  71. if (JavaDetector.isJDK7()) {
  72. if (JavaDetector.isIBM()) {
  73. index = ibm[1];
  74. }
  75. else {
  76. index = oracle[1];
  77. }
  78. }
  79. if (oracle.length == 2) {
  80. return index;
  81. }
  82. // Case 3: JDK7 >= u25
  83. if (JavaDetector.isJDK7() && !_useOldReflection) {
  84. if (JavaDetector.isIBM()) {
  85. index = ibm[2];
  86. }
  87. else {
  88. index = oracle[2];
  89. }
  90. }
  91. return index;
  92. }
  93. private static final Reflection _instance = new Reflection();
  94. private boolean _useOldReflection = true;
  95. }