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: 941994 $
041 */
042 public class SqlBuilder implements Expression, Predicate {
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 <T> T evaluate(Exchange exchange, Class<T> type) {
052 Object result = evaluateQuery(exchange);
053 return exchange.getContext().getTypeConverter().convertTo(type, result);
054 }
055
056 public boolean matches(Exchange exchange) {
057 List list = evaluateQuery(exchange);
058 return matches(exchange, list);
059 }
060
061 public void assertMatches(String text, Exchange exchange) throws AssertionError {
062 List list = evaluateQuery(exchange);
063 if (!matches(exchange, list)) {
064 throw new AssertionError(this + " failed on " + exchange + " as found " + list);
065 }
066 }
067
068 // Builder API
069 // -----------------------------------------------------------------------
070
071 /**
072 * Creates a new builder for the given SQL query string
073 *
074 * @param sql the SQL query to perform
075 * @return a new builder
076 * @throws QueryParseException if there is an issue with the SQL
077 */
078 public static SqlBuilder sql(String sql) throws QueryParseException {
079 Query q = new Query();
080 q.parse(sql);
081 return new SqlBuilder(q);
082 }
083
084 /**
085 * Adds the variable value to be used by the SQL query
086 */
087 public SqlBuilder variable(String name, Object value) {
088 getVariables().put(name, value);
089 return this;
090 }
091
092 // Properties
093 // -----------------------------------------------------------------------
094 public Map<String, Object> getVariables() {
095 return variables;
096 }
097
098 public void setVariables(Map<String, Object> properties) {
099 this.variables = properties;
100 }
101
102 // Implementation methods
103 // -----------------------------------------------------------------------
104 protected boolean matches(Exchange exchange, List list) {
105 return ObjectHelper.matches(list);
106 }
107
108 protected List evaluateQuery(Exchange exchange) {
109 configureQuery(exchange);
110 Message in = exchange.getIn();
111 List list = in.getBody(List.class);
112 if (list == null) {
113 list = Collections.singletonList(in.getBody());
114 }
115 try {
116 return query.execute(list).getResults();
117 } catch (QueryExecutionException e) {
118 throw new RuntimeExpressionException(e);
119 }
120 }
121
122 protected void configureQuery(Exchange exchange) {
123 // lets pass in the headers as variables that the SQL can use
124 addVariables(exchange.getProperties());
125 addVariables(exchange.getIn().getHeaders());
126 addVariables(getVariables());
127
128 query.setVariable("exchange", exchange);
129 query.setVariable("in", exchange.getIn());
130 query.setVariable("out", exchange.getOut());
131 }
132
133 protected void addVariables(Map<String, Object> map) {
134 Set<Map.Entry<String, Object>> propertyEntries = map.entrySet();
135 for (Map.Entry<String, Object> entry : propertyEntries) {
136 query.setVariable(entry.getKey(), entry.getValue());
137 }
138 }
139 }