001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package javax.management.openmbean;
023:
024: import java.io.IOException;
025: import java.io.ObjectInputStream;
026: import java.io.ObjectStreamField;
027: import java.io.Serializable;
028: import java.io.StreamCorruptedException;
029: import java.math.BigDecimal;
030: import java.math.BigInteger;
031: import java.util.Date;
032:
033: import javax.management.ObjectName;
034:
035: import org.jboss.mx.util.MetaDataUtil;
036:
037: /**
038: * A parent for all classes describing open types of open data values.
039: *
040: * @author <a href="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>
041: * @version $Revision: 57200 $
042: */
043: public abstract class OpenType implements Serializable {
044: // Constants -----------------------------------------------------------------
045:
046: private static final long serialVersionUID = -9195195325186646468L;
047: private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[] {
048: new ObjectStreamField("className", String.class),
049: new ObjectStreamField("description", String.class),
050: new ObjectStreamField("typeName", String.class) };
051:
052: // Attributes ----------------------------------------------------
053:
054: /**
055: * The open type's class name
056: */
057: private String className;
058:
059: /**
060: * The type's description
061: */
062: private String description;
063:
064: /**
065: * The type's name
066: */
067: private String typeName;
068:
069: /**
070: * Whether the class is an array
071: */
072: private transient boolean array = false;
073:
074: // Static --------------------------------------------------------
075:
076: /**
077: * The allowed classnames.<p>
078: *
079: * One of<br>
080: * java.lang.Void<br>
081: * java.lang.Boolean<br>
082: * java.lang.Character<br>
083: * java.lang.Byte<br>
084: * java.lang.Short<br>
085: * java.lang.Integer<br>
086: * java.lang.Long<br>
087: * java.lang.Float<br>
088: * java.lang.Double<br>
089: * java.lang.String<br>
090: * java.lang.Date<br>
091: * java.math.BigDecimal<br>
092: * java.math.BigInteger<br>
093: * javax.management.ObjectName<br>
094: * {@link CompositeData}.class.getName()<br>
095: * {@link TabularData}.class.getName()
096: */
097: public static final String[] ALLOWED_CLASSNAMES = {
098: Void.class.getName(), Boolean.class.getName(),
099: Character.class.getName(), Byte.class.getName(),
100: Short.class.getName(), Integer.class.getName(),
101: Long.class.getName(), Float.class.getName(),
102: Double.class.getName(), String.class.getName(),
103: Date.class.getName(), BigDecimal.class.getName(),
104: BigInteger.class.getName(), ObjectName.class.getName(),
105: CompositeData.class.getName(), TabularData.class.getName() };
106:
107: // Constructors --------------------------------------------------
108:
109: /**
110: * Construct an OpenType.<p>
111: *
112: * The class name must be in {@link #ALLOWED_CLASSNAMES} or an
113: * array of those classes.
114: *
115: * @param className the name of the class implementing the open type,
116: * cannot be null
117: * @param typeName the name of the open type, cannot be null
118: * @param description the human readable description of the type, cannot
119: * be null
120: * @exception OpenDataException when class name is not allowed class
121: * @exception IllegalArgumentException for a null argument
122: */
123: protected OpenType(String className, String typeName,
124: String description) throws OpenDataException {
125: init(className, typeName, description);
126: }
127:
128: // Public --------------------------------------------------------
129:
130: /**
131: * Retrieve the class name of the open data values of this open data
132: * type. It is one of those listed in ALLOWED_CLASSNAMES or
133: * a (multi-dimensional) array of one of those classes.
134: *
135: * @return the class name
136: */
137: public String getClassName() {
138: return className;
139: }
140:
141: /**
142: * Retrieve the name of the open data type
143: *
144: * @return the type name
145: */
146: public String getTypeName() {
147: return typeName;
148: }
149:
150: /**
151: * Retrieve the description of the type
152: *
153: * @return the description
154: */
155: public String getDescription() {
156: return description;
157: }
158:
159: /**
160: * Retrieve whether the class name of the type is an array
161: *
162: * @return true when it is an array or false otherwise
163: */
164: public boolean isArray() {
165: return array;
166: }
167:
168: /**
169: * Whether the passed value is one of those described by this open type.
170: *
171: * @param obj the object to test
172: * @return true when it is value for this open type, false otherwise
173: */
174: public abstract boolean isValue(Object obj);
175:
176: // Serializable Implementation -----------------------------------
177:
178: private void readObject(ObjectInputStream in) throws IOException,
179: ClassNotFoundException {
180: ObjectInputStream.GetField getField = in.readFields();
181: String className = (String) getField.get("className", null);
182: String typeName = (String) getField.get("typeName", null);
183: String description = (String) getField.get("description", null);
184: try {
185: init(className, typeName, description);
186: } catch (Exception e) {
187: throw new StreamCorruptedException(e.toString());
188: }
189: }
190:
191: // Object Overrides ----------------------------------------------
192:
193: /**
194: * Compares two object types for equality
195: *
196: * @return obj the object to test with this one
197: * @return true when they are equal, false otherwise
198: */
199: public abstract boolean equals(Object obj);
200:
201: /**
202: * Retrieve the hashCode for this OpenType
203: *
204: * @return the hash code
205: */
206: public abstract int hashCode();
207:
208: /**
209: * Retrieve a string representation of this open type
210: *
211: * @return the string representation
212: */
213: public abstract String toString();
214:
215: // Private -------------------------------------------------------
216:
217: /**
218: * Initialise the object
219: *
220: * @param className the name of the class implementing the open type,
221: * cannot be null or an empty
222: * @param typeName the name of the open type, cannot be null or an empty
223: * string
224: * @param description the human readable description of the type, cannot
225: * be null or an empty string
226: * @exception OpenDataException when class name is not allowed class
227: * @exception IllegalArgumentException for a null or empty argument
228: */
229: private void init(String className, String typeName,
230: String description) throws OpenDataException {
231: if (className == null || className.trim().equals(""))
232: throw new IllegalArgumentException(
233: "null or empty class name");
234: if (typeName == null || typeName.trim().equals(""))
235: throw new IllegalArgumentException(
236: "null or empty type name");
237: if (description == null || description.trim().equals(""))
238: throw new IllegalArgumentException(
239: "null or empty description");
240:
241: // Calculate the underlying class and whether this is an array
242: String testClassName = MetaDataUtil.getBaseClassName(className);
243: if (testClassName == null)
244: throw new OpenDataException(
245: "Invalid array declaration (see the javadocs for java.lang.Class): "
246: + className);
247: if (testClassName.equals(className) == false)
248: array = true;
249:
250: // Check the underlying class
251: boolean ok = false;
252: for (int i = 0; i < ALLOWED_CLASSNAMES.length; i++)
253: if (testClassName.equals(ALLOWED_CLASSNAMES[i])) {
254: ok = true;
255: break;
256: }
257: if (ok == false)
258: throw new OpenDataException(
259: "Not an OpenType allowed class name: " + className);
260:
261: // Looks ok
262: this.className = className;
263: this.typeName = typeName;
264: this.description = description;
265: }
266: }
|