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 */
017
018 package org.apache.geronimo.gbean;
019
020 import java.io.IOException;
021 import java.io.ObjectInputStream;
022 import java.io.Serializable;
023 import java.lang.reflect.Method;
024 import java.util.ArrayList;
025 import java.util.Arrays;
026 import java.util.Collection;
027 import java.util.Collections;
028 import java.util.HashMap;
029 import java.util.HashSet;
030 import java.util.Iterator;
031 import java.util.List;
032 import java.util.Map;
033 import java.util.Set;
034
035 import org.apache.geronimo.kernel.management.NotificationType;
036
037 /**
038 * Describes a GBean. This class should never be constructed directly. Insted use GBeanInfoBuilder.
039 *
040 * @version $Rev: 487175 $ $Date: 2006-12-14 03:10:31 -0800 (Thu, 14 Dec 2006) $
041 */
042 public final class GBeanInfo implements Serializable {
043 private static final long serialVersionUID = -6198804067155550221L;
044
045 public static final int PRIORITY_CLASSLOADER = 1;
046 public static final int PRIORITY_NORMAL = 5;
047
048 private static final Set DEFAULT_NOTIFICATIONS = Collections.unmodifiableSet(new HashSet(Arrays.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, ClassLoader classLoader) throws InvalidConfigurationException {
060 Class clazz;
061 try {
062 clazz = classLoader.loadClass(className);
063 } catch (ClassNotFoundException e) {
064 throw new InvalidConfigurationException("Could not load class " + className, e);
065 } catch (NoClassDefFoundError e) {
066 throw new InvalidConfigurationException("Could not load class " + className, e);
067 }
068 Method method;
069 try {
070 method = clazz.getDeclaredMethod("getGBeanInfo", new Class[]{});
071 } catch (NoSuchMethodException e) {
072 try {
073 // try to get the info from ${className}GBean
074 clazz = classLoader.loadClass(className + "GBean");
075 method = clazz.getDeclaredMethod("getGBeanInfo", new Class[]{});
076 } catch (Exception ignored) {
077 throw new InvalidConfigurationException("Class does not have a getGBeanInfo() method: " + className);
078 }
079 } catch (NoClassDefFoundError e) {
080 throw new InvalidConfigurationException("Could not find getGBeanInfo method on " + className, e);
081 }
082 try {
083 return (GBeanInfo) method.invoke(null, new Object[]{});
084 } catch (Exception e) {
085 throw new InvalidConfigurationException("Could not get GBeanInfo from class: " + className, e);
086 }
087 }
088
089 private final String sourceClass;
090 private final String name;
091 private final String className;
092 private final String j2eeType;
093 private final Set attributes;
094 private final Map attributesByName;
095 private final GConstructorInfo constructor;
096 private final Set operations;
097 private final Set notifications;
098 private final Set references;
099 private final Map referencesByName;
100 private final Set interfaces;
101 private int priority;
102
103 /**
104 * @deprecated use GBeanInfoBuilder
105 */
106 public GBeanInfo(String name, String className, String j2eeType, Collection attributes, GConstructorInfo constructor, Collection operations, Set references, Set interfaces) {
107 this(null, name, className, j2eeType, attributes, constructor, operations, references, interfaces, DEFAULT_NOTIFICATIONS, PRIORITY_NORMAL);
108 }
109
110 /**
111 * @deprecated use GBeanInfoBuilder
112 */
113 public GBeanInfo(String className, String j2eeType, Collection attributes, GConstructorInfo constructor, Collection operations, Set references, Set interfaces) {
114 this(null, className, className, j2eeType, attributes, constructor, operations, references, interfaces, DEFAULT_NOTIFICATIONS, PRIORITY_NORMAL);
115 }
116
117 /**
118 * @deprecated use GBeanInfoBuilder
119 */
120 public GBeanInfo(String className, String j2eeType, Collection attributes, GConstructorInfo constructor, Collection operations, Set references, Set interfaces, Set notifications) {
121 this(null, className, className, j2eeType, attributes, constructor, operations, references, interfaces, notifications, PRIORITY_NORMAL);
122 }
123
124 /**
125 * @deprecated use GBeanInfoBuilder
126 */
127 public GBeanInfo(String name, String className, String j2eeType, Collection attributes, GConstructorInfo constructor, Collection operations, Set references, Set interfaces, Set notifications) {
128 this(null, name, className, j2eeType, attributes, constructor, operations, references, interfaces, notifications, PRIORITY_NORMAL);
129 }
130
131 GBeanInfo(String sourceClass, String name, String className, String j2eeType, Collection attributes, GConstructorInfo constructor, Collection operations, Set references, Set interfaces, int priority) {
132 this(sourceClass, name, className, j2eeType, attributes, constructor, operations, references, interfaces, DEFAULT_NOTIFICATIONS, priority);
133 }
134
135 GBeanInfo(String sourceClass, String name, String className, String j2eeType, Collection attributes, GConstructorInfo constructor, Collection operations, Set references, Set interfaces, Set notifications, int priority) {
136 this.sourceClass = sourceClass;
137 this.name = name;
138 this.className = className;
139 this.j2eeType = j2eeType;
140 if (attributes == null) {
141 this.attributes = Collections.EMPTY_SET;
142 this.attributesByName = Collections.EMPTY_MAP;
143 } else {
144 Map map = new HashMap();
145 for (Iterator iterator = attributes.iterator(); iterator.hasNext();) {
146 GAttributeInfo attribute = (GAttributeInfo) iterator.next();
147 map.put(attribute.getName(), attribute);
148 }
149 this.attributesByName = Collections.unmodifiableMap(map);
150 this.attributes = Collections.unmodifiableSet(new HashSet(map.values()));
151 }
152 if (constructor == null) {
153 this.constructor = new GConstructorInfo(Collections.EMPTY_LIST);
154 } else {
155 this.constructor = constructor;
156 }
157 if (operations == null) {
158 this.operations = Collections.EMPTY_SET;
159 } else {
160 this.operations = Collections.unmodifiableSet(new HashSet(operations));
161 }
162 if (references == null) {
163 this.references = Collections.EMPTY_SET;
164 this.referencesByName = Collections.EMPTY_MAP;
165 } else {
166 Map map = new HashMap();
167 for (Iterator iterator = references.iterator(); iterator.hasNext();) {
168 GReferenceInfo reference = (GReferenceInfo) iterator.next();
169 map.put(reference.getName(), reference);
170 }
171 this.referencesByName = Collections.unmodifiableMap(map);
172 this.references = Collections.unmodifiableSet(new HashSet(references));
173 }
174 if (interfaces == null) {
175 this.interfaces = Collections.EMPTY_SET;
176 } else {
177 this.interfaces = Collections.unmodifiableSet(new HashSet(interfaces));
178 }
179 if (notifications == null) {
180 this.notifications = Collections.EMPTY_SET;
181 } else {
182 this.notifications = Collections.unmodifiableSet(new HashSet(notifications));
183 }
184 this.priority = priority;
185 }
186
187 /**
188 * Gets the source class from which this GBeanInfo can be retrieved using GBeanInfo.getGBeanInfo(className, classLoader).
189 * A null source class means the gbean info was dynamically generated.
190 *
191 * @return the source of this GBeanInfo, or null if it was dynamically generated
192 */
193 public String getSourceClass() {
194 return sourceClass;
195 }
196
197 public String getName() {
198 return name;
199 }
200
201 public String getClassName() {
202 return className;
203 }
204
205 public String getJ2eeType() {
206 return j2eeType;
207 }
208
209 /**
210 * Gets the info for the specified attribute, or null if there is no such
211 * attribute. Note that the attribute may have a getter or setter or both;
212 * being an attribute does not imply that both methods are available.
213 */
214 public GAttributeInfo getAttribute(String name) {
215 return (GAttributeInfo) attributesByName.get(name);
216 }
217
218 /**
219 * Returns a Set where the elements are type GAttributeInfo
220 */
221 public Set getAttributes() {
222 return attributes;
223 }
224
225 /**
226 * Returns a list where the elements are type GAttributeInfo
227 */
228 public List getPersistentAttributes() {
229 List attrs = new ArrayList();
230 for (Iterator i = attributes.iterator(); i.hasNext();) {
231 GAttributeInfo info = (GAttributeInfo) i.next();
232 if (info.isPersistent()) {
233 attrs.add(info);
234 }
235 }
236 return attrs;
237 }
238
239 /**
240 * Returns a list where the elements are type GAttributeInfo
241 */
242 public List getManageableAttributes() {
243 List attrs = new ArrayList();
244 for (Iterator i = attributes.iterator(); i.hasNext();) {
245 GAttributeInfo info = (GAttributeInfo) i.next();
246 if (info.isManageable()) {
247 attrs.add(info);
248 }
249 }
250 return attrs;
251 }
252
253 public GConstructorInfo getConstructor() {
254 return constructor;
255 }
256
257 public Set getOperations() {
258 return operations;
259 }
260
261 public Set getNotifications() {
262 return notifications;
263 }
264
265 public Set getReferences() {
266 return references;
267 }
268
269 public GReferenceInfo getReference(String name) {
270 return (GReferenceInfo) referencesByName.get(name);
271 }
272
273 public Set getInterfaces() {
274 return interfaces;
275 }
276
277 public int getPriority() {
278 return priority;
279 }
280
281 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
282 priority = GBeanInfo.PRIORITY_NORMAL;
283 in.defaultReadObject();
284 }
285
286 public String toString() {
287 StringBuffer result = new StringBuffer("[GBeanInfo:");
288 result.append(" id=").append(super.toString());
289 result.append(" sourceClass=").append(sourceClass);
290 result.append(" name=").append(name);
291 for (Iterator iterator = attributes.iterator(); iterator.hasNext();) {
292 GAttributeInfo geronimoAttributeInfo = (GAttributeInfo) iterator.next();
293 result.append("\n attribute: ").append(geronimoAttributeInfo);
294 }
295 for (Iterator iterator = operations.iterator(); iterator.hasNext();) {
296 GOperationInfo geronimoOperationInfo = (GOperationInfo) iterator.next();
297 result.append("\n operation: ").append(geronimoOperationInfo);
298 }
299 for (Iterator iterator = references.iterator(); iterator.hasNext();) {
300 GReferenceInfo referenceInfo = (GReferenceInfo) iterator.next();
301 result.append("\n reference: ").append(referenceInfo);
302 }
303 result.append("]");
304 return result.toString();
305 }
306 }