Coverage Report - org.apache.camel.component.jpa.JpaConsumer
 
Classes in this File Line Coverage Branch Coverage Complexity
JpaConsumer
71% 
94% 
0
 
 1  
 /**
 2  
  *
 3  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 4  
  * contributor license agreements.  See the NOTICE file distributed with
 5  
  * this work for additional information regarding copyright ownership.
 6  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 7  
  * (the "License"); you may not use this file except in compliance with
 8  
  * 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, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 package org.apache.camel.component.jpa;
 19  
 
 20  
 import java.lang.reflect.Method;
 21  
 import java.util.List;
 22  
 import javax.persistence.EntityManager;
 23  
 import javax.persistence.LockModeType;
 24  
 import javax.persistence.PersistenceException;
 25  
 import javax.persistence.Query;
 26  
 
 27  
 import org.apache.camel.Exchange;
 28  
 import org.apache.camel.Processor;
 29  
 import org.apache.camel.impl.ScheduledPollConsumer;
 30  
 import org.apache.camel.util.ObjectHelper;
 31  
 import org.apache.commons.logging.Log;
 32  
 import org.apache.commons.logging.LogFactory;
 33  
 import org.springframework.orm.jpa.JpaCallback;
 34  
 
 35  
 /**
 36  
  * @version $Revision: 541335 $
 37  
  */
 38  3
 public class JpaConsumer extends ScheduledPollConsumer<Exchange> {
 39  1
     private static final transient Log log = LogFactory.getLog(JpaConsumer.class);
 40  
     private final JpaEndpoint endpoint;
 41  
     private final TransactionStrategy template;
 42  
     private QueryFactory queryFactory;
 43  
     private DeleteHandler<Object> deleteHandler;
 44  
     private String query;
 45  
     private String namedQuery;
 46  
     private String nativeQuery;
 47  
 
 48  
     public JpaConsumer(JpaEndpoint endpoint, Processor processor) {
 49  3
         super(endpoint, processor);
 50  3
         this.endpoint = endpoint;
 51  3
         this.template = endpoint.createTransactionStrategy();
 52  3
     }
 53  
 
 54  
     protected void poll() throws Exception {
 55  5
         template.execute(new JpaCallback() {
 56  5
             public Object doInJpa(EntityManager entityManager) throws PersistenceException {
 57  5
                 Query query = getQueryFactory().createQuery(entityManager);
 58  5
                 configureParameters(query);
 59  5
                 List results = query.getResultList();
 60  5
                 for (Object result : results) {
 61  3
                     if (log.isDebugEnabled()) {
 62  0
                         log.debug("Processing new entity: " + result);
 63  
                     }
 64  
 
 65  3
                     if (lockEntity(result, entityManager)) {
 66  
                         // lets turn the result into an exchange and fire it into the processor
 67  3
                         Exchange exchange = createExchange(result);
 68  
                         try {
 69  3
                                                         getProcessor().process(exchange);
 70  0
                                                 } catch (Exception e) {
 71  0
                                                         throw new PersistenceException(e);
 72  3
                                                 }
 73  3
                         getDeleteHandler().deleteObject(entityManager, result);
 74  
                     }
 75  3
                 }
 76  5
                 entityManager.flush();
 77  5
                 return null;
 78  
             }
 79  
         });
 80  5
     }
 81  
 
 82  
     // Properties
 83  
     //-------------------------------------------------------------------------
 84  
     public JpaEndpoint getEndpoint() {
 85  3
         return endpoint;
 86  
     }
 87  
 
 88  
     public QueryFactory getQueryFactory() {
 89  5
         if (queryFactory == null) {
 90  3
             queryFactory = createQueryFactory();
 91  3
             if (queryFactory == null) {
 92  0
                 throw new IllegalArgumentException("No queryType property configured on this consumer, nor an entityType configured on the endpoint so cannot consume");
 93  
             }
 94  
         }
 95  5
         return queryFactory;
 96  
     }
 97  
 
 98  
     public void setQueryFactory(QueryFactory queryFactory) {
 99  0
         this.queryFactory = queryFactory;
 100  0
     }
 101  
 
 102  
     public DeleteHandler getDeleteHandler() {
 103  3
         if (deleteHandler == null) {
 104  3
             deleteHandler = createDeleteHandler();
 105  
         }
 106  3
         return deleteHandler;
 107  
     }
 108  
 
 109  
     public void setDeleteHandler(DeleteHandler deleteHandler) {
 110  0
         this.deleteHandler = deleteHandler;
 111  0
     }
 112  
 
 113  
     public String getNamedQuery() {
 114  0
         return namedQuery;
 115  
     }
 116  
 
 117  
     public void setNamedQuery(String namedQuery) {
 118  1
         this.namedQuery = namedQuery;
 119  1
     }
 120  
 
 121  
     public String getNativeQuery() {
 122  0
         return nativeQuery;
 123  
     }
 124  
 
 125  
     public void setNativeQuery(String nativeQuery) {
 126  0
         this.nativeQuery = nativeQuery;
 127  0
     }
 128  
 
 129  
     public String getQuery() {
 130  0
         return query;
 131  
     }
 132  
 
 133  
     public void setQuery(String query) {
 134  0
         this.query = query;
 135  0
     }
 136  
 
 137  
     // Implementation methods
 138  
     //-------------------------------------------------------------------------
 139  
 
 140  
     /**
 141  
      * A strategy method to lock an object with an exclusive lock so that it can be processed
 142  
      *
 143  
      * @param entity        the entity to be locked
 144  
      * @param entityManager
 145  
      * @return true if the entity was locked
 146  
      */
 147  
     protected boolean lockEntity(Object entity, EntityManager entityManager) {
 148  
         try {
 149  3
             if (log.isDebugEnabled()) {
 150  0
                 log.debug("Acquiring exclusive lock on entity: " + entity);
 151  
             }
 152  3
             entityManager.lock(entity, LockModeType.WRITE);
 153  3
             return true;
 154  
         }
 155  0
         catch (Exception e) {
 156  0
             if (log.isDebugEnabled()) {
 157  0
                 log.debug("Failed to achieve lock on entity: " + entity + ". Reason: " + e, e);
 158  
             }
 159  0
             return false;
 160  
         }
 161  
     }
 162  
 
 163  
     protected QueryFactory createQueryFactory() {
 164  3
         if (query != null) {
 165  0
             return QueryBuilder.query(query);
 166  
         }
 167  3
         else if (namedQuery != null) {
 168  1
             return QueryBuilder.namedQuery(namedQuery);
 169  
         }
 170  2
         else if (nativeQuery != null) {
 171  0
             return QueryBuilder.nativeQuery(nativeQuery);
 172  
         }
 173  
         else {
 174  2
             Class<?> entityType = endpoint.getEntityType();
 175  2
             if (entityType == null) {
 176  0
                 return null;
 177  
             }
 178  
             else {
 179  2
                 return QueryBuilder.query("select x from " + entityType.getName() + " x");
 180  
             }
 181  
         }
 182  
     }
 183  
 
 184  
     protected DeleteHandler<Object> createDeleteHandler() {
 185  
         // TODO auto-discover an annotation in the entity bean to indicate the process completed method call?
 186  3
         Class<?> entityType = getEndpoint().getEntityType();
 187  3
         if (entityType != null) {
 188  3
             List<Method> methods = ObjectHelper.findMethodsWithAnnotation(entityType, Consumed.class);
 189  3
             if (methods.size() > 1) {
 190  0
                 throw new IllegalArgumentException("Only one method can be annotated with the @Consumed annotation but found: " + methods);
 191  
             }
 192  3
             else if (methods.size() == 1) {
 193  1
                 final Method method = methods.get(0);
 194  
 
 195  1
                 return new DeleteHandler<Object>() {
 196  1
                     public void deleteObject(EntityManager entityManager, Object entityBean) {
 197  1
                         ObjectHelper.invokeMethod(method, entityBean);
 198  1
                     }
 199  
                 };
 200  
             }
 201  
         }
 202  2
         return new DeleteHandler<Object>() {
 203  2
             public void deleteObject(EntityManager entityManager, Object entityBean) {
 204  2
                 entityManager.remove(entityBean);
 205  2
             }
 206  
         };
 207  
     }
 208  
 
 209  
     protected void configureParameters(Query query) {
 210  5
         int maxResults = endpoint.getMaximumResults();
 211  5
         if (maxResults > 0) {
 212  0
             query.setMaxResults(maxResults);
 213  
         }
 214  5
     }
 215  
 
 216  
     protected Exchange createExchange(Object result) {
 217  3
         Exchange exchange = endpoint.createExchange();
 218  3
         exchange.getIn().setBody(result);
 219  3
         return exchange;
 220  
     }
 221  
 }