001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.command;
017    
018    import java.util.HashSet;
019    import java.util.Iterator;
020    import java.util.LinkedHashSet;
021    import java.util.List;
022    
023    import org.springframework.richclient.command.config.CommandButtonConfigurer;
024    import org.springframework.richclient.util.Assert;
025    
026    /**
027     * A collection of {@link GroupMember}s that represent a subsection of a {@link CommandGroup}. 
028     *
029     */
030    public class ExpansionPointGroupMember extends GroupMember {
031    
032        private static final String DEFAULT_EXPANSION_POINT_NAME = "default";
033    
034        private final HashSet members = new LinkedHashSet(5);
035    
036        private final String expansionPointName;
037    
038        private boolean leadingSeparator;
039    
040        private boolean endingSeparator;
041    
042        /**
043         * Creates a new {@code ExpansionPointGroupMember} with a default name.
044         */
045        protected ExpansionPointGroupMember() {
046            expansionPointName = DEFAULT_EXPANSION_POINT_NAME;
047        }
048    
049        /**
050         * Creates a new {@code ExpansionPointGroupMember} with the given name.
051         *
052         * @param expansionPointName The name of the expansion point. Must not be null.
053         * 
054         * @throws IllegalArgumentException if {@code expansionPointName} is null.
055         */
056        protected ExpansionPointGroupMember(String expansionPointName) {
057            Assert.required(expansionPointName, "expansionPointName");
058            this.expansionPointName = expansionPointName;
059        }
060    
061        /**
062         * Returns true if the visual representation of this expansion point will include a leading
063         * separator.
064         *
065         * @return true for a leading separator.
066         */
067        public boolean isLeadingSeparator() {
068            return leadingSeparator;
069        }
070    
071        /**
072         * Sets the flag that indicates whether or not the visual representation of this expansion
073         * point will display a leading separator.
074         *
075         * @param leadingSeparator Set to true to display a leading separator.
076         */
077        public void setLeadingSeparator(boolean leadingSeparator) {
078            this.leadingSeparator = leadingSeparator;
079        }
080    
081        /**
082         * Returns true if the visual representation of this expansion point will include a trailing
083         * separator.
084         *
085         * @return true for a trailing separator.
086         */
087        public boolean isEndingSeparator() {
088            return endingSeparator;
089        }
090    
091        /**
092         * Sets the flag that indicates whether or not the visual representation of this expansion
093         * point will display a trailing separator.
094         *
095         * @param endingSeparator Set to true to display a trailing separator.
096         */
097        public void setEndingSeparator(boolean endingSeparator) {
098            this.endingSeparator = endingSeparator;
099        }
100    
101        /**
102         * Returns the name of this expansion point.
103         *
104         * @return The expansion point name, never null.
105         */
106        public String getExpansionPointName() {
107            return expansionPointName;
108        }
109    
110        /**
111         * Attempts to add the given member to this expansion point. The member will not be added if
112         * an equivalent entry (according to its equals() method) already exists. If added, the member's
113         * {@link GroupMember#onAdded()} method will be called.
114         *
115         * @param member The member to be added. Must not be null.
116         * 
117         * @throws IllegalArgumentException if {@code member} is null.
118         */
119        protected void add(GroupMember member) {
120            
121            Assert.required(member, "member");
122            
123            if (members.add(member)) {
124                member.onAdded();
125            }
126            
127        }
128    
129        /**
130         * If the given member belongs to this exponsion point, it will be removed. Its 
131         * {@link GroupMember#onRemoved()} method will be called.  
132         *
133         * @param member The member that is to be removed.
134         */
135        public void remove(GroupMember member) {
136            if (members.remove(member)) {
137                member.onRemoved();
138            }
139        }
140    
141        /**
142         * Removes all the group members from this expansion point.
143         */
144        protected void clear() {
145            members.clear();
146        }
147    
148        /**
149         * Adds each member of this expansion point to a GUI container using the given container 
150         * populator. Leading and trailing separators will also be added as determined by the 
151         * appropriate flags set on this instance.
152         * 
153         * {@inheritDoc}
154         */
155        protected void fill(GroupContainerPopulator containerPopulator, 
156                            Object controlFactory, 
157                            CommandButtonConfigurer configurer,
158                            List previousButtons) {
159            
160            Assert.required(containerPopulator, "containerPopulator");
161            Assert.required(controlFactory, "controlFactory");
162            Assert.required(configurer, "configurer");
163            
164            if (members.size() > 0 && isLeadingSeparator()) {
165                containerPopulator.addSeparator();
166            }
167    
168            for (Iterator iterator = members.iterator(); iterator.hasNext();) {
169                GroupMember member = (GroupMember)iterator.next();
170                member.fill(containerPopulator, controlFactory, configurer, previousButtons);
171            }
172    
173            if (members.size() > 0 && isEndingSeparator()) {
174                containerPopulator.addSeparator();
175            }
176            
177        }
178    
179        /**
180         * Returns the group member that manages the command with the given id, or null if none of the
181         * members in this expansion point manage a command with that id.
182         * 
183         * @param commandId The id of the command whose managing member is to be returned.
184         * @return The group member that manages the command with the given id, or null.
185         */
186        public GroupMember getMemberFor(String commandId) {
187            for (Iterator it = members.iterator(); it.hasNext();) {
188                GroupMember member = (GroupMember)it.next();
189                if (member.managesCommand(commandId)) {
190                    return member;
191                }
192            }
193            return null;
194        }
195    
196        /**
197         * {@inheritDoc}
198         */
199        public boolean managesCommand(String commandId) {
200            for (Iterator iterator = members.iterator(); iterator.hasNext();) {
201                GroupMember member = (GroupMember)iterator.next();
202                if (member.managesCommand(commandId))
203                    return true;
204            }
205    
206            return false;
207        }
208    
209        /**
210         * Returns true if this expansion point has no members.
211         * @return true if this expansion point has no members.
212         */
213        public boolean isEmpty() {
214            return members.isEmpty();
215        }
216    
217        /**
218         * Default implementation, performs no operation.
219         */
220        public void setEnabled(boolean enabled) {
221            //do nothing
222        }
223    
224    }