org.apache.openejb.config.ApplicationComposerDeployer Maven / Gradle / Ivy
/*
* 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.config;
import org.apache.openejb.BeanContext;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.api.configuration.ApplicationComposer;
import org.apache.openejb.jee.Beans;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.TransactionType;
import org.apache.openejb.jee.jpa.unit.Persistence;
import org.apache.openejb.jee.jpa.unit.PersistenceUnit;
import org.apache.openejb.testing.Classes;
import org.apache.openejb.testing.Configuration;
import org.apache.openejb.testing.Descriptor;
import org.apache.openejb.testing.Descriptors;
import org.apache.openejb.testing.JaxrsProviders;
import org.apache.xbean.finder.AnnotationFinder;
import org.apache.xbean.finder.archive.Archive;
import org.apache.xbean.finder.archive.ClassesArchive;
import org.apache.xbean.finder.archive.CompositeArchive;
import org.apache.xbean.finder.archive.FilteredArchive;
import org.apache.xbean.finder.filter.Filters;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Properties;
// use temp classloader so be careful with the decorated class
//
// dont reuse ApplicationComposers to control what we support here + cleanup what we don't want to support (XModule -> test only)
public class ApplicationComposerDeployer implements DynamicDeployer {
@Override
public AppModule deploy(final AppModule appModule) throws OpenEJBException {
if (!appModule.isStandaloneModule()) {
return appModule;
}
for (final EjbModule ejbModule : appModule.getEjbModules()) {
if (ejbModule.getFinder() == null) {
continue;
}
WebModule webModule = null;
for (final WebModule web : appModule.getWebModules()) {
if (!web.getModuleId().equals(ejbModule.getModuleId())) {
continue;
}
webModule = web;
break;
}
if (webModule == null) {
continue;
}
for (final Class> clazz : ejbModule.getFinder().findAnnotatedClasses(ApplicationComposer.class)) {
final ApplicationComposer applicationComposer = clazz.getAnnotation(ApplicationComposer.class);
final Descriptor descriptor = clazz.getAnnotation(Descriptor.class);
if (descriptor != null) {
configureDescriptor(appModule, descriptor);
}
final Descriptors descriptors = clazz.getAnnotation(Descriptors.class);
if (descriptors != null) {
for (final Descriptor d : descriptors.value()) {
configureDescriptor(appModule, descriptor);
}
}
final Classes classes = clazz.getAnnotation(Classes.class);
if (classes != null) {
configureClasses(webModule, ejbModule, applicationComposer, classes);
}
Object instance = null;
final AnnotationFinder finder = new AnnotationFinder(new ClassesArchive(org.apache.openejb.util.Classes.ancestors(clazz)));
for (final Method m : finder.findAnnotatedMethods(org.apache.openejb.testing.Module.class)) {
instance = configureModule(appModule, ejbModule, clazz, instance, m);
}
for (final Method m : finder.findAnnotatedMethods(Configuration.class)) {
instance = configureConfiguration(appModule, clazz, instance, m);
}
final JaxrsProviders jaxrsProviders = clazz.getAnnotation(JaxrsProviders.class);
if (jaxrsProviders != null) {
for (final Class> c : jaxrsProviders.value()) {
webModule.getJaxrsProviders().add(c.getName());
}
}
}
}
return appModule;
}
private Object configureConfiguration(final AppModule appModule, final Class> clazz, Object instance, final Method m) {
final int modifiers = m.getModifiers();
if (!Modifier.isPublic(modifiers)) {
throw new IllegalArgumentException("@Configuration should be public");
}
final boolean isStatic = Modifier.isStatic(modifiers);
if (!isStatic) {
try {
instance = clazz.newInstance();
} catch (final Exception e) {
// no-op
}
}
try {
final Object result = m.invoke(isStatic ? null : instance);
if (Properties.class.isInstance(result)) {
appModule.getProperties().putAll(Properties.class.cast(result));
} else {
throw new IllegalArgumentException(result + " not yet supported (" + m + ")");
}
} catch (final IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException(e);
}
return instance;
}
private Object configureModule(final AppModule appModule, final EjbModule ejbModule, final Class> clazz, Object instance, final Method m) {
final int modifiers = m.getModifiers();
if (!Modifier.isPublic(modifiers)) {
throw new IllegalArgumentException("@Module should be public");
}
final boolean isStatic = Modifier.isStatic(modifiers);
if (!isStatic) {
try {
instance = clazz.newInstance();
} catch (final Exception e) {
// no-op
}
}
try {
final Object result = m.invoke(isStatic ? null : instance);
if (EjbJar.class.isInstance(result)) {
ejbModule.setEjbJar(EjbJar.class.cast(result));
} else if (Persistence.class.isInstance(result)) {
final Persistence persistence = Persistence.class.cast(result);
if (!persistence.getPersistenceUnit().isEmpty()) {
appModule.getPersistenceModules().add(new PersistenceModule(appModule, rootUrl(ejbModule), persistence));
}
} else if (PersistenceUnit.class.isInstance(result)) {
final PersistenceUnit unit = PersistenceUnit.class.cast(result);
appModule.addPersistenceModule(new PersistenceModule(appModule, rootUrl(ejbModule), new Persistence(unit)));
} else if (Beans.class.isInstance(result)) {
final Beans beans = Beans.class.cast(result);
ejbModule.setBeans(beans);
} else {
throw new IllegalArgumentException(result + " not yet supported (" + m + ")");
}
} catch (final IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException(e);
}
return instance;
}
private String rootUrl(final EjbModule ejbModule) {
try {
return ejbModule.getModuleUri().toURL().toExternalForm();
} catch (final Exception e) { // malformed, npe...shouldn't occur at this point
return null; // actually would be nicer to return null by default to skip any other scanning but needed by some provider and us sometimes
}
}
private void configureClasses(final WebModule web, final EjbModule ejbModule,
final ApplicationComposer applicationComposer, final Classes classes) {
ejbModule.getEjbJar().setMetadataComplete(applicationComposer.metadataComplete());
final Collection archives = new LinkedList<>();
if (classes.value().length > 0) {
archives.add(new ClassesArchive(classes.value()));
}
if (classes.cdi()) {
final Beans beans = new Beans();
for (final Class> c : classes.cdiAlternatives()) {
beans.addAlternativeClass(c);
}
for (final Class> c : classes.cdiDecorators()) {
beans.addDecorator(c);
}
for (final Class> c : classes.cdiInterceptors()) {
beans.addInterceptor(c);
}
ejbModule.setBeans(beans);
if (applicationComposer.metadataComplete()) {
for (final Class> c : classes.value()) {
beans.addManagedClass(null, c.getName());
}
final String name = BeanContext.Comp.openejbCompName(web.getModuleId());
final org.apache.openejb.jee.ManagedBean managedBean = new CompManagedBean(name, BeanContext.Comp.class);
managedBean.setTransactionType(TransactionType.BEAN);
ejbModule.getEjbJar().addEnterpriseBean(managedBean);
}
}
final CompositeArchive archive = new CompositeArchive(archives);
final Archive finalArchive = classes.excludes().length > 0 ? new FilteredArchive(archive, Filters.invert(Filters.prefixes(classes.excludes()))) : archive;
ejbModule.setFinder(new FinderFactory.OpenEJBAnnotationFinder(finalArchive).link());
web.setFinder(ejbModule.getFinder());
web.getWebApp().setMetadataComplete(ejbModule.getEjbJar().isMetadataComplete());
}
private void configureDescriptor(final AppModule appModule, final Descriptor descriptor) {
URL resource = appModule.getClassLoader().getResource(descriptor.path());
try {
appModule.getAltDDs().put(descriptor.name(), resource == null ? new File(descriptor.path()).toURI().toURL() : resource);
} catch (final MalformedURLException e) {
throw new IllegalArgumentException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy