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.builder.sql;
018
019 import java.util.Collections;
020 import java.util.HashMap;
021 import java.util.List;
022 import java.util.Map;
023 import java.util.Set;
024
025 import org.apache.camel.Exchange;
026 import org.apache.camel.Expression;
027 import org.apache.camel.Message;
028 import org.apache.camel.Predicate;
029 import org.apache.camel.RuntimeExpressionException;
030 import org.apache.camel.util.ObjectHelper;
031
032 import org.josql.Query;
033 import org.josql.QueryExecutionException;
034 import org.josql.QueryParseException;
035
036 /**
037 * A builder of SQL {@link org.apache.camel.Expression} and
038 * {@link org.apache.camel.Predicate} implementations
039 *
040 * @version $Revision: $
041 */
042 public class SqlBuilder<E extends Exchange> implements Expression<E>, Predicate<E> {
043
044 private Query query;
045 private Map<String, Object> variables = new HashMap<String, Object>();
046
047 public SqlBuilder(Query query) {
048 this.query = query;
049 }
050
051 public Object evaluate(E exchange) {
052 return evaluateQuery(exchange);
053 }
054
055 public boolean matches(E exchange) {
056 List list = evaluateQuery(exchange);
057 return matches(exchange, list);
058 }
059
060 public void assertMatches(String text, E exchange) throws AssertionError {
061 List list = evaluateQuery(exchange);
062 if (!matches(exchange, list)) {
063 throw new AssertionError(this + " failed on " + exchange + " as found " + list);
064 }
065 }
066
067 // Builder API
068 // -----------------------------------------------------------------------
069
070 /**
071 * Creates a new builder for the given SQL query string
072 *
073 * @param sql the SQL query to perform
074 * @return a new builder
075 * @throws QueryParseException if there is an issue with the SQL
076 */
077 public static <E extends Exchange> SqlBuilder<E> sql(String sql) throws QueryParseException {
078 Query q = new Query();
079 q.parse(sql);
080 return new SqlBuilder(q);
081 }
082
083 /**
084 * Adds the variable value to be used by the SQL query
085 */
086 public SqlBuilder<E> variable(String name, Object value) {
087 getVariables().put(name, value);
088 return this;
089 }
090
091 // Properties
092 // -----------------------------------------------------------------------
093 public Map<String, Object> getVariables() {
094 return variables;
095 }
096
097 public void setVariables(Map<String, Object> properties) {
098 this.variables = properties;
099 }
100
101 // Implementation methods
102 // -----------------------------------------------------------------------
103 protected boolean matches(E exchange, List list) {
104 return ObjectHelper.matches(list);
105 }
106
107 protected List evaluateQuery(E exchange) {
108 configureQuery(exchange);
109 Message in = exchange.getIn();
110 List list = in.getBody(List.class);
111 if (list == null) {
112 list = Collections.singletonList(in.getBody());
113 }
114 try {
115 return query.execute(list).getResults();
116 } catch (QueryExecutionException e) {
117 throw new RuntimeExpressionException(e);
118 }
119 }
120
121 protected void configureQuery(E exchange) {
122 // lets pass in the headers as variables that the SQL can use
123 addVariables(exchange.getProperties());
124 addVariables(exchange.getIn().getHeaders());
125 addVariables(getVariables());
126
127 query.setVariable("exchange", exchange);
128 query.setVariable("in", exchange.getIn());
129 query.setVariable("out", exchange.getOut());
130 }
131
132 protected void addVariables(Map<String, Object> map) {
133 Set<Map.Entry<String, Object>> propertyEntries = map.entrySet();
134 for (Map.Entry<String, Object> entry : propertyEntries) {
135 query.setVariable(entry.getKey(), entry.getValue());
136 }
137 }
138 }