• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2006-2013 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.objenesis.tck;
17 
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.PrintStream;
21 import java.util.Properties;
22 
23 /**
24  * Loads a set of candidate classes from a properties file into the TCK. <p/> The properties file
25  * takes the form of candidateClassName=shortDescription.
26  *
27  * @author Joe Walnes
28  * @see TCK
29  */
30 public class CandidateLoader {
31 
32    private final TCK tck;
33    private final ClassLoader classloader;
34    private final ErrorHandler errorHandler;
35 
36    /**
37     * Handler for reporting errors from the CandidateLoader.
38     */
39    public static interface ErrorHandler {
40       /**
41        * Called whenever, trying to retrieve a candidate class from its name, a
42        * ClassNotFoundException is thrown
43        *
44        * @param name Candidate class name
45        */
classNotFound(String name)46       void classNotFound(String name);
47    }
48 
49    /**
50     * Error handler that logs errors to a text stream.
51     */
52    public static class LoggingErrorHandler implements CandidateLoader.ErrorHandler {
53 
54       private final PrintStream out;
55 
56       /**
57        * @param out Stream in which to log
58        */
LoggingErrorHandler(PrintStream out)59       public LoggingErrorHandler(PrintStream out) {
60          this.out = out;
61       }
62 
classNotFound(String name)63       public void classNotFound(String name) {
64          out.println("Class not found : " + name);
65       }
66 
67    }
68 
69    /**
70     * @param tck TCK that will use the candidates
71     * @param classloader ClassLoader from which candidates classes are loaded
72     * @param errorHandler Handler called in case of error
73     */
CandidateLoader(TCK tck, ClassLoader classloader, ErrorHandler errorHandler)74    public CandidateLoader(TCK tck, ClassLoader classloader, ErrorHandler errorHandler) {
75       this.tck = tck;
76       this.classloader = classloader;
77       this.errorHandler = errorHandler;
78    }
79 
80    /**
81     * @param inputStream Stream containing the properties
82     * @throws IOException If something goes wrong while reading the stream
83     */
loadFrom(InputStream inputStream)84    public void loadFrom(InputStream inputStream) throws IOException {
85       // Properties contains a convenient key=value parser, however it stores
86       // the entries in a Hashtable which loses the original order.
87       // So, we create a special Properties instance that writes its
88       // entries directly to the TCK (which retains order).
89       Properties properties = new Properties() {
90          private static final long serialVersionUID = 1L;
91          public Object put(Object key, Object value) {
92             handlePropertyEntry((String) key, (String) value);
93             return null;
94          }
95       };
96       properties.load(inputStream);
97    }
98 
99    /**
100     * Load a candidate property file
101     *
102     * @param cls Class on which <code>getResourceAsStream</code> is called
103     * @param resource File name
104     * @throws IOException If there's problem reading the file
105     */
loadFromResource(Class cls, String resource)106    public void loadFromResource(Class cls, String resource) throws IOException {
107       InputStream candidatesConfig = cls.getResourceAsStream(resource);
108       if(candidatesConfig == null) {
109          throw new IOException("Resource '" + resource + "' not found relative to " + cls.getName());
110       }
111       try {
112          loadFrom(candidatesConfig);
113       }
114       finally {
115          candidatesConfig.close();
116       }
117    }
118 
handlePropertyEntry(String key, String value)119    private void handlePropertyEntry(String key, String value) {
120       try {
121          Class candidate = Class.forName(key, true, classloader);
122          tck.registerCandidate(candidate, value);
123       }
124       catch(ClassNotFoundException e) {
125          errorHandler.classNotFound(key);
126       }
127    }
128 
129 }
130