Package org.jboss.seam.jms

Source Code of org.jboss.seam.jms.Seam3JmsExtension

/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat, Inc. and/or its affiliates, 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.jboss.seam.jms;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.inject.Inject;
import javax.inject.Qualifier;
import javax.jms.Destination;

import org.jboss.logging.Logger;
import org.jboss.seam.jms.annotations.EventRouting;
import org.jboss.seam.jms.annotations.Routing;
import org.jboss.seam.jms.bridge.EgressRoutingObserver;
import org.jboss.seam.jms.bridge.Route;
import org.jboss.seam.jms.bridge.RouteImpl;
import org.jboss.seam.jms.bridge.RouteManager;
import org.jboss.seam.jms.bridge.RouteManagerImpl;
import org.jboss.seam.jms.bridge.RouteType;
import org.jboss.seam.jms.impl.wrapper.JmsAnnotatedTypeWrapper;
import org.jboss.seam.solder.core.VersionLoggerUtil;
import org.jboss.seam.solder.literal.NamedLiteral;

/**
* Seam 3 JMS Portable Extension
*
* @author Jordan Ganoff
* @author <a href="john.d.ament@gmail.com">John Ament</a>
*/
public class Seam3JmsExtension implements Extension {


    private static final Logger log = Logger.getLogger(Seam3JmsExtension.class);
    private List<Route> ingressRoutes = new ArrayList<Route>();
    private List<Route> egressRoutes = new ArrayList<Route>();
    private List<EgressRoutingObserver> observerMethods = new ArrayList<EgressRoutingObserver>();
    private Set<AnnotatedType<?>> eventRoutingRegistry = new HashSet<AnnotatedType<?>>();
    private Set<AnnotatedMethod<?>> observerMethodRegistry = new HashSet<AnnotatedMethod<?>>();
    private boolean readyToRoute = false;

    public void buildRoutes(@Observes final AfterBeanDiscovery abd, final BeanManager bm) {
        log.debug("Building JMS Routes.");
        RouteManager routeManager = new RouteManagerImpl();
        for (AnnotatedType<?> at : eventRoutingRegistry) {
            Object instance = null;
            try {
                instance = at.getJavaClass().newInstance();
            } catch (InstantiationException ex) {
                abd.addDefinitionError(ex);
                break;
            } catch (IllegalAccessException ex) {
                abd.addDefinitionError(ex);
                break;
            }
            for (AnnotatedMethod<?> am : at.getMethods()) {
                Object result = null;
                try {
                    result = am.getJavaMember().invoke(instance, routeManager);
                } catch (IllegalAccessException ex) {
                    abd.addDefinitionError(ex);
                } catch (IllegalArgumentException ex) {
                    abd.addDefinitionError(ex);
                } catch (InvocationTargetException ex) {
                    abd.addDefinitionError(ex);
                }
                if (result != null) {
                    if (Collection.class.isAssignableFrom(result.getClass())) {
                        @SuppressWarnings("unchecked")
                        Collection<Route> routes = Collection.class.cast(result);
                        for (Route route : routes) {
                            if (route == null) {
                                log.warn("No routes found for " + am);
                            } else {
                                addRoute(route);
                            }
                        }
                    } else if (Route.class.isAssignableFrom(result.getClass())) {
                        addRoute(Route.class.cast(result));
                    } else {
                        abd.addDefinitionError(new IllegalArgumentException("Unsupported route configuration type: " + result));
                    }
                }
            }
        }
        /* when going through the observer method registry, we pick up cases where we dynamically build routes based on
         * observer interfaces.  An example method of this can be seen in the test case ObserverInterface. */
        for (AnnotatedMethod<?> m : observerMethodRegistry) {
            for (AnnotatedParameter<?> ap : m.getParameters()) {
                log.debug("In method " + m.getJavaMember().getName() + " with param type " + ap.getBaseType());
            }
            Class<?> intfClazz = m.getJavaMember().getDeclaringClass();
            String methodName = m.getJavaMember().getName();
            String routeId = intfClazz.getCanonicalName() + "." + methodName;
            Routing routing = null;
            if (m.isAnnotationPresent(Routing.class)) {
                routing = m.getAnnotation(Routing.class);
            } else {
                log.debug("Routing not found on method " + m.getJavaMember().getName());
            }
            RouteType routeType = (routing == null) ? RouteType.BOTH : routing.value();
            Route route = new RouteImpl(routeType).id(routeId);
            boolean isResourced = m.isAnnotationPresent(Resource.class);
            if (isResourced) {
                Resource r = m.getAnnotation(Resource.class);
                log.debug("Loading resource " + r.mappedName());
                route.addDestinationJndiName(r.mappedName());
            }

            /* in this case, each method has one non destination and multiple
             * destinations.  this can take the form of resources or qualified
             * resources.
             */
            try {
                for (AnnotatedParameter<?> ap : m.getParameters()) {
                    if (ap.getBaseType() instanceof Class) {
                        Class<?> clazz = (Class<?>) ap.getBaseType();
                        if (Destination.class.isAssignableFrom(clazz)) {
                            log.debug("Found another type of qualifier.");
                            //route.addDestinationQualifiers(ap.getAnnotations());
                            route.addAnnotatedParameter(ap);
                        } else if (ap.isAnnotationPresent(Observes.class)) {
                            route.setType(ap.getBaseType());
                            route.getQualifiers().addAll(getQualifiersFrom(ap.getAnnotations()));
                        }
                    }
                }
            } catch (Exception e) {
                log.warn("Exception mapping for method " + m.getJavaMember().getDeclaringClass() + "." + m.getJavaMember().getName() + ", ", e);
            }
            addRoute(route);
        }
        for (Route egress : this.egressRoutes) {
            EgressRoutingObserver ero = new EgressRoutingObserver(egress, this);
            abd.addObserverMethod(ero);
            this.observerMethods.add(ero);
        }
    }

