1 /* 2 * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.management; 27 28 import java.util.HashMap; 29 import java.util.Map; 30 import java.util.function.Predicate; 31 import javax.management.openmbean.CompositeType; 32 import javax.management.openmbean.CompositeData; 33 import javax.management.openmbean.CompositeDataSupport; 34 import javax.management.openmbean.OpenDataException; 35 36 /** 37 * A CompositeData for StackTraceElement for the local management support. 38 * This class avoids the performance penalty paid to the 39 * construction of a CompositeData use in the local case. 40 */ 41 public class StackTraceElementCompositeData extends LazyCompositeData { 42 private final StackTraceElement ste; 43 44 private StackTraceElementCompositeData(StackTraceElement ste) { 45 this.ste = ste; 46 } 47 48 public StackTraceElement getStackTraceElement() { 49 return ste; 50 } 51 52 public static StackTraceElement from(CompositeData cd) { 53 validateCompositeData(cd); 54 55 if (stackTraceElementV6CompositeType.equals(cd.getCompositeType())) { 56 return new StackTraceElement(getString(cd, CLASS_NAME), 57 getString(cd, METHOD_NAME), 58 getString(cd, FILE_NAME), 59 getInt(cd, LINE_NUMBER)); 60 } else { 61 return new StackTraceElement(getString(cd, CLASS_LOADER_NAME), 62 getString(cd, MODULE_NAME), 63 getString(cd, MODULE_VERSION), 64 getString(cd, CLASS_NAME), 65 getString(cd, METHOD_NAME), 66 getString(cd, FILE_NAME), 67 getInt(cd, LINE_NUMBER)); 68 } 69 } 70 71 public static CompositeData toCompositeData(StackTraceElement ste) { 72 StackTraceElementCompositeData cd = new StackTraceElementCompositeData(ste); 73 return cd.getCompositeData(); 74 } 75 76 protected CompositeData getCompositeData() { 77 // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH 78 // stackTraceElementItemNames! 79 final Object[] stackTraceElementItemValues = { 80 ste.getClassLoaderName(), 81 ste.getModuleName(), 82 ste.getModuleVersion(), 83 ste.getClassName(), 84 ste.getMethodName(), 85 ste.getFileName(), 86 ste.getLineNumber(), 87 ste.isNativeMethod(), 88 }; 89 try { 90 return new CompositeDataSupport(stackTraceElementCompositeType, 91 stackTraceElementItemNames, 92 stackTraceElementItemValues); 93 } catch (OpenDataException e) { 94 // Should never reach here 95 throw new AssertionError(e); 96 } 97 } 98 99 // Attribute names 100 private static final String CLASS_LOADER_NAME = "classLoaderName"; 101 private static final String MODULE_NAME = "moduleName"; 102 private static final String MODULE_VERSION = "moduleVersion"; 103 private static final String CLASS_NAME = "className"; 104 private static final String METHOD_NAME = "methodName"; 105 private static final String FILE_NAME = "fileName"; 106 private static final String LINE_NUMBER = "lineNumber"; 107 private static final String NATIVE_METHOD = "nativeMethod"; 108 109 110 private static final String[] stackTraceElementItemNames = { 111 CLASS_LOADER_NAME, 112 MODULE_NAME, 113 MODULE_VERSION, 114 CLASS_NAME, 115 METHOD_NAME, 116 FILE_NAME, 117 LINE_NUMBER, 118 NATIVE_METHOD, 119 }; 120 121 private static final String[] stackTraceElementV9ItemNames = { 122 CLASS_LOADER_NAME, 123 MODULE_NAME, 124 MODULE_VERSION, 125 }; 126 127 private static final CompositeType stackTraceElementCompositeType; 128 private static final CompositeType stackTraceElementV6CompositeType; 129 static { 130 try { 131 stackTraceElementCompositeType = (CompositeType) 132 MappedMXBeanType.toOpenType(StackTraceElement.class); 133 stackTraceElementV6CompositeType = 134 TypeVersionMapper.getInstance().getVersionedCompositeType( 135 stackTraceElementCompositeType, 136 TypeVersionMapper.V6 137 ); 138 } catch (OpenDataException e) { 139 // Should never reach here 140 throw new AssertionError(e); 141 } 142 } 143 144 /** Validate if the input CompositeData has the expected 145 * CompositeType (i.e. contain all attributes with expected 146 * names and types). 147 */ 148 public static void validateCompositeData(CompositeData cd) { 149 if (cd == null) { 150 throw new NullPointerException("Null CompositeData"); 151 } 152 153 CompositeType ct = cd.getCompositeType(); 154 if (!isTypeMatched(stackTraceElementCompositeType, ct)) { 155 if (!isTypeMatched(stackTraceElementV6CompositeType, ct)) { 156 throw new IllegalArgumentException( 157 "Unexpected composite type for StackTraceElement"); 158 } 159 } 160 } 161 162 static boolean isV6Attribute(String name) { 163 for(String attrName : stackTraceElementV9ItemNames) { 164 if (name.equals(attrName)) { 165 return false; 166 } 167 } 168 return true; 169 } 170 171 private static final long serialVersionUID = -2704607706598396827L; 172 }