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    /**
019     * A registry for command objects. 
020     * 
021     * <p>
022     * The commands to be placed in the registry must have non-null identifiers available via their 
023     * {@link AbstractCommand#getId()} method, and this id is expected to be unique amongst all the 
024     * commands in the application. Generally speaking, this uniqueness will not be enforced by the 
025     * framework but will instead allow commands to be overwritten by others with the same id.
026     * </p>
027     * 
028     * <p>
029     * Implementations may allow for the creation of hierarchical registries whereby a registry may have
030     * a parent registry. In this case, if a registry does not contain a requested command it will
031     * delegate to its parent to find the command. Commands in a child registry will override commands
032     * with the same ID in any ancestor registries.
033     * </p>
034     * 
035     * @author Keith Donald
036     * @author Kevin Stembridge
037     *
038     */
039    public interface CommandRegistry {
040        
041        /**
042         * Returns true if the registry contains a command with the given identifier.
043         *
044         * @param commandId The ID of the command to search for.
045         * @return true if the registry contains the command, false otherwise.
046         * 
047         * @throws IllegalArgumentException if {@code commandId} is null.
048         */
049        boolean containsCommand(String commandId);
050        
051        /**
052         * Retrieves from the registry the command with the given identifier.
053         *
054         * @param commandId The ID of the command to be retrieved.
055         * @return The command with the given ID, or null if no such command could be found.
056         * 
057         * @throws IllegalArgumentException if {@code commandId} is null.
058         */
059        Object getCommand(String commandId);
060        
061        /**
062         * Retrieves from the registry the command with the given identifier. An exception is thrown
063         * if the retrieved command is not assignable to the required type.
064         *
065         * @param commandId The identifier of the command to be retrieved. Must not be null.
066         * @param requiredType The required type of the command with the given id. 
067         * 
068         * @return The command with the given id if it exists in the registry and is of the required type.
069         * 
070         * @throws CommandNotOfRequiredTypeException if the retrieved command is not assignable to 
071         * the required type.
072         */
073        Object getCommand(String commandId, Class requiredType) throws CommandNotOfRequiredTypeException;
074        
075        /**
076         * Returns the type of the command with the given identifier, if it is contained in the 
077         * registry.
078         *
079         * @param commandId The ID of the command whose type is to be returned. Must not be null.
080         * @return The type of the command with the given ID, or null if no such command exists in
081         * the registry.
082         * 
083         * @throws IllegalArgumentException if {@code commandId} is null.
084         */
085        Class getType(String commandId);
086        
087        /**
088         * Returns true if the command with the given identifier is assignable to the given type.
089         *
090         * @param commandId The ID of the command whose type will be checked. Must not be null.
091         * @param targetType The type to be checked against the type of the command. Must not be null.
092         * @return true if a command with the given ID exists in the registry and it is assignable to 
093         * the given target type, false otherwise.
094         * 
095         * @throws IllegalArgumentException if either argument is null.
096         */
097        boolean isTypeMatch(String commandId, Class targetType); 
098        
099        /**
100         * Returns the {@link ActionCommand} that has the given id.
101         *
102         * @param commandId The id of the action command to be returned.
103         * @return The action command with the given id, or null if no such command exists in the 
104         * registry.
105         * 
106         * @throws IllegalArgumentException if {@code commandId} is null.
107         * @throws CommandNotOfRequiredTypeException if there is a command with the given id in the 
108         * registry but it is not of type {@link ActionCommand}. 
109         * 
110         * @deprecated use {@link #getCommand(String, Class)} instead. You may choose to either catch
111         * the {@link CommandNotOfRequiredTypeException} or call {@link #isTypeMatch(String, Class)} first.
112         */
113        ActionCommand getActionCommand(String commandId);
114    
115        /**
116         * Returns the {@link CommandGroup} that has the given id.
117         *
118         * @param groupId The id of the command group to be returned.
119         * @return The command group with the given id, or null if no such command group exists in the 
120         * registry.
121         * 
122         * @throws IllegalArgumentException if {@code commandId} is null.
123         * @throws CommandNotOfRequiredTypeException if there is a command with the given id in the 
124         * registry but it is not of type {@link CommandGroup}. 
125         * 
126         * @deprecated use {@link #getCommand(String, Class)} instead. You may choose to either catch
127         * the {@link CommandNotOfRequiredTypeException} or call {@link #isTypeMatch(String, Class)} first.
128         */
129        CommandGroup getCommandGroup(String groupId);
130    
131        /**
132         * Returns true if the registry contains a command of type {@link ActionCommand} with the 
133         * given id.
134         *
135         * @param commandId The id of the command to be searched for.
136         * @return true if the registry contains the command and it is assignable to {@link ActionCommand}.
137         * 
138         * @deprecated Replaced by {@link #isTypeMatch(String, Class)}
139         */
140        boolean containsActionCommand(String commandId);
141    
142        /**
143         * Returns true if the registry contains a command of type {@link CommandGroup} with the 
144         * given id.
145         *
146         * @param groupId The id of the command group to be searched for.
147         * @return true if the registry contains the command and it is assignable to {@link CommandGroup}.
148         * 
149         * @deprecated Replaced by {@link #isTypeMatch(String, Class)}
150         */
151        boolean containsCommandGroup(String groupId);
152    
153        /**
154         * Registers the given command with the registry. Neither the command nor its id can be null. 
155         * All registered listeners will be notified of the newly registered command via their 
156         * {@link CommandRegistryListener#commandRegistered(CommandRegistryEvent)} method. If the 
157         * given command is an instance of {@link CommandGroup}, its 
158         * {@link CommandGroup#setCommandRegistry(CommandRegistry)} method must be called to set this
159         * instance as the registry for the command group. 
160         *
161         * @param command The command to be registered. Must not be null.
162         * 
163         * @throws IllegalArgumentException if {@code command} is null or if its id is null.
164         */
165        void registerCommand(AbstractCommand command);
166    
167        /**
168         * Sets a command executor for the command with the given id. The actual type of the command 
169         * must be assignable to {@link TargetableActionCommand}.
170         *
171         * @param targetableCommandId The id of the targetable command that will have its executor set. 
172         * Must not be null.
173         * @param commandExecutor The command executor. May be null.
174         * 
175         * @throws IllegalArgumentException if {@code targetableCommandId} is null.
176         * @throws CommandNotOfRequiredTypeException if the command with the given id is not a
177         * {@link TargetableActionCommand}.
178         */
179        void setTargetableActionCommandExecutor(String targetableCommandId, ActionCommandExecutor commandExecutor);
180    
181        /**
182         * Adds the given listener to the colleciton of listeners that will be notified of registry events.
183         *
184         * @param listener The listener to be added. Must not be null.
185         */
186        void addCommandRegistryListener(CommandRegistryListener listener);
187    
188        /**
189         * Remove the given listener from the collection of listeners that will be notified of registry events.
190         *
191         * @param listener The listener to be removed.
192         */
193        void removeCommandRegistryListener(CommandRegistryListener listener);
194        
195    }