Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java
38829 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.management;2627import java.lang.reflect.Method;28import java.security.AccessController;2930import com.sun.jmx.mbeanserver.GetPropertyAction;31import com.sun.jmx.mbeanserver.Introspector;32import java.util.Objects;333435/**36* Describes an MBean attribute exposed for management. Instances of37* this class are immutable. Subclasses may be mutable but this is38* not recommended.39*40* @since 1.541*/42@SuppressWarnings("serial") // serialVersionUID not constant43public class MBeanAttributeInfo extends MBeanFeatureInfo implements Cloneable {4445/* Serial version */46private static final long serialVersionUID;47static {48/* For complicated reasons, the serialVersionUID changed49between JMX 1.0 and JMX 1.1, even though JMX 1.1 did not50have compatibility code for this class. So the51serialization produced by this class with JMX 1.2 and52jmx.serial.form=1.0 is not the same as that produced by53this class with JMX 1.1 and jmx.serial.form=1.0. However,54the serialization without that property is the same, and55that is the only form required by JMX 1.2.56*/57long uid = 8644704819898565848L;58try {59GetPropertyAction act = new GetPropertyAction("jmx.serial.form");60String form = AccessController.doPrivileged(act);61if ("1.0".equals(form))62uid = 7043855487133450673L;63} catch (Exception e) {64// OK: exception means no compat with 1.0, too bad65}66serialVersionUID = uid;67}6869static final MBeanAttributeInfo[] NO_ATTRIBUTES =70new MBeanAttributeInfo[0];7172/**73* @serial The actual attribute type.74*/75private final String attributeType;7677/**78* @serial The attribute write right.79*/80private final boolean isWrite;8182/**83* @serial The attribute read right.84*/85private final boolean isRead;8687/**88* @serial Indicates if this method is a "is"89*/90private final boolean is;919293/**94* Constructs an <CODE>MBeanAttributeInfo</CODE> object.95*96* @param name The name of the attribute.97* @param type The type or class name of the attribute.98* @param description A human readable description of the attribute.99* @param isReadable True if the attribute has a getter method, false otherwise.100* @param isWritable True if the attribute has a setter method, false otherwise.101* @param isIs True if this attribute has an "is" getter, false otherwise.102*103* @throws IllegalArgumentException if {@code isIs} is true but104* {@code isReadable} is not, or if {@code isIs} is true and105* {@code type} is not {@code boolean} or {@code java.lang.Boolean}.106* (New code should always use {@code boolean} rather than107* {@code java.lang.Boolean}.)108*/109public MBeanAttributeInfo(String name,110String type,111String description,112boolean isReadable,113boolean isWritable,114boolean isIs) {115this(name, type, description, isReadable, isWritable, isIs,116(Descriptor) null);117}118119/**120* Constructs an <CODE>MBeanAttributeInfo</CODE> object.121*122* @param name The name of the attribute.123* @param type The type or class name of the attribute.124* @param description A human readable description of the attribute.125* @param isReadable True if the attribute has a getter method, false otherwise.126* @param isWritable True if the attribute has a setter method, false otherwise.127* @param isIs True if this attribute has an "is" getter, false otherwise.128* @param descriptor The descriptor for the attribute. This may be null129* which is equivalent to an empty descriptor.130*131* @throws IllegalArgumentException if {@code isIs} is true but132* {@code isReadable} is not, or if {@code isIs} is true and133* {@code type} is not {@code boolean} or {@code java.lang.Boolean}.134* (New code should always use {@code boolean} rather than135* {@code java.lang.Boolean}.)136*137* @since 1.6138*/139public MBeanAttributeInfo(String name,140String type,141String description,142boolean isReadable,143boolean isWritable,144boolean isIs,145Descriptor descriptor) {146super(name, description, descriptor);147148this.attributeType = type;149this.isRead = isReadable;150this.isWrite = isWritable;151if (isIs && !isReadable) {152throw new IllegalArgumentException("Cannot have an \"is\" getter " +153"for a non-readable attribute");154}155if (isIs && !type.equals("java.lang.Boolean") &&156!type.equals("boolean")) {157throw new IllegalArgumentException("Cannot have an \"is\" getter " +158"for a non-boolean attribute");159}160this.is = isIs;161}162163/**164* <p>This constructor takes the name of a simple attribute, and Method165* objects for reading and writing the attribute. The {@link Descriptor}166* of the constructed object will include fields contributed by any167* annotations on the {@code Method} objects that contain the168* {@link DescriptorKey} meta-annotation.169*170* @param name The programmatic name of the attribute.171* @param description A human readable description of the attribute.172* @param getter The method used for reading the attribute value.173* May be null if the property is write-only.174* @param setter The method used for writing the attribute value.175* May be null if the attribute is read-only.176* @exception IntrospectionException There is a consistency177* problem in the definition of this attribute.178*/179public MBeanAttributeInfo(String name,180String description,181Method getter,182Method setter) throws IntrospectionException {183this(name,184attributeType(getter, setter),185description,186(getter != null),187(setter != null),188isIs(getter),189ImmutableDescriptor.union(Introspector.descriptorForElement(getter),190Introspector.descriptorForElement(setter)));191}192193/**194* <p>Returns a shallow clone of this instance.195* The clone is obtained by simply calling <tt>super.clone()</tt>,196* thus calling the default native shallow cloning mechanism197* implemented by <tt>Object.clone()</tt>.198* No deeper cloning of any internal field is made.</p>199*200* <p>Since this class is immutable, cloning is chiefly of201* interest to subclasses.</p>202*/203public Object clone () {204try {205return super.clone() ;206} catch (CloneNotSupportedException e) {207// should not happen as this class is cloneable208return null;209}210}211212/**213* Returns the class name of the attribute.214*215* @return the class name.216*/217public String getType() {218return attributeType;219}220221/**222* Whether the value of the attribute can be read.223*224* @return True if the attribute can be read, false otherwise.225*/226public boolean isReadable() {227return isRead;228}229230/**231* Whether new values can be written to the attribute.232*233* @return True if the attribute can be written to, false otherwise.234*/235public boolean isWritable() {236return isWrite;237}238239/**240* Indicates if this attribute has an "is" getter.241*242* @return true if this attribute has an "is" getter.243*/244public boolean isIs() {245return is;246}247248public String toString() {249String access;250if (isReadable()) {251if (isWritable())252access = "read/write";253else254access = "read-only";255} else if (isWritable())256access = "write-only";257else258access = "no-access";259260return261getClass().getName() + "[" +262"description=" + getDescription() + ", " +263"name=" + getName() + ", " +264"type=" + getType() + ", " +265access + ", " +266(isIs() ? "isIs, " : "") +267"descriptor=" + getDescriptor() +268"]";269}270271/**272* Compare this MBeanAttributeInfo to another.273*274* @param o the object to compare to.275*276* @return true if and only if <code>o</code> is an MBeanAttributeInfo such277* that its {@link #getName()}, {@link #getType()}, {@link278* #getDescription()}, {@link #isReadable()}, {@link279* #isWritable()}, and {@link #isIs()} values are equal (not280* necessarily identical) to those of this MBeanAttributeInfo.281*/282public boolean equals(Object o) {283if (o == this)284return true;285if (!(o instanceof MBeanAttributeInfo))286return false;287MBeanAttributeInfo p = (MBeanAttributeInfo) o;288return (Objects.equals(p.getName(), getName()) &&289Objects.equals(p.getType(), getType()) &&290Objects.equals(p.getDescription(), getDescription()) &&291Objects.equals(p.getDescriptor(), getDescriptor()) &&292p.isReadable() == isReadable() &&293p.isWritable() == isWritable() &&294p.isIs() == isIs());295}296297/* We do not include everything in the hashcode. We assume that298if two operations are different they'll probably have different299names or types. The penalty we pay when this assumption is300wrong should be less than the penalty we would pay if it were301right and we needlessly hashed in the description and parameter302array. */303public int hashCode() {304return Objects.hash(getName(), getType());305}306307private static boolean isIs(Method getter) {308return (getter != null &&309getter.getName().startsWith("is") &&310(getter.getReturnType().equals(Boolean.TYPE) ||311getter.getReturnType().equals(Boolean.class)));312}313314/**315* Finds the type of the attribute.316*/317private static String attributeType(Method getter, Method setter)318throws IntrospectionException {319Class<?> type = null;320321if (getter != null) {322if (getter.getParameterTypes().length != 0) {323throw new IntrospectionException("bad getter arg count");324}325type = getter.getReturnType();326if (type == Void.TYPE) {327throw new IntrospectionException("getter " + getter.getName() +328" returns void");329}330}331332if (setter != null) {333Class<?> params[] = setter.getParameterTypes();334if (params.length != 1) {335throw new IntrospectionException("bad setter arg count");336}337if (type == null)338type = params[0];339else if (type != params[0]) {340throw new IntrospectionException("type mismatch between " +341"getter and setter");342}343}344345if (type == null) {346throw new IntrospectionException("getter and setter cannot " +347"both be null");348}349350return type.getName();351}352353}354355356