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 }