View Javadoc
1   /*
2    * Copyright 2001-2008 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  
18  package org.apache.juddi.query.util;
19  
20  import java.util.StringTokenizer;
21  import java.util.Vector;
22  import java.util.List;
23  import javax.persistence.Query;
24  import javax.persistence.EntityManager;
25  
26  /**
27   * @author <a href="mailto:jfaath@apache.org">Jeff Faath</a>
28   * @author Steve Viens (steve@viens.net)
29   */
30  public class DynamicQuery {
31  	public static final String CLAUSE_WHERE = "where";
32  	public static final String CLAUSE_GROUPBY = "group by";
33  	public static final String CLAUSE_ORDERBY = "order by";
34  	public static final String CLAUSE_HAVING = "having";
35  	public static final String OPERATOR_OR = "or";
36  	public static final String OPERATOR_AND = "and";
37  	public static final String PREDICATE_EQUALS = "=";
38  	public static final String PREDICATE_NOTEQUALS = "<>";
39  	public static final String PREDICATE_LIKE = "like";
40  	public static final String PREDICATE_IN = "in";
41  	public static final String PREDICATE_GREATERTHAN = ">";
42  	public static final String PREDICATE_LESSTHAN = "<";
43  	public static final String SORT_ASC = "asc";
44  	public static final String SORT_DESC = "desc";
45  	public static final String WILDCARD = "%";
46  	
47  	private Vector<Object> values = null;
48  	private StringBuffer sql = null;
49  
50  	public DynamicQuery() {
51  		this.values = new Vector<Object>();
52  		this.sql = new StringBuffer();
53  	} 
54  
55  	public DynamicQuery(String sql) {
56  		this.values = new Vector<Object>();
57  		this.sql = new StringBuffer(sql);
58  	}
59  
60  	public DynamicQuery append(String sql) {
61  		this.sql.append(sql);
62  		return this;
63  	}
64  
65  	public DynamicQuery pad() {
66  		this.sql.append(" ");
67  		return this;
68  	}
69  	
70  	public DynamicQuery openParen() {
71  		this.sql.append("(");
72  		return this;
73  	}
74  
75  	public DynamicQuery closeParen() {
76  		this.sql.append(")");
77  		return this;
78  	}
79  
80  	public DynamicQuery param() {
81  		this.sql.append("?");
82  		return this;
83  	}
84  	
85  	public DynamicQuery comma() {
86  		this.sql.append(",");
87  		return this;
88  	}
89  
90  	public DynamicQuery AND() {
91  		this.sql.append(OPERATOR_AND);
92  		return this;
93  	}
94  	
95  	public DynamicQuery OR() {
96  		this.sql.append(OPERATOR_OR);
97  		return this;
98  	}
99  
100 	public DynamicQuery WHERE() {
101 		this.sql.append(CLAUSE_WHERE);
102 		return this;
103 	}
104 
105 	public DynamicQuery IN() {
106 		this.sql.append(PREDICATE_IN);
107 		return this;
108 	}
109 
110 	public DynamicQuery GROUPBY() {
111 		this.sql.append(CLAUSE_GROUPBY);
112 		return this;
113 	}
114 
115 	public DynamicQuery ORDERBY() {
116 		this.sql.append(CLAUSE_ORDERBY);
117 		return this;
118 	}
119 
120 	public DynamicQuery HAVING() {
121 		this.sql.append(CLAUSE_HAVING);
122 		return this;
123 	}
124 	
125 	public DynamicQuery appendGroupedAnd(Parameter... params) {
126 		return appendCondition(OPERATOR_AND, params);
127 	}
128 
129 	public DynamicQuery appendGroupedOr(Parameter... params) {
130 		return appendCondition(OPERATOR_OR, params);
131 	}
132 
133 	public DynamicQuery appendCondition(String operator, Parameter... params) {
134 		if (params == null || operator == null)
135 			return this;
136 		
137 		openParen();
138 		for (int i = 0; i < params.length; i++) {
139 			if (params[i] != null) {
140 				append(params[i].getName()).pad().append(params[i].getPredicate()).pad().param();
141 				addValue(params[i].getValue());
142 				
143 				if (i + 1 < params.length) {
144 					pad().append(operator).pad();
145 				}
146 			}
147 		}
148 		closeParen().pad();
149 		return this;
150 		
151 	}
152 	
153 	public DynamicQuery appendInListWithAnd(String term, List<?> list) {
154 		if (list == null || list.size() == 0)
155 			return this;
156 		
157 		AND().pad();
158 		
159 		return appendInList(term, list);
160 	}
161 	
162 	public DynamicQuery appendInList(String term, List<?> list) {
163 		if (list == null || list.size() == 0)
164 			return this;
165 		
166 		append(term).pad().IN().pad().openParen().pad();
167 		int count = 0;
168 		for (Object item : list) {
169 			param();
170 			addValue(item);
171 			
172 			if (count + 1 < list.size())
173 				comma().pad();
174 			
175 			count++;
176 		}
177 		closeParen().pad();
178 		return this;
179 	}
180 
181 	public void addValue(Object obj) {
182 		this.values.addElement(obj);
183 	}
184 	
185 	public Query buildJPAQuery(EntityManager em) {
186 		StringTokenizer tokenizer = new StringTokenizer(sql.toString(),"?");
187 		StringBuffer sqlBuffer = new StringBuffer();
188 		int numberOfTokens = tokenizer.countTokens();
189 		for (int i=1; i<numberOfTokens; i++) {
190 			sqlBuffer.append(tokenizer.nextToken() + "?" + i);
191 		}
192 		if (tokenizer.hasMoreTokens()) sqlBuffer.append(tokenizer.nextToken());
193 		Query qry = em.createQuery(sqlBuffer.toString());
194 		
195 		for (int i = 0; i < values.size(); i++)
196 			qry.setParameter(i + 1, values.elementAt(i));
197 			
198 		return qry;
199 	}
200 
201 	public String toString() { 
202 		StringBuffer buffer = new StringBuffer(sql.toString());
203 		buffer.append("\n\n");
204 	
205 		for (int i=0; i<values.size(); i++) {
206 			Object obj = values.elementAt(i);
207 	  
208 			buffer.append(i+1);
209 			buffer.append("\t");
210 			buffer.append(obj.getClass().getName());
211 			buffer.append("\t");
212 			buffer.append(obj.toString());
213 			buffer.append("\n");
214 		}
215 	    
216 		return buffer.toString();
217 	}
218 	
219 	public static class Parameter {
220 		private String name;
221 		private Object value;
222 		private String predicate;
223 		
224 		public Parameter(String name, Object value, String predicate) {
225 			this.name = name;
226 			this.value = value;
227 			this.predicate = predicate;
228 		}
229 
230 		public String getName() {
231 			return name;
232 		}
233 		public void setName(String name) {
234 			this.name = name;
235 		}
236 
237 		public Object getValue() {
238 			return value;
239 		}
240 		public void setValue(Object value) {
241 			this.value = value;
242 		}
243 
244 		public String getPredicate() {
245 			return predicate;
246 		}
247 		public void setPredicate(String predicate) {
248 			this.predicate = predicate;
249 		}
250 
251 		
252 	}
253 }