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 import org.apache.jsieve.tests.ExecutableTest;
26
27 /**
28 * <p>Maps Test names to configured Test implementation classes.</p>
29 * <h4>Thread Safety</h4>
30 * <p>
31 * Instances may safely be accessed concurrently by multiple threads.
32 * </p>
33 */
34 public class TestManagerImpl implements TestManager {
35
36 private final ConcurrentMap<String, String> classNameMap;
37
38 /**
39 * TestManager is instanciated with getInstance
40 */
41 public TestManagerImpl(final ConcurrentMap<String, String> classNameMap) {
42 super();
43 this.classNameMap = classNameMap;
44 }
45
46 /**
47 * <p>
48 * Method lookup answers the class to which a Test name is mapped.
49 * </p>
50 *
51 * @param name -
52 * The name of the Test
53 * @return Class - The class of the Test
54 * @throws LookupException
55 */
56 public Class lookup(String name) throws LookupException {
57 Class testClass = null;
58
59 try {
60 testClass = getClass().getClassLoader().loadClass(
61 getClassName(name));
62 } catch (ClassNotFoundException e) {
63 throw new LookupException("Test named '" + name + "' not found.");
64 }
65 if (!ExecutableTest.class.isAssignableFrom(testClass))
66 throw new LookupException("Class " + testClass.getName()
67 + " must implement " + ExecutableTest.class.getName());
68 return testClass;
69 }
70
71 /**
72 * <p>
73 * Method newInstance answers an instance of the class to which a Test name
74 * is mapped.
75 * </p>
76 *
77 * @param name -
78 * The name of the Test
79 * @return Class - The class of the Test
80 * @throws LookupException
81 */
82 public ExecutableTest getTest(String name) throws LookupException {
83 try {
84 return (ExecutableTest) lookup(name).newInstance();
85 } catch (InstantiationException e) {
86 throw new LookupException(e.getMessage());
87 } catch (IllegalAccessException e) {
88 throw new LookupException(e.getMessage());
89 }
90 }
91
92 /**
93 * <p>
94 * Method getClassName answers the name of the class to which a Test name is
95 * mapped.
96 * </p>
97 *
98 * @param name -
99 * The name of the Test
100 * @return String - The name of the class
101 * @throws LookupException
102 */
103 private String getClassName(String name) throws LookupException {
104 final String className = classNameMap.get(name.toLowerCase());
105 if (null == className)
106 throw new LookupException("Test named '" + name + "' not mapped.");
107 return className;
108 }
109 }