View Javadoc

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 }