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    
021    import javax.persistence.EntityManager;
022    import javax.persistence.EntityManagerFactory;
023    import javax.persistence.Persistence;
024    
025    import org.apache.camel.Consumer;
026    import org.apache.camel.Exchange;
027    import org.apache.camel.Expression;
028    import org.apache.camel.NoTypeConversionAvailableException;
029    import org.apache.camel.Processor;
030    import org.apache.camel.Producer;
031    import org.apache.camel.builder.ExpressionBuilder;
032    import org.apache.camel.impl.DefaultExchange;
033    import org.apache.camel.impl.ScheduledPollEndpoint;
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: 769677 $
042     */
043    public class JpaEndpoint extends ScheduledPollEndpoint<Exchange> {
044        private EntityManagerFactory entityManagerFactory;
045        private PlatformTransactionManager transactionManager;
046        private String persistenceUnit = "camel";
047        private JpaTemplate template;
048        private Expression<Exchange> producerExpression;
049        private int maximumResults = -1;
050        private Class<?> entityType;
051        private Map entityManagerProperties;
052        private boolean consumeDelete = true;
053        private boolean consumeLockEntity = true;
054        private boolean flushOnSend = true;
055    
056        public JpaEndpoint(String endpointUri) {
057            super(endpointUri);
058        }
059    
060        public JpaEndpoint(String uri, JpaComponent component) {
061            super(uri, component);
062            entityManagerFactory = component.getEntityManagerFactory();
063            transactionManager = component.getTransactionManager();
064        }
065    
066        public JpaEndpoint(String endpointUri, EntityManagerFactory entityManagerFactory) {
067            super(endpointUri);
068            this.entityManagerFactory = entityManagerFactory;
069        }
070    
071        public JpaEndpoint(String endpointUri, EntityManagerFactory entityManagerFactory, PlatformTransactionManager transactionManager) {
072            super(endpointUri);
073            this.entityManagerFactory = entityManagerFactory;
074            this.transactionManager = transactionManager;
075        }
076    
077        public Producer<Exchange> createProducer() throws Exception {
078            validate();
079            return new JpaProducer(this, getProducerExpression());
080        }
081    
082        public Consumer<Exchange> createConsumer(Processor processor) throws Exception {
083            validate();
084            JpaConsumer consumer = new JpaConsumer(this, processor);
085            configureConsumer(consumer);
086            return consumer;
087        }
088    
089        @Override
090        public void configureProperties(Map options) {
091            super.configureProperties(options);
092            Map emProperties = IntrospectionSupport.extractProperties(options, "emf.");
093            if (emProperties != null) {
094                setEntityManagerProperties(emProperties);
095            }
096        }
097    
098        public boolean isSingleton() {
099            return false;
100        }
101    
102        // Properties
103        // -------------------------------------------------------------------------
104        public JpaTemplate getTemplate() {
105            if (template == null) {
106                template = createTemplate();
107            }
108            return template;
109        }
110    
111        public void setTemplate(JpaTemplate template) {
112            this.template = template;
113        }
114    
115        public Expression<Exchange> getProducerExpression() {
116            if (producerExpression == null) {
117                producerExpression = createProducerExpression();
118            }
119            return producerExpression;
120        }
121    
122        public void setProducerExpression(Expression<Exchange> producerExpression) {
123            this.producerExpression = producerExpression;
124        }
125    
126        public int getMaximumResults() {
127            return maximumResults;
128        }
129    
130        public void setMaximumResults(int maximumResults) {
131            this.maximumResults = maximumResults;
132        }
133    
134        public Class<?> getEntityType() {
135            return entityType;
136        }
137    
138        public void setEntityType(Class<?> entityType) {
139            this.entityType = entityType;
140        }
141    
142        public EntityManagerFactory getEntityManagerFactory() {
143            if (entityManagerFactory == null) {
144                entityManagerFactory = createEntityManagerFactory();
145            }
146            return entityManagerFactory;
147        }
148    
149        public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
150            this.entityManagerFactory = entityManagerFactory;
151        }
152    
153        public PlatformTransactionManager getTransactionManager() {
154            if (transactionManager == null) {
155                transactionManager = createTransactionManager();
156            }
157            return transactionManager;
158        }
159    
160        public void setTransactionManager(PlatformTransactionManager transactionManager) {
161            this.transactionManager = transactionManager;
162        }
163    
164        public Map getEntityManagerProperties() {
165            if (entityManagerProperties == null) {
166                entityManagerProperties = System.getProperties();
167            }
168            return entityManagerProperties;
169        }
170    
171        public void setEntityManagerProperties(Map entityManagerProperties) {
172            this.entityManagerProperties = entityManagerProperties;
173        }
174    
175        public String getPersistenceUnit() {
176            return persistenceUnit;
177        }
178    
179        public void setPersistenceUnit(String persistenceUnit) {
180            this.persistenceUnit = persistenceUnit;
181        }
182    
183        public boolean isConsumeDelete() {
184            return consumeDelete;
185        }
186    
187        public void setConsumeDelete(boolean consumeDelete) {
188            this.consumeDelete = consumeDelete;
189        }
190    
191        public boolean isConsumeLockEntity() {
192            return consumeLockEntity;
193        }
194    
195        public void setConsumeLockEntity(boolean consumeLockEntity) {
196            this.consumeLockEntity = consumeLockEntity;
197        }
198    
199        public boolean isFlushOnSend() {
200            return flushOnSend;
201        }
202    
203        public void setFlushOnSend(boolean flushOnSend) {
204            this.flushOnSend = flushOnSend;
205        }
206    
207        // Implementation methods
208        // -------------------------------------------------------------------------
209    
210        protected void validate() {
211            ObjectHelper.notNull(getEntityManagerFactory(), "entityManagerFactory property");
212        }
213    
214        protected JpaTemplate createTemplate() {
215            return new JpaTemplate(getEntityManagerFactory());
216        }
217    
218        protected EntityManagerFactory createEntityManagerFactory() {
219            return Persistence.createEntityManagerFactory(persistenceUnit, getEntityManagerProperties());
220        }
221    
222        protected PlatformTransactionManager createTransactionManager() {
223            JpaTransactionManager tm = new JpaTransactionManager(getEntityManagerFactory());
224            tm.afterPropertiesSet();
225            return tm;
226        }
227    
228        protected EntityManager createEntityManager() {
229            return getEntityManagerFactory().createEntityManager();
230        }
231    
232        protected TransactionStrategy createTransactionStrategy() {
233            return JpaTemplateTransactionStrategy.newInstance(getTransactionManager(), getTemplate());
234        }
235    
236        protected Expression<Exchange> createProducerExpression() {
237            final Class<?> type = getEntityType();
238            if (type == null) {
239                return ExpressionBuilder.bodyExpression();
240            } else {
241                return new Expression<Exchange>() {
242                    public Object evaluate(Exchange exchange) {
243                        Object answer = exchange.getIn().getBody(type);
244                        if (answer == null) {
245                            Object defaultValue = exchange.getIn().getBody();
246                            if (defaultValue != null) {
247                                throw new NoTypeConversionAvailableException(defaultValue, type);
248                            }
249    
250                            // if we don't have a body then
251                            // lets instantiate and inject a new instance
252                            answer = exchange.getContext().getInjector().newInstance(type);
253                        }
254                        return answer;
255                    }
256                };
257            }
258        }
259    }