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 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 + 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 * Creates a native SQL query with a provided resultClass 088 */ 089 public static QueryBuilder nativeQuery(final String nativeQuery, final Class resultClass) { 090 return new QueryBuilder() { 091 protected Query makeQueryObject(EntityManager entityManager) { 092 return entityManager.createNativeQuery(nativeQuery, resultClass); 093 } 094 095 @Override 096 public String toString() { 097 return "NativeQuery: " + nativeQuery + " resultClass:" + resultClass + getParameterDescription(); 098 } 099 }; 100 } 101 102 /** 103 * Specifies the parameters to the query 104 * 105 * @param parameters the parameters to be configured on the query 106 * @return this query builder 107 */ 108 public QueryBuilder parameters(Object... parameters) { 109 return parameters(Arrays.asList(parameters)); 110 } 111 112 /** 113 * Specifies the parameters to the query as an ordered collection of 114 * parameters 115 * 116 * @param parameters the parameters to be configured on the query 117 * @return this query builder 118 */ 119 public QueryBuilder parameters(final Collection parameters) { 120 checkNoParametersConfigured(); 121 parameterBuilder = new ParameterBuilder() { 122 public void populateQuery(EntityManager entityManager, Query query) { 123 int counter = 0; 124 for (Object parameter : parameters) { 125 query.setParameter(counter++, parameter); 126 } 127 } 128 129 @Override 130 public String toString() { 131 return "Parameters: " + parameters; 132 } 133 }; 134 return this; 135 } 136 137 /** 138 * Specifies the parameters to the query as a Map of key/value pairs 139 * 140 * @param parameterMap the parameters to be configured on the query 141 * @return this query builder 142 */ 143 public QueryBuilder parameters(final Map<String, Object> parameterMap) { 144 checkNoParametersConfigured(); 145 parameterBuilder = new ParameterBuilder() { 146 public void populateQuery(EntityManager entityManager, Query query) { 147 Set<Map.Entry<String, Object>> entries = parameterMap.entrySet(); 148 for (Map.Entry<String, Object> entry : entries) { 149 query.setParameter(entry.getKey(), entry.getValue()); 150 } 151 } 152 153 @Override 154 public String toString() { 155 return "Parameters: " + parameterMap; 156 } 157 }; 158 return this; 159 } 160 161 protected void checkNoParametersConfigured() { 162 if (parameterBuilder != null) { 163 throw new IllegalArgumentException("Cannot add parameters to a QueryBuilder which already has parameters configured"); 164 } 165 } 166 167 public Query createQuery(EntityManager entityManager) { 168 Query query = makeQueryObject(entityManager); 169 populateQuery(entityManager, query); 170 return query; 171 } 172 173 protected String getParameterDescription() { 174 if (parameterBuilder == null) { 175 return ""; 176 } else { 177 return " " + parameterBuilder.toString(); 178 } 179 } 180 181 protected void populateQuery(EntityManager entityManager, Query query) { 182 if (parameterBuilder != null) { 183 parameterBuilder.populateQuery(entityManager, query); 184 } 185 } 186 187 protected abstract Query makeQueryObject(EntityManager entityManager); 188 189 /** 190 * A plugin strategy to populate the query with parameters 191 */ 192 protected abstract static class ParameterBuilder { 193 public abstract void populateQuery(EntityManager entityManager, Query query); 194 } 195 }