Home » apache-openwebbeans-1.0.0-incubating-M3-sources » org.apache.webbeans.event » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements. See the NOTICE file distributed with this
    4    * work for additional information regarding copyright ownership. The ASF
    5    * licenses this file to You under the Apache License, Version 2.0 (the
    6    * "License"); you may not use this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
    9    * or agreed to in writing, software distributed under the License is
   10    * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   11    * KIND, either express or implied. See the License for the specific language
   12    * governing permissions and limitations under the License.
   13    */
   14   package org.apache.webbeans.event;
   15   
   16   import java.lang.annotation.Annotation;
   17   import java.lang.reflect.Method;
   18   import java.lang.reflect.Type;
   19   import java.util.Arrays;
   20   import java.util.HashSet;
   21   import java.util.Iterator;
   22   import java.util.Map;
   23   import java.util.Set;
   24   import java.util.concurrent.ConcurrentHashMap;
   25   import java.util.concurrent.CopyOnWriteArraySet;
   26   
   27   import javax.enterprise.event.Reception;
   28   import javax.enterprise.event.Observer;
   29   import javax.enterprise.event.ObserverException;
   30   import javax.enterprise.event.Observes;
   31   import javax.enterprise.inject.TypeLiteral;
   32   import javax.transaction.Status;
   33   import javax.transaction.Synchronization;
   34   import javax.transaction.Transaction;
   35   
   36   import org.apache.webbeans.component.InjectionTargetBean;
   37   import org.apache.webbeans.container.BeanManagerImpl;
   38   import org.apache.webbeans.container.activity.ActivityManager;
   39   import org.apache.webbeans.exception.WebBeansException;
   40   import org.apache.webbeans.logger.WebBeansLogger;
   41   import org.apache.webbeans.spi.ServiceLoader;
   42   import org.apache.webbeans.spi.TransactionService;
   43   import org.apache.webbeans.util.AnnotationUtil;
   44   import org.apache.webbeans.util.Asserts;
   45   import org.apache.webbeans.util.ClassUtil;
   46   
   47   @SuppressWarnings("unchecked")
   48   public final class NotificationManager implements Synchronization
   49   {
   50       private static final WebBeansLogger logger = WebBeansLogger.getLogger(NotificationManager.class);
   51   
   52       private Map<Type, Set<ObserverWrapper<?>>> observers = new ConcurrentHashMap<Type, Set<ObserverWrapper<?>>>();
   53   
   54       private Set<TransactionalNotifier> transactionSet = new CopyOnWriteArraySet<TransactionalNotifier>();
   55       
   56       private TransactionService transactionService = ServiceLoader.getService(TransactionService.class);
   57   
   58       public NotificationManager()
   59       {
   60   
   61       }
   62   
   63       public static NotificationManager getInstance()
   64       {
   65           BeanManagerImpl manager =  ActivityManager.getInstance().getCurrentActivity();
   66           
   67           return manager.getNotificationManager();
   68       }
   69   
   70       public <T> void addObserver(Observer<T> observer, Type eventType, Annotation... annotations)
   71       {
   72           addObserver(observer, false, TransactionalObserverType.NONE, eventType, annotations);
   73       }
   74   
   75       public <T> void addObserver(Observer<T> observer, boolean ifExist, TransactionalObserverType type, Type eventType, Annotation... annotations)
   76       {
   77           EventUtil.checkEventBindings(annotations);
   78   
   79           ObserverWrapper<T> observerImpl = new ObserverWrapper<T>(observer, ifExist, type, eventType, annotations);
   80   
   81           Set<ObserverWrapper<?>> set = observers.get(eventType);
   82           if (set == null)
   83           {
   84               set = new HashSet<ObserverWrapper<?>>();
   85               observers.put(eventType, set);
   86           }
   87   
   88           set.add(observerImpl);
   89       }
   90   
   91       public <T> void addObserver(Observer<T> observer, TypeLiteral<T> eventType, Annotation... annotations)
   92       {
   93           EventUtil.checkEventType(eventType.getRawType());
   94           EventUtil.checkEventBindings(annotations);
   95   
   96           ObserverWrapper<T> observerImpl = new ObserverWrapper<T>(observer, eventType.getRawType(), annotations);
   97   
   98           Set<ObserverWrapper<?>> set = observers.get(eventType.getRawType());
   99           if (set == null)
  100           {
  101               set = new HashSet<ObserverWrapper<?>>();
  102               observers.put(eventType.getRawType(), set);
  103           }
  104   
  105           set.add(observerImpl);
  106       }
  107   
  108       public <T> void removeObserver(Observer<T> observer, Class<T> eventType, Annotation... annotations)
  109       {
  110           EventUtil.checkEventType(eventType);
  111           EventUtil.checkEventBindings(annotations);
  112   
  113           if (observers.containsKey(eventType))
  114           {
  115               Set<ObserverWrapper<?>> set = observers.get(eventType);
  116               Iterator<ObserverWrapper<?>> it = set.iterator();
  117               while (it.hasNext())
  118               {
  119                   ObserverWrapper<?> s = it.next();
  120                   Observer<T> ob = (Observer<T>) s.getObserver();
  121   
  122                   Set<Annotation> evenBindings = s.getEventQualifiers();
  123                   Annotation[] anns = new Annotation[evenBindings.size()];
  124                   anns = evenBindings.toArray(anns);
  125                   
  126                   if (ob.equals(observer) && Arrays.equals(anns, annotations))
  127                   {
  128                       set.remove(s);
  129                   }
  130               }
  131           }
  132       }
  133   
  134       public <T> void removeObserver(Observer<T> observer, TypeLiteral<T> eventType, Annotation... annotations)
  135       {
  136           EventUtil.checkEventType(eventType.getRawType());
  137           EventUtil.checkEventBindings(annotations);
  138   
  139           if (observers.containsKey(eventType.getRawType()))
  140           {
  141               Set<ObserverWrapper<?>> set = observers.get(eventType.getRawType());
  142               Iterator<ObserverWrapper<?>> it = set.iterator();
  143               while (it.hasNext())
  144               {
  145                   ObserverWrapper<?> s = it.next();
  146                   Observer<T> ob = (Observer<T>) s.getObserver();
  147   
  148                   Set<Annotation> evenBindings = s.getEventQualifiers();
  149                   Annotation[] anns = new Annotation[evenBindings.size()];
  150                   anns = evenBindings.toArray(anns);
  151                   
  152                   if (ob.equals(observer) && Arrays.equals(anns, annotations))
  153                   {
  154                       set.remove(s);
  155                   }
  156               }
  157           }
  158       }
  159   
  160       public <T> Set<Observer<T>> resolveObservers(T event, Annotation... bindings)
  161       {
  162   
  163           Set<ObserverWrapper<?>> resolvedSet = new HashSet<ObserverWrapper<?>>();
  164           Set<Observer<T>> unres = new HashSet<Observer<T>>();
  165   
  166           Class<T> eventType = (Class<T>) event.getClass();
  167           
  168           
  169           Set<Type> types = new HashSet<Type>();
  170           ClassUtil.setTypeHierarchy(types, eventType);
  171   
  172           //EventUtil.checkEventType(eventType);
  173           EventUtil.checkEventBindings(bindings);
  174   
  175           Set<Type> keySet = this.observers.keySet();
  176           Iterator<Type> itKeySet = keySet.iterator();
  177   
  178           while (itKeySet.hasNext())
  179           {
  180               Type type = itKeySet.next();
  181               
  182               for(Type check : types)
  183               {
  184                   if (ClassUtil.isAssignable(check, type))
  185                   {
  186                       resolvedSet.addAll(this.observers.get(type));
  187                       break;
  188                   }                
  189               }            
  190           }
  191   
  192           Iterator<ObserverWrapper<?>> it = resolvedSet.iterator();
  193           while (it.hasNext())
  194           {
  195               ObserverWrapper<T> impl = (ObserverWrapper<T>) it.next();
  196   
  197               if (impl.isObserverOfQualifiers(bindings))
  198               {
  199                   unres.add(impl.getObserver());
  200               }
  201           }
  202   
  203           return unres;
  204       }
  205   
  206       public void fireEvent(Object event, Annotation... bindings)
  207       {
  208           Set<Observer<Object>> observers = resolveObservers(event, bindings);
  209           Iterator<Observer<Object>> it = observers.iterator();
  210   
  211           TransactionalNotifier transNotifier = null;
  212           while (it.hasNext())
  213           {
  214               Observer<Object> observer = it.next();
  215               try
  216               {             
  217                   if(observer instanceof BeanObserverImpl)
  218                   {
  219                       BeanObserverImpl<Object> beanObserver = (BeanObserverImpl<Object>) observer;
  220                       TransactionalObserverType type = beanObserver.getType();
  221                       if (!(type.equals(TransactionalObserverType.NONE)))
  222                       {
  223                           Transaction transaction = transactionService.getTransaction();
  224                           
  225                           if (transaction != null)
  226                           {
  227                               transaction.registerSynchronization(this);
  228                           
  229                               if (transNotifier == null)
  230                               {
  231                                   transNotifier = new TransactionalNotifier(event);
  232                                   this.transactionSet.add(transNotifier);
  233                               }
  234   
  235                               // Register for transaction
  236                               if (type.equals(TransactionalObserverType.AFTER_TRANSACTION_COMPLETION))
  237                               {
  238                                   transNotifier.addAfterCompletionObserver(observer);
  239                               }
  240                               else if (type.equals(TransactionalObserverType.AFTER_TRANSACTION_SUCCESS))
  241                               {
  242                                   transNotifier.addAfterCompletionSuccessObserver(observer);
  243                               }
  244                               else if (type.equals(TransactionalObserverType.AFTER_TRANSACTION_FAILURE))
  245                               {
  246                                   transNotifier.addAfterCompletionFailureObserver(observer);
  247                               }
  248                               else if (type.equals(TransactionalObserverType.BEFORE_TRANSACTION_COMPLETION))
  249                               {
  250                                   transNotifier.addBeforeCompletionObserver(observer);
  251                               }
  252                           }
  253                           else
  254                           {
  255                               observer.notify(event);   
  256                           }
  257                       }
  258                       else
  259                       {
  260                           observer.notify(event);   
  261                       }
  262                       
  263                   }
  264                   else
  265                   {
  266                       observer.notify(event);
  267                   }
  268               }
  269               catch (WebBeansException e)
  270               {
  271                   if (!RuntimeException.class.isAssignableFrom(e.getCause().getClass()))
  272                   {
  273                       throw new ObserverException("Exception is thrown while handling event object with type : " + event.getClass().getName(), e);
  274                   }
  275                   else
  276                   {
  277                       RuntimeException rte = (RuntimeException)e.getCause();
  278                       throw rte;
  279                   }
  280               }
  281               catch(RuntimeException e)
  282               {
  283                   throw e;
  284               }
  285               
  286               catch(Exception e)
  287               {
  288                   throw new WebBeansException(e);
  289               }
  290           }
  291       }
  292   
  293       public <T> void addObservableComponentMethods(InjectionTargetBean<?> component)
  294       {
  295           Asserts.assertNotNull(component, "component parameter can not be null");
  296           Set<Method> observableMethods = component.getObservableMethods();
  297           Iterator<Method> itMethods = observableMethods.iterator();
  298   
  299           while (itMethods.hasNext())
  300           {
  301               Method observableMethod = itMethods.next();
  302               Observes observes = AnnotationUtil.getMethodFirstParameterAnnotation(observableMethod, Observes.class);
  303               
  304               Annotation[] bindingTypes = AnnotationUtil.getMethodFirstParameterQualifierWithGivenAnnotation(observableMethod, Observes.class);
  305               
  306               boolean ifExist = false;
  307   
  308               if (observes.notifyObserver().equals(Reception.IF_EXISTS))
  309               {
  310                   ifExist = true;
  311               }
  312   
  313               TransactionalObserverType type = EventUtil.getObserverMethodTransactionType(observableMethod);
  314   
  315               BeanObserverImpl<T> observer = new BeanObserverImpl(component, observableMethod, ifExist, type);
  316   
  317               Class<T> clazz = (Class<T>) AnnotationUtil.getMethodFirstParameterTypeClazzWithAnnotation(observableMethod, Observes.class);
  318   
  319               addObserver(observer, ifExist, type, clazz, bindingTypes);
  320           }
  321   
  322       }
  323   
  324       public void afterCompletion(int status)
  325       {
  326           try
  327           {
  328               Iterator<TransactionalNotifier> it = this.transactionSet.iterator();
  329   
  330               while (it.hasNext())
  331               {
  332                   TransactionalNotifier notifier = it.next();
  333   
  334                   notifier.notifyAfterCompletion();
  335   
  336                   if (status == Status.STATUS_COMMITTED)
  337                   {
  338                       notifier.notifyAfterCompletionSuccess();
  339   
  340                   }
  341                   else if (status == Status.STATUS_ROLLEDBACK)
  342                   {
  343                       notifier.notifyAfterCompletionFailure();
  344                   }
  345   
  346               }
  347   
  348           }
  349           catch (Exception e)
  350           {
  351               logger.error("Exception is occured in the transational observer ", e);
  352           }
  353           finally
  354           {
  355               this.transactionSet.clear();
  356           }
  357       }
  358   
  359       public void beforeCompletion()
  360       {
  361           // Call @BeforeTransactionCompletion
  362           try
  363           {
  364               Iterator<TransactionalNotifier> it = this.transactionSet.iterator();
  365               while (it.hasNext())
  366               {
  367                   TransactionalNotifier notifier = it.next();
  368                   notifier.notifyBeforeCompletion();
  369               }
  370   
  371           }
  372           catch (Exception e)
  373           {
  374               logger.error("Exception is occured in the transational observer ", e);
  375           }
  376       }
  377   }

Home » apache-openwebbeans-1.0.0-incubating-M3-sources » org.apache.webbeans.event » [javadoc | source]