Coverage Report - org.apache.shiro.guice.ShiroModule
 
Classes in this File Line Coverage Branch Coverage Complexity
ShiroModule
94%
34/36
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 java.util.Collection;
 22  
 import java.util.Collections;
 23  
 import java.util.Set;
 24  
 import java.util.WeakHashMap;
 25  
 
 26  
 import javax.annotation.PreDestroy;
 27  
 
 28  
 import org.apache.shiro.config.ConfigurationException;
 29  
 import org.apache.shiro.env.Environment;
 30  
 import org.apache.shiro.mgt.DefaultSecurityManager;
 31  
 import org.apache.shiro.mgt.SecurityManager;
 32  
 import org.apache.shiro.realm.Realm;
 33  
 import org.apache.shiro.session.mgt.DefaultSessionManager;
 34  
 import org.apache.shiro.session.mgt.SessionManager;
 35  
 import org.apache.shiro.util.Destroyable;
 36  
 
 37  
 import com.google.inject.Key;
 38  
 import com.google.inject.PrivateModule;
 39  
 import com.google.inject.TypeLiteral;
 40  
 import com.google.inject.binder.AnnotatedBindingBuilder;
 41  
 import com.google.inject.binder.LinkedBindingBuilder;
 42  
 import com.google.inject.multibindings.Multibinder;
 43  
 import com.google.inject.util.Types;
 44  
 
 45  
 
 46  
 /**
 47  
  * Sets up Shiro lifecycles within Guice, enables the injecting of Shiro objects, and binds a default
 48  
  * {@link org.apache.shiro.mgt.SecurityManager} and {@link org.apache.shiro.session.mgt.SessionManager}.  At least one realm must be added by using
 49  
  * {@link #bindRealm() bindRealm}.
 50  
  */
 51  22
 public abstract class ShiroModule extends PrivateModule implements Destroyable {
 52  
 
 53  22
         private Set<Destroyable> destroyables = Collections.newSetFromMap(new WeakHashMap<Destroyable, Boolean>());
 54  
     public void configure() {
 55  
         // setup security manager
 56  22
         bindSecurityManager(bind(SecurityManager.class));
 57  22
         bindSessionManager(bind(SessionManager.class));
 58  22
         bindEnvironment(bind(Environment.class));
 59  22
         bindListener(BeanTypeListener.MATCHER, new BeanTypeListener());
 60  22
         final DestroyableInjectionListener.DestroyableRegistry registry = new DestroyableInjectionListener.DestroyableRegistry() {
 61  
             public void add(Destroyable destroyable) {
 62  40
                 ShiroModule.this.add(destroyable);
 63  40
             }
 64  
 
 65  
             @PreDestroy
 66  
             public void destroy() throws Exception {
 67  0
                 ShiroModule.this.destroy();
 68  0
             }
 69  
         };
 70  22
         bindListener(LifecycleTypeListener.MATCHER, new LifecycleTypeListener(registry));
 71  
 
 72  22
         expose(SecurityManager.class);
 73  
 
 74  22
         configureShiro();
 75  22
         bind(realmCollectionKey())
 76  22
                 .to(realmSetKey());
 77  
 
 78  22
         bind(DestroyableInjectionListener.DestroyableRegistry.class).toInstance(registry);
 79  22
         BeanTypeListener.ensureBeanTypeMapExists(binder());
 80  22
     }
 81  
 
 82  
     @SuppressWarnings({"unchecked"})
 83  
     private Key<Set<Realm>> realmSetKey() {
 84  22
         return (Key<Set<Realm>>) Key.get(TypeLiteral.get(Types.setOf(Realm.class)));
 85  
     }
 86  
 
 87  
     @SuppressWarnings({"unchecked"})
 88  
     private Key<Collection<Realm>> realmCollectionKey() {
 89  22
         return (Key<Collection<Realm>>) Key.get(Types.newParameterizedType(Collection.class, Realm.class));
 90  
     }
 91  
 
 92  
     /**
 93  
      * Implement this method in order to configure your realms and any other Shiro customization you may need.
 94  
      */
 95  
     protected abstract void configureShiro();
 96  
 
 97  
     /**
 98  
      * This is the preferred manner to bind a realm.  The {@link org.apache.shiro.mgt.SecurityManager} will be injected with any Realm bound
 99  
      * with this method.
 100  
      *
 101  
      * @return a binding builder for a realm
 102  
      */
 103  
     protected final LinkedBindingBuilder<Realm> bindRealm() {
 104  22
         Multibinder<Realm> multibinder = Multibinder.newSetBinder(binder(), Realm.class);
 105  22
         return multibinder.addBinding();
 106  
     }
 107  
 
 108  
     /**
 109  
      * Binds the security manager.  Override this method in order to provide your own security manager binding.
 110  
      * <p/>
 111  
      * By default, a {@link org.apache.shiro.mgt.DefaultSecurityManager} is bound as an eager singleton.
 112  
      *
 113  
      * @param bind
 114  
      */
 115  
     protected void bindSecurityManager(AnnotatedBindingBuilder<? super SecurityManager> bind) {
 116  
         try {
 117  10
             bind.toConstructor(DefaultSecurityManager.class.getConstructor(Collection.class)).asEagerSingleton();
 118  0
         } catch (NoSuchMethodException e) {
 119  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);
 120  10
         }
 121  10
     }
 122  
 
 123  
     /**
 124  
      * Binds the session manager.  Override this method in order to provide your own session manager binding.
 125  
      * <p/>
 126  
      * By default, a {@link org.apache.shiro.session.mgt.DefaultSessionManager} is bound as an eager singleton.
 127  
      *
 128  
      * @param bind
 129  
      */
 130  
     protected void bindSessionManager(AnnotatedBindingBuilder<SessionManager> bind) {
 131  10
         bind.to(DefaultSessionManager.class).asEagerSingleton();
 132  10
     }
 133  
 
 134  
     /**
 135  
      * Binds the environment.  Override this method in order to provide your own environment binding.
 136  
      * <p/>
 137  
      * By default, a {@link GuiceEnvironment} is bound as an eager singleton.
 138  
      *
 139  
      * @param bind
 140  
      */
 141  
     protected void bindEnvironment(AnnotatedBindingBuilder<Environment> bind) {
 142  10
         bind.to(GuiceEnvironment.class).asEagerSingleton();
 143  10
     }
 144  
 
 145  
     /**
 146  
      * Binds a key to use for injecting setters in shiro classes.
 147  
      * @param typeLiteral the bean property type
 148  
      * @param key the key to use to satisfy the bean property dependency
 149  
      * @param <T>
 150  
      */
 151  
     protected final <T> void bindBeanType(TypeLiteral<T> typeLiteral, Key<? extends T> key) {
 152  10
         BeanTypeListener.bindBeanType(binder(), typeLiteral, key);
 153  10
     }
 154  
 
 155  
     /**
 156  
      * Destroys all beans created within this module that implement {@link org.apache.shiro.util.Destroyable}.  Should be called when this
 157  
      * module will no longer be used.
 158  
      *
 159  
      * @throws Exception
 160  
      */
 161  
     public final void destroy() throws Exception {
 162  2
         for (Destroyable destroyable : destroyables) {
 163  4
             destroyable.destroy();
 164  4
         }
 165  2
     }
 166  
 
 167  
     public void add(Destroyable destroyable) {
 168  40
         this.destroyables.add(destroyable);
 169  40
     }
 170  
 }