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, MODULE_NAME), 62 getString(cd, MODULE_VERSION), 63 getString(cd, CLASS_NAME), 64 getString(cd, METHOD_NAME), 65 getString(cd, FILE_NAME), 66 getInt(cd, LINE_NUMBER)); 67 } 68 } 69 70 public static CompositeData toCompositeData(StackTraceElement ste) { 71 StackTraceElementCompositeData cd = new StackTraceElementCompositeData(ste); 72 return cd.getCompositeData(); 73 } 74 75 protected CompositeData getCompositeData() { 76 // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH 77 // stackTraceElementItemNames! 78 final Object[] stackTraceElementItemValues = { 79 ste.getClassName(), 80 ste.getMethodName(), 81 ste.getFileName(), 82 ste.getLineNumber(), 83 ste.isNativeMethod(), 84 ste.getModuleName(), 85 ste.getModuleVersion(), 86 }; 87 try { 88 return new CompositeDataSupport(stackTraceElementCompositeType, 89 stackTraceElementItemNames, 90 stackTraceElementItemValues); 91 } catch (OpenDataException e) { 92 // Should never reach here 93 throw new AssertionError(e); 94 } 95 } 96 97 // Attribute names 98 private static final String CLASS_NAME = "className"; 99 private static final String METHOD_NAME = "methodName"; 100 private static final String FILE_NAME = "fileName"; 101 private static final String LINE_NUMBER = "lineNumber"; 102 private static final String NATIVE_METHOD = "nativeMethod"; 103 private static final String MODULE_NAME = "moduleName"; 104 private static final String MODULE_VERSION = "moduleVersion"; 105 106 private static final String[] stackTraceElementItemNames = { 107 CLASS_NAME, 108 METHOD_NAME, 109 FILE_NAME, 110 LINE_NUMBER, 111 NATIVE_METHOD, 112 MODULE_NAME, 113 MODULE_VERSION, 114 }; 115 116 private static final String[] stackTraceElementV9ItemNames = { 117 MODULE_NAME, 118 MODULE_VERSION, 119 }; 120 121 private static final CompositeType stackTraceElementCompositeType; 122 private static final CompositeType stackTraceElementV6CompositeType; 123 static { 124 try { 125 stackTraceElementCompositeType = (CompositeType) 126 MappedMXBeanType.toOpenType(StackTraceElement.class); 127 stackTraceElementV6CompositeType = 128 TypeVersionMapper.getInstance().getVersionedCompositeType( 129 stackTraceElementCompositeType, 130 TypeVersionMapper.V6 131 ); 132 } catch (OpenDataException e) { 133 // Should never reach here 134 throw new AssertionError(e); 135 } 136 } 137 138 /** Validate if the input CompositeData has the expected 139 * CompositeType (i.e. contain all attributes with expected 140 * names and types). 141 */ 142 public static void validateCompositeData(CompositeData cd) { 143 if (cd == null) { 144 throw new NullPointerException("Null CompositeData"); 145 } 146 147 CompositeType ct = cd.getCompositeType(); 148 if (!isTypeMatched(stackTraceElementCompositeType, ct)) { 149 if (!isTypeMatched(stackTraceElementV6CompositeType, ct)) { 150 throw new IllegalArgumentException( 151 "Unexpected composite type for StackTraceElement"); 152 } 153 } 154 } 155 156 static boolean isV6Attribute(String name) { 157 for(String attrName : stackTraceElementV9ItemNames) { 158 if (name.equals(attrName)) { 159 return false; 160 } 161 } 162 return true; 163 } 164 165 private static final long serialVersionUID = -2704607706598396827L; 166 }