/*******************************************************************************
* Copyright (c) 1998, 2015 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.tools.workbench.mappingsmodel.query.relational;
import java.util.List;
import org.eclipse.persistence.tools.workbench.mappingsmodel.MWModel;
import org.eclipse.persistence.tools.workbench.mappingsmodel.ProblemConstants;
import org.eclipse.persistence.tools.workbench.mappingsmodel.project.relational.MWRelationalProject;
import org.eclipse.persistence.tools.workbench.mappingsmodel.project.relational.MWRelationalProjectDefaultsPolicy;
import org.eclipse.persistence.tools.workbench.mappingsmodel.query.MWAbstractQuery;
import org.eclipse.persistence.tools.workbench.utility.TriStateBoolean;
import org.eclipse.persistence.tools.workbench.utility.node.Node;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
public final class MWRelationalSpecificQueryOptions
extends MWModel
implements MWRelationalQuery {
/**
* Cache the prepared statement, this requires full parameter binding as well.
*/
private volatile TriStateBoolean cacheStatement;
/**
* Bind all arguments to the SQL statement.
*/
private volatile TriStateBoolean bindAllParameters;
private volatile boolean prepare;
/**
* Query format
*/
private volatile MWQueryFormat queryFormat;
public static XMLDescriptor buildDescriptor() {
XMLDescriptor descriptor = new XMLDescriptor();
descriptor.setJavaClass(MWRelationalSpecificQueryOptions.class);
XMLCompositeObjectMapping formatMapping = new XMLCompositeObjectMapping();
formatMapping.setAttributeName("queryFormat");
formatMapping.setReferenceClass(MWQueryFormat.class);
formatMapping.setXPath("format");
descriptor.addMapping(formatMapping);
XMLDirectMapping bindAllParameters =
(XMLDirectMapping) descriptor.addDirectMapping(
"bindAllParameters",
"getBindAllParametersForTopLink",
"setBindAllParametersForTopLink",
"bind-all-parameters/text()");
bindAllParameters.setNullValue(null);
XMLDirectMapping cacheStatement =
(XMLDirectMapping) descriptor.addDirectMapping(
"cacheStatement",
"getCacheStatementForTopLink",
"setCacheStatementForTopLink",
"cache-statement/text()");
cacheStatement.setNullValue(null);
((XMLDirectMapping) descriptor.addDirectMapping("prepare", "prepare/text()")).setNullValue(Boolean.TRUE);
return descriptor;
}
private MWRelationalSpecificQueryOptions() {
super();
}
MWRelationalSpecificQueryOptions(MWRelationalQuery parent) {
super(parent);
}
protected void initialize(Node parent) {
super.initialize(parent);
this.cacheStatement = TriStateBoolean.UNDEFINED;
this.bindAllParameters = TriStateBoolean.TRUE;
this.prepare = true;
this.queryFormat = new MWExpressionQueryFormat(this);
}
protected void addChildrenTo(List list) {
super.addChildrenTo(list);
list.add(this.queryFormat);
}
public MWAbstractQuery getQuery() {
return (MWAbstractQuery) getParent();
}
void initializeFrom(MWRelationalSpecificQueryOptions oldOptions) {
setCacheStatement(oldOptions.isCacheStatement());
setBindAllParameters(oldOptions.isBindAllParameters());
setPrepare(oldOptions.isPrepare());
setQueryFormat(oldOptions.getQueryFormat());
getQueryFormat().setParent(this);
}
// ************ Bind All Parameters ************
public TriStateBoolean isBindAllParameters() {
return this.bindAllParameters;
}
public void setBindAllParameters(TriStateBoolean bindAllParameters) {
TriStateBoolean oldBindAllParameters = isBindAllParameters();
this.bindAllParameters = bindAllParameters;
firePropertyChanged(BIND_ALL_PARAMETERS_PROPERTY, oldBindAllParameters, bindAllParameters);
}
// ************ Cache Statement ************
public TriStateBoolean isCacheStatement() {
return this.cacheStatement;
}
public void setCacheStatement(TriStateBoolean cacheStatement) {
TriStateBoolean oldCacheStatement = isCacheStatement();
this.cacheStatement = cacheStatement;
firePropertyChanged(CACHE_STATEMENT_PROPERTY, oldCacheStatement, cacheStatement);
}
// ************ prepare ************
public boolean isPrepare() {
return this.prepare;
}
public void setPrepare(boolean prepare) {
boolean oldPrepare = isPrepare();
this.prepare = prepare;
firePropertyChanged(PREPARE_PROPERTY, oldPrepare, prepare);
}
// ************ query format ************
public MWQueryFormat getQueryFormat() {
return this.queryFormat;
}
public String getQueryFormatType() {
return this.queryFormat.getType();
}
public void setQueryFormatType(String queryFormat) {
Object oldValue = getQueryFormatType();
if (oldValue == queryFormat) {
return;
}
if (queryFormat == EXPRESSION_FORMAT) {
setQueryFormatToExpression();
}
else if (queryFormat == AUTO_GENERATED_FORMAT) {
setQueryFormatToAutoGenerated();
}
else if (queryFormat == SQL_FORMAT) {
setQueryFormatToSql();
}
else if (queryFormat == EJBQL_FORMAT) {
setQueryFormatToEjbql();
}
else if (queryFormat == STORED_PROCEDURE_FORMAT) {
setQueryFormatToStoredProcedure();
}
else {
throw new IllegalArgumentException("queryFormatType must be set to : MWQuery.EXPRESSION_FORMAT, MWQuery.AUTO_GENERATED_FORMAT, MWQuery.SQL_FORMAT, MWQuery.STORED_PROCEDURE_FORMAT, or MWQuery.EJBQL_FORMAT");
}
firePropertyChanged(QUERY_FORMAT_TYPE_PROPERTY, oldValue, getQueryFormatType());
}
private void setDefaultQueryFormat() {
setQueryFormat(new MWExpressionQueryFormat(this));
}
MWAutoGeneratedQueryFormat setQueryFormatToAutoGenerated() {
MWAutoGeneratedQueryFormat queryFormat = new MWAutoGeneratedQueryFormat(this);
setQueryFormat(queryFormat);
return queryFormat;
}
void setQueryFormatToEjbql() {
MWStringQueryFormat queryFormat = new MWEJBQLQueryFormat(this);
setQueryFormat(queryFormat);
((MWRelationalQuery) getParent()).formatSetToEjbql();
}
void setQueryFormatToExpression() {
MWExpressionQueryFormat queryFormat = new MWExpressionQueryFormat(this);
setQueryFormat(queryFormat);
}
void setQueryFormatToStoredProcedure() {
MWStoredProcedureQueryFormat queryFormat = new MWStoredProcedureQueryFormat(this);
setQueryFormat(queryFormat);
}
void setQueryFormatToSql() {
MWStringQueryFormat queryFormat = new MWSQLQueryFormat(this);
setQueryFormat(queryFormat);
((MWRelationalQuery) getParent()).formatSetToSql();
}
private void setQueryFormat(MWQueryFormat queryFormat) {
this.queryFormat = queryFormat;
}
public void notifyExpressionsToRecalculateQueryables() {
if (getQueryFormat().getExpression() != null) {
getQueryFormat().getExpression().recalculateQueryables();
}
}
public MWRelationalSpecificQueryOptions getRelationalOptions() {
return this;
}
public void formatSetToEjbql() {
// do nothing
}
public void formatSetToSql() {
// do nothing
}
// ************* Problem Handling **************
protected void addProblemsTo(List currentProblems) {
super.addProblemsTo(currentProblems);
checkCachesStatementButDoesNotBindParameters(currentProblems);
}
private void checkCachesStatementButDoesNotBindParameters(List currentProblems) {
if (isCacheStatement().isTrue()) {
if (isBindAllParameters().isUndefined())
{
MWRelationalProject project = (MWRelationalProject)getProject();
if(!((MWRelationalProjectDefaultsPolicy)project.getDefaultsPolicy()).shouldQueriesBindAllParameters()) {
currentProblems.add(buildProblem(ProblemConstants.DESCRIPTOR_QUERY_CACHES_STATEMENT_WITHOUT_BINDING_PARAMETERS,
getQuery().getName()));
}
}
else if (isBindAllParameters().isFalse()) {
currentProblems.add(buildProblem(ProblemConstants.DESCRIPTOR_QUERY_CACHES_STATEMENT_WITHOUT_BINDING_PARAMETERS,
getQuery().getName()));
}
}
}
// ***************** runtime conversion ***************
void adjustRuntimeQuery(DatabaseQuery runtimeQuery) {
runtimeQuery.setShouldPrepare(isPrepare());
if (!isBindAllParameters().isUndefined()) {
runtimeQuery.setShouldBindAllParameters(isBindAllParameters().booleanValue());
}
if (!isCacheStatement().isUndefined()) {
runtimeQuery.setShouldCacheStatement(isCacheStatement().booleanValue());
}
getQueryFormat().convertToRuntime(runtimeQuery);
}
public void adjustFromRuntime(DatabaseQuery runtimeQuery) {
setPrepare(runtimeQuery.shouldPrepare());
if (!runtimeQuery.shouldIgnoreBindAllParameters())
setBindAllParameters(new TriStateBoolean(runtimeQuery.shouldBindAllParameters()));
else
setBindAllParameters(TriStateBoolean.UNDEFINED);
if (!runtimeQuery.shouldIgnoreCacheStatement())
setCacheStatement(new TriStateBoolean(runtimeQuery.shouldCacheStatement()));
else
setCacheStatement(TriStateBoolean.UNDEFINED);
//must initialize parameters before this in case there is an expression using a parameter
setDefaultQueryFormat();
if (runtimeQuery.getSQLString() != null) {
setQueryFormatToSql();
}
else if (runtimeQuery.getEJBQLString() != null) {
setQueryFormatToEjbql();
}
getQueryFormat().convertFromRuntime(runtimeQuery);
}
// ************ TopLink only methods **************
private Boolean getBindAllParametersForTopLink() {
return this.bindAllParameters.getValue();
}
void setBindAllParametersForTopLink(Boolean bindAllParameters) {
this.bindAllParameters = new TriStateBoolean(bindAllParameters);
}
private Boolean getCacheStatementForTopLink() {
return this.cacheStatement.getValue();
}
private void setCacheStatementForTopLink(Boolean cacheStatement) {
this.cacheStatement = new TriStateBoolean(cacheStatement);
}
}