View Javadoc
1   /*
2    * Copyright (c) 2004, 2012, 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.io.Serializable;
29  import java.util.*;
30  import javax.management.openmbean.CompositeData;
31  import javax.management.openmbean.CompositeType;
32  import javax.management.openmbean.OpenType;
33  import javax.management.openmbean.TabularType;
34  
35  /**
36   * This abstract class provides the implementation of the CompositeData
37   * interface.  A CompositeData object will be lazily created only when
38   * the CompositeData interface is used.
39   *
40   * Classes that extends this abstract class will implement the
41   * getCompositeData() method. The object returned by the
42   * getCompositeData() is an instance of CompositeData such that
43   * the instance serializes itself as the type CompositeDataSupport.
44   */
45  public abstract class LazyCompositeData
46          implements CompositeData, Serializable {
47  
48      private CompositeData compositeData;
49  
50      // Implementation of the CompositeData interface
51      public boolean containsKey(String key) {
52          return compositeData().containsKey(key);
53      }
54  
55      public boolean containsValue(Object value) {
56          return compositeData().containsValue(value);
57      }
58  
59      public boolean equals(Object obj) {
60          return compositeData().equals(obj);
61      }
62  
63      public Object get(String key) {
64          return compositeData().get(key);
65      }
66  
67      public Object[] getAll(String[] keys) {
68          return compositeData().getAll(keys);
69      }
70  
71      public CompositeType getCompositeType() {
72          return compositeData().getCompositeType();
73      }
74  
75      public int hashCode() {
76          return compositeData().hashCode();
77      }
78  
79      public String toString() {
80          /** FIXME: What should this be?? */
81          return compositeData().toString();
82      }
83  
84      public Collection<?> values() {
85          return compositeData().values();
86      }
87  
88      /* Lazy creation of a CompositeData object
89       * only when the CompositeData interface is used.
90       */
91      private synchronized CompositeData compositeData() {
92          if (compositeData != null)
93              return compositeData;
94          compositeData = getCompositeData();
95          return compositeData;
96      }
97  
98      /**
99       * Designate to a CompositeData object when writing to an
100      * output stream during serialization so that the receiver
101      * only requires JMX 1.2 classes but not any implementation
102      * specific class.
103      */
104     protected Object writeReplace() throws java.io.ObjectStreamException {
105         return compositeData();
106     }
107 
108     /**
109      * Returns the CompositeData representing this object.
110      * The returned CompositeData object must be an instance
111      * of javax.management.openmbean.CompositeDataSupport class
112      * so that no implementation specific class is required
113      * for unmarshalling besides JMX 1.2 classes.
114      */
115     protected abstract CompositeData getCompositeData();
116 
117     // Helper methods
118     static String getString(CompositeData cd, String itemName) {
119         if (cd == null)
120             throw new IllegalArgumentException("Null CompositeData");
121 
122         return (String) cd.get(itemName);
123     }
124 
125     static boolean getBoolean(CompositeData cd, String itemName) {
126         if (cd == null)
127             throw new IllegalArgumentException("Null CompositeData");
128 
129         return ((Boolean) cd.get(itemName)).booleanValue();
130     }
131 
132     static long getLong(CompositeData cd, String itemName) {
133         if (cd == null)
134             throw new IllegalArgumentException("Null CompositeData");
135 
136         return ((Long) cd.get(itemName)).longValue();
137     }
138 
139     static int getInt(CompositeData cd, String itemName) {
140         if (cd == null)
141             throw new IllegalArgumentException("Null CompositeData");
142 
143         return ((Integer) cd.get(itemName)).intValue();
144     }
145 
146     /**
147      * Compares two CompositeTypes and returns true if
148      * all items in type1 exist in type2 and their item types
149      * are the same.
150      */
151     protected static boolean isTypeMatched(CompositeType type1, CompositeType type2) {
152         if (type1 == type2) return true;
153 
154         // We can't use CompositeType.isValue() since it returns false
155         // if the type name doesn't match.
156         Set<String> allItems = type1.keySet();
157 
158         // Check all items in the type1 exist in type2
159         if (!type2.keySet().containsAll(allItems))
160             return false;
161 
162         for (String item: allItems) {
163             OpenType<?> ot1 = type1.getType(item);
164             OpenType<?> ot2 = type2.getType(item);
165             if (ot1 instanceof CompositeType) {
166                 if (! (ot2 instanceof CompositeType))
167                     return false;
168                 if (!isTypeMatched((CompositeType) ot1, (CompositeType) ot2))
169                     return false;
170             } else if (ot1 instanceof TabularType) {
171                 if (! (ot2 instanceof TabularType))
172                     return false;
173                 if (!isTypeMatched((TabularType) ot1, (TabularType) ot2))
174                     return false;
175             } else if (!ot1.equals(ot2)) {
176                 return false;
177             }
178         }
179         return true;
180     }
181 
182     protected static boolean isTypeMatched(TabularType type1, TabularType type2) {
183         if (type1 == type2) return true;
184 
185         List<String> list1 = type1.getIndexNames();
186         List<String> list2 = type2.getIndexNames();
187 
188         // check if the list of index names are the same
189         if (!list1.equals(list2))
190             return false;
191 
192         return isTypeMatched(type1.getRowType(), type2.getRowType());
193     }
194 
195     private static final long serialVersionUID = -2190411934472666714L;
196 }