001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.gbean;
017:
018: import java.io.IOException;
019: import java.io.ObjectInputStream;
020: import java.io.Serializable;
021: import java.lang.reflect.Method;
022: import java.util.ArrayList;
023: import java.util.Arrays;
024: import java.util.Collection;
025: import java.util.Collections;
026: import java.util.HashMap;
027: import java.util.HashSet;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Map;
031: import java.util.Set;
032:
033: import org.apache.geronimo.kernel.management.NotificationType;
034:
035: /**
036: * Describes a GBean. This class should never be constructed directly. Insted use GBeanInfoBuilder.
037: *
038: * @version $Rev: 564608 $ $Date: 2007-08-10 07:43:14 -0700 (Fri, 10 Aug 2007) $
039: */
040: public final class GBeanInfo implements Serializable {
041: private static final long serialVersionUID = -6198804067155550221L;
042:
043: public static final int PRIORITY_CLASSLOADER = 1;
044: public static final int PRIORITY_NORMAL = 5;
045:
046: private static final Set DEFAULT_NOTIFICATIONS = Collections
047: .unmodifiableSet(new HashSet(Arrays
048: .asList(NotificationType.TYPES)));
049:
050: /**
051: * Static helper to try to get the GBeanInfo from the class supplied.
052: *
053: * @param className name of the class to get the GBeanInfo from
054: * @param classLoader the class loader use to load the specifiec class
055: * @return GBeanInfo generated by supplied class
056: * @throws InvalidConfigurationException
057: * if there is a problem getting the GBeanInfo from the class
058: */
059: public static GBeanInfo getGBeanInfo(String className,
060: ClassLoader classLoader)
061: throws InvalidConfigurationException {
062: Class clazz;
063: try {
064: clazz = classLoader.loadClass(className);
065: } catch (ClassNotFoundException e) {
066: throw new InvalidConfigurationException(
067: "Could not load class " + className, e);
068: } catch (NoClassDefFoundError e) {
069: throw new InvalidConfigurationException(
070: "Could not load class " + className, e);
071: }
072: Method method;
073: try {
074: method = clazz.getDeclaredMethod("getGBeanInfo",
075: new Class[] {});
076: } catch (NoSuchMethodException e) {
077: try {
078: // try to get the info from ${className}GBean
079: clazz = classLoader.loadClass(className + "GBean");
080: method = clazz.getDeclaredMethod("getGBeanInfo",
081: new Class[] {});
082: } catch (Exception ignored) {
083: throw new InvalidConfigurationException(
084: "Class does not have a getGBeanInfo() method: "
085: + className);
086: }
087: } catch (NoClassDefFoundError e) {
088: String message = e.getMessage();
089: StringBuffer buf = new StringBuffer(
090: "Could not load gbean class ").append(className)
091: .append(" due to NoClassDefFoundError\n");
092: if (message != null) {
093: message = message.replace('/', '.');
094: buf.append(" problematic class ").append(message);
095: try {
096: Class hardToLoad = classLoader.loadClass(message);
097: buf.append(
098: " can be loaded in supplied classloader ")
099: .append(classLoader).append("\n");
100: buf.append(" and is found in ").append(
101: hardToLoad.getClassLoader());
102: } catch (ClassNotFoundException e1) {
103: buf
104: .append(
105: " cannot be loaded in supplied classloader ")
106: .append(classLoader).append("\n");
107: }
108: }
109: throw new InvalidConfigurationException(buf.toString(), e);
110: }
111: try {
112: return (GBeanInfo) method.invoke(null, new Object[] {});
113: } catch (Exception e) {
114: throw new InvalidConfigurationException(
115: "Could not get GBeanInfo from class: " + className,
116: e);
117: }
118: }
119:
120: private final String sourceClass;
121: private final String name;
122: private final String className;
123: private final String j2eeType;
124: private final Set<GAttributeInfo> attributes;
125: private final Map attributesByName;
126: private final GConstructorInfo constructor;
127: private final Set operations;
128: private final Set notifications;
129: private final Set references;
130: private final Map referencesByName;
131: private final Set interfaces;
132: private int priority;
133:
134: /**
135: * @deprecated use GBeanInfoBuilder
136: */
137: public GBeanInfo(String name, String className, String j2eeType,
138: Collection attributes, GConstructorInfo constructor,
139: Collection operations, Set references, Set interfaces) {
140: this (null, name, className, j2eeType, attributes, constructor,
141: operations, references, interfaces,
142: DEFAULT_NOTIFICATIONS, PRIORITY_NORMAL);
143: }
144:
145: /**
146: * @deprecated use GBeanInfoBuilder
147: */
148: public GBeanInfo(String className, String j2eeType,
149: Collection attributes, GConstructorInfo constructor,
150: Collection operations, Set references, Set interfaces) {
151: this (null, className, className, j2eeType, attributes,
152: constructor, operations, references, interfaces,
153: DEFAULT_NOTIFICATIONS, PRIORITY_NORMAL);
154: }
155:
156: /**
157: * @deprecated use GBeanInfoBuilder
158: */
159: public GBeanInfo(String className, String j2eeType,
160: Collection attributes, GConstructorInfo constructor,
161: Collection operations, Set references, Set interfaces,
162: Set notifications) {
163: this (null, className, className, j2eeType, attributes,
164: constructor, operations, references, interfaces,
165: notifications, PRIORITY_NORMAL);
166: }
167:
168: /**
169: * @deprecated use GBeanInfoBuilder
170: */
171: public GBeanInfo(String name, String className, String j2eeType,
172: Collection attributes, GConstructorInfo constructor,
173: Collection operations, Set references, Set interfaces,
174: Set notifications) {
175: this (null, name, className, j2eeType, attributes, constructor,
176: operations, references, interfaces, notifications,
177: PRIORITY_NORMAL);
178: }
179:
180: GBeanInfo(String sourceClass, String name, String className,
181: String j2eeType, Collection attributes,
182: GConstructorInfo constructor, Collection operations,
183: Set references, Set interfaces, int priority) {
184: this (sourceClass, name, className, j2eeType, attributes,
185: constructor, operations, references, interfaces,
186: DEFAULT_NOTIFICATIONS, priority);
187: }
188:
189: GBeanInfo(String sourceClass, String name, String className,
190: String j2eeType, Collection attributes,
191: GConstructorInfo constructor, Collection operations,
192: Set references, Set interfaces, Set notifications,
193: int priority) {
194: this .sourceClass = sourceClass;
195: this .name = name;
196: this .className = className;
197: this .j2eeType = j2eeType;
198: if (attributes == null) {
199: this .attributes = Collections.EMPTY_SET;
200: this .attributesByName = Collections.EMPTY_MAP;
201: } else {
202: Map map = new HashMap();
203: for (Iterator iterator = attributes.iterator(); iterator
204: .hasNext();) {
205: GAttributeInfo attribute = (GAttributeInfo) iterator
206: .next();
207: map.put(attribute.getName(), attribute);
208: }
209: this .attributesByName = Collections.unmodifiableMap(map);
210: this .attributes = Collections.unmodifiableSet(new HashSet(
211: map.values()));
212: }
213: if (constructor == null) {
214: this .constructor = new GConstructorInfo(
215: Collections.EMPTY_LIST);
216: } else {
217: this .constructor = constructor;
218: }
219: if (operations == null) {
220: this .operations = Collections.EMPTY_SET;
221: } else {
222: this .operations = Collections.unmodifiableSet(new HashSet(
223: operations));
224: }
225: if (references == null) {
226: this .references = Collections.EMPTY_SET;
227: this .referencesByName = Collections.EMPTY_MAP;
228: } else {
229: Map map = new HashMap();
230: for (Iterator iterator = references.iterator(); iterator
231: .hasNext();) {
232: GReferenceInfo reference = (GReferenceInfo) iterator
233: .next();
234: map.put(reference.getName(), reference);
235: }
236: this .referencesByName = Collections.unmodifiableMap(map);
237: this .references = Collections.unmodifiableSet(new HashSet(
238: references));
239: }
240: if (interfaces == null) {
241: this .interfaces = Collections.EMPTY_SET;
242: } else {
243: this .interfaces = Collections.unmodifiableSet(new HashSet(
244: interfaces));
245: }
246: if (notifications == null) {
247: this .notifications = Collections.EMPTY_SET;
248: } else {
249: this .notifications = Collections
250: .unmodifiableSet(new HashSet(notifications));
251: }
252: this .priority = priority;
253: }
254:
255: /**
256: * Gets the source class from which this GBeanInfo can be retrieved using GBeanInfo.getGBeanInfo(className, classLoader).
257: * A null source class means the gbean info was dynamically generated.
258: *
259: * @return the source of this GBeanInfo, or null if it was dynamically generated
260: */
261: public String getSourceClass() {
262: return sourceClass;
263: }
264:
265: public String getName() {
266: return name;
267: }
268:
269: public String getClassName() {
270: return className;
271: }
272:
273: public String getJ2eeType() {
274: return j2eeType;
275: }
276:
277: /**
278: * Gets the info for the specified attribute, or null if there is no such
279: * attribute. Note that the attribute may have a getter or setter or both;
280: * being an attribute does not imply that both methods are available.
281: */
282: public GAttributeInfo getAttribute(String name) {
283: return (GAttributeInfo) attributesByName.get(name);
284: }
285:
286: /**
287: * Returns a Set where the elements are type GAttributeInfo
288: */
289: public Set<GAttributeInfo> getAttributes() {
290: return attributes;
291: }
292:
293: /**
294: * Returns a list where the elements are type GAttributeInfo
295: */
296: public List getPersistentAttributes() {
297: List attrs = new ArrayList();
298: for (Iterator i = attributes.iterator(); i.hasNext();) {
299: GAttributeInfo info = (GAttributeInfo) i.next();
300: if (info.isPersistent()) {
301: attrs.add(info);
302: }
303: }
304: return attrs;
305: }
306:
307: /**
308: * Returns a list where the elements are type GAttributeInfo
309: */
310: public List getManageableAttributes() {
311: List attrs = new ArrayList();
312: for (Iterator i = attributes.iterator(); i.hasNext();) {
313: GAttributeInfo info = (GAttributeInfo) i.next();
314: if (info.isManageable()) {
315: attrs.add(info);
316: }
317: }
318: return attrs;
319: }
320:
321: public GConstructorInfo getConstructor() {
322: return constructor;
323: }
324:
325: public Set getOperations() {
326: return operations;
327: }
328:
329: public Set getNotifications() {
330: return notifications;
331: }
332:
333: public Set getReferences() {
334: return references;
335: }
336:
337: public GReferenceInfo getReference(String name) {
338: return (GReferenceInfo) referencesByName.get(name);
339: }
340:
341: public Set getInterfaces() {
342: return interfaces;
343: }
344:
345: public int getPriority() {
346: return priority;
347: }
348:
349: private void readObject(ObjectInputStream in) throws IOException,
350: ClassNotFoundException {
351: priority = GBeanInfo.PRIORITY_NORMAL;
352: in.defaultReadObject();
353: }
354:
355: public String toString() {
356: StringBuffer result = new StringBuffer("[GBeanInfo:");
357: result.append(" id=").append(super .toString());
358: result.append(" sourceClass=").append(sourceClass);
359: result.append(" name=").append(name);
360: for (Iterator iterator = attributes.iterator(); iterator
361: .hasNext();) {
362: GAttributeInfo geronimoAttributeInfo = (GAttributeInfo) iterator
363: .next();
364: result.append("\n attribute: ").append(
365: geronimoAttributeInfo);
366: }
367: for (Iterator iterator = operations.iterator(); iterator
368: .hasNext();) {
369: GOperationInfo geronimoOperationInfo = (GOperationInfo) iterator
370: .next();
371: result.append("\n operation: ").append(
372: geronimoOperationInfo);
373: }
374: for (Iterator iterator = references.iterator(); iterator
375: .hasNext();) {
376: GReferenceInfo referenceInfo = (GReferenceInfo) iterator
377: .next();
378: result.append("\n reference: ").append(referenceInfo);
379: }
380: result.append("]");
381: return result.toString();
382: }
383:
384: public String toXML(AbstractName abstractName) {
385: StringBuilder xml = new StringBuilder();
386:
387: xml.append("<gBeanInfo ");
388: xml.append("id='" + super .toString() + "' ");
389: xml.append("sourceClass='" + sourceClass + "' ");
390: xml.append("name='" + name + "' ");
391: xml.append("className='" + className + "' ");
392: xml.append("type='" + j2eeType + "' ");
393: xml.append("priority='" + priority + "' ");
394: xml.append(">");
395:
396: xml.append("<attributes>");
397:
398: for (Iterator loop = attributes.iterator(); loop.hasNext();) {
399: xml.append(((GAttributeInfo) loop.next())
400: .toXML(abstractName));
401: }
402:
403: xml.append("</attributes>");
404:
405: xml.append(constructor.toXML());
406:
407: xml.append("<operations>");
408:
409: for (Iterator loop = operations.iterator(); loop.hasNext();) {
410: xml.append(((GOperationInfo) loop.next()).toXML());
411: }
412:
413: xml.append("</operations>");
414:
415: xml.append("<notifications>");
416:
417: // I had expected this to be a set of GNotification Objects
418: // but it was just strings
419: for (Iterator loop = notifications.iterator(); loop.hasNext();) {
420: Object note = loop.next();
421:
422: xml.append("<notification>" + note + "</notification>");
423: }
424:
425: xml.append("</notifications>");
426:
427: xml.append("<references>");
428:
429: for (Iterator loop = references.iterator(); loop.hasNext();) {
430: xml.append(((GReferenceInfo) loop.next()).toXML());
431: }
432:
433: xml.append("</references>");
434:
435: xml.append("</gBeanInfo>");
436:
437: return xml.toString();
438: }
439: }
|