Source Code Cross Referenced for GBeanInstance.java in  » EJB-Server-geronimo » kernel » org » apache » geronimo » gbean » runtime » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server geronimo » kernel » org.apache.geronimo.gbean.runtime 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         */package org.apache.geronimo.gbean.runtime;
0017:
0018:        import java.io.PrintWriter;
0019:        import java.io.StringWriter;
0020:        import java.lang.reflect.Constructor;
0021:        import java.lang.reflect.InvocationTargetException;
0022:        import java.util.Collection;
0023:        import java.util.Collections;
0024:        import java.util.HashMap;
0025:        import java.util.HashSet;
0026:        import java.util.Iterator;
0027:        import java.util.LinkedHashSet;
0028:        import java.util.List;
0029:        import java.util.Map;
0030:        import java.util.Set;
0031:        import java.util.Arrays;
0032:
0033:        import javax.management.ObjectName;
0034:
0035:        import org.apache.commons.logging.Log;
0036:        import org.apache.commons.logging.LogFactory;
0037:        import org.apache.geronimo.gbean.AbstractName;
0038:        import org.apache.geronimo.gbean.AbstractNameQuery;
0039:        import org.apache.geronimo.gbean.GAttributeInfo;
0040:        import org.apache.geronimo.gbean.GBeanData;
0041:        import org.apache.geronimo.gbean.GBeanInfo;
0042:        import org.apache.geronimo.gbean.GBeanLifecycle;
0043:        import org.apache.geronimo.gbean.GConstructorInfo;
0044:        import org.apache.geronimo.gbean.GOperationInfo;
0045:        import org.apache.geronimo.gbean.GOperationSignature;
0046:        import org.apache.geronimo.gbean.GReferenceInfo;
0047:        import org.apache.geronimo.gbean.InvalidConfigurationException;
0048:        import org.apache.geronimo.gbean.ReferencePatterns;
0049:        import org.apache.geronimo.kernel.DependencyManager;
0050:        import org.apache.geronimo.kernel.GBeanNotFoundException;
0051:        import org.apache.geronimo.kernel.Kernel;
0052:        import org.apache.geronimo.kernel.NoSuchAttributeException;
0053:        import org.apache.geronimo.kernel.NoSuchOperationException;
0054:        import org.apache.geronimo.kernel.repository.Artifact;
0055:        import org.apache.geronimo.kernel.config.ManageableAttributeStore;
0056:        import org.apache.geronimo.kernel.management.State;
0057:        import org.apache.geronimo.kernel.management.StateManageable;
0058:
0059:        /**
0060:         * A GBeanInstance is a J2EE Management Managed Object, and is standard base for Geronimo services.
0061:         *
0062:         * @version $Rev:385718 $ $Date: 2008-01-04 16:47:14 -0800 (Fri, 04 Jan 2008) $
0063:         */
0064:        public final class GBeanInstance implements  StateManageable {
0065:            private static final Log log = LogFactory
0066:                    .getLog(GBeanInstance.class);
0067:
0068:            private static final int DESTROYED = 0;
0069:            private static final int CREATING = 1;
0070:            private static final int RUNNING = 2;
0071:            private static final int DESTROYING = 3;
0072:
0073:            /**
0074:             * Attribute name used to retrieve the RawInvoker for the GBean
0075:             */
0076:            public static final String RAW_INVOKER = "$$RAW_INVOKER$$";
0077:
0078:            /**
0079:             * The kernel in which this server is registered.
0080:             */
0081:            private final Kernel kernel;
0082:
0083:            /**
0084:             * The ManageableAttributeStore notified of any changes to manageable
0085:             * attributes.  This is lazy-loaded as manageable attributes are set.
0086:             */
0087:            private ManageableAttributeStore manageableStore;
0088:
0089:            /**
0090:             * the abstract name of this service
0091:             */
0092:            private final AbstractName abstractName;
0093:
0094:            /**
0095:             * This handles all state transiitions for this instance.
0096:             */
0097:            private final GBeanInstanceState gbeanInstanceState;
0098:
0099:            /**
0100:             * The constructor used to create the instance
0101:             */
0102:            private final Constructor constructor;
0103:
0104:            /**
0105:             * A fast index based raw invoker for this GBean.
0106:             */
0107:            private final RawInvoker rawInvoker;
0108:
0109:            /**
0110:             * The single listener to which we broadcast lifecycle change events.
0111:             */
0112:            private final LifecycleBroadcaster lifecycleBroadcaster;
0113:
0114:            /**
0115:             * Interfaces for this GBean
0116:             */
0117:            private final String[] interfaces;
0118:
0119:            /**
0120:             * Attributes lookup table
0121:             */
0122:            private final GBeanAttribute[] attributes;
0123:
0124:            /**
0125:             * Attributes supported by this GBeanMBean by (String) name.
0126:             */
0127:            private final Map attributeIndex = new HashMap();
0128:
0129:            /**
0130:             * References lookup table
0131:             */
0132:            private final GBeanReference[] references;
0133:
0134:            /**
0135:             * References supported by this GBeanMBean by (String) name.
0136:             */
0137:            private final Map referenceIndex = new HashMap();
0138:
0139:            /**
0140:             * Dependencies supported by this GBean.
0141:             */
0142:            private final GBeanDependency[] dependencies;
0143:
0144:            /**
0145:             * Operations lookup table
0146:             */
0147:            private final GBeanOperation[] operations;
0148:
0149:            /**
0150:             * Operations supported by this GBeanMBean by (GOperationSignature) name.
0151:             */
0152:            private final Map operationIndex = new HashMap();
0153:
0154:            /**
0155:             * The classloader used for all invocations and creating targets.
0156:             */
0157:            private final ClassLoader classLoader;
0158:
0159:            /**
0160:             * Metadata describing the attributes, operations and references of this GBean
0161:             */
0162:            private final GBeanInfo gbeanInfo;
0163:
0164:            /**
0165:             * Our name
0166:             */
0167:            private final String name;
0168:
0169:            /**
0170:             * Java type of the wrapped GBean class
0171:             */
0172:            private final Class type;
0173:
0174:            /**
0175:             * Has this instance been destroyed?
0176:             */
0177:            private boolean dead = false;
0178:
0179:            /**
0180:             * The state of the internal gbean instance that we are wrapping.
0181:             */
0182:            private int instanceState = DESTROYED;
0183:
0184:            /**
0185:             * Target instance of this GBean wrapper
0186:             */
0187:            private Object target;
0188:
0189:            /**
0190:             * The time this application started.
0191:             */
0192:            private long startTime;
0193:
0194:            /**
0195:             * This is used to signal the creating thread that it should
0196:             * fail when it returns from usercode.  This is set when a
0197:             * reference has gone offline during construction.
0198:             */
0199:            private boolean shouldFail = false;
0200:
0201:            /**
0202:             * Used to track instance
0203:             */
0204:            private InstanceRegistry instanceRegistry;
0205:
0206:            private String stateReason;
0207:
0208:            /**
0209:             * Construct a GBeanMBean using the supplied GBeanData and class loader
0210:             *
0211:             * @param gbeanData   the data for the new GBean including GBeanInfo, intial attribute values, and reference patterns
0212:             * @param classLoader the class loader used to load the gbean instance and attribute/reference types
0213:             * @throws org.apache.geronimo.gbean.InvalidConfigurationException
0214:             *          if the gbeanInfo is inconsistent with the actual java classes, such as
0215:             *          mismatched attribute types or the intial data cannot be set
0216:             */
0217:            public GBeanInstance(GBeanData gbeanData, Kernel kernel,
0218:                    DependencyManager dependencyManager,
0219:                    LifecycleBroadcaster lifecycleBroadcaster,
0220:                    ClassLoader classLoader)
0221:                    throws InvalidConfigurationException {
0222:                this .abstractName = gbeanData.getAbstractName();
0223:                this .kernel = kernel;
0224:                this .lifecycleBroadcaster = lifecycleBroadcaster;
0225:                this .gbeanInstanceState = new GBeanInstanceState(abstractName,
0226:                        kernel, dependencyManager, this , lifecycleBroadcaster);
0227:                this .classLoader = classLoader;
0228:
0229:                GBeanInfo gbeanInfo = gbeanData.getGBeanInfo();
0230:                try {
0231:                    type = classLoader.loadClass(gbeanInfo.getClassName());
0232:                } catch (ClassNotFoundException e) {
0233:                    throw new InvalidConfigurationException(
0234:                            "Could not load GBeanInfo class from classloader: "
0235:                                    + classLoader + " className="
0236:                                    + gbeanInfo.getClassName(), e);
0237:                }
0238:
0239:                name = gbeanInfo.getName();
0240:
0241:                //
0242:                Set constructorArgs = new HashSet(gbeanInfo.getConstructor()
0243:                        .getAttributeNames());
0244:
0245:                // interfaces
0246:                interfaces = (String[]) gbeanInfo.getInterfaces().toArray(
0247:                        new String[0]);
0248:
0249:                // attributes
0250:                Map attributesMap = new HashMap();
0251:                for (Iterator iterator = gbeanInfo.getAttributes().iterator(); iterator
0252:                        .hasNext();) {
0253:                    GAttributeInfo attributeInfo = (GAttributeInfo) iterator
0254:                            .next();
0255:                    attributesMap.put(attributeInfo.getName(),
0256:                            new GBeanAttribute(this , attributeInfo,
0257:                                    constructorArgs.contains(attributeInfo
0258:                                            .getName())));
0259:                }
0260:                addManagedObjectAttributes(attributesMap);
0261:                attributes = (GBeanAttribute[]) attributesMap.values().toArray(
0262:                        new GBeanAttribute[attributesMap.size()]);
0263:                for (int i = 0; i < attributes.length; i++) {
0264:                    attributeIndex.put(attributes[i].getName(), new Integer(i));
0265:                }
0266:
0267:                // references
0268:                Set referencesSet = new HashSet();
0269:                Set dependencySet = new HashSet();
0270:                // add the references
0271:                Map dataReferences = gbeanData.getReferences();
0272:                for (Iterator iterator = gbeanInfo.getReferences().iterator(); iterator
0273:                        .hasNext();) {
0274:                    GReferenceInfo referenceInfo = (GReferenceInfo) iterator
0275:                            .next();
0276:                    String referenceName = referenceInfo.getName();
0277:                    ReferencePatterns referencePatterns = (ReferencePatterns) dataReferences
0278:                            .remove(referenceName);
0279:                    if (referenceInfo.getProxyType().equals(
0280:                            Collection.class.getName())) {
0281:                        referencesSet.add(new GBeanCollectionReference(this ,
0282:                                referenceInfo, kernel, referencePatterns));
0283:
0284:                    } else {
0285:                        referencesSet.add(new GBeanSingleReference(this ,
0286:                                referenceInfo, kernel, referencePatterns));
0287:                        if (referencePatterns != null) {
0288:                            dependencySet
0289:                                    .add(new GBeanDependency(
0290:                                            this ,
0291:                                            referencePatterns.getAbstractName(),
0292:                                            kernel));
0293:                        }
0294:                    }
0295:                }
0296:                if (!dataReferences.isEmpty()) {
0297:                    throw new IllegalStateException(
0298:                            "Attempting to set unknown references: "
0299:                                    + dataReferences.keySet());
0300:                }
0301:
0302:                references = (GBeanReference[]) referencesSet
0303:                        .toArray(new GBeanReference[referencesSet.size()]);
0304:                for (int i = 0; i < references.length; i++) {
0305:                    referenceIndex.put(references[i].getName(), new Integer(i));
0306:                }
0307:
0308:                //dependencies
0309:                for (Iterator iterator = gbeanData.getDependencies().iterator(); iterator
0310:                        .hasNext();) {
0311:                    AbstractName dependencyName = ((ReferencePatterns) iterator
0312:                            .next()).getAbstractName();
0313:                    dependencySet.add(new GBeanDependency(this , dependencyName,
0314:                            kernel));
0315:                }
0316:
0317:                dependencies = (GBeanDependency[]) dependencySet
0318:                        .toArray(new GBeanDependency[dependencySet.size()]);
0319:
0320:                // framework operations -- all framework operations have currently been removed
0321:
0322:                // operations
0323:                Map operationsMap = new HashMap();
0324:                for (Iterator iterator = gbeanInfo.getOperations().iterator(); iterator
0325:                        .hasNext();) {
0326:                    GOperationInfo operationInfo = (GOperationInfo) iterator
0327:                            .next();
0328:                    GOperationSignature signature = new GOperationSignature(
0329:                            operationInfo.getName(), operationInfo
0330:                                    .getParameterList());
0331:                    // do not allow overriding of framework operations
0332:                    if (!operationsMap.containsKey(signature)) {
0333:                        GBeanOperation operation = new GBeanOperation(this ,
0334:                                operationInfo);
0335:                        operationsMap.put(signature, operation);
0336:                    }
0337:                }
0338:                operations = new GBeanOperation[operationsMap.size()];
0339:                int opCounter = 0;
0340:                for (Iterator iterator = operationsMap.entrySet().iterator(); iterator
0341:                        .hasNext();) {
0342:                    Map.Entry entry = (Map.Entry) iterator.next();
0343:                    operations[opCounter] = (GBeanOperation) entry.getValue();
0344:                    operationIndex.put(entry.getKey(), new Integer(opCounter));
0345:                    opCounter++;
0346:                }
0347:
0348:                // get the constructor
0349:                List arguments = gbeanInfo.getConstructor().getAttributeNames();
0350:                Class[] parameterTypes = new Class[arguments.size()];
0351:                for (int i = 0; i < parameterTypes.length; i++) {
0352:                    String argumentName = (String) arguments.get(i);
0353:                    if (referenceIndex.containsKey(argumentName)) {
0354:                        Integer index = (Integer) referenceIndex
0355:                                .get(argumentName);
0356:                        GBeanReference reference = references[index.intValue()];
0357:                        parameterTypes[i] = reference.getProxyType();
0358:                    } else if (attributeIndex.containsKey(argumentName)) {
0359:                        Integer index = (Integer) attributeIndex
0360:                                .get(argumentName);
0361:                        GBeanAttribute attribute = attributes[index.intValue()];
0362:                        parameterTypes[i] = attribute.getType();
0363:                    }
0364:                }
0365:                try {
0366:                    constructor = type.getConstructor(parameterTypes);
0367:                } catch (NoSuchMethodException e) {
0368:                    StringBuffer buf = new StringBuffer(
0369:                            "Could not find a valid constructor for GBean: ")
0370:                            .append(gbeanInfo.getName()).append("\n");
0371:                    buf.append("ParameterTypes: ").append(
0372:                            Arrays.asList(parameterTypes)).append("\n");
0373:                    Constructor[] constructors = type.getConstructors();
0374:                    for (int i = 0; i < constructors.length; i++) {
0375:                        Constructor testConstructor = constructors[i];
0376:                        buf.append("constructor types: ").append(
0377:                                Arrays.asList(testConstructor
0378:                                        .getParameterTypes())).append("\n");
0379:                        if (testConstructor.getParameterTypes().length == parameterTypes.length) {
0380:                            Class[] testParameterTypes = testConstructor
0381:                                    .getParameterTypes();
0382:                            for (int k = 0; k < testParameterTypes.length; k++) {
0383:                                Class testParameterType = testParameterTypes[k];
0384:                                if (parameterTypes[k].getName().equals(
0385:                                        testParameterType.getName())) {
0386:                                    if (parameterTypes[k].getClassLoader() != testParameterType
0387:                                            .getClassLoader()) {
0388:                                        buf
0389:                                                .append(
0390:                                                        "different classloaders in position: ")
0391:                                                .append(k).append(
0392:                                                        " class name: ")
0393:                                                .append(
0394:                                                        testParameterType
0395:                                                                .getName())
0396:                                                .append("\n");
0397:                                        buf
0398:                                                .append(
0399:                                                        "parameter type classloader: ")
0400:                                                .append(
0401:                                                        parameterTypes[k]
0402:                                                                .getClassLoader())
0403:                                                .append("\n");
0404:                                        buf
0405:                                                .append(
0406:                                                        "constructor type classloader: ")
0407:                                                .append(
0408:                                                        testParameterType
0409:                                                                .getClassLoader())
0410:                                                .append("\n");
0411:                                    }
0412:                                } else {
0413:                                    buf.append("different type in position: ")
0414:                                            .append(k).append("\n");
0415:                                }
0416:                            }
0417:                        }
0418:                    }
0419:                    throw new InvalidConfigurationException(buf.toString());
0420:                } catch (NoClassDefFoundError e) {
0421:                    throw new InvalidConfigurationException(e);
0422:                }
0423:
0424:                // rebuild the gbean info based on the current attributes, operations, and references because
0425:                // the above code add new attributes and operations
0426:                this .gbeanInfo = rebuildGBeanInfo(gbeanInfo.getConstructor(),
0427:                        gbeanInfo.getJ2eeType());
0428:
0429:                // create the raw invokers
0430:                rawInvoker = new RawInvoker(this );
0431:
0432:                // set the initial attribute values
0433:                try {
0434:                    // set the attributes
0435:                    Map dataAttributes = gbeanData.getAttributes();
0436:                    for (Iterator iterator = dataAttributes.entrySet()
0437:                            .iterator(); iterator.hasNext();) {
0438:                        Map.Entry entry = (Map.Entry) iterator.next();
0439:                        String attributeName = (String) entry.getKey();
0440:                        Object attributeValue = entry.getValue();
0441:                        if (entry.getValue() != null) {
0442:                            setAttribute(attributeName, attributeValue, false);
0443:                        }
0444:                    }
0445:
0446:                } catch (Exception e) {
0447:                    throw new InvalidConfigurationException(
0448:                            "Could not inject configuration data into the GBean "
0449:                                    + abstractName, e);
0450:                }
0451:
0452:                //Add the reference to all applicable reference collections before possibly starting the gbean having an
0453:                //explicit reference to the reference.
0454:                for (int i = 0; i < references.length; i++) {
0455:                    references[i].online();
0456:                }
0457:                for (int i = 0; i < dependencies.length; i++) {
0458:                    dependencies[i].online();
0459:                }
0460:            }
0461:
0462:            public void die() throws GBeanNotFoundException {
0463:                synchronized (this ) {
0464:                    if (dead) {
0465:                        // someone beat us to the punch... this instance should have never been found in the first place
0466:                        throw new GBeanNotFoundException(abstractName);
0467:                    }
0468:                    dead = true;
0469:                }
0470:
0471:                // if the bean is already stopped or failed, this will do nothing; otherwise it will shutdown the bean
0472:                gbeanInstanceState.fail();
0473:
0474:                for (int i = 0; i < references.length; i++) {
0475:                    references[i].offline();
0476:                }
0477:                for (int i = 0; i < dependencies.length; i++) {
0478:                    dependencies[i].offline();
0479:                }
0480:
0481:                // tell everyone we are done
0482:                lifecycleBroadcaster.fireUnloadedEvent();
0483:
0484:                manageableStore = null;
0485:            }
0486:
0487:            public synchronized void setInstanceRegistry(
0488:                    InstanceRegistry instanceRegistry) {
0489:                this .instanceRegistry = instanceRegistry;
0490:            }
0491:
0492:            /**
0493:             * Gets the name of the GBean as defined in the gbean info.
0494:             *
0495:             * @return the gbean name
0496:             */
0497:            public String getName() {
0498:                return name;
0499:            }
0500:
0501:            /**
0502:             * The class loader used to build this gbean.  This class loader is set into the thread context
0503:             * class loader before callint the target instace.
0504:             *
0505:             * @return the class loader used to build this gbean
0506:             */
0507:            public ClassLoader getClassLoader() {
0508:                return classLoader;
0509:            }
0510:
0511:            /**
0512:             * Has this gbean instance been destroyed. An destroyed gbean can no longer be used.
0513:             *
0514:             * @return true if the gbean has been destroyed
0515:             */
0516:            public synchronized boolean isDead() {
0517:                return dead;
0518:            }
0519:
0520:            /**
0521:             * Gets the reason we are in the current state.
0522:             * @return the reason we are in the current state
0523:             */
0524:            public String getStateReason() {
0525:                return stateReason;
0526:            }
0527:
0528:            /**
0529:             * Sets the reason we are in the current state.
0530:             * @param reason  The reason we are in the current state
0531:             */
0532:            public void setStateReason(String reason) {
0533:                stateReason = reason;
0534:            }
0535:
0536:            /**
0537:             * The java type of the wrapped gbean instance
0538:             *
0539:             * @return the java type of the gbean
0540:             */
0541:            public Class getType() {
0542:                return type;
0543:            }
0544:
0545:            public synchronized Object getTarget() {
0546:                return target;
0547:            }
0548:
0549:            public final String getObjectName() {
0550:                return abstractName.getObjectName().getCanonicalName();
0551:            }
0552:
0553:            public final ObjectName getObjectNameObject() {
0554:                return abstractName.getObjectName();
0555:            }
0556:
0557:            public final AbstractName getAbstractName() {
0558:                return abstractName;
0559:            }
0560:
0561:            public synchronized final long getStartTime() {
0562:                return startTime;
0563:            }
0564:
0565:            public int getState() {
0566:                return gbeanInstanceState.getState();
0567:            }
0568:
0569:            public final State getStateInstance() {
0570:                return gbeanInstanceState.getStateInstance();
0571:            }
0572:
0573:            /**
0574:             * Gets an unmodifiable map from attribute names to index number (Integer).  This index number
0575:             * can be used to efficiently set or retrieve an attribute value.
0576:             *
0577:             * @return an unmodifiable map of attribute indexes by name
0578:             */
0579:            public Map getAttributeIndex() {
0580:                return Collections.unmodifiableMap(new HashMap(attributeIndex));
0581:            }
0582:
0583:            /**
0584:             * Gets an unmodifiable map from operation signature (GOperationSignature) to index number (Integer).
0585:             * This index number can be used to efficciently invoke the operation.
0586:             *
0587:             * @return an unmodifiable map of operation indexec by signature
0588:             */
0589:            public Map getOperationIndex() {
0590:                return Collections.unmodifiableMap(new HashMap(operationIndex));
0591:            }
0592:
0593:            /**
0594:             * Gets the GBeanInfo used to build this gbean.
0595:             *
0596:             * @return the GBeanInfo used to build this gbean
0597:             */
0598:            public GBeanInfo getGBeanInfo() {
0599:                return gbeanInfo;
0600:            }
0601:
0602:            /**
0603:             * Moves this GBeanInstance to the starting state and then attempts to move this MBean immediately
0604:             * to the running state.
0605:             *
0606:             * @throws IllegalStateException If the gbean is disabled
0607:             */
0608:            public final void start() {
0609:                synchronized (this ) {
0610:                    if (dead) {
0611:                        throw new IllegalStateException(
0612:                                "A dead GBean can not be started: abstractName="
0613:                                        + abstractName);
0614:                    }
0615:                }
0616:                gbeanInstanceState.start();
0617:            }
0618:
0619:            /**
0620:             * Starts this GBeanInstance and then attempts to start all of its start dependent children.
0621:             *
0622:             * @throws IllegalStateException If the gbean is disabled
0623:             */
0624:            public final void startRecursive() {
0625:                synchronized (this ) {
0626:                    if (dead) {
0627:                        throw new IllegalStateException(
0628:                                "A dead GBean can not be started: abstractName="
0629:                                        + abstractName);
0630:                    }
0631:                }
0632:                gbeanInstanceState.startRecursive();
0633:            }
0634:
0635:            /**
0636:             * Moves this GBeanInstance to the STOPPING state, calls stop on all start dependent children, and then attempt
0637:             * to move this MBean to the STOPPED state.
0638:             */
0639:            public final void stop() {
0640:                gbeanInstanceState.stop();
0641:            }
0642:
0643:            /**
0644:             * Moves this GBeanInstance to the FAILED state.  There are no calls to dependent children, but they will be
0645:             * notified using standard J2EE management notification.
0646:             */
0647:            final void referenceFailed() {
0648:                gbeanInstanceState.fail();
0649:            }
0650:
0651:            /**
0652:             * Gets the gbean data for the gbean held by this gbean mbean.
0653:             *
0654:             * @return the gbean data
0655:             */
0656:            public GBeanData getGBeanData() {
0657:                GBeanData gbeanData = new GBeanData(abstractName, gbeanInfo);
0658:
0659:                // copy target into local variables from within a synchronized block to gaurentee a consistent read
0660:                int state;
0661:                Object instance;
0662:                synchronized (this ) {
0663:                    state = instanceState;
0664:                    instance = target;
0665:                }
0666:
0667:                // add the attributes
0668:                for (int i = 0; i < attributes.length; i++) {
0669:                    GBeanAttribute attribute = attributes[i];
0670:                    if (attribute.isPersistent()) {
0671:                        String name = attribute.getName();
0672:                        Object value;
0673:                        if ((state != DESTROYED || attribute.isFramework())
0674:                                && attribute.isReadable()) {
0675:                            try {
0676:                                value = attribute.getValue(instance);
0677:                            } catch (Throwable throwable) {
0678:                                value = attribute.getPersistentValue();
0679:                                log
0680:                                        .debug(
0681:                                                "Could not get the current value of persistent attribute.  The persistent "
0682:                                                        + "attribute will not reflect the current state attribute. "
0683:                                                        + attribute
0684:                                                                .getDescription(),
0685:                                                throwable);
0686:                            }
0687:                        } else {
0688:                            value = attribute.getPersistentValue();
0689:                        }
0690:                        gbeanData.setAttribute(name, value);
0691:                    }
0692:                }
0693:
0694:                // add the references
0695:                for (int i = 0; i < references.length; i++) {
0696:                    GBeanReference reference = references[i];
0697:                    String name = reference.getName();
0698:                    if (reference instanceof  GBeanSingleReference) {
0699:                        AbstractName abstractName = ((GBeanSingleReference) reference)
0700:                                .getTargetName();
0701:                        if (abstractName != null) {
0702:                            gbeanData.setReferencePattern(name, abstractName);
0703:                        }
0704:                    } else if (reference instanceof  GBeanCollectionReference) {
0705:                        Set patterns = ((GBeanCollectionReference) reference)
0706:                                .getPatterns();
0707:                        if (patterns != null) {
0708:                            gbeanData.setReferencePatterns(name, patterns);
0709:                        }
0710:                    } else {
0711:                        throw new IllegalStateException(
0712:                                "Unrecognized GBeanReference '"
0713:                                        + reference.getClass().getName() + "'");
0714:                    }
0715:                }
0716:                //TODO copy the dependencies??
0717:                return gbeanData;
0718:            }
0719:
0720:            /**
0721:             * Gets the attribute value using the attribute index.  This is the most efficient way to get
0722:             * an attribute as it avoids a HashMap lookup.
0723:             *
0724:             * @param index the index of the attribute
0725:             * @return the attribute value
0726:             * @throws Exception                 if a target instance throws and exception
0727:             * @throws IndexOutOfBoundsException if the index is invalid
0728:             */
0729:            public Object getAttribute(int index) throws Exception {
0730:                GBeanAttribute attribute = attributes[index];
0731:
0732:                // copy target into local variables from within a synchronized block to gaurentee a consistent read
0733:                int state;
0734:                Object instance;
0735:                synchronized (this ) {
0736:                    state = instanceState;
0737:                    instance = target;
0738:                }
0739:
0740:                if (state != DESTROYED || attribute.isFramework()) {
0741:                    return attribute.getValue(instance);
0742:                } else {
0743:                    if (attribute.isPersistent()) {
0744:                        return attribute.getPersistentValue();
0745:                    } else {
0746:                        throw new IllegalStateException(
0747:                                "Cannot retrieve the value for non-persistent attribute \""
0748:                                        + attribute.getName()
0749:                                        + "\" when GBeanInstance is DESTROYED");
0750:                    }
0751:                }
0752:            }
0753:
0754:            /**
0755:             * Gets an attribute's value by name.  This get style is less efficient becuse the attribute must
0756:             * first be looked up in a HashMap.
0757:             *
0758:             * @param attributeName the name of the attribute to retrieve
0759:             * @return the attribute value
0760:             * @throws Exception                if a problem occurs while getting the value
0761:             * @throws NoSuchAttributeException if the attribute name is not found in the map
0762:             */
0763:            public Object getAttribute(String attributeName)
0764:                    throws NoSuchAttributeException, Exception {
0765:                GBeanAttribute attribute;
0766:                try {
0767:                    attribute = getAttributeByName(attributeName);
0768:                } catch (NoSuchAttributeException e) {
0769:                    if (attributeName.equals(RAW_INVOKER)) {
0770:                        return rawInvoker;
0771:                    }
0772:                    throw e;
0773:                }
0774:
0775:                // copy target into local variables from within a synchronized block to gaurentee a consistent read
0776:                int state;
0777:                Object instance;
0778:                synchronized (this ) {
0779:                    state = instanceState;
0780:                    instance = target;
0781:                }
0782:
0783:                if (state != DESTROYED || attribute.isFramework()) {
0784:                    return attribute.getValue(instance);
0785:                } else {
0786:                    if (attribute.isPersistent()) {
0787:                        return attribute.getPersistentValue();
0788:                    } else {
0789:                        throw new IllegalStateException(
0790:                                "Cannot retrieve the value for non-persistent attribute "
0791:                                        + attributeName
0792:                                        + " when gbean has been destroyed: "
0793:                                        + abstractName);
0794:                    }
0795:                }
0796:            }
0797:
0798:            /**
0799:             * Sets the attribute value using the attribute index.  This is the most efficient way to set
0800:             * an attribute as it avoids a HashMap lookup.
0801:             *
0802:             * @param index the index of the attribute
0803:             * @param value the new value of attribute value
0804:             * @throws Exception                 if a target instance throws and exception
0805:             * @throws IndexOutOfBoundsException if the index is invalid
0806:             */
0807:            public void setAttribute(int index, Object value) throws Exception,
0808:                    IndexOutOfBoundsException {
0809:                setAttribute(index, value, true);
0810:            }
0811:
0812:            private void setAttribute(int index, Object value, boolean manage)
0813:                    throws Exception, IndexOutOfBoundsException {
0814:                GBeanAttribute attribute = attributes[index];
0815:
0816:                // copy target into local variables from within a synchronized block to gaurentee a consistent read
0817:                int state;
0818:                Object instance;
0819:                synchronized (this ) {
0820:                    state = instanceState;
0821:                    instance = target;
0822:                }
0823:
0824:                if (state != DESTROYED || attribute.isFramework()) {
0825:                    attribute.setValue(instance, value);
0826:                } else {
0827:                    attribute.setPersistentValue(value);
0828:                }
0829:                if (manage && attribute.isManageable()) {
0830:                    updateManageableAttribute(attribute, value);
0831:                }
0832:            }
0833:
0834:            /**
0835:             * Sets an attribute's value by name.  This set style is less efficient becuse the attribute must
0836:             * first be looked up in a HashMap.
0837:             *
0838:             * @param attributeName the name of the attribute to retrieve
0839:             * @param value         the new attribute value
0840:             * @throws Exception                if a target instance throws and exception
0841:             * @throws NoSuchAttributeException if the attribute name is not found in the map
0842:             */
0843:            public void setAttribute(String attributeName, Object value)
0844:                    throws Exception, NoSuchAttributeException {
0845:                setAttribute(attributeName, value, true);
0846:            }
0847:
0848:            public void setAttribute(String attributeName, Object value,
0849:                    boolean manage) throws Exception, NoSuchAttributeException {
0850:                GBeanAttribute attribute = getAttributeByName(attributeName);
0851:
0852:                // copy target into local variables from within a synchronized block to gaurentee a consistent read
0853:                int state;
0854:                Object instance;
0855:                synchronized (this ) {
0856:                    state = instanceState;
0857:                    instance = target;
0858:                }
0859:
0860:                if (state != DESTROYED || attribute.isFramework()) {
0861:                    attribute.setValue(instance, value);
0862:                } else {
0863:                    attribute.setPersistentValue(value);
0864:                }
0865:                if (manage && attribute.isManageable()) {
0866:                    updateManageableAttribute(attribute, value);
0867:                }
0868:            }
0869:
0870:            private void updateManageableAttribute(GBeanAttribute attribute,
0871:                    Object value) {
0872:                if (manageableStore == null) {
0873:                    manageableStore = getManageableAttributeStore();
0874:                    if (manageableStore == null) {
0875:                        return;
0876:                    }
0877:                }
0878:                Artifact configName = abstractName.getArtifact();
0879:                if (configName != null) {
0880:                    manageableStore.setValue(configName, abstractName,
0881:                            attribute.getAttributeInfo(), value, classLoader);
0882:                } else {
0883:                    log.error("Unable to identify Configuration for GBean "
0884:                            + abstractName + ".  Manageable attribute "
0885:                            + attribute.getName()
0886:                            + " was not updated in persistent store.");
0887:                }
0888:            }
0889:
0890:            private ManageableAttributeStore getManageableAttributeStore() {
0891:                Set set = kernel.listGBeans(new AbstractNameQuery(
0892:                        ManageableAttributeStore.class.getName()));
0893:                for (Iterator iterator = set.iterator(); iterator.hasNext();) {
0894:                    AbstractName abstractName1 = (AbstractName) iterator.next();
0895:                    try {
0896:                        return (ManageableAttributeStore) kernel
0897:                                .getGBean(abstractName1);
0898:                    } catch (GBeanNotFoundException e) {
0899:                        // ignored... gbean was unregistered
0900:                    }
0901:                }
0902:                return null;
0903:            }
0904:
0905:            private GBeanAttribute getAttributeByName(String name)
0906:                    throws NoSuchAttributeException {
0907:                Integer index = (Integer) attributeIndex.get(name);
0908:                if (index == null) {
0909:                    throw new NoSuchAttributeException("Unknown attribute \""
0910:                            + name + "\" in gbean " + abstractName);
0911:                }
0912:                return attributes[index.intValue()];
0913:            }
0914:
0915:            /**
0916:             * Invokes an opreation using the operation index.  This is the most efficient way to invoke
0917:             * an operation as it avoids a HashMap lookup.
0918:             *
0919:             * @param index     the index of the attribute
0920:             * @param arguments the arguments to the operation
0921:             * @return the result of the operation
0922:             * @throws Exception                 if a target instance throws and exception
0923:             * @throws IndexOutOfBoundsException if the index is invalid
0924:             * @throws IllegalStateException     if the gbean instance has been destroyed
0925:             */
0926:            public Object invoke(int index, Object[] arguments)
0927:                    throws Exception {
0928:                GBeanOperation operation = operations[index];
0929:
0930:                // copy target into local variables from within a synchronized block to gaurentee a consistent read
0931:                int state;
0932:                Object instance;
0933:                synchronized (this ) {
0934:                    state = instanceState;
0935:                    instance = target;
0936:                }
0937:
0938:                if (state == DESTROYED && !operation.isFramework()) {
0939:                    throw new IllegalStateException(
0940:                            "Operations can only be invoke while the GBean instance is running: "
0941:                                    + abstractName);
0942:                }
0943:                return operation.invoke(instance, arguments);
0944:            }
0945:
0946:            /**
0947:             * Invokes an operation on the target gbean by method signature.  This style if invocation is
0948:             * inefficient, because the target method must be looked up in a hashmap using a freshly constructed
0949:             * GOperationSignature object.
0950:             *
0951:             * @param operationName the name of the operation to invoke
0952:             * @param arguments     arguments to the operation
0953:             * @param types         types of the operation arguemtns
0954:             * @return the result of the operation
0955:             * @throws Exception                if a target instance throws and exception
0956:             * @throws NoSuchOperationException if the operation signature is not found in the map
0957:             * @throws IllegalStateException    if the gbean instance has been destroyed
0958:             */
0959:            public Object invoke(String operationName, Object[] arguments,
0960:                    String[] types) throws Exception, NoSuchOperationException {
0961:                GOperationSignature signature = new GOperationSignature(
0962:                        operationName, types);
0963:                Integer index = (Integer) operationIndex.get(signature);
0964:                if (index == null) {
0965:                    throw new NoSuchOperationException("Unknown operation "
0966:                            + signature);
0967:                }
0968:                GBeanOperation operation = operations[index.intValue()];
0969:
0970:                // copy target into local variables from within a synchronized block to gaurentee a consistent read
0971:                int state;
0972:                Object instance;
0973:                synchronized (this ) {
0974:                    state = instanceState;
0975:                    instance = target;
0976:                }
0977:
0978:                if (state == DESTROYED && !operation.isFramework()) {
0979:                    throw new IllegalStateException(
0980:                            "Operations can only be invoke while the GBean is running: "
0981:                                    + abstractName);
0982:                }
0983:                return operation.invoke(instance, arguments);
0984:            }
0985:
0986:            private GBeanReference getReferenceByName(String name) {
0987:                Integer index = (Integer) referenceIndex.get(name);
0988:                if (index == null) {
0989:                    throw new IllegalArgumentException("Unknown reference "
0990:                            + name);
0991:                }
0992:                return references[index.intValue()];
0993:            }
0994:
0995:            boolean createInstance() throws Exception {
0996:                synchronized (this ) {
0997:                    // first check we are still in the correct state to start
0998:                    if (instanceState == CREATING || instanceState == RUNNING) {
0999:                        // another thread already completed starting
1000:                        return false;
1001:                    } else if (instanceState == DESTROYING) {
1002:                        // this should never ever happen... this method is protected by the GBeanState class which should
1003:                        // prevent stuff like this happening, but check anyway
1004:                        stateReason = "an internal error has occurred.  An attempt was made to start an instance that was still stopping which is an illegal state transition.";
1005:                        throw new IllegalStateException(
1006:                                "A stopping instance can not be started until fully stopped");
1007:                    }
1008:                    assert instanceState == DESTROYED;
1009:
1010:                    stateReason = null;
1011:
1012:                    // Call all start on every reference.  This way the dependecies are held until we can start
1013:                    LinkedHashSet unstarted = new LinkedHashSet();
1014:                    for (int i = 0; i < dependencies.length; i++) {
1015:                        if (!dependencies[i].start()) {
1016:                            unstarted.add(dependencies[i].getTargetName());
1017:                        }
1018:                    }
1019:                    for (int i = 0; i < references.length; i++) {
1020:                        if (!references[i].start()) {
1021:                            if (references[i] instanceof  GBeanSingleReference) {
1022:                                GBeanSingleReference reference = (GBeanSingleReference) references[i];
1023:                                unstarted.add(reference.getTargetName());
1024:                            }
1025:                        }
1026:                    }
1027:                    if (!unstarted.isEmpty()) {
1028:                        if (unstarted.size() == 1) {
1029:                            stateReason = unstarted.iterator().next()
1030:                                    + " did not start.";
1031:                        } else {
1032:                            stateReason = "the following dependent services did not start: "
1033:                                    + unstarted;
1034:                        }
1035:                        return false;
1036:                    }
1037:
1038:                    // we are definately going to (try to) start... if this fails the must clean up these variables
1039:                    instanceState = CREATING;
1040:                    startTime = System.currentTimeMillis();
1041:                }
1042:
1043:                ClassLoader oldCL = Thread.currentThread()
1044:                        .getContextClassLoader();
1045:                Thread.currentThread().setContextClassLoader(classLoader);
1046:                Object instance = null;
1047:                try {
1048:                    GConstructorInfo constructorInfo = gbeanInfo
1049:                            .getConstructor();
1050:                    Class[] parameterTypes = constructor.getParameterTypes();
1051:
1052:                    // create constructor parameter array
1053:                    Object[] parameters = new Object[parameterTypes.length];
1054:                    Iterator names = constructorInfo.getAttributeNames()
1055:                            .iterator();
1056:                    for (int i = 0; i < parameters.length; i++) {
1057:                        String name = (String) names.next();
1058:                        if (referenceIndex.containsKey(name)) {
1059:                            parameters[i] = getReferenceByName(name).getProxy();
1060:                        } else if (attributeIndex.containsKey(name)) {
1061:                            GBeanAttribute attribute = getAttributeByName(name);
1062:                            parameters[i] = attribute.getPersistentValue();
1063:                        } else {
1064:                            stateReason = "the service constructor definition contained the name '"
1065:                                    + name
1066:                                    + "' which is not a known attribute or reference of the service.";
1067:                            throw new InvalidConfigurationException(
1068:                                    "Unknown attribute or reference name in constructor: referenceName="
1069:                                            + name + ", gbean=" + abstractName);
1070:                        }
1071:                    }
1072:
1073:                    // create instance
1074:                    try {
1075:                        instance = constructor.newInstance(parameters);
1076:                    } catch (InvocationTargetException e) {
1077:                        Throwable targetException = e.getTargetException();
1078:                        if (targetException instanceof  Exception) {
1079:                            stateReason = "the service constructor threw an exception. \n"
1080:                                    + printException(targetException);
1081:                            throw (Exception) targetException;
1082:                        } else if (targetException instanceof  Error) {
1083:                            stateReason = "the service constructor threw an exception. \n"
1084:                                    + printException(targetException);
1085:                            throw (Error) targetException;
1086:                        }
1087:                        stateReason = "the service constructor threw an exception. \n"
1088:                                + printException(e);
1089:                        throw e;
1090:                    } catch (IllegalArgumentException e) {
1091:                        stateReason = "the service constructor threw an exception due to a parameter type mismatch. \n"
1092:                                + printException(e);
1093:                        log.warn("Constructor mismatch for " + abstractName, e);
1094:                        throw e;
1095:                    }
1096:
1097:                    // write the target variable in a synchronized block so it is available to all threads
1098:                    // we do this before calling the setters or start method so the bean can be called back
1099:                    // from a setter start method
1100:                    synchronized (this ) {
1101:                        target = instance;
1102:                    }
1103:
1104:                    // inject the persistent attribute value into the new instance
1105:                    for (int i = 0; i < attributes.length; i++) {
1106:                        checkIfShouldFail();
1107:                        try {
1108:                            attributes[i].inject(instance);
1109:                        } catch (Exception e) {
1110:                            stateReason = "the setter for attribute '"
1111:                                    + attributes[i].getName()
1112:                                    + "' threw an exception. \n"
1113:                                    + printException(e);
1114:                            throw e;
1115:                        }
1116:                    }
1117:
1118:                    // inject the proxies into the new instance
1119:                    for (int i = 0; i < references.length; i++) {
1120:                        checkIfShouldFail();
1121:                        try {
1122:                            references[i].inject(instance);
1123:                        } catch (Exception e) {
1124:                            stateReason = "the setter for reference '"
1125:                                    + references[i].getName()
1126:                                    + "' threw an exception. \n"
1127:                                    + printException(e);
1128:                            throw e;
1129:                        }
1130:                    }
1131:
1132:                    if (instance instanceof  GBeanLifecycle) {
1133:                        checkIfShouldFail();
1134:                        try {
1135:                            ((GBeanLifecycle) instance).doStart();
1136:                        } catch (Exception e) {
1137:                            stateReason = "the doStart method threw an exception. \n"
1138:                                    + printException(e);
1139:                            throw e;
1140:                        }
1141:                    }
1142:
1143:                    // all done... we are now fully running
1144:                    synchronized (this ) {
1145:                        checkIfShouldFail();
1146:                        if (instanceRegistry != null) {
1147:                            instanceRegistry.instanceCreated(instance, this );
1148:                        }
1149:                        instanceState = RUNNING;
1150:                        this .notifyAll();
1151:                    }
1152:
1153:                    stateReason = null;
1154:                    return true;
1155:                } catch (Throwable t) {
1156:                    stateReason = "Throwable during start of gbean: \n"
1157:                            + printException(t);
1158:                    // something went wrong... we need to destroy this instance
1159:                    synchronized (this ) {
1160:                        instanceState = DESTROYING;
1161:                    }
1162:
1163:                    if (instance instanceof  GBeanLifecycle) {
1164:                        try {
1165:                            ((GBeanLifecycle) instance).doFail();
1166:                        } catch (Throwable ignored) {
1167:                            log.error("Problem in doFail of " + abstractName,
1168:                                    ignored);
1169:                        }
1170:                    }
1171:
1172:                    // bean has been notified... drop our reference
1173:                    synchronized (this ) {
1174:                        // stop all of the references
1175:                        for (int i = 0; i < references.length; i++) {
1176:                            references[i].stop();
1177:                        }
1178:                        for (int i = 0; i < dependencies.length; i++) {
1179:                            dependencies[i].stop();
1180:                        }
1181:
1182:                        target = null;
1183:                        instanceState = DESTROYED;
1184:                        startTime = 0;
1185:                        this .notifyAll();
1186:                    }
1187:
1188:                    if (t instanceof  Exception) {
1189:                        throw (Exception) t;
1190:                    } else if (t instanceof  Error) {
1191:                        throw (Error) t;
1192:                    } else {
1193:                        throw new Error(t);
1194:                    }
1195:                } finally {
1196:                    Thread.currentThread().setContextClassLoader(oldCL);
1197:                }
1198:            }
1199:
1200:            private String printException(Throwable t) {
1201:                StringWriter stringWriter = new StringWriter();
1202:                PrintWriter printWriter = new PrintWriter(stringWriter);
1203:                t.printStackTrace(printWriter);
1204:                printWriter.flush();
1205:                return stringWriter.toString();
1206:            }
1207:
1208:            private synchronized void checkIfShouldFail() throws Exception {
1209:                if (shouldFail) {
1210:                    shouldFail = false;
1211:                    throw new Exception(
1212:                            "A reference has failed so construction can not complete");
1213:                }
1214:            }
1215:
1216:            boolean destroyInstance(boolean stop) throws Exception {
1217:                Object instance;
1218:                synchronized (this ) {
1219:                    if (!stop && instanceState == CREATING) {
1220:                        // signal to the creating thead that it should fail
1221:                        shouldFail = true;
1222:                        return false;
1223:                    }
1224:
1225:                    // if the instance is being created we need to wait
1226:                    //  for it to finish before we can try to stop it
1227:                    while (instanceState == CREATING) {
1228:                        // todo should we limit this wait?  If so, how do we configure the wait time?
1229:                        try {
1230:                            this .wait();
1231:                        } catch (InterruptedException e) {
1232:                            // clear the interrupted flag
1233:                            Thread.interrupted();
1234:                            // rethrow the interrupted exception.... someone was sick of us waiting
1235:                            throw e;
1236:                        }
1237:                    }
1238:
1239:                    if (instanceState == DESTROYING
1240:                            || instanceState == DESTROYED) {
1241:                        // another thread is already stopping or has already stopped
1242:                        return false;
1243:                    }
1244:                    assert instanceState == RUNNING;
1245:                    stateReason = null;
1246:
1247:                    // we are definately going to stop... if this fails the must clean up these variables
1248:                    instanceState = DESTROYING;
1249:                    instance = target;
1250:                }
1251:
1252:                // update the persistent attributes
1253:                // do not update the persistent attibute values in the case of a failure
1254:                // failed gbeans may have corrupted attributes that would be persisted
1255:                Exception problem = null;
1256:                if (stop && instance != null) {
1257:                    try {
1258:                        // get all the data but don't update in case there is an exception
1259:                        Map data = new HashMap();
1260:                        for (int i = 0; i < attributes.length; i++) {
1261:                            GBeanAttribute attribute = attributes[i];
1262:                            if (attribute.isPersistent()
1263:                                    && attribute.isReadable()) {
1264:                                // copy the current attribute value to the persistent value
1265:                                Object value;
1266:                                try {
1267:                                    value = attribute.getValue(instance);
1268:                                } catch (Throwable e) {
1269:                                    // There is no reason to create a new Exception sub class as this exception will
1270:                                    // simply be caught and logged on GBeanInstanceState
1271:                                    throw new Exception(
1272:                                            "Problem while updaing the persistent value of attibute: "
1273:                                                    + "Attribute Name: "
1274:                                                    + attribute.getName()
1275:                                                    + ", " + "Type: "
1276:                                                    + attribute.getType()
1277:                                                    + ", " + "GBeanInstance: "
1278:                                                    + getName(), e);
1279:                                }
1280:                                data.put(attribute, value);
1281:                            }
1282:                        }
1283:                        // now we have all the data we can update the persistent values
1284:                        for (int i = 0; i < attributes.length; i++) {
1285:                            GBeanAttribute attribute = attributes[i];
1286:                            if (attribute.isPersistent()
1287:                                    && attribute.isReadable()) {
1288:                                // copy the current attribute value to the persistent value
1289:                                Object value = data.get(attribute);
1290:                                attribute.setPersistentValue(value);
1291:                            }
1292:                        }
1293:                    } catch (Exception e) {
1294:                        // the getter threw an exception; now we must to fail
1295:                        stop = false;
1296:                        problem = e;
1297:                    }
1298:                }
1299:
1300:                // we notify the bean before removing our reference so the bean can be called back while stopping
1301:                ClassLoader oldCL = Thread.currentThread()
1302:                        .getContextClassLoader();
1303:                Thread.currentThread().setContextClassLoader(classLoader);
1304:                try {
1305:                    if (instance instanceof  GBeanLifecycle) {
1306:                        if (stop) {
1307:                            try {
1308:                                ((GBeanLifecycle) instance).doStop();
1309:                            } catch (Throwable ignored) {
1310:                                log.error("Problem in doStop of "
1311:                                        + abstractName, ignored);
1312:                            }
1313:                        } else {
1314:                            try {
1315:                                ((GBeanLifecycle) instance).doFail();
1316:                            } catch (Throwable ignored) {
1317:                                log.error("Problem in doFail of "
1318:                                        + abstractName, ignored);
1319:                            }
1320:                        }
1321:                    }
1322:                } finally {
1323:                    Thread.currentThread().setContextClassLoader(oldCL);
1324:                }
1325:
1326:                // bean has been notified... drop our reference
1327:                synchronized (this ) {
1328:                    // stop all of the references
1329:                    for (int i = 0; i < references.length; i++) {
1330:                        references[i].stop();
1331:                    }
1332:                    for (int i = 0; i < dependencies.length; i++) {
1333:                        dependencies[i].stop();
1334:                    }
1335:
1336:                    target = null;
1337:                    instanceState = DESTROYED;
1338:                    if (instanceRegistry != null) {
1339:                        instanceRegistry.instanceDestroyed(instance);
1340:                    }
1341:                    startTime = 0;
1342:                }
1343:
1344:                if (problem != null) {
1345:                    throw problem;
1346:                }
1347:                return true;
1348:            }
1349:
1350:            private void addManagedObjectAttributes(Map attributesMap) {
1351:                //
1352:                //  Special attributes
1353:                //
1354:                attributesMap.put("abstractName", GBeanAttribute
1355:                        .createSpecialAttribute((GBeanAttribute) attributesMap
1356:                                .get("abstractName"), this , "abstractName",
1357:                                AbstractName.class, getAbstractName()));
1358:
1359:                attributesMap.put("objectName", GBeanAttribute
1360:                        .createSpecialAttribute((GBeanAttribute) attributesMap
1361:                                .get("objectName"), this , "objectName",
1362:                                String.class, getObjectName()));
1363:
1364:                attributesMap.put("classLoader", GBeanAttribute
1365:                        .createSpecialAttribute((GBeanAttribute) attributesMap
1366:                                .get("classLoader"), this , "classLoader",
1367:                                ClassLoader.class, classLoader));
1368:
1369:                attributesMap.put("kernel", GBeanAttribute
1370:                        .createSpecialAttribute((GBeanAttribute) attributesMap
1371:                                .get("kernel"), this , "kernel", Kernel.class,
1372:                                kernel));
1373:
1374:            }
1375:
1376:            private GBeanInfo rebuildGBeanInfo(GConstructorInfo constructor,
1377:                    String j2eeType) {
1378:                Set attributeInfos = new HashSet();
1379:                for (int i = 0; i < attributes.length; i++) {
1380:                    GBeanAttribute attribute = attributes[i];
1381:                    attributeInfos.add(attribute.getAttributeInfo());
1382:                }
1383:                Set operationInfos = new HashSet();
1384:                for (int i = 0; i < operations.length; i++) {
1385:                    operationInfos.add(operations[i].getOperationInfo());
1386:                }
1387:
1388:                Set referenceInfos = new HashSet();
1389:                for (int i = 0; i < references.length; i++) {
1390:                    referenceInfos.add(references[i].getReferenceInfo());
1391:                }
1392:
1393:                Set interfaceInfos = new HashSet();
1394:                for (int i = 0; i < interfaces.length; i++) {
1395:                    interfaceInfos.add(interfaces[i]);
1396:                }
1397:
1398:                return new GBeanInfo(name, type.getName(), j2eeType,
1399:                        attributeInfos, constructor, operationInfos,
1400:                        referenceInfos, interfaceInfos);
1401:            }
1402:
1403:            public boolean equals(Object obj) {
1404:                if (obj == this )
1405:                    return true;
1406:                if (!(obj instanceof  GBeanInstance))
1407:                    return false;
1408:                return abstractName.equals(((GBeanInstance) obj).abstractName);
1409:            }
1410:
1411:            public int hashCode() {
1412:                return abstractName.hashCode();
1413:            }
1414:
1415:            public String toString() {
1416:                return abstractName.toString();
1417:            }
1418:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.