blob: 13bd310a2a88de437e41d4079155762c529542c0 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.openejb.junit5.jee;
import org.apache.openejb.Injector;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.OpenEjbContainer;
import org.apache.openejb.injection.FallbackPropertyInjector;
import org.apache.openejb.junit.jee.config.Properties;
import org.apache.openejb.junit.jee.config.Property;
import org.apache.openejb.junit.jee.config.PropertyFile;
import org.apache.openejb.junit.jee.resources.TestResource;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.osgi.client.LocalInitialContextFactory;
import org.apache.openejb.testing.TestInstance;
import org.apache.openejb.util.Classes;
import org.junit.jupiter.api.extension.*;
import javax.ejb.embeddable.EJBContainer;
import javax.naming.Context;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Hashtable;
import java.util.Optional;
public class EjbContainerExtension implements AfterAllCallback, BeforeAllCallback, BeforeEachCallback {
private java.util.Properties properties;
private EJBContainer container;
@Override
public void beforeAll(ExtensionContext extensionContext) throws Exception {
Optional<Class<?>> oClazz = extensionContext.getTestClass();
if (!oClazz.isPresent()) {
throw new RuntimeException("Could not get class from extension context");
}
Class<?> clazz = oClazz.get();
properties = new java.util.Properties();
{ // set caller first to let it be overridable by @Property
final StringBuilder b = new StringBuilder();
for (final Class<?> c : Classes.ancestors(clazz)) {
if (c != Object.class) {
b.append(c.getName()).append(",");
}
}
b.setLength(b.length() - 1);
properties.put(OpenEjbContainer.Provider.OPENEJB_ADDITIONNAL_CALLERS_KEY, b.toString());
}
// default implicit config
{
try (final InputStream is = clazz.getClassLoader().getResourceAsStream("openejb-junit.properties")) {
if (is != null) {
properties.load(is);
}
}
}
final PropertyFile propertyFile = clazz.getAnnotation(PropertyFile.class);
if (propertyFile != null) {
final String path = propertyFile.value();
if (!path.isEmpty()) {
InputStream is = null;
try {
is = clazz.getClassLoader().getResourceAsStream(path);
if (is == null) {
final File file = new File(path);
if (file.exists()) {
is = new FileInputStream(file);
} else {
throw new OpenEJBException("properties resource '" + path + "' not found");
}
}
properties.load(is);
} finally {
if (is != null) {
is.close();
}
}
}
}
final Properties annotationConfig = clazz.getAnnotation(Properties.class);
if (annotationConfig != null) {
for (final Property property : annotationConfig.value()) {
properties.put(property.key(), property.value());
}
}
if (!properties.containsKey(Context.INITIAL_CONTEXT_FACTORY)) {
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
}
container = EJBContainer.createEJBContainer(properties);
}
@Override
public void beforeEach(ExtensionContext extensionContext) throws Exception {
Class<?> clazz = extensionContext.getTestClass().isPresent() ? extensionContext.getTestClass().get() : null;
Object test = extensionContext.getTestInstance().isPresent() ? extensionContext.getTestInstance().get() : null;
if (clazz != null){
while (!Object.class.equals(clazz)) {
for (final Field field : clazz.getDeclaredFields()) {
final TestResource resource = field.getAnnotation(TestResource.class);
if (resource != null) {
if (Context.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
field.set(Modifier.isStatic(field.getModifiers()) ? null : test, getContainer().getContext());
} else if (Hashtable.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
field.set(Modifier.isStatic(field.getModifiers()) ? null : test, getProperties());
} else if (EJBContainer.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
field.set(Modifier.isStatic(field.getModifiers()) ? null : test, getContainer());
} else {
throw new OpenEJBException("can't inject field '" + field.getName() + "'");
}
}
}
clazz = clazz.getSuperclass();
}
}
if (test != null) {
SystemInstance.get().setComponent(TestInstance.class, new TestInstance(test.getClass(), test));
SystemInstance.get().getComponent(FallbackPropertyInjector.class); // force eager init (MockitoInjector initialize everything in its constructor)
Injector.inject(test);
}
}
@Override
public void afterAll(ExtensionContext extensionContext) throws Exception {
if (container != null) {
container.close();
}
}
public java.util.Properties getProperties() {
return properties;
}
public EJBContainer getContainer() {
return container;
}
}