001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.launcher.types;
019    
020    import java.util.ArrayList;
021    import java.util.Stack;
022    import org.apache.commons.launcher.Launcher;
023    import org.apache.tools.ant.BuildException;
024    import org.apache.tools.ant.types.DataType;
025    import org.apache.tools.ant.types.Reference;
026    
027    /**
028     * A class that represents a set of nested elements of
029     * {@link ConditionalVariable} objects.
030     *
031     * @author Patrick Luby
032     */
033    public class ConditionalVariableSet extends DataType {
034    
035        //------------------------------------------------------------------ Fields
036    
037        /**
038         * Cached variables and nested ConditionalVariableSet objects
039         */
040        private ArrayList list = new ArrayList();
041    
042        //----------------------------------------------------------------- Methods
043    
044        /**
045         * Add a {@link ConditionalVariable}.
046         *
047         * @param variable the {@link ConditionalVariable} to be
048         *  added
049         */
050        protected void addConditionalvariable(ConditionalVariable variable) {
051    
052            if (isReference())
053                throw noChildrenAllowed();
054            list.add(variable);
055    
056        }
057    
058        /**
059         * Add a {@link ConditionalVariableSet}.
060         *
061         * @param set the {@link ConditionalVariableSet} to be added
062         */
063        protected void addConditionalvariableset(ConditionalVariableSet set) {
064    
065            if (isReference())
066                throw noChildrenAllowed();
067            list.add(set);
068    
069        }
070    
071        /**
072         * Get {@link ConditionalVariable} instances.
073         *
074         * @return the {@link ConditionalVariable} instances
075         */
076        public ArrayList getList() {
077    
078            // Make sure we don't have a circular reference to this instance
079            if (!checked) {
080                Stack stk = new Stack();
081                stk.push(this);
082                dieOnCircularReference(stk, project);
083            }
084    
085            // Recursively work through the tree of ConditionalVariableSet objects
086            // and accumulate the list of ConditionalVariable objects.
087            ArrayList mergedList = new ArrayList(list.size());
088            for (int i = 0; i < list.size(); i++) {
089                Object o = list.get(i);
090                ConditionalVariableSet nestedSet = null;
091                if (o instanceof Reference) {
092                    o = ((Reference)o).getReferencedObject(project);
093                    // Only references to this class are allowed
094                    if (!o.getClass().isInstance(this))
095                        throw new BuildException(Launcher.getLocalizedString("cannot.reference", this.getClass().getName()));
096                    nestedSet = (ConditionalVariableSet)o;
097                } else if (o.getClass().isInstance(this)) {
098                    nestedSet = (ConditionalVariableSet)o;
099                } else if (o instanceof ConditionalVariable) {
100                    mergedList.add(o);
101                } else {
102                    throw new BuildException(Launcher.getLocalizedString("cannot.nest", this.getClass().getName()));
103                }
104                if (nestedSet != null)
105                    mergedList.addAll(nestedSet.getList());
106            }
107    
108            return mergedList;
109    
110        }
111    
112        /**
113         * Makes this instance a reference to another instance. You must not
114         * set another attribute or nest elements inside this element if you
115         * make it a reference.
116         *
117         * @param r the reference to another {@link ConditionalVariableSet}
118         *  instance
119         */
120        public void setRefid(Reference r) throws BuildException {
121    
122            if (!list.isEmpty())
123                throw tooManyAttributes();
124            list.add(r);
125            super.setRefid(r);
126    
127        }
128    
129    }