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 */ 017package org.apache.commons.chain.impl; 018 019import java.util.Iterator; 020import java.util.Map; 021import java.util.concurrent.ConcurrentHashMap; 022 023import org.apache.commons.chain.Catalog; 024import org.apache.commons.chain.Command; 025import org.apache.commons.chain.Context; 026 027/** 028 * Simple in-memory implementation of {@link Catalog}. This class can 029 * also be used as the basis for more advanced implementations. 030 * 031 * <p>This implementation is thread-safe.</p> 032 * 033 * @param <C> Type of the context associated with this catalog 034 * 035 * @author Craig R. McClanahan 036 * @author Matthew J. Sgarlata 037 * @version $Revision$ $Date$ 038 */ 039public class CatalogBase<C extends Context> implements Catalog<C> { 040 041 // ----------------------------------------------------- Instance Variables 042 043 /** 044 * The map of named {@link Command}s, keyed by name. 045 */ 046 private final Map<String, Command<C>> commands; 047 048 // --------------------------------------------------------- Constructors 049 050 /** 051 * Create an empty catalog. 052 */ 053 public CatalogBase() { 054 commands = new ConcurrentHashMap<>(); 055 } 056 057 /** 058 * Create a catalog whose commands are those specified in the given {@code Map}. 059 * All Map keys should be {@code String} and all values should be {@code Command}. 060 * 061 * @param commands Map of Commands. 062 * 063 * @since Chain 1.1 064 */ 065 public CatalogBase(Map<String, Command<C>> commands) { 066 this.commands = new ConcurrentHashMap<>(commands); 067 } 068 069 // --------------------------------------------------------- Public Methods 070 071 /** 072 * Add a new name and associated {@link Command} 073 * to the set of named commands known to this {@link Catalog}, 074 * replacing any previous command for that name. 075 * 076 * @param <CMD> the {@link Command} type to be added in the {@link Catalog} 077 * @param name Name of the new command 078 * @param command {@link Command} to be returned 079 * for later lookups on this name 080 */ 081 @Override 082 public <CMD extends Command<C>> void addCommand(String name, CMD command) { 083 commands.put(name, command); 084 } 085 086 /** 087 * Return the {@link Command} associated with the 088 * specified name, if any; otherwise, return {@code null}. 089 * 090 * @param <CMD> the expected {@link Command} type to be returned 091 * @param name Name for which a {@link Command} 092 * should be retrieved 093 * 094 * @return The Command associated with the specified name. 095 */ 096 @Override 097 public <CMD extends Command<C>> CMD getCommand(String name) { 098 @SuppressWarnings("unchecked") // it would throw ClassCastException if users try to cast to a different type 099 CMD command = (CMD) commands.get(name); 100 return command; 101 } 102 103 /** 104 * Return an {@code Iterator} over the set of named commands 105 * known to this {@link Catalog}. If there are no known commands, 106 * an empty Iterator is returned. 107 * 108 * @return An iterator of the names in this Catalog. 109 */ 110 @Override 111 public Iterator<String> getNames() { 112 return commands.keySet().iterator(); 113 } 114 115 /** 116 * Converts this Catalog to a String. Useful for debugging purposes. 117 * 118 * @return a representation of this catalog as a String 119 */ 120 @Override 121 public String toString() { 122 Iterator<String> names = getNames(); 123 StringBuilder str = new StringBuilder(); 124 str 125 .append('[') 126 .append(this.getClass().getName()) 127 .append(": "); 128 129 while (names.hasNext()) { 130 str.append(names.next()); 131 if (names.hasNext()) { 132 str.append(", "); 133 } 134 } 135 str.append(']'); 136 137 return str.toString(); 138 } 139}