Source Code Cross Referenced for OpenMBeanAttributeInfoSupport.java in  » 6.0-JDK-Core » management » javax » management » openmbean » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » management » javax.management.openmbean 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.management.openmbean;
0027
0028        // java import
0029        //
0030        import java.lang.reflect.Array;
0031        import java.lang.reflect.Constructor;
0032        import java.lang.reflect.Method;
0033        import java.lang.reflect.Modifier;
0034        import java.util.Arrays;
0035        import java.util.Collection;
0036        import java.util.Collections;
0037        import java.util.HashMap;
0038        import java.util.HashSet;
0039        import java.util.Map;
0040        import java.util.Set;
0041        import javax.management.Descriptor;
0042        import javax.management.DescriptorRead;
0043        import javax.management.ImmutableDescriptor;
0044        import javax.management.MBeanAttributeInfo;
0045        import com.sun.jmx.remote.util.EnvHelp;
0046
0047        /**
0048         * Describes an attribute of an open MBean.
0049         *
0050         *
0051         * @since 1.5
0052         */
0053        public class OpenMBeanAttributeInfoSupport extends MBeanAttributeInfo
0054                implements  OpenMBeanAttributeInfo {
0055
0056            /* Serial version */
0057            static final long serialVersionUID = -4867215622149721849L;
0058
0059            /**
0060             * @serial The open mbean attribute's <i>open type</i>
0061             */
0062            private OpenType<?> openType;
0063
0064            /**
0065             * @serial The open mbean attribute's default value
0066             */
0067            private final Object defaultValue;
0068
0069            /**
0070             * @serial The open mbean attribute's legal values. This {@link
0071             * Set} is unmodifiable
0072             */
0073            private final Set<?> legalValues; // to be constructed unmodifiable
0074
0075            /**
0076             * @serial The open mbean attribute's min value
0077             */
0078            private final Comparable minValue;
0079
0080            /**
0081             * @serial The open mbean attribute's max value
0082             */
0083            private final Comparable maxValue;
0084
0085            // As this instance is immutable, these two values need only
0086            // be calculated once.
0087            private transient Integer myHashCode = null;
0088            private transient String myToString = null;
0089
0090            /**
0091             * Constructs an {@code OpenMBeanAttributeInfoSupport} instance,
0092             * which describes the attribute of an open MBean with the
0093             * specified {@code name}, {@code openType} and {@code
0094             * description}, and the specified read/write access properties.
0095             *
0096             * @param name  cannot be a null or empty string.
0097             *
0098             * @param description  cannot be a null or empty string.
0099             *
0100             * @param openType  cannot be null.
0101             *
0102             * @param isReadable {@code true} if the attribute has a getter
0103             * exposed for management.
0104             *
0105             * @param isWritable {@code true} if the attribute has a setter
0106             * exposed for management.
0107             *
0108             * @param isIs {@code true} if the attribute's getter is of the
0109             * form <tt>is<i>XXX</i></tt>.
0110             *
0111             * @throws IllegalArgumentException if {@code name} or {@code
0112             * description} are null or empty string, or {@code openType} is
0113             * null.
0114             */
0115            public OpenMBeanAttributeInfoSupport(String name,
0116                    String description, OpenType<?> openType,
0117                    boolean isReadable, boolean isWritable, boolean isIs) {
0118                this (name, description, openType, isReadable, isWritable, isIs,
0119                        (Descriptor) null);
0120            }
0121
0122            /**
0123             * <p>Constructs an {@code OpenMBeanAttributeInfoSupport} instance,
0124             * which describes the attribute of an open MBean with the
0125             * specified {@code name}, {@code openType}, {@code
0126             * description}, read/write access properties, and {@code Descriptor}.</p>
0127             *
0128             * <p>The {@code descriptor} can contain entries that will define
0129             * the values returned by certain methods of this class, as
0130             * explained in the {@link <a href="package-summary.html#constraints">
0131             * package description</a>}.
0132             *
0133             * @param name  cannot be a null or empty string.
0134             *
0135             * @param description  cannot be a null or empty string.
0136             *
0137             * @param openType  cannot be null.
0138             *
0139             * @param isReadable {@code true} if the attribute has a getter
0140             * exposed for management.
0141             *
0142             * @param isWritable {@code true} if the attribute has a setter
0143             * exposed for management.
0144             *
0145             * @param isIs {@code true} if the attribute's getter is of the
0146             * form <tt>is<i>XXX</i></tt>.
0147             *
0148             * @param descriptor The descriptor for the attribute.  This may be null
0149             * which is equivalent to an empty descriptor.
0150             *
0151             * @throws IllegalArgumentException if {@code name} or {@code
0152             * description} are null or empty string, or {@code openType} is
0153             * null, or the descriptor entries are invalid as described in the
0154             * {@link <a href="package-summary.html#constraints">package
0155             * description</a>}.
0156             *
0157             * @since 1.6
0158             */
0159            public OpenMBeanAttributeInfoSupport(String name,
0160                    String description, OpenType<?> openType,
0161                    boolean isReadable, boolean isWritable, boolean isIs,
0162                    Descriptor descriptor) {
0163                // Construct parent's state
0164                //
0165                super (name,
0166                        (openType == null) ? null : openType.getClassName(),
0167                        description, isReadable, isWritable, isIs,
0168                        ImmutableDescriptor.union(descriptor,
0169                                (openType == null) ? null : openType
0170                                        .getDescriptor()));
0171
0172                // Initialize this instance's specific state
0173                //
0174                this .openType = openType;
0175
0176                descriptor = getDescriptor(); // replace null by empty
0177                this .defaultValue = valueFrom(descriptor, "defaultValue",
0178                        openType);
0179                this .legalValues = valuesFrom(descriptor, "legalValues",
0180                        openType);
0181                this .minValue = comparableValueFrom(descriptor, "minValue",
0182                        openType);
0183                this .maxValue = comparableValueFrom(descriptor, "maxValue",
0184                        openType);
0185
0186                try {
0187                    check(this );
0188                } catch (OpenDataException e) {
0189                    throw new IllegalArgumentException(e.getMessage(), e);
0190                }
0191            }
0192
0193            /**
0194             * Constructs an {@code OpenMBeanAttributeInfoSupport} instance,
0195             * which describes the attribute of an open MBean with the
0196             * specified {@code name}, {@code openType}, {@code description}
0197             * and {@code defaultValue}, and the specified read/write access
0198             * properties.
0199             *
0200             * @param name  cannot be a null or empty string.
0201             *
0202             * @param description  cannot be a null or empty string.
0203             *
0204             * @param openType  cannot be null.
0205             *
0206             * @param isReadable {@code true} if the attribute has a getter
0207             * exposed for management.
0208             *
0209             * @param isWritable {@code true} if the attribute has a setter
0210             * exposed for management.
0211             *
0212             * @param isIs {@code true} if the attribute's getter is of the
0213             * form <tt>is<i>XXX</i></tt>.
0214             *
0215             * @param defaultValue must be a valid value for the {@code
0216             * openType} specified for this attribute; default value not
0217             * supported for {@code ArrayType} and {@code TabularType}; can
0218             * be null, in which case it means that no default value is set.
0219             *
0220             * @param <T> allows the compiler to check that the {@code defaultValue},
0221             * if non-null, has the correct Java type for the given {@code openType}.
0222             *
0223             * @throws IllegalArgumentException if {@code name} or {@code
0224             * description} are null or empty string, or {@code openType} is
0225             * null.
0226             *
0227             * @throws OpenDataException if {@code defaultValue} is not a
0228             * valid value for the specified {@code openType}, or {@code
0229             * defaultValue} is non null and {@code openType} is an {@code
0230             * ArrayType} or a {@code TabularType}.
0231             */
0232            public <T> OpenMBeanAttributeInfoSupport(String name,
0233                    String description, OpenType<T> openType,
0234                    boolean isReadable, boolean isWritable, boolean isIs,
0235                    T defaultValue) throws OpenDataException {
0236                this (name, description, openType, isReadable, isWritable, isIs,
0237                        defaultValue, (T[]) null);
0238            }
0239
0240            /**
0241             * <p>Constructs an {@code OpenMBeanAttributeInfoSupport} instance,
0242             * which describes the attribute of an open MBean with the
0243             * specified {@code name}, {@code openType}, {@code description},
0244             * {@code defaultValue} and {@code legalValues}, and the specified
0245             * read/write access properties.</p>
0246             *
0247             * <p>The contents of {@code legalValues} are copied, so subsequent
0248             * modifications of the array referenced by {@code legalValues}
0249             * have no impact on this {@code OpenMBeanAttributeInfoSupport}
0250             * instance.</p>
0251             *
0252             * @param name  cannot be a null or empty string.
0253             *
0254             * @param description  cannot be a null or empty string.
0255             *
0256             * @param openType  cannot be null.
0257             *
0258             * @param isReadable {@code true} if the attribute has a getter
0259             * exposed for management.
0260             *
0261             * @param isWritable {@code true} if the attribute has a setter
0262             * exposed for management.
0263             *
0264             * @param isIs {@code true} if the attribute's getter is of the
0265             * form <tt>is<i>XXX</i></tt>.
0266             *
0267             * @param defaultValue must be a valid value
0268             * for the {@code
0269             * openType} specified for this attribute; default value not
0270             * supported for {@code ArrayType} and {@code TabularType}; can
0271             * be null, in which case it means that no default value is set.
0272             *
0273             * @param legalValues each contained value must be valid for the
0274             * {@code openType} specified for this attribute; legal values
0275             * not supported for {@code ArrayType} and {@code TabularType};
0276             * can be null or empty.
0277             *
0278             * @param <T> allows the compiler to check that the {@code
0279             * defaultValue} and {@code legalValues}, if non-null, have the
0280             * correct Java type for the given {@code openType}.
0281             *
0282             * @throws IllegalArgumentException if {@code name} or {@code
0283             * description} are null or empty string, or {@code openType} is
0284             * null.
0285             *
0286             * @throws OpenDataException if {@code defaultValue} is not a
0287             * valid value for the specified {@code openType}, or one value in
0288             * {@code legalValues} is not valid for the specified {@code
0289             * openType}, or {@code defaultValue} is non null and {@code
0290             * openType} is an {@code ArrayType} or a {@code TabularType}, or
0291             * {@code legalValues} is non null and non empty and {@code
0292             * openType} is an {@code ArrayType} or a {@code TabularType}, or
0293             * {@code legalValues} is non null and non empty and {@code
0294             * defaultValue} is not contained in {@code legalValues}.
0295             */
0296            public <T> OpenMBeanAttributeInfoSupport(String name,
0297                    String description, OpenType<T> openType,
0298                    boolean isReadable, boolean isWritable, boolean isIs,
0299                    T defaultValue, T[] legalValues) throws OpenDataException {
0300                this (name, description, openType, isReadable, isWritable, isIs,
0301                        defaultValue, legalValues, null, null);
0302            }
0303
0304            /**
0305             * Constructs an {@code OpenMBeanAttributeInfoSupport} instance,
0306             * which describes the attribute of an open MBean, with the
0307             * specified {@code name}, {@code openType}, {@code description},
0308             * {@code defaultValue}, {@code minValue} and {@code maxValue}.
0309             *
0310             * It is possible to specify minimal and maximal values only for
0311             * an open type whose values are {@code Comparable}.
0312             *
0313             * @param name  cannot be a null or empty string.
0314             *
0315             * @param description  cannot be a null or empty string.
0316             *
0317             * @param openType  cannot be null.
0318             *
0319             * @param isReadable {@code true} if the attribute has a getter
0320             * exposed for management.
0321             *
0322             * @param isWritable {@code true} if the attribute has a setter
0323             * exposed for management.
0324             *
0325             * @param isIs {@code true} if the attribute's getter is of the
0326             * form <tt>is<i>XXX</i></tt>.
0327             *
0328             * @param defaultValue must be a valid value for the {@code
0329             * openType} specified for this attribute; default value not
0330             * supported for {@code ArrayType} and {@code TabularType}; can be
0331             * null, in which case it means that no default value is set.
0332             *
0333             * @param minValue must be valid for the {@code openType}
0334             * specified for this attribute; can be null, in which case it
0335             * means that no minimal value is set.
0336             *
0337             * @param maxValue must be valid for the {@code openType}
0338             * specified for this attribute; can be null, in which case it
0339             * means that no maximal value is set.
0340             *
0341             * @param <T> allows the compiler to check that the {@code
0342             * defaultValue}, {@code minValue}, and {@code maxValue}, if
0343             * non-null, have the correct Java type for the given {@code
0344             * openType}.
0345             *
0346             * @throws IllegalArgumentException if {@code name} or {@code
0347             * description} are null or empty string, or {@code openType} is
0348             * null.
0349             *
0350             * @throws OpenDataException if {@code defaultValue}, {@code
0351             * minValue} or {@code maxValue} is not a valid value for the
0352             * specified {@code openType}, or {@code defaultValue} is non null
0353             * and {@code openType} is an {@code ArrayType} or a {@code
0354             * TabularType}, or both {@code minValue} and {@code maxValue} are
0355             * non-null and {@code minValue.compareTo(maxValue) > 0} is {@code
0356             * true}, or both {@code defaultValue} and {@code minValue} are
0357             * non-null and {@code minValue.compareTo(defaultValue) > 0} is
0358             * {@code true}, or both {@code defaultValue} and {@code maxValue}
0359             * are non-null and {@code defaultValue.compareTo(maxValue) > 0}
0360             * is {@code true}.
0361             */
0362            public <T> OpenMBeanAttributeInfoSupport(String name,
0363                    String description, OpenType<T> openType,
0364                    boolean isReadable, boolean isWritable, boolean isIs,
0365                    T defaultValue, Comparable<T> minValue,
0366                    Comparable<T> maxValue) throws OpenDataException {
0367                this (name, description, openType, isReadable, isWritable, isIs,
0368                        defaultValue, null, minValue, maxValue);
0369            }
0370
0371            private <T> OpenMBeanAttributeInfoSupport(String name,
0372                    String description, OpenType<T> openType,
0373                    boolean isReadable, boolean isWritable, boolean isIs,
0374                    T defaultValue, T[] legalValues, Comparable<T> minValue,
0375                    Comparable<T> maxValue) throws OpenDataException {
0376                super (name,
0377                        (openType == null) ? null : openType.getClassName(),
0378                        description, isReadable, isWritable, isIs,
0379                        makeDescriptor(openType, defaultValue, legalValues,
0380                                minValue, maxValue));
0381
0382                this .openType = openType;
0383
0384                Descriptor d = getDescriptor();
0385                this .defaultValue = defaultValue;
0386                this .minValue = minValue;
0387                this .maxValue = maxValue;
0388                // We already converted the array into an unmodifiable Set
0389                // in the descriptor.
0390                this .legalValues = (Set<?>) d.getFieldValue("legalValues");
0391
0392                check(this );
0393            }
0394
0395            /**
0396             * An object serialized in a version of the API before Descriptors were
0397             * added to this class will have an empty or null Descriptor.
0398             * For consistency with our
0399             * behavior in this version, we must replace the object with one
0400             * where the Descriptors reflect the same values of openType, defaultValue,
0401             * etc.
0402             **/
0403            private Object readResolve() {
0404                if (getDescriptor().getFieldNames().length == 0) {
0405                    OpenType<Object> xopenType = cast(openType);
0406                    Set<Object> xlegalValues = cast(legalValues);
0407                    Comparable<Object> xminValue = cast(minValue);
0408                    Comparable<Object> xmaxValue = cast(maxValue);
0409                    return new OpenMBeanAttributeInfoSupport(name, description,
0410                            openType, isReadable(), isWritable(), isIs(),
0411                            makeDescriptor(xopenType, defaultValue,
0412                                    xlegalValues, xminValue, xmaxValue));
0413                } else
0414                    return this ;
0415            }
0416
0417            static void check(OpenMBeanParameterInfo info)
0418                    throws OpenDataException {
0419                OpenType openType = info.getOpenType();
0420                if (openType == null)
0421                    throw new IllegalArgumentException(
0422                            "OpenType cannot be null");
0423
0424                if (info.getName() == null || info.getName().trim().equals(""))
0425                    throw new IllegalArgumentException(
0426                            "Name cannot be null or empty");
0427
0428                if (info.getDescription() == null
0429                        || info.getDescription().trim().equals(""))
0430                    throw new IllegalArgumentException(
0431                            "Description cannot be null or empty");
0432
0433                // Check and initialize defaultValue
0434                //
0435                if (info.hasDefaultValue()) {
0436                    // Default value not supported for ArrayType and TabularType
0437                    // Cast to Object because "OpenType<T> instanceof" is illegal
0438                    if (openType.isArray()
0439                            || (Object) openType instanceof  TabularType) {
0440                        throw new OpenDataException(
0441                                "Default value not supported "
0442                                        + "for ArrayType and TabularType");
0443                    }
0444                    // Check defaultValue's class
0445                    if (!openType.isValue(info.getDefaultValue())) {
0446                        final String msg = "Argument defaultValue's class [\""
0447                                + info.getDefaultValue().getClass().getName()
0448                                + "\"] does not match the one defined in openType[\""
0449                                + openType.getClassName() + "\"]";
0450                        throw new OpenDataException(msg);
0451                    }
0452                }
0453
0454                // Check that we don't have both legalValues and min or max
0455                //
0456                if (info.hasLegalValues()
0457                        && (info.hasMinValue() || info.hasMaxValue())) {
0458                    throw new OpenDataException(
0459                            "cannot have both legalValue and "
0460                                    + "minValue or maxValue");
0461                }
0462
0463                // Check minValue and maxValue
0464                if (info.hasMinValue() && !openType.isValue(info.getMinValue())) {
0465                    final String msg = "Type of minValue ["
0466                            + info.getMinValue().getClass().getName()
0467                            + "] does not match OpenType ["
0468                            + openType.getClassName() + "]";
0469                    throw new OpenDataException(msg);
0470                }
0471                if (info.hasMaxValue() && !openType.isValue(info.getMaxValue())) {
0472                    final String msg = "Type of maxValue ["
0473                            + info.getMaxValue().getClass().getName()
0474                            + "] does not match OpenType ["
0475                            + openType.getClassName() + "]";
0476                    throw new OpenDataException(msg);
0477                }
0478
0479                // Check that defaultValue is a legal value
0480                //
0481                if (info.hasDefaultValue()) {
0482                    Object defaultValue = info.getDefaultValue();
0483                    if (info.hasLegalValues()
0484                            && !info.getLegalValues().contains(defaultValue)) {
0485                        throw new OpenDataException(
0486                                "defaultValue is not contained "
0487                                        + "in legalValues");
0488                    }
0489
0490                    // Check that minValue <= defaultValue <= maxValue
0491                    //
0492                    if (info.hasMinValue()) {
0493                        if (compare(info.getMinValue(), defaultValue) > 0) {
0494                            throw new OpenDataException(
0495                                    "minValue cannot be greater "
0496                                            + "than defaultValue");
0497                        }
0498                    }
0499                    if (info.hasMaxValue()) {
0500                        if (compare(info.getMaxValue(), defaultValue) < 0) {
0501                            throw new OpenDataException(
0502                                    "maxValue cannot be less "
0503                                            + "than defaultValue");
0504                        }
0505                    }
0506                }
0507
0508                // Check legalValues
0509                //
0510                if (info.hasLegalValues()) {
0511                    // legalValues not supported for TabularType and arrays
0512                    if ((Object) openType instanceof  TabularType
0513                            || openType.isArray()) {
0514                        throw new OpenDataException(
0515                                "Legal values not supported "
0516                                        + "for TabularType and arrays");
0517                    }
0518                    // Check legalValues are valid with openType
0519                    for (Object v : info.getLegalValues()) {
0520                        if (!openType.isValue(v)) {
0521                            final String msg = "Element of legalValues ["
0522                                    + v
0523                                    + "] is not a valid value for the specified openType ["
0524                                    + openType.toString() + "]";
0525                            throw new OpenDataException(msg);
0526                        }
0527                    }
0528                }
0529
0530                // Check that, if both specified, minValue <= maxValue
0531                //
0532                if (info.hasMinValue() && info.hasMaxValue()) {
0533                    if (compare(info.getMinValue(), info.getMaxValue()) > 0) {
0534                        throw new OpenDataException(
0535                                "minValue cannot be greater " + "than maxValue");
0536                    }
0537                }
0538
0539            }
0540
0541            @SuppressWarnings("unchecked")
0542            static int compare(Object x, Object y) {
0543                return ((Comparable) x).compareTo(y);
0544            }
0545
0546            static <T> Descriptor makeDescriptor(OpenType<T> openType,
0547                    T defaultValue, T[] legalValues, Comparable<T> minValue,
0548                    Comparable<T> maxValue) {
0549                Map<String, Object> map = new HashMap<String, Object>();
0550                if (defaultValue != null)
0551                    map.put("defaultValue", defaultValue);
0552                if (legalValues != null) {
0553                    Set<T> set = new HashSet<T>();
0554                    for (T v : legalValues)
0555                        set.add(v);
0556                    set = Collections.unmodifiableSet(set);
0557                    map.put("legalValues", set);
0558                }
0559                if (minValue != null)
0560                    map.put("minValue", minValue);
0561                if (maxValue != null)
0562                    map.put("maxValue", maxValue);
0563                if (map.isEmpty()) {
0564                    return openType.getDescriptor();
0565                } else {
0566                    map.put("openType", openType);
0567                    return new ImmutableDescriptor(map);
0568                }
0569            }
0570
0571            static <T> Descriptor makeDescriptor(OpenType<T> openType,
0572                    T defaultValue, Set<T> legalValues, Comparable<T> minValue,
0573                    Comparable<T> maxValue) {
0574                T[] legals;
0575                if (legalValues == null)
0576                    legals = null;
0577                else {
0578                    legals = cast(new Object[legalValues.size()]);
0579                    legalValues.toArray(legals);
0580                }
0581                return makeDescriptor(openType, defaultValue, legals, minValue,
0582                        maxValue);
0583            }
0584
0585            static <T> T valueFrom(Descriptor d, String name,
0586                    OpenType<T> openType) {
0587                Object x = d.getFieldValue(name);
0588                if (x == null)
0589                    return null;
0590                try {
0591                    return convertFrom(x, openType);
0592                } catch (Exception e) {
0593                    final String msg = "Cannot convert descriptor field "
0594                            + name + "  to " + openType.getTypeName();
0595                    throw EnvHelp.initCause(new IllegalArgumentException(msg),
0596                            e);
0597                }
0598            }
0599
0600            static <T> Set<T> valuesFrom(Descriptor d, String name,
0601                    OpenType<T> openType) {
0602                Object x = d.getFieldValue(name);
0603                if (x == null)
0604                    return null;
0605                Collection<?> coll;
0606                if (x instanceof  Set<?>) {
0607                    Set<?> set = (Set<?>) x;
0608                    boolean asis = true;
0609                    for (Object element : set) {
0610                        if (!openType.isValue(element)) {
0611                            asis = false;
0612                            break;
0613                        }
0614                    }
0615                    if (asis)
0616                        return cast(set);
0617                    coll = set;
0618                } else if (x instanceof  Object[]) {
0619                    coll = Arrays.asList((Object[]) x);
0620                } else {
0621                    final String msg = "Descriptor value for " + name
0622                            + " must be a Set or " + "an array: "
0623                            + x.getClass().getName();
0624                    throw new IllegalArgumentException(msg);
0625                }
0626
0627                Set<T> result = new HashSet<T>();
0628                for (Object element : coll)
0629                    result.add(convertFrom(element, openType));
0630                return result;
0631            }
0632
0633            static <T> Comparable comparableValueFrom(Descriptor d,
0634                    String name, OpenType<T> openType) {
0635                T t = valueFrom(d, name, openType);
0636                if (t == null || t instanceof  Comparable<?>)
0637                    return (Comparable) t;
0638                final String msg = "Descriptor field " + name + " with value "
0639                        + t + " is not Comparable";
0640                throw new IllegalArgumentException(msg);
0641            }
0642
0643            private static <T> T convertFrom(Object x, OpenType<T> openType) {
0644                if (openType.isValue(x)) {
0645                    T t = OpenMBeanAttributeInfoSupport.<T> cast(x);
0646                    return t;
0647                }
0648                return convertFromStrings(x, openType);
0649            }
0650
0651            private static <T> T convertFromStrings(Object x,
0652                    OpenType<T> openType) {
0653                if (openType instanceof  ArrayType<?>)
0654                    return convertFromStringArray(x, openType);
0655                else if (x instanceof  String)
0656                    return convertFromString((String) x, openType);
0657                final String msg = "Cannot convert value " + x + " of type "
0658                        + x.getClass().getName() + " to type "
0659                        + openType.getTypeName();
0660                throw new IllegalArgumentException(msg);
0661            }
0662
0663            private static <T> T convertFromString(String s,
0664                    OpenType<T> openType) {
0665                Class<T> c;
0666                try {
0667                    c = cast(Class.forName(openType.getClassName()));
0668                } catch (ClassNotFoundException e) {
0669                    throw new NoClassDefFoundError(e.toString()); // can't happen
0670                }
0671
0672                // Look for: public static T valueOf(String)
0673                Method valueOf;
0674                try {
0675                    valueOf = c.getMethod("valueOf", String.class);
0676                    if (!Modifier.isStatic(valueOf.getModifiers())
0677                            || valueOf.getReturnType() != c)
0678                        valueOf = null;
0679                } catch (NoSuchMethodException e) {
0680                    valueOf = null;
0681                }
0682                if (valueOf != null) {
0683                    try {
0684                        return c.cast(valueOf.invoke(null, s));
0685                    } catch (Exception e) {
0686                        final String msg = "Could not convert \"" + s
0687                                + "\" using method: " + valueOf;
0688                        throw new IllegalArgumentException(msg);
0689                    }
0690                }
0691
0692                // Look for: public T(String)
0693                Constructor<T> con;
0694                try {
0695                    con = c.getConstructor(String.class);
0696                } catch (NoSuchMethodException e) {
0697                    con = null;
0698                }
0699                if (con != null) {
0700                    try {
0701                        return con.newInstance(s);
0702                    } catch (Exception e) {
0703                        final String msg = "Could not convert \"" + s
0704                                + "\" using constructor: " + con;
0705                        throw new IllegalArgumentException(msg);
0706                    }
0707                }
0708
0709                throw new IllegalArgumentException("Don't know how to convert "
0710                        + "string to " + openType.getTypeName());
0711            }
0712
0713            /* A Descriptor contained an array value encoded as Strings.  The
0714               Strings must be organized in an array corresponding to the desired
0715               array.  If the desired array has n dimensions, so must the String
0716               array.  We will convert element by element from String to desired
0717               component type. */
0718            private static <T> T convertFromStringArray(Object x,
0719                    OpenType<T> openType) {
0720                ArrayType<?> arrayType = (ArrayType<?>) openType;
0721                OpenType<?> baseType = arrayType.getElementOpenType();
0722                int dim = arrayType.getDimension();
0723                String squareBrackets = "[";
0724                for (int i = 1; i < dim; i++)
0725                    squareBrackets += "[";
0726                Class<?> stringArrayClass;
0727                Class<?> targetArrayClass;
0728                try {
0729                    stringArrayClass = Class.forName(squareBrackets
0730                            + "Ljava.lang.String;");
0731                    targetArrayClass = Class.forName(squareBrackets + "L"
0732                            + baseType.getClassName() + ";");
0733                } catch (ClassNotFoundException e) {
0734                    throw new NoClassDefFoundError(e.toString()); // can't happen
0735                }
0736                if (!stringArrayClass.isInstance(x)) {
0737                    final String msg = "Value for " + dim
0738                            + "-dimensional array of " + baseType.getTypeName()
0739                            + " must be same type or a String "
0740                            + "array with same dimensions";
0741                    throw new IllegalArgumentException(msg);
0742                }
0743                Class<?> targetComponentClass = targetArrayClass
0744                        .getComponentType();
0745                OpenType<?> componentOpenType;
0746                if (dim == 1)
0747                    componentOpenType = baseType;
0748                else {
0749                    try {
0750                        componentOpenType = new ArrayType<T>(dim - 1, baseType);
0751                    } catch (OpenDataException e) {
0752                        throw new IllegalArgumentException(e.getMessage(), e);
0753                        // can't happen
0754                    }
0755                }
0756                int n = Array.getLength(x);
0757                Object[] targetArray = (Object[]) Array.newInstance(
0758                        targetArrayClass.getComponentType(), n);
0759                for (int i = 0; i < n; i++) {
0760                    Object stringish = Array.get(x, i); // String or String[] etc
0761                    Object converted = convertFromStrings(stringish,
0762                            componentOpenType);
0763                    Array.set(targetArray, i, converted);
0764                }
0765                return OpenMBeanAttributeInfoSupport.<T> cast(targetArray);
0766            }
0767
0768            @SuppressWarnings("unchecked")
0769            static <T> T cast(Object x) {
0770                return (T) x;
0771            }
0772
0773            /**
0774             * Returns the open type for the values of the attribute described
0775             * by this {@code OpenMBeanAttributeInfoSupport} instance.
0776             */
0777            public OpenType<?> getOpenType() {
0778                return openType;
0779            }
0780
0781            /**
0782             * Returns the default value for the attribute described by this
0783             * {@code OpenMBeanAttributeInfoSupport} instance, if specified,
0784             * or {@code null} otherwise.
0785             */
0786            public Object getDefaultValue() {
0787
0788                // Special case for ArrayType and TabularType
0789                // [JF] TODO: clone it so that it cannot be altered,
0790                // [JF] TODO: if we decide to support defaultValue as an array itself.
0791                // [JF] As of today (oct 2000) it is not supported so
0792                // defaultValue is null for arrays. Nothing to do.
0793
0794                return defaultValue;
0795            }
0796
0797            /**
0798             * Returns an unmodifiable Set of legal values for the attribute
0799             * described by this {@code OpenMBeanAttributeInfoSupport}
0800             * instance, if specified, or {@code null} otherwise.
0801             */
0802            public Set<?> getLegalValues() {
0803
0804                // Special case for ArrayType and TabularType
0805                // [JF] TODO: clone values so that they cannot be altered,
0806                // [JF] TODO: if we decide to support LegalValues as an array itself.
0807                // [JF] As of today (oct 2000) it is not supported so
0808                // legalValues is null for arrays. Nothing to do.
0809
0810                // Returns our legalValues Set (set was constructed unmodifiable)
0811                return (legalValues);
0812            }
0813
0814            /**
0815             * Returns the minimal value for the attribute described by this
0816             * {@code OpenMBeanAttributeInfoSupport} instance, if specified,
0817             * or {@code null} otherwise.
0818             */
0819            public Comparable<?> getMinValue() {
0820
0821                // Note: only comparable values have a minValue,
0822                // so that's not the case of arrays and tabulars (always null).
0823
0824                return minValue;
0825            }
0826
0827            /**
0828             * Returns the maximal value for the attribute described by this
0829             * {@code OpenMBeanAttributeInfoSupport} instance, if specified,
0830             * or {@code null} otherwise.
0831             */
0832            public Comparable<?> getMaxValue() {
0833
0834                // Note: only comparable values have a maxValue,
0835                // so that's not the case of arrays and tabulars (always null).
0836
0837                return maxValue;
0838            }
0839
0840            /**
0841             * Returns {@code true} if this {@code
0842             * OpenMBeanAttributeInfoSupport} instance specifies a non-null
0843             * default value for the described attribute, {@code false}
0844             * otherwise.
0845             */
0846            public boolean hasDefaultValue() {
0847
0848                return (defaultValue != null);
0849            }
0850
0851            /**
0852             * Returns {@code true} if this {@code
0853             * OpenMBeanAttributeInfoSupport} instance specifies a non-null
0854             * set of legal values for the described attribute, {@code false}
0855             * otherwise.
0856             */
0857            public boolean hasLegalValues() {
0858
0859                return (legalValues != null);
0860            }
0861
0862            /**
0863             * Returns {@code true} if this {@code
0864             * OpenMBeanAttributeInfoSupport} instance specifies a non-null
0865             * minimal value for the described attribute, {@code false}
0866             * otherwise.
0867             */
0868            public boolean hasMinValue() {
0869
0870                return (minValue != null);
0871            }
0872
0873            /**
0874             * Returns {@code true} if this {@code
0875             * OpenMBeanAttributeInfoSupport} instance specifies a non-null
0876             * maximal value for the described attribute, {@code false}
0877             * otherwise.
0878             */
0879            public boolean hasMaxValue() {
0880
0881                return (maxValue != null);
0882            }
0883
0884            /**
0885             * Tests whether {@code obj} is a valid value for the attribute
0886             * described by this {@code OpenMBeanAttributeInfoSupport}
0887             * instance.
0888             *
0889             * @param obj the object to be tested.
0890             *
0891             * @return {@code true} if {@code obj} is a valid value for
0892             * the parameter described by this {@code
0893             * OpenMBeanAttributeInfoSupport} instance, {@code false}
0894             * otherwise.
0895             */
0896            public boolean isValue(Object obj) {
0897                return isValue(this , obj);
0898            }
0899
0900            @SuppressWarnings("unchecked")
0901            // cast to Comparable
0902            static boolean isValue(OpenMBeanParameterInfo info, Object obj) {
0903                if (info.hasDefaultValue() && obj == null)
0904                    return true;
0905                return info.getOpenType().isValue(obj)
0906                        && (!info.hasLegalValues() || info.getLegalValues()
0907                                .contains(obj))
0908                        && (!info.hasMinValue() || ((Comparable) info
0909                                .getMinValue()).compareTo(obj) <= 0)
0910                        && (!info.hasMaxValue() || ((Comparable) info
0911                                .getMaxValue()).compareTo(obj) >= 0);
0912            }
0913
0914            /* ***  Commodity methods from java.lang.Object  *** */
0915
0916            /**
0917             * Compares the specified {@code obj} parameter with this {@code
0918             * OpenMBeanAttributeInfoSupport} instance for equality.
0919             * <p>
0920             * Returns {@code true} if and only if all of the following statements are true:
0921             * <ul>
0922             * <li>{@code obj} is non null,</li>
0923             * <li>{@code obj} also implements the {@code OpenMBeanAttributeInfo} interface,</li>
0924             * <li>their names are equal</li>
0925             * <li>their open types are equal</li>
0926             * <li>their access properties (isReadable, isWritable and isIs) are equal</li>
0927             * <li>their default, min, max and legal values are equal.</li>
0928             * </ul>
0929             * This ensures that this {@code equals} method works properly for
0930             * {@code obj} parameters which are different implementations of
0931             * the {@code OpenMBeanAttributeInfo} interface.
0932             *
0933             * <p>If {@code obj} also implements {@link DescriptorRead}, then its
0934             * {@link DescriptorRead#getDescriptor() getDescriptor()} method must
0935             * also return the same value as for this object.</p>
0936             *
0937             * @param obj the object to be compared for equality with this
0938             * {@code OpenMBeanAttributeInfoSupport} instance.
0939             *
0940             * @return {@code true} if the specified object is equal to this
0941             * {@code OpenMBeanAttributeInfoSupport} instance.
0942             */
0943            public boolean equals(Object obj) {
0944                if (!(obj instanceof  OpenMBeanAttributeInfo))
0945                    return false;
0946
0947                OpenMBeanAttributeInfo other = (OpenMBeanAttributeInfo) obj;
0948
0949                return this .isReadable() == other.isReadable()
0950                        && this .isWritable() == other.isWritable()
0951                        && this .isIs() == other.isIs() && equal(this , other);
0952            }
0953
0954            static boolean equal(OpenMBeanParameterInfo x1,
0955                    OpenMBeanParameterInfo x2) {
0956                if (x1 instanceof  DescriptorRead) {
0957                    if (!(x2 instanceof  DescriptorRead))
0958                        return false;
0959                    Descriptor d1 = ((DescriptorRead) x1).getDescriptor();
0960                    Descriptor d2 = ((DescriptorRead) x2).getDescriptor();
0961                    if (!d1.equals(d2))
0962                        return false;
0963                } else if (x2 instanceof  DescriptorRead)
0964                    return false;
0965
0966                return x1.getName().equals(x2.getName())
0967                        && x1.getOpenType().equals(x2.getOpenType())
0968                        && (x1.hasDefaultValue() ? x1.getDefaultValue().equals(
0969                                x2.getDefaultValue()) : !x2.hasDefaultValue())
0970                        && (x1.hasMinValue() ? x1.getMinValue().equals(
0971                                x2.getMinValue()) : !x2.hasMinValue())
0972                        && (x1.hasMaxValue() ? x1.getMaxValue().equals(
0973                                x2.getMaxValue()) : !x2.hasMaxValue())
0974                        && (x1.hasLegalValues() ? x1.getLegalValues().equals(
0975                                x2.getLegalValues()) : !x2.hasLegalValues());
0976            }
0977
0978            /**
0979             * <p>Returns the hash code value for this {@code
0980             * OpenMBeanAttributeInfoSupport} instance.</p>
0981             *
0982             * <p>The hash code of an {@code OpenMBeanAttributeInfoSupport}
0983             * instance is the sum of the hash codes of all elements of
0984             * information used in {@code equals} comparisons (ie: its name,
0985             * its <i>open type</i>, its default, min, max and legal
0986             * values, and its Descriptor).
0987             *
0988             * <p>This ensures that {@code t1.equals(t2)} implies that {@code
0989             * t1.hashCode()==t2.hashCode()} for any two {@code
0990             * OpenMBeanAttributeInfoSupport} instances {@code t1} and {@code
0991             * t2}, as required by the general contract of the method {@link
0992             * Object#hashCode() Object.hashCode()}.
0993             *
0994             * <p>However, note that another instance of a class implementing
0995             * the {@code OpenMBeanAttributeInfo} interface may be equal to
0996             * this {@code OpenMBeanAttributeInfoSupport} instance as defined
0997             * by {@link #equals(java.lang.Object)}, but may have a different
0998             * hash code if it is calculated differently.
0999             *
1000             * <p>As {@code OpenMBeanAttributeInfoSupport} instances are
1001             * immutable, the hash code for this instance is calculated once,
1002             * on the first call to {@code hashCode}, and then the same value
1003             * is returned for subsequent calls.
1004             *
1005             * @return the hash code value for this {@code
1006             * OpenMBeanAttributeInfoSupport} instance
1007             */
1008            public int hashCode() {
1009
1010                // Calculate the hash code value if it has not yet been done
1011                // (ie 1st call to hashCode())
1012                //
1013                if (myHashCode == null)
1014                    myHashCode = hashCode(this );
1015
1016                // return always the same hash code for this instance (immutable)
1017                //
1018                return myHashCode.intValue();
1019            }
1020
1021            static int hashCode(OpenMBeanParameterInfo info) {
1022                int value = 0;
1023                value += info.getName().hashCode();
1024                value += info.getOpenType().hashCode();
1025                if (info.hasDefaultValue())
1026                    value += info.getDefaultValue().hashCode();
1027                if (info.hasMinValue())
1028                    value += info.getMinValue().hashCode();
1029                if (info.hasMaxValue())
1030                    value += info.getMaxValue().hashCode();
1031                if (info.hasLegalValues())
1032                    value += info.getLegalValues().hashCode();
1033                if (info instanceof  DescriptorRead)
1034                    value += ((DescriptorRead) info).getDescriptor().hashCode();
1035                return value;
1036            }
1037
1038            /**
1039             * Returns a string representation of this
1040             * {@code OpenMBeanAttributeInfoSupport} instance.
1041             * <p>
1042             * The string representation consists of the name of this class (i.e.
1043             * {@code javax.management.openmbean.OpenMBeanAttributeInfoSupport}),
1044             * the string representation of the name and open type of the
1045             * described parameter, the string representation of its
1046             * default, min, max and legal values and the string
1047             * representation of its descriptor.
1048             *
1049             * <p>As {@code OpenMBeanAttributeInfoSupport} instances are
1050             * immutable, the string representation for this instance is
1051             * calculated once, on the first call to {@code toString}, and
1052             * then the same value is returned for subsequent calls.
1053             *
1054             * @return a string representation of this
1055             * {@code OpenMBeanAttributeInfoSupport} instance.
1056             */
1057            public String toString() {
1058
1059                // Calculate the string value if it has not yet been done
1060                // (ie 1st call to toString())
1061                //
1062                if (myToString == null)
1063                    myToString = toString(this );
1064
1065                // return always the same string representation for this
1066                // instance (immutable)
1067                //
1068                return myToString;
1069            }
1070
1071            static String toString(OpenMBeanParameterInfo info) {
1072                Descriptor d = (info instanceof  DescriptorRead) ? ((DescriptorRead) info)
1073                        .getDescriptor()
1074                        : null;
1075                return info.getClass().getName() + "(name=" + info.getName()
1076                        + ",openType=" + info.getOpenType() + ",default="
1077                        + info.getDefaultValue() + ",minValue="
1078                        + info.getMinValue() + ",maxValue="
1079                        + info.getMaxValue() + ",legalValues="
1080                        + info.getLegalValues()
1081                        + ((d == null) ? "" : ",descriptor=" + d) + ")";
1082            }
1083        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.