001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.camel.component.jpa;
019
020 import javax.persistence.EntityManager;
021 import javax.persistence.Query;
022 import java.util.Arrays;
023 import java.util.Collection;
024 import java.util.Map;
025 import java.util.Set;
026
027 /**
028 * A builder of query expressions
029 *
030 * @version $Revision: 525537 $
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 parameters
098 *
099 * @param parameters the parameters to be configured on the query
100 * @return this query builder
101 */
102 public QueryBuilder parameters(final Collection parameters) {
103 checkNoParametersConfigured();
104 parameterBuilder = new ParameterBuilder() {
105 public void populateQuery(EntityManager entityManager, Query query) {
106 int counter = 0;
107 for (Object parameter : parameters) {
108 query.setParameter(counter++, parameter);
109 }
110 }
111
112 @Override
113 public String toString() {
114 return "Parameters: " + parameters;
115 }
116 };
117 return this;
118 }
119
120 /**
121 * Specifies the parameters to the query as a Map of key/value pairs
122 *
123 * @param parameterMap the parameters to be configured on the query
124 * @return this query builder
125 */
126 public QueryBuilder parameters(final Map<String, Object> parameterMap) {
127 checkNoParametersConfigured();
128 parameterBuilder = new ParameterBuilder() {
129 public void populateQuery(EntityManager entityManager, Query query) {
130 Set<Map.Entry<String, Object>> entries = parameterMap.entrySet();
131 for (Map.Entry<String, Object> entry : entries) {
132 query.setParameter(entry.getKey(), entry.getValue());
133 }
134 }
135
136 @Override
137 public String toString() {
138 return "Parameters: " + parameterMap;
139 }
140 };
141 return this;
142 }
143
144 protected void checkNoParametersConfigured() {
145 if (parameterBuilder != null) {
146 throw new IllegalArgumentException("Cannot add parameters to a QueryBuilder which already has parameters configured");
147 }
148 }
149
150 public Query createQuery(EntityManager entityManager) {
151 Query query = makeQueryObject(entityManager);
152 populateQuery(entityManager, query);
153 return query;
154 }
155
156 protected String getParameterDescription() {
157 if (parameterBuilder == null) {
158 return "";
159 }
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 }