001 package org.apache.ojb.broker.query;
002
003 /* Copyright 2002-2005 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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
018 import java.util.List;
019 import java.util.Map;
020
021 /**
022 * abstract baseclass of all criteria classes, can't be instantiated.
023 *
024 * This code is based on stuff from
025 * COBRA - Java Object Persistence Layer
026 * Copyright (C) 1997, 1998 DB Harvey-George
027 * eMail: cobra@lowrent.org
028
029 * @author DB Harvey-George
030 * @author Thomas Mahler
031 * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
032 * @version $Id: SelectionCriteria.java,v 1.1 2007-08-24 22:17:36 ewestfal Exp $
033 */
034 public abstract class SelectionCriteria implements java.io.Serializable
035 {
036 static final long serialVersionUID = -5194901539702756536L; protected static final String EQUAL = " = ";
037 protected static final String NOT_EQUAL = " <> ";
038 protected static final String GREATER = " > ";
039 protected static final String NOT_GREATER = " <= ";
040 protected static final String LESS = " < ";
041 protected static final String NOT_LESS = " >= ";
042 protected static final String LIKE = " LIKE ";
043 protected static final String NOT_LIKE = " NOT LIKE ";
044 protected static final String IS_NULL = " IS NULL ";
045 protected static final String NOT_IS_NULL = " IS NOT NULL ";
046 protected static final String BETWEEN = " BETWEEN ";
047 protected static final String NOT_BETWEEN = " NOT BETWEEN ";
048 protected static final String IN = " IN ";
049 protected static final String NOT_IN = " NOT IN ";
050
051 private Object m_attribute;
052 private Object m_value;
053
054
055 // BRJ: true if criterion is bound
056 private boolean m_bound = false;
057
058 // BRJ: the criterion must be bound for the main class and for all extents
059 private int m_numberOfExtentsToBind = 0;
060
061 private String m_alias = null;
062 private UserAlias m_userAlias = null;
063
064 // BRJ: indicate whether attribute name should be translated into column name
065 private boolean m_translateAttribute = true;
066
067 private Criteria m_criteria;
068
069 /**
070 * Constructor declaration
071 *
072 * @param anAttribute column- or fieldName or a Query
073 * @param aValue the value to compare with
074 * @param negative criteria is negated (ie NOT LIKE instead of LIKE)
075 * @param alias use alias to link anAttribute to
076 */
077 SelectionCriteria(Object anAttribute, Object aValue, String alias)
078 {
079 if (!(anAttribute instanceof String || anAttribute instanceof Query))
080 {
081 throw new IllegalArgumentException("An attribute must be a String or a Query !");
082 }
083
084 m_attribute = anAttribute;
085 m_value = aValue;
086 this.m_bound = !isBindable();
087 this.m_alias = alias;
088 this.m_userAlias = m_alias == null ? null : new UserAlias(m_alias, (String)getAttribute(), true);
089 }
090
091 /**
092 * Constructor declaration
093 *
094 * @param anAttribute column- or fieldName or a Query
095 * @param aValue the value to compare with
096 * @param aUserAlias userAlias to link anAttribute to
097 */
098 SelectionCriteria(Object anAttribute, Object aValue, UserAlias aUserAlias)
099 {
100 if (!(anAttribute instanceof String || anAttribute instanceof Query))
101 {
102 throw new IllegalArgumentException("An attribute must be a String or a Query !");
103 }
104
105 m_attribute = anAttribute;
106 m_value = aValue;
107 this.m_bound = !isBindable();
108 this.m_userAlias = aUserAlias;
109 this.m_alias = m_userAlias == null ? null : m_userAlias.getName();
110 }
111
112 /**
113 * Answer the SQL compare-clause for this criteria
114 */
115 abstract public String getClause();
116
117 /**
118 * sets the value of the criteria to newValue. Used by the ODMG OQLQuery.bind() operation
119 */
120 public void bind(Object newValue)
121 {
122 setValue(newValue);
123 setBound(true);
124 }
125
126 /**
127 * Answer the value
128 */
129 public Object getValue()
130 {
131 return m_value;
132 }
133
134 /**
135 * Answer the attribute
136 */
137 public Object getAttribute()
138 {
139 return m_attribute;
140 }
141
142 /**
143 * String representation
144 */
145 public String toString()
146 {
147 return m_attribute + getClause() + m_value;
148 }
149
150 /**
151 * BRJ : Used by the ODMG OQLQuery.bind() operation
152 * @return Returns a boolean indicator
153 */
154 public boolean isBound()
155 {
156 return m_bound;
157 }
158
159 /**
160 * Sets the bound.
161 * @param bound The bound to set
162 */
163 protected void setBound(boolean bound)
164 {
165 this.m_bound = bound;
166 }
167
168 /**
169 * Sets the value.
170 * @param value The value to set
171 */
172 protected void setValue(Object value)
173 {
174 this.m_value = value;
175 }
176
177 /**
178 * answer true if the selection criteria is bindable
179 * BRJ: value null is bindable
180 */
181 protected boolean isBindable()
182 {
183 return (getValue() == null);
184 }
185 /**
186 * Returns the numberOfExtentsToBind.
187 * @return int
188 */
189 public int getNumberOfExtentsToBind()
190 {
191 return m_numberOfExtentsToBind;
192 }
193
194 /**
195 * Sets the numberOfExtentsToBind.
196 * @param numberOfExtentsToBind The numberOfExtentsToBind to set
197 */
198 public void setNumberOfExtentsToBind(int numberOfExtentsToBind)
199 {
200 this.m_numberOfExtentsToBind = numberOfExtentsToBind;
201 }
202
203 /**
204 * @return String
205 */
206 public String getAlias()
207 {
208 return m_alias;
209 }
210
211 /**
212 * Sets the alias. By default the entire attribute path participates in the alias
213 * @param alias The name of the alias to set
214 */
215 public void setAlias(String alias)
216 {
217 m_alias = alias;
218 String attributePath = (String)getAttribute();
219 boolean allPathsAliased = true;
220 m_userAlias = new UserAlias(alias, attributePath, allPathsAliased);
221
222 }
223
224 /**
225 * Sets the alias.
226 * @param alias The alias to set
227 */
228 public void setAlias(String alias, String aliasPath)
229 {
230 m_alias = alias;
231 m_userAlias = new UserAlias(alias, (String)getAttribute(), aliasPath);
232 }
233
234 /**
235 * Sets the alias using a userAlias object.
236 * @param userAlias The alias to set
237 */
238 public void setAlias(UserAlias userAlias)
239 {
240 m_alias = userAlias.getName();
241 m_userAlias = userAlias;
242 }
243
244 public UserAlias getUserAlias()
245 {
246 return m_userAlias;
247 }
248 /**
249 * @return true if attribute name should be translated into column name
250 */
251 public boolean isTranslateAttribute()
252 {
253 return m_translateAttribute;
254 }
255
256 /**
257 * @param b
258 */
259 void setTranslateAttribute(boolean b)
260 {
261 m_translateAttribute = b;
262 }
263
264 /**
265 * @return
266 */
267 public Criteria getCriteria()
268 {
269 return m_criteria;
270 }
271
272 /**
273 * @param criteria
274 */
275 void setCriteria(Criteria criteria)
276 {
277 m_criteria = criteria;
278 }
279
280 public QueryByCriteria getQuery()
281 {
282 if (getCriteria() != null)
283 {
284 return getCriteria().getQuery();
285 }
286 else
287 {
288 return null;
289 }
290 }
291
292 /**
293 * Gets the pathClasses from the parent Criteria.
294 * A Map containing hints about what Class to be used for what path segment
295 * @return Returns a Map
296 */
297 public Map getPathClasses()
298 {
299 return getCriteria().getPathClasses();
300 }
301
302 /**
303 * Get the a List of Class objects used as hints for a path
304 *
305 * @param aPath the path segment ie: allArticlesInGroup
306 * @return a List o Class objects to be used in SqlStatment
307 * @see org.apache.ojb.broker.QueryTest#testInversePathExpression()
308 */
309 public List getClassesForPath(String aPath)
310 {
311 return getCriteria().getClassesForPath(aPath);
312 }
313 }