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