/* * JBoss, Home of Professional Open Source * Copyright 2013, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * 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 org.hibernate.jpamodelgen.test.util; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; /** * Custom JUnit runner which makes sure the annotation processor runs prior to the test method. * * @author Hardy Ferentschik * @see CompilationStatement */ public class CompilationRunner extends BlockJUnit4ClassRunner { private final List<Class<?>> testEntities; private final List<Class<?>> preCompileEntities; private final List<String> mappingFiles; private final Map<String, String> processorOptions; private final String packageName; private boolean ignoreCompilationErrors; public CompilationRunner(Class<?> clazz) throws InitializationError { super( clazz ); this.testEntities = new ArrayList<Class<?>>(); this.preCompileEntities = new ArrayList<Class<?>>(); this.mappingFiles = new ArrayList<String>(); this.processorOptions = new HashMap<String, String>(); Package pkg = clazz.getPackage(); this.packageName = pkg != null ? pkg.getName() : null; processWithClasses( clazz.getAnnotation( WithClasses.class ) ); processWithMappingFiles( clazz.getAnnotation( WithMappingFiles.class ) ); processOptions( clazz.getAnnotation( WithProcessorOption.class ), clazz.getAnnotation( WithProcessorOption.List.class ) ); ignoreCompilationErrors = clazz.getAnnotation( IgnoreCompilationErrors.class ) != null; } @Override protected Statement methodBlock(FrameworkMethod method) { Statement statement = super.methodBlock( method ); processAnnotations( method ); if ( !annotationProcessorNeedsToRun() ) { return statement; } return new CompilationStatement( statement, testEntities, preCompileEntities, mappingFiles, processorOptions, ignoreCompilationErrors ); } private void processWithClasses(WithClasses withClasses) { if ( withClasses != null ) { Collections.addAll( testEntities, withClasses.value() ); Collections.addAll( preCompileEntities, withClasses.preCompile() ); } } private void processWithMappingFiles(WithMappingFiles withMappingFiles) { if ( withMappingFiles != null ) { String packageNameAsPath = TestUtil.fcnToPath( packageName ); for ( String mappingFile : withMappingFiles.value() ) { mappingFiles.add( packageNameAsPath + File.separator + mappingFile ); } } } private void processOptions(WithProcessorOption withProcessorOption, WithProcessorOption.List withProcessorOptionsListAnnotation) { addOptions( withProcessorOption ); if ( withProcessorOptionsListAnnotation != null ) { for ( WithProcessorOption option : withProcessorOptionsListAnnotation.value() ) { addOptions( option ); } } } private void processAnnotations(FrameworkMethod method) { // configuration will be added to potential class level configuration processWithClasses( method.getAnnotation( WithClasses.class ) ); processWithMappingFiles( method.getAnnotation( WithMappingFiles.class ) ); processOptions( method.getAnnotation( WithProcessorOption.class ), method.getAnnotation( WithProcessorOption.List.class ) ); // overrides potential class level configuration ignoreCompilationErrors = method.getAnnotation( IgnoreCompilationErrors.class ) != null; } private void addOptions(WithProcessorOption withProcessorOptionsAnnotation) { if ( withProcessorOptionsAnnotation != null ) { processorOptions.put( withProcessorOptionsAnnotation.key(), withProcessorOptionsAnnotation.value() ); } } private boolean annotationProcessorNeedsToRun() { return !testEntities.isEmpty() || !mappingFiles.isEmpty(); } }