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.bam.processor;
018    
019    import org.apache.camel.Exchange;
020    import org.apache.camel.Expression;
021    import org.apache.camel.Processor;
022    import org.apache.camel.bam.model.ProcessDefinition;
023    import org.apache.camel.bam.rules.ActivityRules;
024    import org.apache.camel.util.IntrospectionSupport;
025    import org.springframework.orm.jpa.JpaTemplate;
026    import org.springframework.transaction.support.TransactionTemplate;
027    
028    import java.util.List;
029    
030    /**
031     * A base class for JPA based BAM which can use any entity to store the process instance information which
032     * allows derived classes to specialise the process instance entity.
033     *
034     * @version $Revision: $
035     */
036    public class JpaBamProcessorSupport<T> extends BamProcessorSupport<T> {
037        private ActivityRules activityRules;
038        private JpaTemplate template;
039        private String findByKeyQuery;
040        private String keyPropertyName = "correlationKey";
041    
042        public JpaBamProcessorSupport(TransactionTemplate transactionTemplate, JpaTemplate template, Expression<Exchange> correlationKeyExpression, ActivityRules activityRules, Class<T> entitytype) {
043            super(transactionTemplate, correlationKeyExpression, entitytype);
044            this.activityRules = activityRules;
045            this.template = template;
046        }
047    
048        public JpaBamProcessorSupport(TransactionTemplate transactionTemplate, JpaTemplate template, Expression<Exchange> correlationKeyExpression, ActivityRules activityRules) {
049            super(transactionTemplate, correlationKeyExpression);
050            this.activityRules = activityRules;
051            this.template = template;
052        }
053    
054        public String getFindByKeyQuery() {
055            if (findByKeyQuery == null) {
056                findByKeyQuery = createFindByKeyQuery();
057            }
058            return findByKeyQuery;
059        }
060    
061        public void setFindByKeyQuery(String findByKeyQuery) {
062            this.findByKeyQuery = findByKeyQuery;
063        }
064    
065        public ActivityRules getActivityRules() {
066            return activityRules;
067        }
068    
069        public void setActivityRules(ActivityRules activityRules) {
070            this.activityRules = activityRules;
071        }
072    
073        public String getKeyPropertyName() {
074            return keyPropertyName;
075        }
076    
077        public void setKeyPropertyName(String keyPropertyName) {
078            this.keyPropertyName = keyPropertyName;
079        }
080    
081        public JpaTemplate getTemplate() {
082            return template;
083        }
084    
085        public void setTemplate(JpaTemplate template) {
086            this.template = template;
087        }
088    
089        // Implementatiom methods
090        //-----------------------------------------------------------------------
091        protected T loadEntity(Exchange exchange, Object key) {
092            List<T> list = template.find(getFindByKeyQuery(), key);
093            T entity = null;
094            if (!list.isEmpty()) {
095                entity = list.get(0);
096            }
097            if (entity == null) {
098                entity = createEntity(exchange, key);
099                setKeyProperty(entity, key);
100                ProcessDefinition definition = ProcessDefinition.getRefreshedProcessDefinition(template, getActivityRules().getProcessRules().getProcessDefinition());
101                setProcessDefinitionProperty(entity, definition);
102                template.persist(entity);
103            }
104            return entity;
105        }
106    
107        /**
108         * Sets the key property on the new entity
109         */
110        protected void setKeyProperty(T entity, Object key) {
111            IntrospectionSupport.setProperty(entity, getKeyPropertyName(), key);
112        }
113    
114        protected void setProcessDefinitionProperty(T entity, ProcessDefinition processDefinition) {
115            IntrospectionSupport.setProperty(entity, "processDefinition", processDefinition);
116        }
117    
118        /**
119         * Create a new instance of the entity for the given key
120         */
121        protected T createEntity(Exchange exchange, Object key) {
122            return (T) exchange.getContext().getInjector().newInstance(getEntityType());
123        }
124    
125        protected void processEntity(Exchange exchange, T entity) throws Exception {
126            if (entity instanceof Processor) {
127                Processor processor = (Processor) entity;
128                processor.process(exchange);
129            }
130            else {
131                // TODO add other extension points - eg. passing in Activity
132                throw new IllegalArgumentException("No processor defined for this route");
133            }
134        }
135    
136        protected String createFindByKeyQuery() {
137            return "select x from " + getEntityType().getName() + " x where x." + getKeyPropertyName() + " = ?1";
138        }
139    }