001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.jpa;
018    
019    import java.util.Map;
020    import javax.persistence.EntityManager;
021    import javax.persistence.EntityManagerFactory;
022    import javax.persistence.Persistence;
023    
024    import org.apache.camel.Consumer;
025    import org.apache.camel.Exchange;
026    import org.apache.camel.Expression;
027    import org.apache.camel.InvalidPayloadException;
028    import org.apache.camel.InvalidPayloadRuntimeException;
029    import org.apache.camel.Processor;
030    import org.apache.camel.Producer;
031    import org.apache.camel.impl.ExpressionAdapter;
032    import org.apache.camel.impl.ScheduledPollEndpoint;
033    import org.apache.camel.util.CastUtils;
034    import org.apache.camel.util.IntrospectionSupport;
035    import org.apache.camel.util.ObjectHelper;
036    import org.springframework.orm.jpa.JpaTemplate;
037    import org.springframework.orm.jpa.JpaTransactionManager;
038    import org.springframework.transaction.PlatformTransactionManager;
039    
040    /**
041     * @version $Revision: 889234 $
042     */
043    public class JpaEndpoint extends ScheduledPollEndpoint {
044        private EntityManagerFactory entityManagerFactory;
045        private PlatformTransactionManager transactionManager;
046        private String persistenceUnit = "camel";
047        private JpaTemplate template;
048        private Expression producerExpression;
049        private int maximumResults = -1;
050        private Class<?> entityType;
051        private Map<Object, Object> entityManagerProperties;
052        private boolean consumeDelete = true;
053        private boolean consumeLockEntity = true;
054        private boolean flushOnSend = true;
055        private int maxMessagesPerPoll;
056    
057        public JpaEndpoint() {
058        }
059    
060        public JpaEndpoint(String endpointUri) {
061            super(endpointUri);
062        }
063    
064        public JpaEndpoint(String uri, JpaComponent component) {
065            super(uri, component);
066            entityManagerFactory = component.getEntityManagerFactory();
067            transactionManager = component.getTransactionManager();
068        }
069    
070        public JpaEndpoint(String endpointUri, EntityManagerFactory entityManagerFactory) {
071            super(endpointUri);
072            this.entityManagerFactory = entityManagerFactory;
073        }
074    
075        public JpaEndpoint(String endpointUri, EntityManagerFactory entityManagerFactory, PlatformTransactionManager transactionManager) {
076            super(endpointUri);
077            this.entityManagerFactory = entityManagerFactory;
078            this.transactionManager = transactionManager;
079        }
080    
081        public Producer createProducer() throws Exception {
082            validate();
083            return new JpaProducer(this, getProducerExpression());
084        }
085    
086        public Consumer createConsumer(Processor processor) throws Exception {
087            validate();
088            JpaConsumer consumer = new JpaConsumer(this, processor);
089            consumer.setMaxMessagesPerPoll(getMaxMessagesPerPoll());
090            configureConsumer(consumer);
091            return consumer;
092        }
093    
094        @Override
095        public void configureProperties(Map<String, Object> options) {
096            super.configureProperties(options);
097            Map<String, Object> emProperties = IntrospectionSupport.extractProperties(options, "emf.");
098            if (emProperties != null) {
099                setEntityManagerProperties(CastUtils.cast(emProperties));
100            }
101        }
102    
103        public boolean isSingleton() {
104            return false;
105        }
106    
107        @Override
108        protected String createEndpointUri() {
109            return "jpa" + (entityType != null ? "://" + entityType.getName() : "");
110        }
111    
112    
113        // Properties
114        // -------------------------------------------------------------------------
115        public JpaTemplate getTemplate() {
116            if (template == null) {
117                template = createTemplate();
118            }
119            return template;
120        }
121    
122        public void setTemplate(JpaTemplate template) {
123            this.template = template;
124        }
125    
126        public Expression getProducerExpression() {
127            if (producerExpression == null) {
128                producerExpression = createProducerExpression();
129            }
130            return producerExpression;
131        }
132    
133        public void setProducerExpression(Expression producerExpression) {
134            this.producerExpression = producerExpression;
135        }
136    
137        public int getMaximumResults() {
138            return maximumResults;
139        }
140    
141        public void setMaximumResults(int maximumResults) {
142            this.maximumResults = maximumResults;
143        }
144    
145        public Class<?> getEntityType() {
146            return entityType;
147        }
148    
149        public void setEntityType(Class<?> entityType) {
150            this.entityType = entityType;
151        }
152    
153        public EntityManagerFactory getEntityManagerFactory() {
154            if (entityManagerFactory == null) {
155                entityManagerFactory = createEntityManagerFactory();
156            }
157            return entityManagerFactory;
158        }
159    
160        public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
161            this.entityManagerFactory = entityManagerFactory;
162        }
163    
164        public PlatformTransactionManager getTransactionManager() {
165            if (transactionManager == null) {
166                transactionManager = createTransactionManager();
167            }
168            return transactionManager;
169        }
170    
171        public void setTransactionManager(PlatformTransactionManager transactionManager) {
172            this.transactionManager = transactionManager;
173        }
174    
175        public Map<Object, Object> getEntityManagerProperties() {
176            if (entityManagerProperties == null) {
177                entityManagerProperties = System.getProperties();
178            }
179            return entityManagerProperties;
180        }
181    
182        public void setEntityManagerProperties(Map<Object, Object> entityManagerProperties) {
183            this.entityManagerProperties = entityManagerProperties;
184        }
185    
186        public String getPersistenceUnit() {
187            return persistenceUnit;
188        }
189    
190        public void setPersistenceUnit(String persistenceUnit) {
191            this.persistenceUnit = persistenceUnit;
192        }
193    
194        public boolean isConsumeDelete() {
195            return consumeDelete;
196        }
197    
198        public void setConsumeDelete(boolean consumeDelete) {
199            this.consumeDelete = consumeDelete;
200        }
201    
202        public boolean isConsumeLockEntity() {
203            return consumeLockEntity;
204        }
205    
206        public void setConsumeLockEntity(boolean consumeLockEntity) {
207            this.consumeLockEntity = consumeLockEntity;
208        }
209    
210        public boolean isFlushOnSend() {
211            return flushOnSend;
212        }
213    
214        public void setFlushOnSend(boolean flushOnSend) {
215            this.flushOnSend = flushOnSend;
216        }
217    
218        public int getMaxMessagesPerPoll() {
219            return maxMessagesPerPoll;
220        }
221    
222        public void setMaxMessagesPerPoll(int maxMessagesPerPoll) {
223            this.maxMessagesPerPoll = maxMessagesPerPoll;
224        }
225    
226        // Implementation methods
227        // -------------------------------------------------------------------------
228    
229        protected void validate() {
230            ObjectHelper.notNull(getEntityManagerFactory(), "entityManagerFactory");
231        }
232    
233        protected JpaTemplate createTemplate() {
234            return new JpaTemplate(getEntityManagerFactory());
235        }
236    
237        protected EntityManagerFactory createEntityManagerFactory() {
238            return Persistence.createEntityManagerFactory(persistenceUnit, getEntityManagerProperties());
239        }
240    
241        protected PlatformTransactionManager createTransactionManager() {
242            JpaTransactionManager tm = new JpaTransactionManager(getEntityManagerFactory());
243            tm.afterPropertiesSet();
244            return tm;
245        }
246    
247        protected EntityManager createEntityManager() {
248            return getEntityManagerFactory().createEntityManager();
249        }
250    
251        protected TransactionStrategy createTransactionStrategy() {
252            return JpaTemplateTransactionStrategy.newInstance(getTransactionManager(), getTemplate());
253        }
254    
255        protected Expression createProducerExpression() {
256            return new ExpressionAdapter() {
257                public Object evaluate(Exchange exchange) {
258                    Object answer;
259    
260                    // must have a body
261                    try {
262                        if (getEntityType() == null) {
263                            answer = exchange.getIn().getMandatoryBody();
264                        } else {
265                            answer = exchange.getIn().getMandatoryBody(getEntityType());
266                        }
267                    } catch (InvalidPayloadException e) {
268                        throw new InvalidPayloadRuntimeException(exchange, getEntityType(), e.getCause());
269                    }
270    
271                    if (answer == null) {
272                        throw new InvalidPayloadRuntimeException(exchange, getEntityType());
273                    } else {
274                        return answer;
275                    }
276                }
277            };
278        }
279    }