View Javadoc
1   package org.apache.onami.persist;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import com.google.inject.AbstractModule;
23  import com.google.inject.Key;
24  import com.google.inject.Scopes;
25  import com.google.inject.TypeLiteral;
26  
27  import javax.inject.Provider;
28  import javax.persistence.EntityManagerFactory;
29  import java.util.ArrayList;
30  import java.util.List;
31  
32  import static com.google.inject.matcher.Matchers.annotatedWith;
33  import static com.google.inject.matcher.Matchers.any;
34  import static org.apache.onami.persist.Preconditions.checkNotNull;
35  
36  /**
37   * Main module of the onami persist guice extension.
38   */
39  public abstract class PersistenceModule
40      extends AbstractModule
41  {
42  
43      /**
44       * List of configurations. Each configurator can be used to build a {@link PersistenceUnitModule}.
45       */
46      private List<PersistenceUnitModuleConfiguration> configurations;
47  
48      /**
49       * {@inheritDoc}
50       */
51      @Override
52      protected final void configure()
53      {
54          if ( configurations != null )
55          {
56              throw new RuntimeException( "cannot reenter the configure method" );
57          }
58          try
59          {
60              configurations = new ArrayList<PersistenceUnitModuleConfiguration>();
61              configurePersistenceUnits();
62          }
63          finally
64          {
65              configurations = null;
66          }
67      }
68  
69      /**
70       * Configures the persistence units.
71       */
72      private void configurePersistenceUnits()
73      {
74          configurePersistence();
75  
76          bind( PersistenceFilter.class ).to( PersistenceFilterImpl.class ).in( Scopes.SINGLETON );
77  
78          final AllPersistenceUnits allPersistenceUnits = new AllPersistenceUnits();
79          requestInjection( allPersistenceUnits );
80          bind( AllPersistenceServices.class ).toInstance( allPersistenceUnits );
81          bind( AllUnitsOfWork.class ).toInstance( allPersistenceUnits );
82  
83          for ( PersistenceUnitModuleConfiguration config : configurations )
84          {
85              final TxnInterceptor txnInterceptor = new TxnInterceptor();
86  
87              install( new PersistenceUnitModule( config, txnInterceptor, allPersistenceUnits ) );
88  
89              bindInterceptor( any(), annotatedWith( Transactional.class ), txnInterceptor );
90              bindInterceptor( annotatedWith( Transactional.class ), any(), txnInterceptor );
91          }
92      }
93  
94      /**
95       * Configures the persistence units over the exposed methods.
96       */
97      protected abstract void configurePersistence();
98  
99      /**
100      * Binds an application managed persistence unit.
101      *
102      * @param puName the name of the persistence unit as defined in the persistence.xml.
103      * @return the next builder step.
104      */
105     protected UnannotatedPersistenceUnitBuilder bindApplicationManagedPersistenceUnit( String puName )
106     {
107         checkNotNull( configurations,
108                       "calling bindApplicationManagedPersistenceUnit outside of configurePersistence is not supported" );
109         final PersistenceUnitModuleConfiguration configurator = createAndAddConfiguration();
110         configurator.setPuName( puName );
111         return configurator;
112     }
113 
114     /**
115      * Binds a container managed persistence unit for a given entity manager factory.
116      *
117      * @param emf the entity manager factory to use when creating new entity managers.
118      * @return the next builder step.
119      */
120     protected UnannotatedPersistenceUnitBuilder bindContainerManagedPersistenceUnit( EntityManagerFactory emf )
121     {
122         checkNotNull( configurations,
123                       "calling bindContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
124         final PersistenceUnitModuleConfiguration configurator = createAndAddConfiguration();
125         configurator.setEmf( emf );
126         return configurator;
127     }
128 
129     /**
130      * Binds a container managed persistence unit. The entity manager factory will be retrieved from the JNDI context.
131      *
132      * @param jndiName the JNDI name of the entity manager factory.
133      * @return the next builder step.
134      */
135     protected UnannotatedPersistenceUnitBuilder bindContainerManagedPersistenceUnitWithJndiName( String jndiName )
136     {
137         checkNotNull( configurations,
138                       "calling bindContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
139         final PersistenceUnitModuleConfiguration configurator = createAndAddConfiguration();
140         configurator.setEmfJndiName( jndiName );
141         return configurator;
142     }
143 
144     /**
145      * Binds a container managed persistence unit. The entity manager factory will be retrieved from the given provider.
146      *
147      * @param emfProvider the provider for the entity manager factory.
148      * @return the next builder step.
149      */
150     protected UnannotatedPersistenceUnitBuilder bindContainerManagedPersistenceUnitProvidedBy(
151         Provider<EntityManagerFactory> emfProvider )
152     {
153         checkNotNull( configurations,
154                       "calling bindContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
155         final PersistenceUnitModuleConfiguration configurator = createAndAddConfiguration();
156         configurator.setEmfProvider( emfProvider );
157         return configurator;
158     }
159 
160     /**
161      * Binds a container managed persistence unit. The entity manager factory will be retrieved from the given provider.
162      *
163      * @param emfProviderClass the provider for the entity manager factory.
164      * @return the next builder step.
165      */
166     protected UnannotatedPersistenceUnitBuilder bindContainerManagedPersistenceUnitProvidedBy(
167         Class<? extends Provider<EntityManagerFactory>> emfProviderClass )
168     {
169         checkNotNull( configurations,
170                       "calling bindContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
171         final PersistenceUnitModuleConfiguration configurator = createAndAddConfiguration();
172         configurator.setEmfProviderClass( emfProviderClass );
173         return configurator;
174     }
175 
176     /**
177      * Binds a container managed persistence unit. The entity manager factory will be retrieved from the given provider.
178      *
179      * @param emfProviderType the provider for the entity manager factory.
180      * @return the next builder step.
181      */
182     protected UnannotatedPersistenceUnitBuilder bindContainerManagedPersistenceUnitProvidedBy(
183         TypeLiteral<? extends Provider<EntityManagerFactory>> emfProviderType )
184     {
185         checkNotNull( configurations,
186                       "calling bindContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
187         final PersistenceUnitModuleConfiguration configurator = createAndAddConfiguration();
188         configurator.setEmfProviderType( emfProviderType );
189         return configurator;
190     }
191 
192     /**
193      * Binds a container managed persistence unit. The entity manager factory will be retrieved from the given provider.
194      *
195      * @param emfProviderKey the provider for the entity manager factory.
196      * @return the next builder step.
197      */
198     protected UnannotatedPersistenceUnitBuilder bindContainerManagedPersistenceUnitProvidedBy(
199         Key<? extends Provider<EntityManagerFactory>> emfProviderKey )
200     {
201         checkNotNull( configurations,
202                       "calling bindContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
203         final PersistenceUnitModuleConfiguration configuration = createAndAddConfiguration();
204         configuration.setEmfProviderKey( emfProviderKey );
205         return configuration;
206     }
207 
208     private PersistenceUnitModuleConfiguration createAndAddConfiguration()
209     {
210         final PersistenceUnitModuleConfiguration configurator = new PersistenceUnitModuleConfiguration();
211         configurations.add( configurator );
212         return configurator;
213     }
214 
215 }