/modules/core/portal-security-pacl/src/main/java/com/liferay/portal/security/pacl/Reflection.java

http://github.com/liferay/liferay-portal · Java · 126 lines · 70 code · 30 blank · 26 comment · 18 complexity · e3771d49dafad7da8acdf7d539d2b3e3 MD5 · raw file

  1. /**
  2. * Copyright (c) 2000-present 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. /**
  17. * <p>
  18. * See https://issues.liferay.com/browse/LPS-38327.
  19. * </p>
  20. *
  21. * @author Raymond AugĂŠ
  22. */
  23. public class Reflection extends SecurityManager {
  24. public static Class<?> getCallerClass(int depth) {
  25. return _instance._getCallerClass(depth);
  26. }
  27. public static int getStackIndex(int oracle, int ibm) {
  28. return _instance._getStackIndex(new int[] {oracle}, new int[] {ibm});
  29. }
  30. public static int getStackIndex(int[] oracle, int[] ibm) {
  31. return _instance._getStackIndex(oracle, ibm);
  32. }
  33. private Reflection() {
  34. boolean useOldReflection = true;
  35. try {
  36. sun.reflect.Reflection.getCallerClass(1);
  37. }
  38. catch (UnsupportedOperationException uoe) {
  39. useOldReflection = false;
  40. }
  41. _useOldReflection = useOldReflection;
  42. }
  43. @SuppressWarnings("deprecation")
  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 + _STACK_OFFSET;
  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 + _STACK_OFFSET;
  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 + _STACK_OFFSET;
  92. }
  93. private static final int _STACK_OFFSET = 10;
  94. private static final Reflection _instance = new Reflection();
  95. private final boolean _useOldReflection;
  96. }