1 /**************************************************************** 2 * Licensed to the Apache Software Foundation (ASF) under one * 3 * or more contributor license agreements. See the NOTICE file * 4 * distributed with this work for additional information * 5 * regarding copyright ownership. The ASF licenses this file * 6 * to you under the Apache License, Version 2.0 (the * 7 * "License"); you may not use this file except in compliance * 8 * with the License. You may obtain a copy of the License at * 9 * * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, * 13 * software distributed under the License is distributed on an * 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 15 * KIND, either express or implied. See the License for the * 16 * specific language governing permissions and limitations * 17 * under the License. * 18 ****************************************************************/ 19 20 package org.apache.jsieve; 21 22 import java.util.concurrent.ConcurrentMap; 23 24 import org.apache.jsieve.exception.LookupException; 25 26 /** 27 * <p>Maps command names to comman implementations.</p> 28 * <h4>Thread Safety</h4> 29 * <p> 30 * Instances may safely be accessed concurrently by multiple threads. 31 * </p> 32 */ 33 public class CommandManagerImpl implements CommandManager { 34 35 private final ConcurrentMap<String, String> classNameMap; 36 37 /** 38 * Constructor for CommandManager. 39 */ 40 public CommandManagerImpl(final ConcurrentMap<String, String> classNameMap) { 41 super(); 42 this.classNameMap = classNameMap; 43 } 44 45 /** 46 * <p> 47 * Method lookup answers the class to which a Command name is mapped. 48 * </p> 49 * 50 * @param name - 51 * The name of the Command 52 * @return Class - The class of the Command 53 * @throws LookupException 54 */ 55 private Class lookup(String name) throws LookupException { 56 Class cmdClass = null; 57 try { 58 cmdClass = getClass().getClassLoader() 59 .loadClass(getClassName(name)); 60 } catch (ClassNotFoundException e) { 61 throw new LookupException("Command named '" + name + "' not found."); 62 } 63 if (!ExecutableCommand.class.isAssignableFrom(cmdClass)) 64 throw new LookupException("Class " + cmdClass.getName() 65 + " must implement " + ExecutableCommand.class.getName()); 66 return cmdClass; 67 } 68 69 /** 70 * <p> 71 * Method newInstance answers an instance of the class to which a Command 72 * name is mapped. 73 * </p> 74 * 75 * @param name - 76 * The name of the Command 77 * @return Class - The class of the Command 78 * @throws LookupException 79 */ 80 public ExecutableCommand getCommand(String name) throws LookupException { 81 try { 82 return (ExecutableCommand) lookup(name).newInstance(); 83 } catch (InstantiationException e) { 84 throw new LookupException(e.getMessage()); 85 } catch (IllegalAccessException e) { 86 throw new LookupException(e.getMessage()); 87 } 88 } 89 90 /** 91 * Method isSupported answers a boolean indicating if a Command name is 92 * configured. 93 * 94 * @param name - 95 * The Command name 96 * @return boolean - True if the Command name is configured. 97 */ 98 public boolean isCommandSupported(String name) { 99 boolean isSupported = false; 100 try { 101 lookup(name); 102 isSupported = true; 103 } catch (LookupException e) { 104 } 105 return isSupported; 106 } 107 108 /** 109 * <p> 110 * Method getClassName answers the name of the class to which a Command name 111 * is mapped. 112 * </p> 113 * 114 * @param name - 115 * The name of the Command 116 * @return String - The name of the class 117 * @throws LookupException 118 */ 119 protected String getClassName(String name) throws LookupException { 120 final String className = classNameMap.get(name.toLowerCase()); 121 if (null == className) 122 throw new LookupException("Command named '" + name 123 + "' not mapped."); 124 return className; 125 } 126 }