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 }