    001    /*****************************************************************************
    002     * Copyright (C) NanoContainer Organization. All rights reserved.            *
    003     * ------------------------------------------------------------------------- *
    004     * The software in this package is published under the terms of the BSD      *
    005     * style license a copy of which has been included with this distribution in *
    006     * the LICENSE.txt file.                                                     *
    007     *                                                                           *
    008     * Original code by Michael Rimov                                            *
    009     *****************************************************************************/
    010
    011
    012    package org.nanocontainer.script.groovy.buildernodes;
    013
    014    import java.util.Map;
    015    import org.nanocontainer.NanoContainer;
    016    import org.nanocontainer.script.NanoContainerMarkupException;
    017    import org.picocontainer.PicoContainer;
    018
    019    /**
    020     * Sometimes it is worthwhile to split apart Nanocontainer building
    021     * into functions.  For example, you might want to group adding the domain
    022     * object repositories (DAOs) into a single function to make your composition script
    023     * easier to maintain.
    024     * <p>Unfortunately, normally this is not allowed under normal builder rules.  If
    025     * you wish to separate code you must revert to standard picocontainer calling
    026     * systax.</p>
    027     * <p>This node corrects that deficiency.</p>
    028     * <p>With it you can perform:
    029     * <code><pre>
    030     * pico = builder.container(parent:parent) {
    031     * &nbsp;&nbsp;component(....)
    032     * &nbsp;&nbsp;//...
    033     * }
    034     * <br/>
    035     * //<em>Now add more to pico.</em>
    036     * builder.append(container: pico) {
    037     * &nbsp;&nbsp;component(....)
    038     * &nbsp;&nbsp;//...
    039     * }
    040     * </pre></code>
    041     * </p>
    042     * @author Michael Rimov
    043     * @version 1.0
    044     */
    045    public class AppendContainerNode extends AbstractBuilderNode {
    046        /**
    047         * Node name.
    048         */
    049        public static final String NODE_NAME = "append";
    050
    051
    052        /**
    053         * Supported Attribute (Required): 'container.'  Reference to the container
    054         * we are going to append to.
    055         */
    056        public static final String CONTAINER = "container";
    057
    058        /**
    059         * Constructs an append container node.
    060         */
    061        public AppendContainerNode() {
    062            super(NODE_NAME);
    063        }
    064
    065        /**
    066         * Returns the container passed in as the &quot;container&quot; attribute.
    067         * @param current Object unused.
    068         * @param attributes Map attributes passed in.  This must have the container
    069         * attribute defined.
    070         * @return Object the passed in Nanocontainer.
    071         * @throws NanoContainerMarkupException if the container attribute
    072         * is not supplied.
    073         * @throws ClassCastException if the container node specified is  not
    074         * a nano or picocontainer.
    075         */
    076        public Object createNewNode(final Object current, final Map attributes) throws NanoContainerMarkupException, ClassCastException {
    077            if (!isAttribute(attributes, CONTAINER)) {
    078                throw new NanoContainerMarkupException(NODE_NAME + " must have a container attribute");
    079            }
    080
    081
    082            Object attributeValue = attributes.get(CONTAINER);
    083            if (! (attributeValue instanceof NanoContainer) && !(attributeValue instanceof PicoContainer) ) {
    084                throw new ClassCastException(attributeValue.toString() + " must be a derivative of nanocontainer.  Got: "
    085                    + attributeValue.getClass().getName() + " instead.");
    086            }
    087            return attributeValue;
    088        }
    089
    090
    091    }