blob: 548d2720d07ad6c732e096264bdc6978650c1427 [file] [log] [blame]
/*
* Copyright (C) 2015 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.caliper.runner;
import com.google.caliper.Param;
import com.google.caliper.util.Parser;
import com.google.caliper.util.Parsers;
import com.google.common.collect.ImmutableSortedMap;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import javax.inject.Inject;
/**
* Responsible for creating instances of the benchmark class.
*/
final class BenchmarkCreator {
private static final String BENCHMARK_NO_PUBLIC_DEFAULT_CONSTRUCTOR =
"Benchmark %s does not have a publicly visible default constructor";
private final Class<?> benchmarkClass;
private final ImmutableSortedMap<String, String> parameters;
private final Constructor<?> benchmarkClassCtor;
@Inject
BenchmarkCreator(
@Running.BenchmarkClass Class<?> benchmarkClass,
@Running.Benchmark ImmutableSortedMap<String, String> parameters) {
this.benchmarkClass = benchmarkClass;
this.benchmarkClassCtor = findDefaultConstructor(benchmarkClass);
this.parameters = parameters;
}
private static Constructor<?> findDefaultConstructor(Class<?> benchmarkClass) {
Constructor<?> defaultConstructor = null;
for (Constructor<?> constructor : benchmarkClass.getDeclaredConstructors()) {
if (constructor.getParameterTypes().length == 0) {
defaultConstructor = constructor;
defaultConstructor.setAccessible(true);
break;
}
}
if (defaultConstructor == null) {
throw new UserCodeException(
String.format(BENCHMARK_NO_PUBLIC_DEFAULT_CONSTRUCTOR, benchmarkClass), null);
}
return defaultConstructor;
}
Object createBenchmarkInstance() {
Object instance;
try {
instance = benchmarkClassCtor.newInstance();
} catch (InstantiationException e) {
throw new AssertionError(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
} catch (InvocationTargetException e) {
Throwable userException = e.getCause();
throw new UserCodeException(userException);
}
// Inject values for the user parameters.
for (Field field : benchmarkClass.getDeclaredFields()) {
if (field.isAnnotationPresent(Param.class)) {
try {
field.setAccessible(true);
Parser<?> parser = Parsers.conventionalParser(field.getType());
field.set(instance, parser.parse(parameters.get(field.getName())));
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (ParseException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new AssertionError("types have been checked");
} catch (IllegalAccessException e) {
throw new AssertionError("already set access");
}
}
}
return instance;
}
}