View Javadoc
1   /*******************************************************************************
2    * Copyright 2012 pw999
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  package net.sf.oqt.jpa;
17  
18  import java.lang.reflect.Field;
19  import java.sql.SQLException;
20  import java.util.Collection;
21  import java.util.Iterator;
22  import java.util.Map;
23  import java.util.Map.Entry;
24  import java.util.Set;
25  
26  import javax.persistence.EntityManager;
27  import javax.persistence.Query;
28  
29  import net.sf.oqt.core.CoreFactory;
30  import net.sf.oqt.driver.NullDriver;
31  import net.sf.oqt.model.EntityVO;
32  import net.sf.oqt.model.PackageVO;
33  import net.sf.oqt.model.QueryType;
34  import net.sf.oqt.model.QueryVO;
35  
36  import org.apache.openjpa.kernel.DelegatingQuery;
37  import org.apache.openjpa.persistence.OpenJPAQuery;
38  
39  
40  /**
41   * This class does all the calls to openJPA to get the SQL query using the {@link NullDriver} and {@link NullConnection}
42   * 
43   * @author phillip
44   * 
45   */
46  public class JPATransformer {
47  
48      /**
49       * Transforms all the JPQL queries to SQL queries.
50       * 
51       * @param packages the initialized set of PackageVO's. Ideally the output from the
52       *            {@link EntityFinder#findAllEntities(Set)} method.
53       * @throws ClassNotFoundException
54       * @throws InstantiationException
55       * @throws IllegalAccessException
56       * @throws SQLException
57       */
58      public static final void transformAllQueries(final Collection<PackageVO> packages) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
59          final Iterator<PackageVO> packIt = packages.iterator();
60          while (packIt.hasNext()) {
61              final PackageVO pack = packIt.next();
62              final Iterator<EntityVO> entIt = pack.getEntities().iterator();
63              while (entIt.hasNext()) {
64                  final EntityVO ent = entIt.next();
65                  final Iterator<QueryVO> qIt = ent.getQueries().iterator();
66                  while (qIt.hasNext()) {
67                      final QueryVO q = qIt.next();
68                      transform(q);
69                  }
70              }
71          }
72      }
73  
74      public static final void validateOnly(final Collection<PackageVO> packages) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
75          final Iterator<PackageVO> packIt = packages.iterator();
76          while (packIt.hasNext()) {
77              final PackageVO pack = packIt.next();
78              final Iterator<EntityVO> entIt = pack.getEntities().iterator();
79              while (entIt.hasNext()) {
80                  final EntityVO ent = entIt.next();
81                  final Iterator<QueryVO> qIt = ent.getQueries().iterator();
82                  while (qIt.hasNext()) {
83                      final QueryVO q = qIt.next();
84                      validate(q);
85                  }
86              }
87          }
88      }
89  
90      @SuppressWarnings("rawtypes")
91      static final void validate(final QueryVO queryVO) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
92          final EntityManager em = CoreFactory.getEntityManager();
93          try {
94              final Query q = em.createQuery(queryVO.getJPQLQuery());
95              ((OpenJPAQuery) q).compile();
96          } catch (final Throwable t) {
97              queryVO.setError(t);
98              return;
99          }
100     }
101 
102     @SuppressWarnings({ "unchecked", "rawtypes" })
103     static final void transform(final QueryVO queryVO) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
104         CoreFactory.getQueries().clear();
105         final EntityManager em = CoreFactory.getEntityManager();
106         Query q = null;
107         try {
108             q = em.createQuery(queryVO.getJPQLQuery()); // openJPA 2.x throws validation exception here
109             ((OpenJPAQuery) q).compile(); // openJPA 1.x needs manual validation
110         } catch (final Throwable t) {
111             queryVO.setError(t);
112             return;
113         }
114         Field field;
115         try {
116             field = q.getClass().getDeclaredField("_query");
117             field.setAccessible(true);
118             final DelegatingQuery dq = (DelegatingQuery) field.get(q);
119             final Map<String, Class<?>> params = dq.getParameterTypes();
120             final Set<Entry<String, Class<?>>> entrySet = params.entrySet();
121             for (final Entry<String, Class<?>> entry : entrySet) {
122                 q.setParameter(entry.getKey(), ParameterFactory.intialize(entry.getValue()));
123             }
124         } catch (SecurityException e) {
125             // TODO Auto-generated catch block
126             e.printStackTrace();
127         } catch (NoSuchFieldException e) {
128             // TODO Auto-generated catch block
129             e.printStackTrace();
130         }
131         final QueryType type = QueryType.getTypeFromJPQL(queryVO.getJPQLQuery());
132         try {
133             if (type.equals(QueryType.SELECT)) {
134                 q.getResultList();
135             } else {
136                 em.getTransaction().begin();
137                 q.executeUpdate();
138                 em.getTransaction().rollback();
139             }
140         } catch (final Throwable t) {
141             queryVO.setError(t);
142             return;
143         }
144         queryVO.getSQLQuery().addAll(CoreFactory.getQueries());
145     }
146 
147 }