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: 630591 $ 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 }