Home | History | Annotate | Download | only in persist
      1 /**
      2  * Copyright (C) 2010 Google, Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.inject.persist;
     18 
     19 import com.google.inject.Inject;
     20 import com.google.inject.Singleton;
     21 
     22 import java.io.IOException;
     23 
     24 import javax.servlet.Filter;
     25 import javax.servlet.FilterChain;
     26 import javax.servlet.FilterConfig;
     27 import javax.servlet.ServletException;
     28 import javax.servlet.ServletRequest;
     29 import javax.servlet.ServletResponse;
     30 
     31 /**
     32  * Apply this filter to enable the HTTP Request unit of work and to have
     33  * guice-persist manage the lifecycle of active units of work.
     34  * The filter automatically starts and stops the relevant {@link PersistService}
     35  * upon {@link javax.servlet.Filter#init(javax.servlet.FilterConfig)} and
     36  * {@link javax.servlet.Filter#destroy()} respectively.
     37  *
     38  * <p> To be able to use the open session-in-view pattern (i.e. work per request),
     39  * register this filter <b>once</b> in your Guice {@code ServletModule}. It is
     40  * important that you register this filter before any other filter.
     41  *
     42  * For multiple providers, you should register this filter once per provider, inside
     43  * a private module for each persist module installed (this must be the same private
     44  * module where the specific persist module is itself installed).
     45  *
     46  * <p>
     47  * Example configuration:
     48  * <pre>{@code
     49  *  public class MyModule extends ServletModule {
     50  *    public void configureServlets() {
     51  *      filter("/*").through(PersistFilter.class);
     52  *
     53  *      serve("/index.html").with(MyHtmlServlet.class);
     54  *      // Etc.
     55  *    }
     56  *  }
     57  * }</pre>
     58  * <p>
     59  * This filter is thread safe and allows you to create injectors concurrently
     60  * and deploy multiple guice-persist modules within the same injector, or even
     61  * multiple injectors with persist modules withing the same JVM or web app.
     62  * <p>
     63  * This filter requires the Guice Servlet extension.
     64  *
     65  * @author Dhanji R. Prasanna (dhanji (at) gmail.com)
     66  */
     67 @Singleton
     68 public final class PersistFilter implements Filter {
     69   private final UnitOfWork unitOfWork;
     70   private final PersistService persistService;
     71 
     72   @Inject
     73   public PersistFilter(UnitOfWork unitOfWork, PersistService persistService) {
     74     this.unitOfWork = unitOfWork;
     75     this.persistService = persistService;
     76   }
     77 
     78   public void init(FilterConfig filterConfig) throws ServletException {
     79     persistService.start();
     80   }
     81 
     82   public void destroy() {
     83     persistService.stop();
     84   }
     85 
     86   public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
     87       final FilterChain filterChain) throws IOException, ServletException {
     88 
     89     unitOfWork.begin();
     90     try {
     91       filterChain.doFilter(servletRequest, servletResponse);
     92     } finally {
     93       unitOfWork.end();
     94     }
     95   }
     96 }
     97