Source Code Cross Referenced for ContainerSupport.java in  » Science » Cougaar12_4 » org » cougaar » core » component » 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 » Science » Cougaar12_4 » org.cougaar.core.component 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * <copyright>
0003:         *  
0004:         *  Copyright 2000-2004 BBNT Solutions, LLC
0005:         *  under sponsorship of the Defense Advanced Research Projects
0006:         *  Agency (DARPA).
0007:         * 
0008:         *  You can redistribute this software and/or modify it under the
0009:         *  terms of the Cougaar Open Source License as published on the
0010:         *  Cougaar Open Source Website (www.cougaar.org).
0011:         * 
0012:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023:         *  
0024:         * </copyright>
0025:         */
0026:        package org.cougaar.core.component;
0027:
0028:        import java.util.ArrayList;
0029:        import java.util.Collection;
0030:        import java.util.Collections;
0031:        import java.util.Iterator;
0032:        import java.util.List;
0033:        import java.util.Map;
0034:        import java.beans.beancontext.*; /*make @see reference work*/
0035:
0036:        import org.cougaar.util.GenericStateModel;
0037:        import org.cougaar.util.GenericStateModelAdapter;
0038:        import org.cougaar.util.RarelyModifiedList;
0039:        import org.cougaar.util.Mappings;
0040:        import org.cougaar.util.Mapping;
0041:        import org.cougaar.util.Filters;
0042:        import org.cougaar.util.UnaryPredicate;
0043:        import org.cougaar.util.log.Logger;
0044:        import org.cougaar.util.log.Logging;
0045:
0046:        /**
0047:         * The standard implementation of a Container.
0048:         * <p>
0049:         * Although this implementation defines many protected methods,
0050:         * it is long overdue for a major refactor, so developers should avoid
0051:         * complex subclassing to allow for future ContainerSupport cleanup.
0052:         * A simple ContainerSupport subclass, such as this example in
0053:         * core:<br>
0054:         * <code>org.cougaar.core.wp.resolver.ResolverContainer</code><br>
0055:         * will only define the two required abstract methods and allow
0056:         * child components to advertise any necessary services.
0057:         * <p>
0058:         * Future refactor ideas include:<ul>
0059:         *   <li>Obvious overall code cleanup into smaller classes and
0060:         *       cleaner code.</li>
0061:         *   <li>Remove last remnants of component proprity (HIGH/BINDER/etc),
0062:         *       since the core no longer uses it (bug 2522).</li>
0063:         *   <li>Replace "*.Binder" and ".BinderFactory" insertion point
0064:         *       extension and "attachBinderFactory" with a new
0065:         *       "BinderFactoryService" advertised by this container,
0066:         *       and fix BinderFactories/Binders to use the new service.</li>
0067:         *   <li>Make a clearer distinction between binders that instantiate
0068:         *       components v.s. binders that monitor service access.
0069:         *       Create a new ComponentFactoryService for the former.</li>
0070:         *   <li>Extract state model actions (load/start/etc) to a
0071:         *       binder or StateModelService, to make it easier for binders
0072:         *       to intercept these calls and allow custom state model
0073:         *       implementations (e.g. better threading, new states,
0074:         *       etc).</li>
0075:         *   <li>With the above changes, limit Binders to ServiceBroker
0076:         *       interactions and remove "ContainerProxy" and literal
0077:         *       binder chaining -- to support service-focused binders,
0078:         *       all we need to do is intercept ServiceBroker calls!</li>
0079:         *   <li>Plenty more to do..</li>
0080:         * </ul> 
0081:         */
0082:        public abstract class ContainerSupport extends GenericStateModelAdapter
0083:                implements  Container, StateObject {
0084:            private static final boolean ENABLE_VIEW_SERVICE = true;
0085:
0086:            protected final ComponentFactory componentFactory = specifyComponentFactory();
0087:            /** this is the prefix that all subcomponents must have as a prefix **/
0088:            protected final String containmentPrefix = specifyContainmentPoint()
0089:                    + ".";
0090:
0091:            protected Object loadState = null;
0092:
0093:            private ComponentDescriptions externalComponentDescriptions = null;
0094:
0095:            // my service broker
0096:            protected ServiceBroker serviceBroker = null;
0097:
0098:            // the service broker for all child components
0099:            protected ServiceBroker childServiceBroker = null;
0100:
0101:            /** The actual set of child BoundComponent loaded. 
0102:             * @see org.cougaar.core.component.BoundComponent
0103:             **/
0104:            private final RarelyModifiedList boundComponents = new RarelyModifiedList();
0105:
0106:            /** a Sorted Collection of child BinderFactory components.
0107:             * Note that we cannot use TreeSet because of the Collection API's
0108:             * braindamaged insistance on conflating identity and order, so
0109:             * this is a regular arraylist which we keep sorted by hand.
0110:             **/
0111:            protected final ArrayList binderFactories = new ArrayList();
0112:
0113:            /**
0114:             * The ComponentDescriptions for loaded binder factories.
0115:             **/
0116:            protected final ArrayList binderFactoryDescriptions = new ArrayList();
0117:
0118:            protected ContainerSupport() {
0119:                // child service broker
0120:                ServiceBroker csb = specifyChildServiceBroker();
0121:                if (csb != null)
0122:                    setChildServiceBroker(csb);
0123:
0124:                // binder factory
0125:                BinderFactory bf = createBinderFactory();
0126:                if (bf != null && !attachBinderFactory(bf)) {
0127:                    throw new RuntimeException(
0128:                            "Failed to load the DefaultBinderFactory");
0129:                }
0130:            }
0131:
0132:            /** Overridable by extending classes to capture the BindingSite. **/
0133:            public void setBindingSite(BindingSite bs) {
0134:                this .serviceBroker = bs.getServiceBroker();
0135:
0136:                // late-binding child service broker
0137:                ServiceBroker csb = createChildServiceBroker(bs);
0138:                if (csb != null) {
0139:                    setChildServiceBroker(csb);
0140:                }
0141:            }
0142:
0143:            protected ServiceBroker getServiceBroker() {
0144:                return serviceBroker;
0145:            }
0146:
0147:            /** override to specify a different component factory class. 
0148:             * Called once during initialization.
0149:             **/
0150:            protected ComponentFactory specifyComponentFactory() {
0151:                return new ComponentFactory() {
0152:                };
0153:            }
0154:
0155:            /** override to specify insertion point of this component, 
0156:             * the parent insertion point which sub Components must match,
0157:             * e.g. "Node.AgentManager.Agent.PluginManager"
0158:             * this is called once during initialization.
0159:             **/
0160:            protected abstract String specifyContainmentPoint();
0161:
0162:            /** override to specify a the ServiceBroker object to use for children. 
0163:             * this is called once during initialization.
0164:             * Note that this value might be only part of the process for 
0165:             * actually finding the services for children and/or peers.
0166:             * <p>
0167:             * Either this method must be overridden to return a non-null value,
0168:             * or the subclass must call setChildServiceBroker exactly once with 
0169:             * a non-null value.
0170:             **/
0171:            protected ServiceBroker specifyChildServiceBroker() {
0172:                return null;
0173:            }
0174:
0175:            protected ServiceBroker createChildServiceBroker(BindingSite bs) {
0176:                return new DefaultServiceBroker(bs);
0177:            }
0178:
0179:            protected void destroyChildServiceBroker(ServiceBroker csb) {
0180:                if (csb instanceof  DefaultServiceBroker) {
0181:                    ((DefaultServiceBroker) csb).myDestroy();
0182:                }
0183:            }
0184:
0185:            protected final void setChildServiceBroker(ServiceBroker sb) {
0186:                if (sb == null) {
0187:                    throw new IllegalArgumentException(
0188:                            "Specified ServiceBroker must not be null");
0189:                }
0190:                if (childServiceBroker != null) {
0191:                    throw new IllegalArgumentException(
0192:                            "ServiceBroker already set");
0193:                }
0194:                childServiceBroker = sb;
0195:            }
0196:
0197:            /**
0198:             * For subclass use, get the service broker shared by the child
0199:             * components, which the container subclass can use to directly
0200:             * add services.
0201:             * <p>
0202:             * Subclassing container is messy, and there are only a few
0203:             * examples in Cougaar where it is done, and even those should
0204:             * probably be refactored away.
0205:             * <p> 
0206:             * Here we return a throw-away ViewedServiceBroker to intercept
0207:             * "addService" calls, otherwise the ViewService for the service
0208:             * clients will lack the provider "id" and component description.
0209:             */
0210:            protected ServiceBroker getChildServiceBroker() {
0211:                ServiceBroker csb = childServiceBroker;
0212:                if (!ENABLE_VIEW_SERVICE) {
0213:                    return csb;
0214:                }
0215:                ComponentView cv = getContainerView();
0216:                if (cv == null) {
0217:                    return csb;
0218:                }
0219:                final int id = cv.getId();
0220:                final ComponentDescription cd = cv.getComponentDescription();
0221:                return new ViewedServiceBroker(csb, id, cd, null, null);
0222:            }
0223:
0224:            /** Return (or construct) a serviceBroker instance for 
0225:             * a particular child component.
0226:             * <p>The default is to ignore the child and return the value
0227:             * of getChildServiceBroker with no arguments.
0228:             * <p>This can be used to build per-child ServiceBroker instances
0229:             * as a simpler option than adding an additional high-priority wrapping binder.
0230:             * See also getChildContainerProxy.
0231:             **/
0232:            protected ServiceBroker getChildServiceBroker(Binder b, Object child) {
0233:                ServiceBroker csb = childServiceBroker;
0234:                if (!ENABLE_VIEW_SERVICE) {
0235:                    return csb;
0236:                }
0237:                int id = ViewedServiceBroker.nextId();
0238:                ComponentDescription cd = (child instanceof  ComponentDescription ? ((ComponentDescription) child)
0239:                        : null);
0240:                ContainerView parentView = getContainerView();
0241:                // note that the parentView can be null, which occurs in the root
0242:                // container or if a binder blocks access.  This is fine.   
0243:                return new ViewedServiceBroker(csb, id, cd, parentView, b);
0244:            }
0245:
0246:            // package-private for ContainerBinderSupport access
0247:            List getChildViews() {
0248:                if (!ENABLE_VIEW_SERVICE) {
0249:                    return Collections.EMPTY_LIST;
0250:                }
0251:                int nbf = binderFactoryDescriptions.size();
0252:                List ret = new ArrayList(nbf + boundComponents.size());
0253:                // ugly hack for binders, since they're not created like
0254:                // normal components, but at least we know the compDesc.
0255:                // See above RFE for BinderFactoryService!
0256:                for (int i = 0; i < nbf; i++) {
0257:                    Object o = binderFactoryDescriptions.get(i);
0258:                    if (o instanceof  ComponentDescription) {
0259:                        final ComponentDescription cd = (ComponentDescription) o;
0260:                        // better to have a throw-away id that none at all?
0261:                        final int id = ViewedServiceBroker.nextId();
0262:                        ComponentView cv = new ComponentView() {
0263:                            public int getId() {
0264:                                return id;
0265:                            }
0266:
0267:                            public long getTimestamp() {
0268:                                return 0;
0269:                            }
0270:
0271:                            public ComponentDescription getComponentDescription() {
0272:                                return cd;
0273:                            }
0274:
0275:                            public ContainerView getParentView() {
0276:                                return null;
0277:                            }
0278:
0279:                            public Map getAdvertisedServices() {
0280:                                return null;
0281:                            }
0282:
0283:                            public Map getObtainedServices() {
0284:                                return null;
0285:                            }
0286:                        };
0287:                        ret.add(cv);
0288:                    }
0289:                }
0290:                for (Iterator it = boundComponents.iterator(); it.hasNext();) {
0291:                    BoundComponent bc = (BoundComponent) it.next();
0292:                    ret.add(bc.getComponentView());
0293:                }
0294:                return Collections.unmodifiableList(ret);
0295:            }
0296:
0297:            private boolean gotContainerView;
0298:            private ContainerView containerView;
0299:
0300:            private ContainerView getContainerView() {
0301:                if (!ENABLE_VIEW_SERVICE) {
0302:                    return null;
0303:                }
0304:                if (!gotContainerView) {
0305:                    ViewService vs = (ViewService) serviceBroker.getService(
0306:                            this , ViewService.class, null);
0307:                    if (vs != null) {
0308:                        ComponentView pv = vs.getComponentView();
0309:                        if (pv instanceof  ContainerView) {
0310:                            containerView = (ContainerView) pv;
0311:                        }
0312:                    }
0313:                    gotContainerView = true;
0314:                }
0315:                return containerView;
0316:            }
0317:
0318:            protected BinderFactory createBinderFactory() {
0319:                return new DefaultBinderFactory();
0320:            }
0321:
0322:            //
0323:            // implement collection
0324:            //
0325:
0326:            public int size() {
0327:                return boundComponents.size();
0328:            }
0329:
0330:            public boolean isEmpty() {
0331:                return boundComponents.isEmpty();
0332:            }
0333:
0334:            public boolean contains(Object o) {
0335:                // note that we don't sync on boundComponents here
0336:                if (o instanceof  ComponentDescription) {
0337:                    ComponentDescription cd = (ComponentDescription) o;
0338:                    String ip = cd.getInsertionPoint();
0339:                    if (!(ip.startsWith(containmentPrefix))) {
0340:                        return false;
0341:                    }
0342:                    final boolean isDirectChild = (0 >= ip.indexOf('.',
0343:                            containmentPrefix.length()));
0344:
0345:                    for (Iterator it = boundComponents.iterator(); it.hasNext();) {
0346:                        Object oi = it.next();
0347:                        if (!(oi instanceof  BoundComponent)) {
0348:                            continue;
0349:                        }
0350:                        BoundComponent bc = (BoundComponent) oi;
0351:                        Object bcc = bc.getComponent();
0352:                        if (!(bcc instanceof  ComponentDescription)) {
0353:                            continue;
0354:                        }
0355:                        ComponentDescription bccd = (ComponentDescription) bcc;
0356:                        if (isDirectChild) {
0357:                            // at this level in hierarchy
0358:                            if (cd.equals(bccd)) {
0359:                                return true;
0360:                            }
0361:                        } else {
0362:                            // child container
0363:                            Binder bcb = bc.getBinder();
0364:                            if ((bcb instanceof  ContainerBinder)
0365:                                    && (ip.startsWith(bccd.getInsertionPoint()))
0366:                                    && (((ContainerBinder) bcb).contains(cd))) {
0367:                                return true;
0368:                            }
0369:                        }
0370:                    }
0371:                } else if (o instanceof  Component) {
0372:                    // FIXME no good way to find the insertion point!
0373:                    for (Iterator it = boundComponents.iterator(); it.hasNext();) {
0374:                        BoundComponent bc = (BoundComponent) it.next();
0375:                        if (bc.getComponent().equals(o))
0376:                            return true;
0377:                    }
0378:                }
0379:                return false;
0380:            }
0381:
0382:            /** map BoundComponent to Component (usually ComponentDescription) **/
0383:            private static final Mapping map_bc2c = new Mapping() {
0384:                public final Object map(Object o) {
0385:                    return ((BoundComponent) o).getComponent();
0386:                }
0387:            };
0388:
0389:            /** return an iterator of the boundComponents by component **/
0390:            public Iterator iterator() {
0391:                return componentIterator();
0392:            }
0393:
0394:            public Iterator componentIterator() {
0395:                return Mappings.map(map_bc2c, boundComponents.iterator());
0396:            }
0397:
0398:            protected final Iterator bcIterator() {
0399:                return boundComponents.iterator();
0400:            }
0401:
0402:            public boolean containsComponent(ComponentDescription cd) {
0403:                for (Iterator it = iterator(); it.hasNext();) {
0404:                    if (cd.equals(it.next())) {
0405:                        return true;
0406:                    }
0407:                }
0408:                return false;
0409:            }
0410:
0411:            private static final UnaryPredicate pred_isComponentDescription = new UnaryPredicate() {
0412:                public final boolean execute(Object o) {
0413:                    return o instanceof  ComponentDescription;
0414:                }
0415:            };
0416:
0417:            /** Get a List of all child components by description.
0418:             * @note this creates a new list each call unless it is empty.
0419:             * it is better to use the iterator.
0420:             */
0421:            protected List listComponents() {
0422:                return (List) Filters.filter(iterator(),
0423:                        pred_isComponentDescription);
0424:            }
0425:
0426:            protected List getBoundComponentList() {
0427:                return boundComponents.getUnmodifiableList();
0428:            }
0429:
0430:            protected Iterator getBoundComponentIterator() {
0431:                return boundComponents.iterator();
0432:            }
0433:
0434:            /** Map BoundComponent to Binder **/
0435:            private static final Mapping map_bc2b = new Mapping() {
0436:                public final Object map(Object o) {
0437:                    return ((BoundComponent) o).getBinder();
0438:                }
0439:            };
0440:
0441:            /**
0442:             * Get an Iterator of all child Binders.
0443:             *
0444:             * @see #listBinders
0445:             */
0446:            protected Iterator binderIterator() {
0447:                return Mappings.map(map_bc2b, boundComponents.iterator());
0448:            }
0449:
0450:            /**
0451:             * Get a List of all child Binders.
0452:             * @note this creates a new list each call unless it is empty.
0453:             * it is better to use the binderIterator.
0454:             */
0455:            protected List listBinders() {
0456:                Iterator it = binderIterator();
0457:                if (!it.hasNext()) {
0458:                    return Collections.EMPTY_LIST;
0459:                } else {
0460:                    List l = new ArrayList();
0461:                    while (it.hasNext()) {
0462:                        l.add(it.next());
0463:                    }
0464:                    return l;
0465:                }
0466:            }
0467:
0468:            /**
0469:             * Add to the container, returning true if the object 
0470:             * is added, false if it is already contained, and throw an 
0471:             * exception in all other cases.
0472:             */
0473:            public boolean add(Object o) {
0474:                ComponentDescription cd;
0475:                Object cstate;
0476:                if (o instanceof  ComponentDescription) {
0477:                    // typical component description
0478:                    cd = (ComponentDescription) o;
0479:                    cstate = null;
0480:                } else if (o instanceof  StateTuple) {
0481:                    // description plus initial state
0482:                    StateTuple st = (StateTuple) o;
0483:                    cd = st.getComponentDescription();
0484:                    cstate = st.getState();
0485:                } else if (o instanceof  BinderFactory) {
0486:                    // unusual case -- prefer to load from cd
0487:                    return attachBinderFactory((BinderFactory) o);
0488:                } else if (o instanceof  Component) {
0489:                    // unusual case -- prefer to load from cd
0490:                    return addComponent(o, null);
0491:                } else {
0492:                    // not a clue.
0493:                    throw new IllegalArgumentException(
0494:                            "Unsupported container element type: "
0495:                                    + ((o != null) ? o.getClass().getName()
0496:                                            : "null"));
0497:                }
0498:
0499:                // load from a component description
0500:                String ip = ((cd != null) ? cd.getInsertionPoint() : null);
0501:                if (ip == null) {
0502:                    // description or insertion point not specified
0503:                    throw new IllegalArgumentException(
0504:                            "ComponentDescription must specify an insertion point");
0505:                }
0506:                if (!(ip.startsWith(containmentPrefix))) {
0507:                    // wrong insertion point
0508:                    throw new IncorrectInsertionPointException(
0509:                            "Insertion point " + ip
0510:                                    + " doesn't match container's "
0511:                                    + containmentPrefix, cd);
0512:                }
0513:
0514:                // match! - now do we load it here or below - look for any more 
0515:                // dots beyond the one trailing the prefix...
0516:                String tail = ip.substring(containmentPrefix.length());
0517:                if ("Binder".equals(tail) || "BinderFactory".equals(tail)) {
0518:                    // load binder factory, ignore cstate?
0519:                    return loadBinderFactory(cd);
0520:                }
0521:
0522:                boolean isDirectChild = (0 >= tail.indexOf('.'));
0523:
0524:                if (isDirectChild) { // no more dots
0525:                    // already loaded?
0526:                    if (containsComponent(cd))
0527:                        return false;
0528:
0529:                    return addComponent(cd, cstate);
0530:                } else { // more dots: try inserting in subcomponents
0531:                    for (Iterator it = boundComponents.iterator(); it.hasNext();) {
0532:                        BoundComponent bc = (BoundComponent) it.next();
0533:
0534:                        Binder b = bc.getBinder();
0535:                        if (b instanceof  ContainerBinder) {
0536:                            Object bcc = bc.getComponent();
0537:                            if (bcc instanceof  ComponentDescription) {
0538:                                ComponentDescription bccd = (ComponentDescription) bcc;
0539:                                if (!(ip.startsWith(bccd.getInsertionPoint()))) {
0540:                                    continue;
0541:                                }
0542:                            } else {
0543:                                // non-desc child, but okay
0544:                            }
0545:
0546:                            try {
0547:                                boolean ret = ((ContainerBinder) b).add(o);
0548:                                // child already contains or added it
0549:                                return ret;
0550:                            } catch (IncorrectInsertionPointException ipE) {
0551:                                // wrong insertion point
0552:                            }
0553:                        }
0554:                    }
0555:                }
0556:                // not at this level, and no child accepted it
0557:                throw new ComponentLoadFailure(
0558:                        "Component not loaded by this container ("
0559:                                + containmentPrefix + ") or its children", cd);
0560:            }
0561:
0562:            public boolean remove(Object o) {
0563:                if (!(o instanceof  ComponentDescription)) {
0564:                    // could support Components, but not required at this time
0565:                    throw new UnsupportedOperationException(
0566:                            "Removal of non-ComponentDescription not supported");
0567:                }
0568:
0569:                ComponentDescription cd = (ComponentDescription) o;
0570:                String ip = cd.getInsertionPoint();
0571:                if ((ip == null) || (!(ip.startsWith(containmentPrefix)))) {
0572:                    return false;
0573:                }
0574:                String tail = ip.substring(containmentPrefix.length());
0575:
0576:                if ("Binder".equals(tail) || "BinderFactory".equals(tail)) {
0577:                    throw new UnsupportedOperationException(
0578:                            "Binder and BinderFactory removal not supported ("
0579:                                    + ip + ")");
0580:                }
0581:
0582:                boolean isDirectChild = (0 >= tail.indexOf('.'));
0583:
0584:                // find the child and remove it
0585:                Binder removedBinder = null;
0586:                synchronized (boundComponents) {
0587:                    for (Iterator it = boundComponents.iterator(); it.hasNext();) {
0588:                        BoundComponent bc = (BoundComponent) it.next();
0589:
0590:                        Object bcc = bc.getComponent();
0591:                        if (!(bcc instanceof  ComponentDescription)) {
0592:                            continue;
0593:                        }
0594:                        ComponentDescription bccd = (ComponentDescription) bcc;
0595:                        if (isDirectChild) {
0596:                            // at this level in hierarchy
0597:                            if (cd.equals(bccd)) {
0598:                                removedBinder = bc.getBinder();
0599:                                boundComponents.remove(bc); // cannot use it.remove() here
0600:                                break;
0601:                            }
0602:                        } else {
0603:                            // child container
0604:                            String bctail = bccd.getInsertionPoint().substring(
0605:                                    containmentPrefix.length());
0606:
0607:                            if (tail.startsWith(bctail)) {
0608:                                Binder bcb = bc.getBinder();
0609:                                if ((bcb instanceof  ContainerBinder)
0610:                                        && (((ContainerBinder) bcb).remove(cd))) {
0611:                                    // bail out completely - need not remove anything locally
0612:                                    return true;
0613:                                }
0614:                            }
0615:                        }
0616:                    }
0617:                }
0618:
0619:                if (removedBinder == null) {
0620:                    return false;
0621:                } // wasn't there to remove
0622:
0623:                // unload the removed direct child
0624:                try {
0625:                    switch (removedBinder.getModelState()) {
0626:                    case GenericStateModel.ACTIVE:
0627:                        removedBinder.suspend();
0628:                        // fall-through
0629:                    case GenericStateModel.IDLE:
0630:                        removedBinder.stop();
0631:                        // fall-through
0632:                    case GenericStateModel.LOADED:
0633:                        removedBinder.unload();
0634:                        // fall-through
0635:                    case GenericStateModel.UNLOADED:
0636:                        // unloaded
0637:                        break;
0638:                    default:
0639:                        // should never happen
0640:                        throw new IllegalStateException(
0641:                                "Illegal binder state: "
0642:                                        + removedBinder.getModelState());
0643:                    }
0644:                } catch (RuntimeException e) {
0645:                    throw new ComponentRuntimeException(
0646:                            "Removed component with unclean unload", cd, e);
0647:                }
0648:
0649:                return true;
0650:            }
0651:
0652:            /** Add all elements of Collection to the collection, in the order specified **/
0653:            public boolean addAll(Collection c) {
0654:                boolean allAdded = true;
0655:                for (Iterator it = c.iterator(); it.hasNext();) {
0656:                    Object o = it.next();
0657:                    boolean succ = add(o);
0658:                    allAdded = allAdded && (!succ);
0659:                }
0660:                return allAdded;
0661:            }
0662:
0663:            // unsupported Collection ops
0664:            public void clear() {
0665:                throw new UnsupportedOperationException();
0666:            }
0667:
0668:            public Object[] toArray() {
0669:                throw new UnsupportedOperationException();
0670:            }
0671:
0672:            public Object[] toArray(Object[] ignore) {
0673:                throw new UnsupportedOperationException();
0674:            }
0675:
0676:            public boolean containsAll(Collection c) {
0677:                throw new UnsupportedOperationException();
0678:            }
0679:
0680:            public boolean removeAll(Collection c) {
0681:                throw new UnsupportedOperationException();
0682:            }
0683:
0684:            public boolean retainAll(Collection c) {
0685:                throw new UnsupportedOperationException();
0686:            }
0687:
0688:            /**
0689:             * Add a component into our set.  We are sure that this is
0690:             * the requested level, but might not be certain how much we trust
0691:             * it as of yet.  In particular, we may need to treat different classes
0692:             * of Components differently.
0693:             * <p>
0694:             * The component (and the binder tree) will be transitioned to
0695:             * our container's current model state (e.g. ACTIVE).
0696:             *
0697:             * @return true on success.
0698:             * @throws ComponentLoadFailure when the component can not be loaded.
0699:             **/
0700:            protected boolean addComponent(Object c, Object cstate) {
0701:                Binder b = bindComponent(c);
0702:                if (b == null) {
0703:                    throw new ComponentLoadFailure("No binder found", c);
0704:                }
0705:                ServiceBroker sb = getChildServiceBroker(b, c);
0706:                BindingUtility.setBindingSite(b, getChildContainerProxy(c, sb));
0707:                BindingUtility.setServices(b, sb);
0708:                if (cstate != null) {
0709:                    b.setState(cstate);
0710:                }
0711:                ComponentView cv = (ENABLE_VIEW_SERVICE
0712:                        && (sb instanceof  ViewedServiceBroker) ? ((ViewedServiceBroker) sb)
0713:                        .getComponentView()
0714:                        : null);
0715:                BoundComponent bc = new BoundComponent(b, c, cv);
0716:                boundComponents.add(bc);
0717:
0718:                // transition state to match our container's state
0719:                int myState = getModelState();
0720:                boolean suspend = (myState == GenericStateModel.IDLE);
0721:                boolean start = (suspend || myState == GenericStateModel.ACTIVE);
0722:                boolean load = (start || myState == GenericStateModel.LOADED);
0723:                boolean init = (load || myState != GenericStateModel.UNINITIALIZED);
0724:                if (init) {
0725:                    b.initialize();
0726:                    if (load) {
0727:                        b.load();
0728:                        if (start) {
0729:                            b.start();
0730:                            if (suspend) {
0731:                                b.suspend();
0732:                            }
0733:                        }
0734:                    }
0735:                }
0736:                return true;
0737:            }
0738:
0739:            /**
0740:             * Find a BinderFactory willing to bind this component, then
0741:             * wrap it with BinderFactoryWrappers.
0742:             */
0743:            protected Binder bindComponent(Object c) {
0744:                synchronized (binderFactories) {
0745:                    ArrayList wrappers = null;
0746:
0747:                    // find a binder factory that will bind this component
0748:                    Binder b = null;
0749:                    for (Iterator i = binderFactories.iterator(); i.hasNext();) {
0750:                        BinderFactory bf = (BinderFactory) i.next();
0751:                        if (bf instanceof  BinderFactoryWrapper) {
0752:                            if (wrappers == null) {
0753:                                wrappers = new ArrayList(1);
0754:                            }
0755:                            wrappers.add(bf);
0756:                        } else {
0757:                            b = bf.getBinder(c);
0758:                            if (b != null) {
0759:                                break;
0760:                            }
0761:                        }
0762:                    }
0763:
0764:                    // now apply any wrappers, iterating from "last to innermost"
0765:                    if (wrappers != null) {
0766:                        int l = wrappers.size();
0767:                        for (int i = l - 1; i >= 0; i--) {
0768:                            BinderFactoryWrapper bf = (BinderFactoryWrapper) wrappers
0769:                                    .get(i);
0770:                            Binder w = bf.getBinder((b == null) ? c : b);
0771:                            if (w != null) {
0772:                                b = w;
0773:                            }
0774:                        }
0775:                    }
0776:
0777:                    return b;
0778:                }
0779:            }
0780:
0781:            /** Called when a componentDescription insertion point ends in .Binder or .BinderFactory 
0782:             * @throws ComponentFactoryException if the BinderFactory Cannot be loaded.
0783:             **/
0784:            protected boolean loadBinderFactory(ComponentDescription cd) {
0785:                if (checkBinderFactory(cd)) {
0786:                    Component bfc = componentFactory.createComponent(cd);
0787:                    if (bfc instanceof  BinderFactory) {
0788:                        binderFactoryDescriptions.add(cd);
0789:                        return attachBinderFactory((BinderFactory) bfc);
0790:                    } else {
0791:                        throw new ComponentLoadFailure("Not a BinderFactory",
0792:                                cd);
0793:                    }
0794:                } else {
0795:                    throw new ComponentLoadFailure("Failed BinderFactory test",
0796:                            cd);
0797:                }
0798:            }
0799:
0800:            /** @return true iff the binderfactory is trusted enought to load **/
0801:            protected boolean checkBinderFactory(ComponentDescription cd) {
0802:                return true;
0803:            }
0804:
0805:            /** Activate a binder factory
0806:             **/
0807:            protected boolean attachBinderFactory(BinderFactory c) {
0808:                synchronized (binderFactories) {
0809:                    binderFactories.add(c);
0810:                    Collections.sort(binderFactories, BinderFactory.comparator);
0811:                }
0812:                // FIXME this should be a ViewedServiceBroker!
0813:                ServiceBroker sb = childServiceBroker;
0814:                return BindingUtility.activate(c,
0815:                        getChildContainerProxy(c, sb), sb);
0816:            }
0817:
0818:            /** Specifies an object to use as the "parent" proxy object
0819:             * for a particular object (generally an <em>unbound</em> component).
0820:             * This will be either be the Container itself (this) or a
0821:             * simple proxy for the container so that BinderFactory instances
0822:             * cannot downcast the object to get additional privileges.
0823:             **/
0824:            protected ContainerAPI getChildContainerProxy(Object o,
0825:                    ServiceBroker sb) {
0826:                return new DefaultProxy(sb);
0827:            }
0828:
0829:            /** Matching setter for getExternalComponentDescriptions **/
0830:            protected final void setExternalComponentDescriptions(
0831:                    ComponentDescriptions cds) {
0832:                externalComponentDescriptions = cds;
0833:            }
0834:
0835:            public void setState(Object loadState) {
0836:                this .loadState = loadState;
0837:            }
0838:
0839:            public Object getState() {
0840:                return captureState();
0841:            }
0842:
0843:            protected ComponentDescriptions captureState() {
0844:                synchronized (boundComponents) {
0845:                    List l = new ArrayList(boundComponents.size()
0846:                            + binderFactoryDescriptions.size());
0847:                    l.addAll(binderFactoryDescriptions);
0848:                    for (Iterator it = bcIterator(); it.hasNext();) {
0849:                        BoundComponent bc = (BoundComponent) it.next();
0850:                        Object comp = bc.getComponent();
0851:                        if (comp instanceof  ComponentDescription) {
0852:                            ComponentDescription cd = (ComponentDescription) comp;
0853:                            Binder b = bc.getBinder();
0854:                            Object state = b.getState();
0855:                            StateTuple ti = new StateTuple(cd, state);
0856:                            l.add(ti);
0857:                        } else {
0858:                            // error?
0859:                        }
0860:                    }
0861:                    return new ComponentDescriptions(l);
0862:                }
0863:            }
0864:
0865:            protected abstract ComponentDescriptions findInitialComponentDescriptions();
0866:
0867:            /** return a ComponentDescriptions object which contains a set of ComponentDescriptions
0868:             * defined externally to be loaded into this Container. 
0869:             * This will return the value computed by findExternalComponentDescriptions()
0870:             * Note that this value is not filled until ContainerSupport.load() has been called.
0871:             * @see #findExternalComponentDescriptions
0872:             * @return null if no component descriptions specified.
0873:             */
0874:            protected final ComponentDescriptions getExternalComponentDescriptions() {
0875:                return externalComponentDescriptions;
0876:            }
0877:
0878:            /** Extending classes may override this method to define a set of externally-specified
0879:             * Component to load.  Will be called during load() immediately after super.load().
0880:             * load will set the value returned by getExternalComponentDescriptions(), so that 
0881:             * loadInternalSubcomponents, etc can retrieve the values.
0882:             * @return null if none.
0883:             */
0884:            protected ComponentDescriptions findExternalComponentDescriptions() {
0885:                if (loadState instanceof  ComponentDescriptions) {
0886:                    ComponentDescriptions descs = (ComponentDescriptions) loadState;
0887:                    loadState = null;
0888:                    return descs;
0889:                } else {
0890:                    // ask the container
0891:                    return findInitialComponentDescriptions();
0892:                }
0893:            }
0894:
0895:            public void initialize() {
0896:                super .initialize();
0897:                // not expecting any child components this early
0898:                for (Iterator childBinders = binderIterator(); childBinders
0899:                        .hasNext();) {
0900:                    Binder b = (Binder) childBinders.next();
0901:                    b.initialize();
0902:                }
0903:            }
0904:
0905:            /** 
0906:             * Called by super.load() to transit the state, sets the value of
0907:             * getExternalComponentDescriptions() 
0908:             * by calling
0909:             * findExternalComponentDescriptions(),
0910:             * then invokes each of
0911:             * <ul>
0912:             * <li>loadHighPriorityComponents()</li>
0913:             * <li>loadInternalPriorityComponents()</li>
0914:             * <li>loadBinderPriorityComponents()</li>
0915:             * <li>loadComponentPriorityComponents()</li>
0916:             * <li>loadLowPriorityComponents()</li>
0917:             * </ul>
0918:             * in order.
0919:             */
0920:            public void load() {
0921:                super .load();
0922:                setExternalComponentDescriptions(findExternalComponentDescriptions());
0923:                loadHighPriorityComponents();
0924:                loadInternalPriorityComponents();
0925:                loadBinderPriorityComponents();
0926:                loadComponentPriorityComponents();
0927:                loadLowPriorityComponents();
0928:            }
0929:
0930:            public void start() {
0931:                super .start();
0932:                for (Iterator childBinders = binderIterator(); childBinders
0933:                        .hasNext();) {
0934:                    Binder b = (Binder) childBinders.next();
0935:                    b.start();
0936:                }
0937:            }
0938:
0939:            public void suspend() {
0940:                super .suspend();
0941:                List childBinders = listBinders();
0942:                for (int i = childBinders.size() - 1; i >= 0; i--) {
0943:                    Binder b = (Binder) childBinders.get(i);
0944:                    b.suspend();
0945:                }
0946:            }
0947:
0948:            public void resume() {
0949:                super .resume();
0950:                for (Iterator childBinders = binderIterator(); childBinders
0951:                        .hasNext();) {
0952:                    Binder b = (Binder) childBinders.next();
0953:                    b.resume();
0954:                }
0955:            }
0956:
0957:            public void stop() {
0958:                super .stop();
0959:                List childBinders = listBinders();
0960:                for (int i = childBinders.size() - 1; i >= 0; i--) {
0961:                    Binder b = (Binder) childBinders.get(i);
0962:                    b.stop();
0963:                }
0964:            }
0965:
0966:            public void halt() {
0967:                suspend();
0968:                stop();
0969:            }
0970:
0971:            public void unload() {
0972:                super .unload();
0973:
0974:                List childBinders = listBinders();
0975:                for (int i = childBinders.size() - 1; i >= 0; i--) {
0976:                    Binder b = (Binder) childBinders.get(i);
0977:                    b.unload();
0978:                }
0979:                boundComponents.clear();
0980:
0981:                if (childServiceBroker != null) {
0982:                    destroyChildServiceBroker(childServiceBroker);
0983:                    childServiceBroker = null;
0984:                }
0985:            }
0986:
0987:            /** Should check the ComponentDescription to see if it should
0988:             * be loaded into the Container.  Implementations may use any rules 
0989:             * they'd like.  The default implementation returns true IFF the
0990:             * insertion point of the ComponentDescription is a direct child
0991:             * of the ContainmentPoint.  The basic component model only calls
0992:             * this method during the default load() methods - e.g. only
0993:             * to load components specified by getExternalComponentDescriptions().
0994:             *
0995:             * @param o either a StateTuple or ComponentDescription
0996:             * @return true iff the specified ComponentDescription should be loaded.
0997:             **/
0998:            protected boolean isSubComponentLoadable(Object o) {
0999:                ComponentDescription cd = ((o instanceof  StateTuple) ? (((StateTuple) o)
1000:                        .getComponentDescription())
1001:                        : ((ComponentDescription) o));
1002:                return isInsertionPointLoadable(cd.getInsertionPoint());
1003:            }
1004:
1005:            /** validate a child component's InsertionPoint.  Simpler but
1006:             * less flexible mechanism to isSubComponentLoadable.
1007:             * <p>The default behavior is to return true IFF the insertion point
1008:             * is a direct child of the container's containement prefix.
1009:             **/
1010:            protected boolean isInsertionPointLoadable(String ip) {
1011:                String cpr = containmentPrefix;
1012:                int cprl = cpr.length();
1013:                boolean r = (ip.startsWith(cpr) && // starts with the containment point+'.'
1014:                ip.indexOf(".", cprl + 1) == -1 // no more '.'
1015:                );
1016:                return r;
1017:            }
1018:
1019:            /** Hook for loading all the high priority subcomponents.  The default implementation
1020:             * loads all high priority components which match getSubComponentInsertionPoints().
1021:             **/
1022:            protected void loadHighPriorityComponents() {
1023:                loadSubComponentsByPriority(ComponentDescription.PRIORITY_HIGH);
1024:            }
1025:
1026:            /** Hook for loading all the internal priority subcomponents.  The default implementation
1027:             * loads all internal priority components which match getSubComponentInsertionPoints().
1028:             **/
1029:            protected void loadInternalPriorityComponents() {
1030:                loadSubComponentsByPriority(ComponentDescription.PRIORITY_INTERNAL);
1031:            }
1032:
1033:            /** Hook for loading all the binder priority subcomponents.  The default implementation
1034:             * loads all binder priority components which match getSubComponentInsertionPoints().
1035:             **/
1036:            protected void loadBinderPriorityComponents() {
1037:                loadSubComponentsByPriority(ComponentDescription.PRIORITY_BINDER);
1038:            }
1039:
1040:            /** Hook for loading all the component priority subcomponents.  The default implementation
1041:             * loads all component priority components which match getSubComponentInsertionPoints().
1042:             **/
1043:            protected void loadComponentPriorityComponents() {
1044:                loadSubComponentsByPriority(ComponentDescription.PRIORITY_COMPONENT);
1045:            }
1046:
1047:            /** Hook for loading all the low priority subcomponents.  The default implementation
1048:             * loads all low priority components which match getSubComponentInsertionPoints().
1049:             **/
1050:            protected void loadLowPriorityComponents() {
1051:                loadSubComponentsByPriority(ComponentDescription.PRIORITY_LOW);
1052:            }
1053:
1054:            /** Utility method used buy the Load*PriorityComponents methods.
1055:             * adds components as specified by getExternalComponentDescriptions
1056:             * of the specified priority.
1057:             **/
1058:            protected void loadSubComponentsByPriority(int priority) {
1059:                ComponentDescriptions cds = getExternalComponentDescriptions();
1060:                if (cds == null)
1061:                    return;
1062:
1063:                List pcd = cds.selectComponentDescriptions(priority);
1064:                if (pcd == null)
1065:                    return;
1066:
1067:                for (Iterator it = pcd.iterator(); it.hasNext();) {
1068:                    Object o = it.next();
1069:                    if (isSubComponentLoadable(o)) {
1070:                        try {
1071:                            add(o);
1072:                        } catch (RuntimeException re) {
1073:                            Logger l = Logging
1074:                                    .getLogger(ContainerSupport.class);
1075:                            l.error("Skipping load of " + o + " into " + this ,
1076:                                    re);
1077:                        }
1078:                    }
1079:                }
1080:            }
1081:
1082:            //
1083:            // support classes
1084:            //
1085:
1086:            private static class DefaultBinderFactory extends
1087:                    BinderFactorySupport {
1088:                public Binder getBinder(Object child) {
1089:                    return new DefaultBinder(this , child);
1090:                }
1091:
1092:                private static class DefaultBinder extends
1093:                        ContainerBinderSupport implements  BindingSite {
1094:                    public DefaultBinder(BinderFactory bf, Object child) {
1095:                        super (bf, child);
1096:                    }
1097:
1098:                    protected BindingSite getBinderProxy() {
1099:                        return this ;
1100:                    }
1101:                }
1102:            }
1103:
1104:            private static class DefaultServiceBroker extends
1105:                    PropagatingServiceBroker {
1106:                public DefaultServiceBroker(BindingSite bs) {
1107:                    super (bs);
1108:                }
1109:
1110:                private void myDestroy() {
1111:                    super .destroy();
1112:                }
1113:            }
1114:
1115:            private class DefaultProxy implements  ContainerAPI {
1116:                private final ServiceBroker sb;
1117:
1118:                public DefaultProxy(ServiceBroker sb) {
1119:                    this .sb = sb;
1120:                }
1121:
1122:                public ServiceBroker getServiceBroker() {
1123:                    return sb;
1124:                }
1125:
1126:                public boolean remove(Object childComponent) {
1127:                    return ContainerSupport.this .remove(childComponent);
1128:                }
1129:
1130:                public void requestStop() {
1131:                }
1132:            }
1133:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.