    /** Test to remove.
    public <X> void decorateAnnotatedType(@Observes ProcessAnnotatedType<X> pat) {
      log.info("Calling decorate annotated type");
        pat.setAnnotatedType(JmsAnnotatedTypeWrapper.decorate(pat.getAnnotatedType()));
    }**/

    public void setBeanManager(BeanManager beanManager) {
        log.debug("Handling AfterDeploymentValidation, loading active bean manager into all beans.");
        VersionLoggerUtil.logVersionInformation(this.getClass());
        if (!this.readyToRoute) {
            for (EgressRoutingObserver ero : this.observerMethods) {
                log.debug("Setting observer method beanmanager. " + beanManager);
                ero.setBeanManager(beanManager);
            }
            this.readyToRoute = true;
        }
        log.debug("EgressRoutingObservers: " + this.observerMethods);
        log.debug("Ingress routes: " + this.ingressRoutes);
    }

    public boolean isReadyToRoute() {
        return this.readyToRoute;
    }

    /**
     * Generates the observer method registry for all interfaces that have observer methods.
     *
     * @param pat
     */
    public void registerObserverMethods(@Observes ProcessAnnotatedType<?> pat) {
      if (pat.getAnnotatedType().getJavaClass().isInterface()) {
            log.debug("Found a possible interface... " + pat.getAnnotatedType().getJavaClass());
            for (AnnotatedMethod<?> m : pat.getAnnotatedType().getMethods()) {
                this.observerMethodRegistry.add(m);
            }
        } else {
            Set<AnnotatedMethod<?>> sams = new HashSet<AnnotatedMethod<?>>();
            for (AnnotatedMethod<?> m : pat.getAnnotatedType().getMethods()) {
                if (m.isAnnotationPresent(EventRouting.class)) {
                    sams.add(m);
                }
            }
            if (!sams.isEmpty()) {
                pat.veto();
                this.eventRoutingRegistry.add(pat.getAnnotatedType());
            }
        }
    }

    private void addRoute(Route route) {
        log.debug("RouteType is: " + route.getType());
        if (route.validate()) {
            if (route.getType() == RouteType.EGRESS) {
                this.egressRoutes.add(route);
            } else if (route.getType() == RouteType.INGRESS) {
                this.ingressRoutes.add(route);
            } else {
                log.debug("Adding both types of routes.");
                this.egressRoutes.add(route);
                this.ingressRoutes.add(route);
            }
        } else {
            log.debugf("Not adding route %s to routes, it was not valid.", route);
        }
    }

    public List<Route> getIngressRoutes() {
        return this.ingressRoutes;
    }

    public List<Route> getEgressRoutes() {
        return this.egressRoutes;
    }

    private static Set<Annotation> getQualifiersFrom(Set<Annotation> annotations) {
        Set<Annotation> q = new HashSet<Annotation>();
        log.debug("Annotations in getQualifiersFrom: " + annotations);
        for (Annotation a : annotations) {
            if (a.annotationType().isAnnotationPresent(Qualifier.class)) {
                q.add(a);
            } else {
                log.infof("Skipping annotation %s", a);
            }
        }
        return q;
    }
}
TOP

Related Classes of org.jboss.seam.jms.Seam3JmsExtension

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.