ejbModule.getProperties().setProperty("openejb.cdi.activated", "false");
final FinderFactory.OpenEJBAnnotationFinder finder = new FinderFactory.OpenEJBAnnotationFinder(new ClassesArchive(ancestors(testClass)));
ejbModule.setFinder(finder);
if (finder.findMetaAnnotatedFields(Inject.class).size()
+ finder.findMetaAnnotatedMethods(Inject.class).size() > 0) { // "activate" cdi to avoid WARNINGs
ejbModule.setBeans(new Beans());
}
appModule.getEjbModules().add(ejbModule);
}
// For the moment we just take the first @Configuration method
// maybe later we can add something fancy to allow multiple configurations using a qualifier
// as a sort of altDD/altConfig concept. Say for example the altDD prefix might be "foo",
// we can then imagine something like this:
// @Foo @Configuration public Properties alternateConfig(){...}
// @Foo @Module public Properties alternateModule(){...}
// anyway, one thing at a time ....
final Properties configuration = new Properties();
configuration.put(DEPLOYMENTS_CLASSPATH_PROPERTY, "false");
final EnableServices annotation = testClass.getAnnotation(EnableServices.class);
if (annotation != null && annotation.httpDebug()) {
configuration.setProperty("httpejbd.print", "true");
configuration.setProperty("httpejbd.indent.xml", "true");
configuration.setProperty("logging.level.OpenEJB.server.http", "FINE");
}
final org.apache.openejb.junit.EnableServices annotationOld = testClass.getAnnotation(org.apache.openejb.junit.EnableServices.class);
if (annotationOld != null && annotationOld.httpDebug()) {
configuration.setProperty("httpejbd.print", "true");
configuration.setProperty("httpejbd.indent.xml", "true");
configuration.setProperty("logging.level.OpenEJB.server.http", "FINE");
}
Openejb openejb = null;
final Map<Object, List<Method>> configs = new HashMap<>();
findAnnotatedMethods(configs, Configuration.class);
findAnnotatedMethods(configs, org.apache.openejb.junit.Configuration.class);
for (final Map.Entry<Object, List<Method>> method : configs.entrySet()) {
for (final Method m : method.getValue()) {
final Object o = m.invoke(method.getKey());
if (o instanceof Properties) {
final Properties properties = (Properties) o;
configuration.putAll(properties);
} else if (Openejb.class.isInstance(o)) {
openejb = Openejb.class.cast(o);
} else if (String.class.isInstance(o)) {
final String path = String.class.cast(o);
final URL url = Thread.currentThread().getContextClassLoader().getResource(path);
if (url == null) {
throw new IllegalArgumentException(o.toString() + " not found");
}
final InputStream in = url.openStream();
try {
if (path.endsWith(".json")) {
openejb = JSonConfigReader.read(Openejb.class, in);
} else {
openejb = JaxbOpenejb.readConfig(new InputSource(in));
}
} finally {
IO.close(in);
}
}
}
}
if (SystemInstance.isInitialized()) {
SystemInstance.reset();
}
SystemInstance.init(configuration);
final CdiExtensions cdiExtensions = testClass.getAnnotation(CdiExtensions.class);
if (cdiExtensions != null) {
SystemInstance.get().setComponent(LoaderService.class, new ExtensionAwareOptimizedLoaderService(cdiExtensions.value()));
}
// save the test under test to be able to retrieve it from extensions
// /!\ has to be done before all other init
SystemInstance.get().setComponent(TestInstance.class, new TestInstance(testClass, inputTestInstance));
// call the mock injector before module method to be able to use mocked classes
// it will often use the TestInstance so
final Map<Object, List<Method>> mockInjectors = new HashMap<>();
findAnnotatedMethods(mockInjectors, MockInjector.class);
findAnnotatedMethods(mockInjectors, org.apache.openejb.junit.MockInjector.class);
if (!mockInjectors.isEmpty() && !mockInjectors.values().iterator().next().isEmpty()) {
final Map.Entry<Object, List<Method>> methods = mockInjectors.entrySet().iterator().next();
Object o = methods.getValue().iterator().next().invoke(methods.getKey());
if (o instanceof Class<?>) {
o = ((Class<?>) o).newInstance();
}
if (o instanceof FallbackPropertyInjector) {
SystemInstance.get().setComponent(FallbackPropertyInjector.class, (FallbackPropertyInjector) o);
}
}
for (final Map.Entry<Object, List<Method>> method : findAnnotatedMethods(new HashMap<Object, List<Method>>(), Component.class).entrySet()) {
for (final Method m : method.getValue()) {
setComponent(method.getKey(), m);
}
}
for (final Map.Entry<Object, List<Method>> method : findAnnotatedMethods(new HashMap<Object, List<Method>>(), org.apache.openejb.junit.Component.class).entrySet()) {
for (final Method m : method.getValue()) {
setComponent(method.getKey(), m);
}
}
final Map<String, URL> additionalDescriptors = descriptorsToMap(testClass.getAnnotation(org.apache.openejb.junit.Descriptors.class));
final Map<String, URL> additionalDescriptorsNew = descriptorsToMap(testClass.getAnnotation(Descriptors.class));
additionalDescriptors.putAll(additionalDescriptorsNew);
Application application = null;
int webModulesNb = 0;
// Invoke the @Module producer methods to build out the AppModule
final Map<Object, List<Method>> moduleMethods = new HashMap<>();
findAnnotatedMethods(moduleMethods, Module.class);
findAnnotatedMethods(moduleMethods, org.apache.openejb.junit.Module.class);
for (final Map.Entry<Object, List<Method>> methods : moduleMethods.entrySet()) {
for (final Method method : methods.getValue()) {
final Object obj = method.invoke(methods.getKey());
final Jars jarsAnnotation = method.getAnnotation(Jars.class);
final Classes classesAnnotation = method.getAnnotation(Classes.class);
final org.apache.openejb.junit.Classes classesAnnotationOld = method.getAnnotation(org.apache.openejb.junit.Classes.class);
Class<?>[] classes = null;
Class<?>[] cdiInterceptors = null;
Class<?>[] cdiAlternatives = null;
Class<?>[] cdiDecorators = null;
boolean cdi = false;
boolean innerClassesAsBean = false;
if (classesAnnotation != null) {
classes = classesAnnotation.value();
innerClassesAsBean = classesAnnotation.innerClassesAsBean();
cdiInterceptors = classesAnnotation.cdiInterceptors();
cdiDecorators = classesAnnotation.cdiDecorators();
cdiAlternatives = classesAnnotation.cdiAlternatives();
cdi = classesAnnotation.cdi() || cdiAlternatives.length > 0
|| cdiDecorators.length > 0 || cdiInterceptors.length > 0;
} else if (classesAnnotationOld != null) {
classes = classesAnnotationOld.value();
}
if (obj instanceof WebApp) { // will add the ejbmodule too
webModulesNb++;
final WebApp webapp = (WebApp) obj;
String root = webapp.getContextRoot();
if (root == null) {
root = "/openejb";
}
testBean.getEnvEntry().addAll(webapp.getEnvEntry());
final WebModule webModule = new WebModule(webapp, root, Thread.currentThread().getContextClassLoader(), "", root);
webModule.getAltDDs().putAll(additionalDescriptors);
webModule.getAltDDs().putAll(descriptorsToMap(method.getAnnotation(Descriptors.class)));
final EjbModule ejbModule = DeploymentLoader.addWebModule(webModule, appModule);
if (cdi) {
ejbModule.setBeans(beans(new Beans(), cdiDecorators, cdiInterceptors, cdiAlternatives));
}
final JaxrsProviders providers = method.getAnnotation(JaxrsProviders.class);
final Class<?>[] providersClasses = providers == null ? null : providers.value();
if (providers != null) {
if (classes == null) {
classes = providersClasses;
} else {
final Collection<Class<?>> newClasses = new ArrayList<>(asList(classes));
newClasses.addAll(asList(providersClasses));
classes = newClasses.toArray(new Class<?>[newClasses.size()]);
}
}
if (innerClassesAsBean) {
final Collection<Class<?>> inners = new LinkedList<Class<?>>();
for (final Class<?> clazz : testClass.getClasses()) {
final int modifiers = clazz.getModifiers();
try {
if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && clazz.getConstructor() != null) {
inners.add(clazz);
}
} catch (final NoSuchMethodException nsme) {
// no-op, skip it
}
}
if (!inners.isEmpty()) {
final Collection<Class<?>> newClasses = new ArrayList<Class<?>>(asList(classes));
newClasses.addAll(inners);
classes = newClasses.toArray(new Class<?>[newClasses.size()]);
}
}
final IAnnotationFinder finder = finderFromClasses(webModule, classes, findFiles(jarsAnnotation));
webModule.setFinder(finder);
ejbModule.setFinder(webModule.getFinder());
if (providersClasses != null) {
OpenejbJar openejbJar = ejbModule.getOpenejbJar();
if (openejbJar == null) {
openejbJar = new OpenejbJar();
ejbModule.setOpenejbJar(openejbJar);
}
final PojoDeployment pojoDeployment = new PojoDeployment();
pojoDeployment.setClassName(providers.applicationName());
pojoDeployment.getProperties().setProperty("cxf.jaxrs.providers", Join.join(",", providersClasses).replace("class ", ""));
openejbJar.getPojoDeployment().add(pojoDeployment);
}
} else if (obj instanceof WebModule) { // will add the ejbmodule too
webModulesNb++;
final WebModule webModule = (WebModule) obj;
webModule.getAltDDs().putAll(additionalDescriptors);
webModule.getAltDDs().putAll(descriptorsToMap(method.getAnnotation(Descriptors.class)));
final EjbModule ejbModule = DeploymentLoader.addWebModule(webModule, appModule);
if (cdi) {
ejbModule.setBeans(beans(new Beans(), cdiDecorators, cdiInterceptors, cdiAlternatives));
}
webModule.setFinder(finderFromClasses(webModule, classes, findFiles(jarsAnnotation)));
ejbModule.setFinder(webModule.getFinder());
} else if (obj instanceof EjbModule) {
final EjbModule ejbModule = (EjbModule) obj;
ejbModule.getAltDDs().putAll(additionalDescriptors);
ejbModule.getAltDDs().putAll(descriptorsToMap(method.getAnnotation(Descriptors.class)));
ejbModule.initAppModule(appModule);
appModule.getEjbModules().add(ejbModule);
if (cdi) {
ejbModule.setBeans(beans(new Beans(), cdiDecorators, cdiInterceptors, cdiAlternatives));
}
ejbModule.setFinder(finderFromClasses(ejbModule, classes, findFiles(jarsAnnotation)));
} else if (obj instanceof EjbJar) {
final EjbJar ejbJar = (EjbJar) obj;
setId(ejbJar, method);
final EjbModule ejbModule = new EjbModule(ejbJar);
ejbModule.getAltDDs().putAll(additionalDescriptors);
ejbModule.getAltDDs().putAll(descriptorsToMap(method.getAnnotation(Descriptors.class)));
appModule.getEjbModules().add(ejbModule);
if (cdi) {
ejbModule.setBeans(beans(new Beans(), cdiDecorators, cdiInterceptors, cdiAlternatives));
}
ejbModule.setFinder(finderFromClasses(ejbModule, classes, findFiles(jarsAnnotation)));
} else if (obj instanceof EnterpriseBean) {
final EnterpriseBean bean = (EnterpriseBean) obj;
final EjbJar ejbJar = new EjbJar(method.getName());
ejbJar.addEnterpriseBean(bean);
final EjbModule ejbModule = new EjbModule(ejbJar);
final Beans beans = new Beans();
beans.addManagedClass(bean.getEjbClass());
ejbModule.setBeans(beans);
appModule.getEjbModules().add(ejbModule);
if (cdi) {
ejbModule.setBeans(beans(new Beans(), cdiDecorators, cdiInterceptors, cdiAlternatives));
}
ejbModule.setFinder(finderFromClasses(ejbModule, classes, findFiles(jarsAnnotation)));
} else if (obj instanceof Application) {
application = (Application) obj;
setId(application, method);
} else if (obj instanceof Connector) {
final Connector connector = (Connector) obj;
setId(connector, method);
appModule.getConnectorModules().add(new ConnectorModule(connector));
} else if (obj instanceof Persistence) {
final Persistence persistence = (Persistence) obj;
appModule.addPersistenceModule(new PersistenceModule(appModule, implicitRootUrl(), persistence));
} else if (obj instanceof PersistenceUnit) {
final PersistenceUnit unit = (PersistenceUnit) obj;
appModule.addPersistenceModule(new PersistenceModule(appModule, implicitRootUrl(), new Persistence(unit)));
} else if (obj instanceof Beans) {
final Beans beans = (Beans) obj;
final EjbModule ejbModule = new EjbModule(new EjbJar(method.getName()));
ejbModule.setBeans(beans);
appModule.getEjbModules().add(ejbModule);
if (cdi) {
ejbModule.setBeans(beans(beans, cdiDecorators, cdiInterceptors, cdiAlternatives));
}
ejbModule.setFinder(finderFromClasses(ejbModule, classes, findFiles(jarsAnnotation)));
} else if (obj instanceof Class[]) {
final Class[] beans = (Class[]) obj;
final EjbModule ejbModule = new EjbModule(new EjbJar(method.getName()));
ejbModule.setFinder(new AnnotationFinder(new ClassesArchive(beans)).link());
ejbModule.setBeans(new Beans());
appModule.getEjbModules().add(ejbModule);
} else if (obj instanceof Class) {
final Class bean = (Class) obj;
final EjbModule ejbModule = new EjbModule(new EjbJar(method.getName()));
ejbModule.setFinder(new AnnotationFinder(new ClassesArchive(bean)).link());
ejbModule.setBeans(new Beans());
appModule.getEjbModules().add(ejbModule);
} else if (obj instanceof IAnnotationFinder) {
final EjbModule ejbModule = new EjbModule(new EjbJar(method.getName()));
ejbModule.setFinder((IAnnotationFinder) obj);
ejbModule.setBeans(new Beans());
appModule.getEjbModules().add(ejbModule);
} else if (obj instanceof ClassesArchive) {
final EjbModule ejbModule = new EjbModule(new EjbJar(method.getName()));
ejbModule.setFinder(new AnnotationFinder((Archive) obj).link());
ejbModule.setBeans(new Beans());
appModule.getEjbModules().add(ejbModule);
} else if (obj instanceof AppModule) {
// we can probably go further here
final AppModule module = (AppModule) obj;
module.getAltDDs().putAll(additionalDescriptors);
module.getAltDDs().putAll(descriptorsToMap(method.getAnnotation(Descriptors.class)));
if (module.getWebModules().size() > 0) {
webModulesNb++;
}
appModule.getEjbModules().addAll(module.getEjbModules());
appModule.getPersistenceModules().addAll(module.getPersistenceModules());
appModule.getAdditionalLibMbeans().addAll(module.getAdditionalLibMbeans());
appModule.getWebModules().addAll(module.getWebModules());
appModule.getConnectorModules().addAll(module.getConnectorModules());
appModule.getResources().addAll(module.getResources());
appModule.getServices().addAll(module.getServices());
appModule.getPojoConfigurations().putAll(module.getPojoConfigurations());
appModule.getAdditionalLibraries().addAll(module.getAdditionalLibraries());
appModule.getAltDDs().putAll(module.getAltDDs());
appModule.getProperties().putAll(module.getProperties());
}
}
}
// Application is final in AppModule, which is fine, so we'll create a new one and move everything
if (application != null) {
final AppModule newModule = new AppModule(appModule.getClassLoader(), appModule.getModuleId(), application, false);
newModule.getClientModules().addAll(appModule.getClientModules());
newModule.addPersistenceModules(appModule.getPersistenceModules());
newModule.getEjbModules().addAll(appModule.getEjbModules());
newModule.getConnectorModules().addAll(appModule.getConnectorModules());
appModule = newModule;
}
// copy ejb into beans if cdi is activated and init finder
for (final EjbModule ejb : appModule.getEjbModules()) {
final EnterpriseBean[] enterpriseBeans = ejb.getEjbJar().getEnterpriseBeans();
final Beans beans = ejb.getBeans();
if (beans != null && ejb.getEjbJar() != null) {
for (final EnterpriseBean bean : enterpriseBeans) {
boolean found = false;
for (final List<String> mc : beans.getManagedClasses().values()) {
if (mc.contains(bean.getEjbClass())) {
found = true;
break;
}
}
if (!found) {
beans.addManagedClass(bean.getEjbClass());
}
}
}
}