blob: cf4badf5635bede16cb553ec2c5d254f0d09c9c2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.internal.queries;
import java.util.*;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.queries.*;
/**
* <p><b>Purpose</b>:
* Mechanism used for all queries by example.
* <p>
* <p><b>Responsibilities</b>:
* Builds a selection criteria for this query given an example object and
* a QueryByExample policy. Works akin to EBQLMechanism which builds the
* selection criteria from an EJBQL string.
*
* @author Stephen McRitchie
* @since 9.0.3.5
*/
public class QueryByExampleMechanism extends ExpressionQueryMechanism {
protected boolean isParsed = false;
/** Used for Query By Example. */
protected Object exampleObject;
protected QueryByExamplePolicy queryByExamplePolicy;
/**
* Initialize the state of the query
* @param query - owner of mechanism
*/
public QueryByExampleMechanism(DatabaseQuery query) {
super(query);
}
/**
* Initialize the state of the query
* @param query - owner of mechanism
* @param expression - selection criteria
*/
public QueryByExampleMechanism(DatabaseQuery query, Expression expression) {
super(query, expression);
}
/**
* INTERNAL:
* In the case of EJBQL or query by example, an expression needs to be
* generated. Build the required expression.
*/
public void buildSelectionCriteria(AbstractSession session) {
if (isParsed() || (getExampleObject() == null)) {
return;
}
ObjectLevelReadQuery query = (ObjectLevelReadQuery)getQuery();
query.checkDescriptor(session);
QueryByExamplePolicy policy = getQueryByExamplePolicy();
if (policy == null) {
policy = new QueryByExamplePolicy();
}
if (query.getReferenceClass().isInstance(getExampleObject())) {
Expression exampleExpression = query.getDescriptor().getObjectBuilder().buildExpressionFromExample(getExampleObject(), policy, query.getExpressionBuilder(), new IdentityHashMap(), session);
if (getSelectionCriteria() != null) {
setSelectionCriteria(getSelectionCriteria().and(exampleExpression));
} else {
setSelectionCriteria(exampleExpression);
}
} else {
throw QueryException.exampleAndReferenceObjectClassMismatch(getExampleObject().getClass(), query.getReferenceClass(), query);
}
setIsParsed(true);
}
/**
* PUBLIC:
* This method returns the current example object. The "example" object is an actual domain object, provided
* by the client, from which an expression is generated.
* This expression is used for a query of all objects from the same class, that match the attribute values of
* the "example" object.
*/
public Object getExampleObject() {
return exampleObject;
}
/**
* PUBLIC:
* When using Query By Example, an instance of QueryByExamplePolicy is used to customize the query.
* The policy is useful when special operations are to be used for comparisons (notEqual, lessThan,
* greaterThan, like etc.), when a certain value is to be ignored, or when dealing with nulls.
*/
public QueryByExamplePolicy getQueryByExamplePolicy() {
return queryByExamplePolicy;
}
/**
* INTERNAL:
* Is this query Parsed
*/
public boolean isParsed() {
return isParsed;
}
/**
* Return true if this is a query by example mechanism
*/
public boolean isQueryByExampleMechanism() {
return true;
}
/**
* PUBLIC:
* Set the example object of the query to be the newExampleObject.
* The example object is used for Query By Example.
* When doing a Query By Example, an instance of the desired object is created, and the fields are filled with
* the values that are required in the result set. From these values the corresponding expression is build
* by TopLink, and the query is executed, returning the set of results.
*/
public void setExampleObject(Object newExampleObject) {
exampleObject = newExampleObject;
}
/**
* INTERNAL:
* Set the isParsed state
*/
public void setIsParsed(boolean newIsParsed) {
isParsed = newIsParsed;
}
/**
* PUBLIC:
* The QueryByExamplePolicy, is a useful to customize the query when Query By Example is used.
* The pollicy will control what attributes should, or should not be included in the query.
* When dealing with nulls, using specail operations (notEqual, lessThan, like, etc.)
* for comparison, or chosing to include certain attributes at all times, it is useful to modify
* the policy accordingly.
*/
public void setQueryByExamplePolicy(QueryByExamplePolicy queryByExamplePolicy) {
this.queryByExamplePolicy = queryByExamplePolicy;
}
}