Coverage Report - org.apache.shiro.guice.ShiroModule
 
Classes in this File Line Coverage Branch Coverage Complexity
ShiroModule
94%
32/34
100%
2/2
1.231
ShiroModule$1
60%
3/5
N/A
1.231
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.shiro.guice;
 20  
 
 21  
 import com.google.common.collect.Sets;
 22  
 import com.google.inject.Key;
 23  
 import com.google.inject.PrivateModule;
 24  
 import com.google.inject.TypeLiteral;
 25  
 import com.google.inject.binder.AnnotatedBindingBuilder;
 26  
 import com.google.inject.binder.LinkedBindingBuilder;
 27  
 import com.google.inject.multibindings.Multibinder;
 28  
 import com.google.inject.util.Types;
 29  
 import org.apache.shiro.config.ConfigurationException;
 30  
 import org.apache.shiro.env.Environment;
 31  
 import org.apache.shiro.mgt.DefaultSecurityManager;
 32  
 import org.apache.shiro.mgt.SecurityManager;
 33  
 import org.apache.shiro.realm.Realm;
 34  
 import org.apache.shiro.session.mgt.DefaultSessionManager;
 35  
 import org.apache.shiro.session.mgt.SessionManager;
 36  
 import org.apache.shiro.util.Destroyable;
 37  
 
 38  
 import javax.annotation.PreDestroy;
 39  
 import java.util.Collection;
 40  
 import java.util.Set;
 41  
 import java.util.WeakHashMap;
 42  
 
 43  
 
 44  
 /**
 45  
  * Sets up Shiro lifecycles within Guice, enables the injecting of Shiro objects, and binds a default
 46  
  * {@link org.apache.shiro.mgt.SecurityManager} and {@link org.apache.shiro.session.mgt.SessionManager}.  At least one realm must be added by using
 47  
  * {@link #bindRealm() bindRealm}.
 48  
  */
 49  11
 public abstract class ShiroModule extends PrivateModule implements Destroyable {
 50  
 
 51  11
     private Set<Destroyable> destroyables = Sets.newSetFromMap(new WeakHashMap<Destroyable, Boolean>());
 52  
 
 53  
     public void configure() {
 54  
         // setup security manager
 55  11
         bindSecurityManager(bind(SecurityManager.class));
 56  11
         bindSessionManager(bind(SessionManager.class));
 57  11
         bindEnvironment(bind(Environment.class));
 58  11
         bindListener(BeanTypeListener.MATCHER, new BeanTypeListener());
 59  11
         final DestroyableInjectionListener.DestroyableRegistry registry = new DestroyableInjectionListener.DestroyableRegistry() {
 60  
             public void add(Destroyable destroyable) {
 61  20
                 ShiroModule.this.add(destroyable);
 62  20
             }
 63  
 
 64  
             @PreDestroy
 65  
             public void destroy() throws Exception {
 66  0
                 ShiroModule.this.destroy();
 67  0
             }
 68  
         };
 69  11
         bindListener(LifecycleTypeListener.MATCHER, new LifecycleTypeListener(registry));
 70  
 
 71  11
         expose(SecurityManager.class);
 72  
 
 73  11
         configureShiro();
 74  11
         bind(realmCollectionKey())
 75  
                 .to(realmSetKey());
 76  
 
 77  11
         bind(DestroyableInjectionListener.DestroyableRegistry.class).toInstance(registry);
 78  11
         BeanTypeListener.ensureBeanTypeMapExists(binder());
 79  11
     }
 80  
 
 81  
     @SuppressWarnings({"unchecked"})
 82  
     private Key<Set<Realm>> realmSetKey() {
 83  11
         return (Key<Set<Realm>>) Key.get(TypeLiteral.get(Types.setOf(Realm.class)));
 84  
     }
 85  
 
 86  
     @SuppressWarnings({"unchecked"})
 87  
     private Key<Collection<Realm>> realmCollectionKey() {
 88  11
         return (Key<Collection<Realm>>) Key.get(Types.newParameterizedType(Collection.class, Realm.class));
 89  
     }
 90  
 
 91  
     /**
 92  
      * Implement this method in order to configure your realms and any other Shiro customization you may need.
 93  
      */
 94  
     protected abstract void configureShiro();
 95  
 
 96  
     /**
 97  
      * This is the preferred manner to bind a realm.  The {@link org.apache.shiro.mgt.SecurityManager} will be injected with any Realm bound
 98  
      * with this method.
 99  
      *
 100  
      * @return a binding builder for a realm
 101  
      */
 102  
     protected final LinkedBindingBuilder<Realm> bindRealm() {
 103  11
         Multibinder<Realm> multibinder = Multibinder.newSetBinder(binder(), Realm.class);
 104  11
         return multibinder.addBinding();
 105  
     }
 106  
 
 107  
     /**
 108  
      * Binds the security manager.  Override this method in order to provide your own security manager binding.
 109  
      * <p/>
 110  
      * By default, a {@link org.apache.shiro.mgt.DefaultSecurityManager} is bound as an eager singleton.
 111  
      *
 112  
      * @param bind
 113  
      */
 114  
     protected void bindSecurityManager(AnnotatedBindingBuilder<? super SecurityManager> bind) {
 115  
         try {
 116  5
             bind.toConstructor(DefaultSecurityManager.class.getConstructor(Collection.class)).asEagerSingleton();
 117  0
         } catch (NoSuchMethodException e) {
 118  0
             throw new ConfigurationException("This really shouldn't happen.  Either something has changed in Shiro, or there's a bug in " + ShiroModule.class.getSimpleName(), e);
 119  5
         }
 120  5
     }
 121  
 
 122  
     /**
 123  
      * Binds the session manager.  Override this method in order to provide your own session manager binding.
 124  
      * <p/>
 125  
      * By default, a {@link org.apache.shiro.session.mgt.DefaultSessionManager} is bound as an eager singleton.
 126  
      *
 127  
      * @param bind
 128  
      */
 129  
     protected void bindSessionManager(AnnotatedBindingBuilder<SessionManager> bind) {
 130  5
         bind.to(DefaultSessionManager.class).asEagerSingleton();
 131  5
     }
 132  
 
 133  
     /**
 134  
      * Binds the environment.  Override this method in order to provide your own environment binding.
 135  
      * <p/>
 136  
      * By default, a {@link GuiceEnvironment} is bound as an eager singleton.
 137  
      *
 138  
      * @param bind
 139  
      */
 140  
     protected void bindEnvironment(AnnotatedBindingBuilder<Environment> bind) {
 141  5
         bind.to(GuiceEnvironment.class).asEagerSingleton();
 142  5
     }
 143  
 
 144  
     /**
 145  
      * Binds a key to use for injecting setters in shiro classes.
 146  
      * @param typeLiteral the bean property type
 147  
      * @param key the key to use to satisfy the bean property dependency
 148  
      * @param <T>
 149  
      */
 150  
     protected final <T> void bindBeanType(TypeLiteral<T> typeLiteral, Key<? extends T> key) {
 151  5
         BeanTypeListener.bindBeanType(binder(), typeLiteral, key);
 152  5
     }
 153  
 
 154  
     /**
 155  
      * Destroys all beans created within this module that implement {@link org.apache.shiro.util.Destroyable}.  Should be called when this
 156  
      * module will no longer be used.
 157  
      *
 158  
      * @throws Exception
 159  
      */
 160  
     public final void destroy() throws Exception {
 161  1
         for (Destroyable destroyable : destroyables) {
 162  2
             destroyable.destroy();
 163  
         }
 164  1
     }
 165  
 
 166  
     public void add(Destroyable destroyable) {
 167  20
         this.destroyables.add(destroyable);
 168  20
     }
 169  
 }