View Javadoc
1   package ejava.examples.webtier.web;
2   
3   import java.io.IOException;
4   import java.util.Enumeration;
5   import java.util.Properties;
6   
7   import javax.naming.Context;
8   import javax.naming.NameClassPair;
9   import javax.naming.NamingEnumeration;
10  import javax.naming.NamingException;
11  import javax.persistence.EntityManager;
12  import javax.persistence.PersistenceContext;
13  import javax.servlet.Filter;
14  import javax.servlet.FilterChain;
15  import javax.servlet.FilterConfig;
16  import javax.servlet.ServletException;
17  import javax.servlet.ServletRequest;
18  import javax.servlet.ServletResponse;
19  
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  
23  import ejava.examples.webtier.dao.DAOFactory;
24  import ejava.examples.webtier.dao.DAOTypeFactory;
25  import ejava.examples.webtier.jpa.JPADAOTypeFactory;
26  import ejava.examples.webtier.jpa.JPAUtil;
27  
28  public class JPAFilter implements Filter {
29      private static Log log = LogFactory.getLog(JPAFilter.class);
30      private String puName = "webtier";
31      private Properties emfProperties = new Properties();
32      @PersistenceContext(unitName="webtier")
33      private EntityManager pc;
34  
35      
36      public void init(FilterConfig config) throws ServletException {
37          log.debug("filter initializing JPA DAOs"); 
38          new JPADAOTypeFactory();
39          DAOTypeFactory daoType = DAOFactory.getDAOTypeFactory();
40          log.debug("filter got typeFactory:" + daoType.getName());
41          
42          for(Enumeration<?> e=config.getInitParameterNames();
43              e.hasMoreElements(); ) {
44              String key = (String)e.nextElement();
45              String value=(String)config.getInitParameter(key);
46              emfProperties.put(key, value);
47          }
48          log.debug("emfProperties=" + emfProperties);
49      }    
50  
51      public void doFilter(ServletRequest request, 
52              ServletResponse response, 
53              FilterChain chain) throws IOException, ServletException {
54          
55          log.debug("injected entity manager=" + pc);
56          EntityManager em = getEntityManager();               
57  
58          if (!em.getTransaction().isActive()) {
59              log.debug("filter: beginning JPA transaction");
60              em.getTransaction().begin();
61          }
62          
63          chain.doFilter(request, response);
64  
65          if (em.getTransaction().isActive()) {
66              if (em.getTransaction().getRollbackOnly()==true) {
67                  log.debug("filter: rolling back JPA transaction");
68                  em.getTransaction().rollback();
69              }
70              else {
71                  log.debug("filter: committing JPA transaction");
72                  em.flush();                
73                  em.clear();
74                  em.getTransaction().commit();
75              }
76          }
77          else {
78              log.debug("filter: no transaction was active");
79          }
80      }
81  
82      public void destroy() {
83          JPAUtil.close();
84      }
85  
86      private EntityManager getEntityManager() throws ServletException {
87          if (JPAUtil.peekEntityManager() == null) {
88              JPAUtil.setEntityManagerFactoryProperties(emfProperties);
89          }
90          return JPAUtil.getEntityManager(puName);
91      }        
92  
93      
94      @SuppressWarnings("unused")
95      private Properties getInitialContextProperties() {
96         Properties props = new Properties();
97         props.put("java.naming.factory.initial", 
98                 "org.jnp.interfaces.LocalOnlyContextFactory");
99         props.put("java.naming.factory.url.pkgs", 
100                "org.jboss.naming:org.jnp.interfaces");
101        return props;
102     }    
103 
104     @SuppressWarnings("unused")
105     private Properties getEntityManagerFactoryProperties() {
106         Properties props = new Properties();
107         props.put("hibernate.jndi.naming.factory.initial", 
108                 "org.jnp.interfaces.LocalOnlyContextFactory");
109         props.put("hibernate.jndi.java.naming.factory.url.pkgs", 
110                 "org.jboss.naming:org.jnp.interfaces");
111                 
112         return props;
113      }    
114     
115     @SuppressWarnings("unused")
116     private void dump(Context context, String name) {
117         StringBuilder text = new StringBuilder();
118         try {
119             doDump(0, text, context, name);
120         }
121         catch (NamingException ex) {}
122         log.debug(text.toString());
123     }
124 
125     private void doDump(int level, StringBuilder text, Context context, String name) 
126         throws NamingException {
127         for (NamingEnumeration<NameClassPair> ne = context.list(name); ne.hasMore();) {
128             NameClassPair ncp = (NameClassPair) ne.next();
129             String objectName = ncp.getName();
130             String className = ncp.getClassName();
131             String classText = " :" + className;
132             if (isContext(className)) {
133                 text.append(getPad(level) + "+" + objectName + classText +"\n");
134                 doDump(level + 1, text, context, name + "/" + objectName);
135             } else {
136                 text.append(getPad(level) + "-" + objectName + classText + "\n");
137             }
138         }
139     }
140     
141     protected boolean isContext(String className) {
142         try {
143             Class<?> objectClass = Thread.currentThread().getContextClassLoader()
144                     .loadClass(className);
145             return Context.class.isAssignableFrom(objectClass);
146         }
147         catch (ClassNotFoundException ex) {
148             //object is probably not a context, report as non-context
149             return false;
150         }
151     }
152 
153     protected String getPad(int level) {
154         StringBuffer pad = new StringBuffer();
155         for (int i = 0; i < level; i++) {
156             pad.append(" ");
157         }
158         return pad.toString();
159     }
160 
161 
162 }