private void subscribe ( Object subscriber , SubscriberMethod subscriberMethod ) { Class < ? > eventType = subscriberMethod . eventType ; Subscription newSubscription = new Subscription ( subscriber , subscriberMethod ) ; CopyOnWriteArrayList < Subscription > subscriptions = subscriptionsByEventType . get ( eventType ) ; if ( subscriptions == null ) { subscriptions = new CopyOnWriteArrayList <> ( ) ; subscriptionsByEventType . put ( eventType , subscriptions ) ; } else { if ( subscriptions . contains ( newSubscription ) ) { throw new EventBusException ( "Subscriber " + subscriber . getClass ( ) + " already registered to event " + eventType ) ; } } int size = subscriptions . size ( ) ; for ( int i = 0 ; i <= size ; i ++ ) { if ( i == size || subscriberMethod . priority > subscriptions . get ( i ) . subscriberMethod . priority ) { subscriptions . add ( i , newSubscription ) ; break ; } } List < Class < ? > > subscribedEvents = typesBySubscriber . get ( subscriber ) ; if ( subscribedEvents == null ) { subscribedEvents = new ArrayList <> ( ) ; typesBySubscriber . put ( subscriber , subscribedEvents ) ; } subscribedEvents . add ( eventType ) ; if ( subscriberMethod . sticky ) { if ( eventInheritance ) { // Existing sticky events of all subclasses of eventType have to be considered. // Note: Iterating over all events may be inefficient with lots of sticky events, // thus data structure should be changed to allow a more efficient lookup // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>). Set < Map . Entry < Class < ? > , Object > > entries = stickyEvents . entrySet ( ) ; for ( Map . Entry < Class < ? > , Object > entry : entries ) { Class < ? > candidateEventType = entry . getKey ( ) ; if ( eventType . isAssignableFrom ( candidateEventType ) ) { Object stickyEvent = entry . getValue ( ) ; checkPostStickyEventToSubscription ( newSubscription , stickyEvent ) ; } } } else { Object stickyEvent = stickyEvents . get ( eventType ) ; checkPostStickyEventToSubscription ( newSubscription , stickyEvent ) ; } } }
Must be called in synchronized block