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    
036    import org.springframework.orm.jpa.JpaTemplate;
037    
038    /**
039     * @version $Revision: 563665 $
040     */
041    public class JpaEndpoint extends ScheduledPollEndpoint<Exchange> {
042        private EntityManagerFactory entityManagerFactory;
043        private String persistenceUnit = "camel";
044        private JpaTemplate template;
045        private Expression<Exchange> producerExpression;
046        private int maximumResults = -1;
047        private Class<?> entityType;
048        private Map entityManagerProperties;
049        private boolean consumeDelete = true;
050        private boolean consumeLockEntity = true;
051    
052        public JpaEndpoint(String uri, JpaComponent component) {
053            super(uri, component);
054            entityManagerFactory = component.getEntityManagerFactory();
055        }
056    
057        public Exchange createExchange() {
058            return new DefaultExchange(getContext());
059        }
060    
061        public Producer<Exchange> createProducer() throws Exception {
062            return new JpaProducer(this, getProducerExpression());
063        }
064    
065        public Consumer<Exchange> createConsumer(Processor processor) throws Exception {
066            JpaConsumer consumer = new JpaConsumer(this, processor);
067            configureConsumer(consumer);
068            return consumer;
069        }
070    
071        @Override
072        public void configureProperties(Map options) {
073            super.configureProperties(options);
074            Map emProperties = IntrospectionSupport.extractProperties(options, "emf.");
075            if (emProperties != null) {
076                setEntityManagerProperties(emProperties);
077            }
078        }
079    
080        public boolean isSingleton() {
081            return false;
082        }
083    
084        // Properties
085        // -------------------------------------------------------------------------
086        public JpaTemplate getTemplate() {
087            if (template == null) {
088                template = createTemplate();
089            }
090            return template;
091        }
092    
093        public void setTemplate(JpaTemplate template) {
094            this.template = template;
095        }
096    
097        public Expression<Exchange> getProducerExpression() {
098            if (producerExpression == null) {
099                producerExpression = createProducerExpression();
100            }
101            return producerExpression;
102        }
103    
104        public void setProducerExpression(Expression<Exchange> producerExpression) {
105            this.producerExpression = producerExpression;
106        }
107    
108        public int getMaximumResults() {
109            return maximumResults;
110        }
111    
112        public void setMaximumResults(int maximumResults) {
113            this.maximumResults = maximumResults;
114        }
115    
116        public Class<?> getEntityType() {
117            return entityType;
118        }
119    
120        public void setEntityType(Class<?> entityType) {
121            this.entityType = entityType;
122        }
123    
124        public EntityManagerFactory getEntityManagerFactory() {
125            if (entityManagerFactory == null) {
126                entityManagerFactory = createEntityManagerFactory();
127            }
128            return entityManagerFactory;
129        }
130    
131        public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
132            this.entityManagerFactory = entityManagerFactory;
133        }
134    
135        public Map getEntityManagerProperties() {
136            if (entityManagerProperties == null) {
137                entityManagerProperties = System.getProperties();
138            }
139            return entityManagerProperties;
140        }
141    
142        public void setEntityManagerProperties(Map entityManagerProperties) {
143            this.entityManagerProperties = entityManagerProperties;
144        }
145    
146        public String getPersistenceUnit() {
147            return persistenceUnit;
148        }
149    
150        public void setPersistenceUnit(String persistenceUnit) {
151            this.persistenceUnit = persistenceUnit;
152        }
153    
154        public boolean isConsumeDelete() {
155            return consumeDelete;
156        }
157    
158        public void setConsumeDelete(boolean consumeDelete) {
159            this.consumeDelete = consumeDelete;
160        }
161    
162        public boolean isConsumeLockEntity() {
163            return consumeLockEntity;
164        }
165    
166        public void setConsumeLockEntity(boolean consumeLockEntity) {
167            this.consumeLockEntity = consumeLockEntity;
168        }
169    
170        // Implementation methods
171        // -------------------------------------------------------------------------
172        protected JpaTemplate createTemplate() {
173            return new JpaTemplate(getEntityManagerFactory());
174        }
175    
176        protected EntityManagerFactory createEntityManagerFactory() {
177            return Persistence.createEntityManagerFactory(persistenceUnit, getEntityManagerProperties());
178        }
179    
180        protected EntityManager createEntityManager() {
181            return getEntityManagerFactory().createEntityManager();
182        }
183    
184        protected TransactionStrategy createTransactionStrategy() {
185            EntityManagerFactory emf = getEntityManagerFactory();
186            return JpaTemplateTransactionStrategy.newInstance(emf, getTemplate());
187            // return new DefaultTransactionStrategy(emf);
188        }
189    
190        protected Expression<Exchange> createProducerExpression() {
191            final Class<?> type = getEntityType();
192            if (type == null) {
193                return ExpressionBuilder.bodyExpression();
194            } else {
195                return new Expression<Exchange>() {
196                    public Object evaluate(Exchange exchange) {
197                        Object answer = exchange.getIn().getBody(type);
198                        if (answer == null) {
199                            Object defaultValue = exchange.getIn().getBody();
200                            if (defaultValue != null) {
201                                throw new NoTypeConversionAvailableException(defaultValue, type);
202                            }
203    
204                            // if we don't have a body then
205                            // lets instantiate and inject a new instance
206                            answer = exchange.getContext().getInjector().newInstance(type);
207                        }
208                        return answer;
209                    }
210                };
211            }
212        }
213    }