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.Arrays;
020 import java.util.Collection;
021 import java.util.Map;
022 import java.util.Set;
023
024 import javax.persistence.EntityManager;
025 import javax.persistence.Query;
026
027 /**
028 * A builder of query expressions
029 *
030 * @version $Revision: 563665 $
031 */
032 public abstract class QueryBuilder implements QueryFactory {
033 ParameterBuilder parameterBuilder;
034
035 /**
036 * Creates a query builder using the JPA query syntax
037 *
038 * @param query JPA query language to create
039 * @return a query builder
040 */
041 public static QueryBuilder query(final String query) {
042 return new QueryBuilder() {
043 protected Query makeQueryObject(EntityManager entityManager) {
044 return entityManager.createQuery(query);
045 }
046
047 @Override
048 public String toString() {
049 return "Query: " + query + " params: " + getParameterDescription();
050 }
051 };
052 }
053
054 /**
055 * Creates a named query
056 */
057 public static QueryBuilder namedQuery(final String namedQuery) {
058 return new QueryBuilder() {
059 protected Query makeQueryObject(EntityManager entityManager) {
060 return entityManager.createNamedQuery(namedQuery);
061 }
062
063 @Override
064 public String toString() {
065 return "Named: " + namedQuery + getParameterDescription();
066 }
067 };
068 }
069
070 /**
071 * Creates a native SQL query
072 */
073 public static QueryBuilder nativeQuery(final String nativeQuery) {
074 return new QueryBuilder() {
075 protected Query makeQueryObject(EntityManager entityManager) {
076 return entityManager.createNativeQuery(nativeQuery);
077 }
078
079 @Override
080 public String toString() {
081 return "NativeQuery: " + nativeQuery + getParameterDescription();
082 }
083 };
084 }
085
086 /**
087 * Specifies the parameters to the query
088 *
089 * @param parameters the parameters to be configured on the query
090 * @return this query builder
091 */
092 public QueryBuilder parameters(Object... parameters) {
093 return parameters(Arrays.asList(parameters));
094 }
095
096 /**
097 * Specifies the parameters to the query as an ordered collection of
098 * parameters
099 *
100 * @param parameters the parameters to be configured on the query
101 * @return this query builder
102 */
103 public QueryBuilder parameters(final Collection parameters) {
104 checkNoParametersConfigured();
105 parameterBuilder = new ParameterBuilder() {
106 public void populateQuery(EntityManager entityManager, Query query) {
107 int counter = 0;
108 for (Object parameter : parameters) {
109 query.setParameter(counter++, parameter);
110 }
111 }
112
113 @Override
114 public String toString() {
115 return "Parameters: " + parameters;
116 }
117 };
118 return this;
119 }
120
121 /**
122 * Specifies the parameters to the query as a Map of key/value pairs
123 *
124 * @param parameterMap the parameters to be configured on the query
125 * @return this query builder
126 */
127 public QueryBuilder parameters(final Map<String, Object> parameterMap) {
128 checkNoParametersConfigured();
129 parameterBuilder = new ParameterBuilder() {
130 public void populateQuery(EntityManager entityManager, Query query) {
131 Set<Map.Entry<String, Object>> entries = parameterMap.entrySet();
132 for (Map.Entry<String, Object> entry : entries) {
133 query.setParameter(entry.getKey(), entry.getValue());
134 }
135 }
136
137 @Override
138 public String toString() {
139 return "Parameters: " + parameterMap;
140 }
141 };
142 return this;
143 }
144
145 protected void checkNoParametersConfigured() {
146 if (parameterBuilder != null) {
147 throw new IllegalArgumentException("Cannot add parameters to a QueryBuilder which already has parameters configured");
148 }
149 }
150
151 public Query createQuery(EntityManager entityManager) {
152 Query query = makeQueryObject(entityManager);
153 populateQuery(entityManager, query);
154 return query;
155 }
156
157 protected String getParameterDescription() {
158 if (parameterBuilder == null) {
159 return "";
160 } else {
161 return " " + parameterBuilder.toString();
162 }
163 }
164
165 protected void populateQuery(EntityManager entityManager, Query query) {
166 if (parameterBuilder != null) {
167 parameterBuilder.populateQuery(entityManager, query);
168 }
169 }
170
171 protected abstract Query makeQueryObject(EntityManager entityManager);
172
173 /**
174 * A plugin strategy to populate the query with parameters
175 */
176 protected abstract static class ParameterBuilder {
177 public abstract void populateQuery(EntityManager entityManager, Query query);
178 }
179 }