1 /* 2 * Copyright (c) 2005, 2018, 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 javax.management.openmbean.CompositeType; 29 import javax.management.openmbean.CompositeData; 30 import javax.management.openmbean.CompositeDataSupport; 31 import javax.management.openmbean.OpenDataException; 32 import javax.management.openmbean.OpenType; 33 import java.util.Arrays; 34 import java.util.HashMap; 35 import java.util.Map; 36 import java.util.stream.Stream; 37 38 /** 39 * A CompositeData for StackTraceElement for the local management support. 40 * This class avoids the performance penalty paid to the 41 * construction of a CompositeData use in the local case. 42 */ 43 public class StackTraceElementCompositeData extends LazyCompositeData { 44 private final StackTraceElement ste; 45 46 private StackTraceElementCompositeData(StackTraceElement ste) { 47 this.ste = ste; 48 } 49 50 public StackTraceElement getStackTraceElement() { 51 return ste; 52 } 53 54 public static StackTraceElement from(CompositeData cd) { 55 validateCompositeData(cd); 56 57 if (STACK_TRACE_ELEMENT_COMPOSITE_TYPE.equals(cd.getCompositeType())) { 58 return new StackTraceElement(getString(cd, CLASS_LOADER_NAME), 59 getString(cd, MODULE_NAME), 60 getString(cd, MODULE_VERSION), 61 getString(cd, CLASS_NAME), 62 getString(cd, METHOD_NAME), 63 getString(cd, FILE_NAME), 64 getInt(cd, LINE_NUMBER)); 65 } else { 66 return new StackTraceElement(getString(cd, CLASS_NAME), 67 getString(cd, METHOD_NAME), 68 getString(cd, FILE_NAME), 69 getInt(cd, LINE_NUMBER)); 70 71 } 72 } 73 74 public static CompositeData toCompositeData(StackTraceElement ste) { 75 StackTraceElementCompositeData cd = new StackTraceElementCompositeData(ste); 76 return cd.getCompositeData(); 77 } 78 79 protected CompositeData getCompositeData() { 80 // values may be null; so can't use Map.of 81 Map<String,Object> items = new HashMap<>(); 82 items.put(CLASS_LOADER_NAME, ste.getClassLoaderName()); 83 items.put(MODULE_NAME, ste.getModuleName()); 84 items.put(MODULE_VERSION, ste.getModuleVersion()); 85 items.put(CLASS_NAME, ste.getClassName()); 86 items.put(METHOD_NAME, ste.getMethodName()); 87 items.put(FILE_NAME, ste.getFileName()); 88 items.put(LINE_NUMBER, ste.getLineNumber()); 89 items.put(NATIVE_METHOD, ste.isNativeMethod()); 90 91 try { 92 return new CompositeDataSupport(STACK_TRACE_ELEMENT_COMPOSITE_TYPE, items); 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 private static final String[] V5_ATTRIBUTES = { 110 CLASS_NAME, 111 METHOD_NAME, 112 FILE_NAME, 113 LINE_NUMBER, 114 NATIVE_METHOD, 115 }; 116 117 private static final String[] V9_ATTRIBUTES = { 118 CLASS_LOADER_NAME, 119 MODULE_NAME, 120 MODULE_VERSION, 121 }; 122 123 private static final CompositeType STACK_TRACE_ELEMENT_COMPOSITE_TYPE; 124 private static final CompositeType V5_COMPOSITE_TYPE; 125 static { 126 try { 127 STACK_TRACE_ELEMENT_COMPOSITE_TYPE = (CompositeType) 128 MappedMXBeanType.toOpenType(StackTraceElement.class); 129 130 OpenType<?>[] types = new OpenType<?>[V5_ATTRIBUTES.length]; 131 for (int i=0; i < V5_ATTRIBUTES.length; i++) { 132 String name = V5_ATTRIBUTES[i]; 133 types[i] = STACK_TRACE_ELEMENT_COMPOSITE_TYPE.getType(name); 134 } 135 V5_COMPOSITE_TYPE = new CompositeType("StackTraceElement", 136 "JDK 5 StackTraceElement", 137 V5_ATTRIBUTES, 138 V5_ATTRIBUTES, 139 types); 140 } catch (OpenDataException e) { 141 // Should never reach here 142 throw new AssertionError(e); 143 } 144 } 145 146 static CompositeType v5CompositeType() { 147 return V5_COMPOSITE_TYPE; 148 } 149 150 /** 151 * Validate if the input CompositeData has the expected 152 * CompositeType (i.e. contain all attributes with expected 153 * names and types). 154 */ 155 public static void validateCompositeData(CompositeData cd) { 156 if (cd == null) { 157 throw new NullPointerException("Null CompositeData"); 158 } 159 160 CompositeType ct = cd.getCompositeType(); 161 if (!isTypeMatched(STACK_TRACE_ELEMENT_COMPOSITE_TYPE, ct) && 162 !isTypeMatched(V5_COMPOSITE_TYPE, ct)) { 163 throw new IllegalArgumentException( 164 "Unexpected composite type for StackTraceElement"); 165 } 166 } 167 private static final long serialVersionUID = -2704607706598396827L; 168 }