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.List;
019    
020    import org.springframework.richclient.command.config.CommandButtonConfigurer;
021    import org.springframework.richclient.util.Assert;
022    
023    /**
024     * A {@link GroupMember} implementation that can be used as a placeholder for lazily initialized
025     * commands.
026     *
027     */
028    public class LazyGroupMember extends GroupMember {
029        
030        private final CommandGroup parentGroup;
031    
032        private final String lazyCommandId;
033    
034        private boolean addedLazily;
035    
036        private GroupMember loadedMember;
037        
038        /**
039         * Creates a new {@code LazyGroupMember} belonging to the given command group and managing
040         * a lazily initialized command with the given id.
041         *
042         * @param parentGroup The command group that this member belongs to.
043         * @param lazyCommandId The id of the command that this group member represents.
044         * 
045         * @throws IllegalArgumentException if either argument is null.
046         */
047        public LazyGroupMember(CommandGroup parentGroup, String lazyCommandId) {
048            
049            Assert.required(parentGroup, "parentGroup");
050            Assert.required(lazyCommandId, "lazyCommandId");
051            
052            if (logger.isDebugEnabled()) {
053                logger.debug("Lazy group member '" 
054                             + lazyCommandId 
055                             + "' instantiated for group '" 
056                             + parentGroup.getId()
057                             + "'");
058            }
059            
060            this.parentGroup = parentGroup;
061            this.lazyCommandId = lazyCommandId;
062        }
063    
064        /**
065         * Delegates this call to the lazily loaded member, but only if it has already been loaded.
066         * Calling this method before the underlying member has beeen loaded will have no effect.
067         */
068        public void setEnabled(boolean enabled) {
069            if (loadedMember != null) {
070                loadedMember.setEnabled(enabled);
071            }
072        }
073    
074        protected void fill(GroupContainerPopulator parentContainerPopulator, 
075                            Object controlFactory,
076                            CommandButtonConfigurer buttonConfigurer, 
077                            List previousButtons) {
078            
079            loadIfNecessary();
080            
081            if (loadedMember != null) {
082                loadedMember.fill(parentContainerPopulator, controlFactory, buttonConfigurer, previousButtons);
083            }
084            
085        }
086    
087        /**
088         * Attempts to load the lazy command from the command registry of the parent command group, but
089         * only if it hasn't already been loaded.
090         */
091        private void loadIfNecessary() {
092            
093            if (loadedMember != null) {
094                return;
095            }
096            
097            CommandRegistry commandRegistry = parentGroup.getCommandRegistry();
098    
099            Assert.isTrue(parentGroup.getCommandRegistry() != null, "Command registry must be set for group '"
100                    + parentGroup.getId() + "' in order to load lazy command '" + lazyCommandId + "'.");
101    
102            if (commandRegistry.containsCommandGroup(lazyCommandId)) {
103                CommandGroup group = commandRegistry.getCommandGroup(lazyCommandId);
104                loadedMember = new SimpleGroupMember(parentGroup, group);
105            }
106            else if (commandRegistry.containsActionCommand(lazyCommandId)) {
107                ActionCommand command = commandRegistry.getActionCommand(lazyCommandId);
108                loadedMember = new SimpleGroupMember(parentGroup, command);
109            }
110            else {
111                
112                if (logger.isWarnEnabled()) {
113                    logger.warn("Lazy command '" 
114                                + lazyCommandId
115                                + "' was asked to display; however, no backing command instance exists in registry.");
116                }
117                
118            }
119    
120            if (addedLazily && loadedMember != null) {
121                loadedMember.onAdded();
122            }
123            
124        }
125    
126        /**
127         * {@inheritDoc}
128         */
129        public boolean managesCommand(String commandId) {
130            //FIXME isn't this supposed to recurse if command is a command group?
131            return this.lazyCommandId.equals(commandId);
132        }
133    
134        /**
135         * {@inheritDoc}
136         */
137        protected void onAdded() {
138            if (loadedMember != null) {
139                loadedMember.onAdded();
140            }
141            else {
142                addedLazily = true;
143            }
144        }
145    
146        /**
147         * {@inheritDoc}
148         */
149        protected void onRemoved() {
150            if (loadedMember != null) {
151                loadedMember.onRemoved();
152            }
153            else {
154                addedLazily = false;
155            }
156        }
157    
158    }