Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.efaps.db.AbstractQuery Maven / Gradle / Ivy
/*
* Copyright 2003 - 2012 The eFaps Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Revision: $Rev: 7483 $
* Last Changed: $Date: 2012-05-11 11:57:38 -0500 (Fri, 11 May 2012) $
* Last Changed By: $Author: [email protected] $
*/
package org.efaps.db;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.efaps.admin.access.AccessTypeEnums;
import org.efaps.admin.datamodel.Attribute;
import org.efaps.admin.datamodel.SQLTable;
import org.efaps.admin.datamodel.Type;
import org.efaps.db.query.CachedResult;
import org.efaps.db.query.CompleteStatement;
import org.efaps.db.query.WhereClause;
import org.efaps.db.query.WhereClauseAttrEqAttr;
import org.efaps.db.transaction.ConnectionResource;
import org.efaps.util.EFapsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author The eFaps Team
* @version $Id: AbstractQuery.java 7483 2012-05-11 16:57:38Z [email protected] $
* TODO: description
*/
//CHECKSTYLE:OFF
@Deprecated
public abstract class AbstractQuery
{
/**
* Logging instance used in this class.
*/
private static final Logger LOG = LoggerFactory.getLogger(AbstractQuery.class);
private boolean checkAccess = false;
private CachedResult cachedResult = null;
protected Type type = null;
ArrayList types = new ArrayList();
/**
* The instance variable stores the order of the select types.
*
* @see #getSelectTypesOrder
*/
private final List selectTypesOrder = new ArrayList();
/**
* The instance variable stores all single join elements.
*
* @see #getJoinElements
*/
private final List joinElements = new ArrayList();
/**
* The instance variable maps expressions to join elements.
*/
private final Map mapJoinElements = new HashMap();
/**
* The instance variable stores the main instance of the join element. The
* main join element is that join elment which stores the direct selectable
* attribute values.
*
* @see #getMainJoinElement
*/
private final JoinElement mainJoinElement = new JoinElement();
/**
* The instance variable stores all main selected types. The key in this map
* is the main table.
*
* @see #getSelectTypes
*/
private final Map mainSelectTypes = new HashMap();
/**
* The instance variable stores all main where clauses. This where clauses
* must be used by all join elements! This is a different behaviour than the
* where clauses for a join element.
*
* @see #getMainWhereClauses
*/
private final List mainWhereClauses = new ArrayList();
/**
* WHereClause for the company form the context. (if given)
*/
private WhereClause companyClause;
/**
* Should the child types als be expanded?
*
* @see #isExpandChildTypes
* @see #setExpandChildTypes
*/
private boolean expandChildTypes = true;
/**
* The instance variable stores all select expressions and their relations
* to attributes for this query.
*
* @see #getAllSelExprMap
*/
private final Map allSelExprMap = new HashMap();
/**
* The instance variable stores all OID select expressions and their
* relations to attributes for this query.
*
* @see #getAllOIDSelExprMap
*/
private final Map allOIDSelExprMap = new HashMap();
private final Map oid2access = new HashMap();
// ///////////////////////////////////////////////////////////////////////////
/**
* The instance destructor calls the instance method {@link #close} to close
* the SQL statement if not happend till now. The exception thrown from
* method {@link #close} is catched and no error is thrown from this
* destructor.
*
* @see #close
*/
@Override
public void finalize()
{
try {
close();
} catch (final Exception e) {
}
}
/**
* The method closes the SQL statement. The method must be always called to
* close the query!
*
* @see #statement
*/
public void close() throws EFapsException
{
/*
* if (getStatement()!=null) { try { getStatement().close(); } catch
* (Exception e) { throw e; } finally { setStatement(null); } }
*/
}
/**
* The method adds an expression to the selectstatement.
*
* @param _expression expression to add
*/
public void addSelect(final String _expression) throws EFapsException
{
addSelect(false, _expression, this.type, _expression);
}
/**
* @param _isOID must be set to true is select expression selects the
* OID of the business object.
* @param _key key to store the select expression in the select map
* expression
* @param _attr attribute itself which must be selected
*/
protected void addSelect(final boolean _isOID, final Object _key, final Attribute _attr) throws EFapsException
{
getSelectType(_attr.getParent()).addSelect(_isOID, _key, _attr);
}
/**
* @param _isOID must be set to true is select expression selects the
* OID of the business object.
* @param _key key to store the select expression in the select map
* expression
* @param _expression
*/
protected void addSelect(final boolean _isOID, final Object _key, final Type _type, final String _expression)
throws EFapsException
{
getSelectType(_type).addSelect(_isOID, _key, _expression);
}
/**
* The instance method adds types in the order of the expand.
*
* @param _type type to add in the correct order
* @see #addTypes4Order(Type,boolean)
*/
protected void addTypes4Order(final Type _type)
{
addTypes4Order(_type, false);
}
/**
* The instance method adds types in the order of the expand.
*
* @param _type type to add in the correct order
* @param _nullAllowed type can be null
* @see #selectTypesOrder
* @see #getSelectType
*/
protected void addTypes4Order(final Type _type, final boolean _nullAllowed)
{
final SelectType selectType = getSelectType(_type);
selectType.setOrderIndex(getSelectTypesOrder().size());
selectType.setNullAllowed(_nullAllowed);
getSelectTypesOrder().add(selectType);
}
/**
* Setter method for instance variable {@link #companyClause}.
*
* @param _companyClause value for instance variable {@link #companyClause}
*/
protected void setCompanyClause(final WhereClause _companyClause)
{
this.companyClause = _companyClause;
}
// ///////////////////////////////////////////////////////////////////////////
/**
* The instance method returns for the given type the select type class
* instance of {@link #SelectType}.
*
* @param _type type for which the instance of {@link #SelectType} is
* searched
* @see #addTypes4Order
* @see #selectTypesOrder
*/
public SelectType getSelectType(final Type _type)
{
SelectType selectType = getMainSelectTypes().get(_type);
if (selectType == null) {
selectType = new SelectType(getMainJoinElement(), _type, getSelectTypesOrder().size());
getMainSelectTypes().put(_type, selectType);
for (final JoinElement elm : getJoinElements()) {
elm.addSelectType(selectType);
}
}
return selectType;
}
/**
* The method returns the size of the select expressions.
*
* @return size of the select expressions
* @see #getExpressions
*/
public int selectSize()
{
int ret = 0;
for (final JoinElement elm : getJoinElements()) {
ret += elm.selectSize();
}
return ret;
}
// ///////////////////////////////////////////////////////////////////////////
/**
* The instance method returns for the given key the attribute value.
*
* @param _key key for which the attribute value must returned
* @return atribute value for given key
*/
public Object get(final String _key) throws EFapsException
{
Object ret = null;
if (hasAccess(_key)) {
final SelExpr2Attr selExpr = getAllSelExprMap().get(_key);
if (selExpr != null) {
ret = selExpr.getAttrValue();
}
}
return ret;
}
private boolean hasAccess(final String _key) throws EFapsException
{
boolean hasAccess = true;
if (this.checkAccess) {
Instance instance = null;
String oid = null;
final SelExpr2Attr selExpr = getAllOIDSelExprMap().get(_key);
if (selExpr != null) {
oid = (String) selExpr.getAttrValue();
}
if ((oid != null) && !oid.equals("0.0")) {
instance = Instance.get(oid);
} else {
instance = getInstance(this.type);
}
if (instance != null) {
if (this.oid2access.containsKey(instance.getOid())) {
hasAccess = this.oid2access.get(instance.getOid());
} else {
hasAccess = instance.getType().hasAccess(instance, AccessTypeEnums.SHOW.getAccessType());
this.oid2access.put(instance.getOid(), hasAccess);
}
}
}
return hasAccess;
}
/**
* The instance method returns for the given key the atribute.
*
* @param _key key for which the attribute value must returned
* @return attribute for given key
*/
public Attribute getAttribute(final String _key) throws Exception
{
Attribute ret = null;
final SelExpr2Attr selExpr = getAllSelExprMap().get(_key);
if (selExpr != null) {
ret = selExpr.getAttribute();
}
return ret;
}
/**
* All object ids for one row are returned. The objects id defined in the
* expand are returned in the same order.
*
* @return list of instances from the expand
*/
public List getExpandInstances() throws EFapsException
{
final List ret = new ArrayList();
for (final Type type : this.types) {
ret.add(Instance.get(getOID(type)));
}
return ret;
}
/**
* @param _key key for which the object id value must returned
* @return object id for given key
*/
protected String getOID(final Object _key) throws EFapsException
{
String ret = null;
final SelExpr2Attr selExpr = getAllOIDSelExprMap().get(_key);
if (selExpr != null) {
ret = (String) selExpr.getAttrValue();
}
return ret;
}
/**
* The instance method returns the instance for the current selected row.
*
* @param _type
* TODO: why is in this way implemented (other way than method getOID above)
*/
protected Instance getInstance(final Type _type) throws EFapsException
{
final SelectType selectType = getMainSelectTypes().get(_type);
if (selectType == null) {
AbstractQuery.LOG.error("Type '" + _type.getName() + "' is not selected! New Instance can not created!");
throw new EFapsException(getClass(), "getInstance.TypeNotSelected", _type.getName());
}
// String id =
// getResultSet().getString(selectType.getIndexId().intValue());
final String id = this.cachedResult.getString(selectType.getIndexId().intValue());
Type type = _type;
if (selectType.getIndexType() != null) {
// long typeId =
// getResultSet().getLong(selectType.getIndexType().intValue());
final long typeId = this.cachedResult.getLong(selectType.getIndexType().intValue());
type = Type.get(typeId);
}
return Instance.get(type, id);
}
// ///////////////////////////////////////////////////////////////////////////
/**
* The instance method executes the query.
*/
public void execute() throws EFapsException
{
this.checkAccess = true;
executeWithoutAccessCheck();
}
/**
* The instance method executes the query.
*/
public void executeWithoutAccessCheck() throws EFapsException
{
if (getMainJoinElement().selectSize() > 0) {
int incSelIndex = 0;
this.cachedResult = new CachedResult();
for (final JoinElement joinElement : getJoinElements()) {
joinElement.setIncSelIndex(incSelIndex);
// warum diese Ueberpruefung? weil der join jeweils die spalte
// mit der id zum vergleichen rauschmeisst!!
if (incSelIndex == 0) {
incSelIndex += joinElement.getSelectExpressions().size();
} else {
incSelIndex += joinElement.getSelectExpressions().size() - 1;
}
final CompleteStatement completeStatement = new CompleteStatement();
joinElement.appendStatement(completeStatement, -1, isExpandChildTypes());
for (final SelectType selectType : getSelectTypesOrder()) {
if (selectType.isNullAllowed()) {
completeStatement.appendUnion();
joinElement.appendStatement(completeStatement, selectType.getOrderIndex(),
isExpandChildTypes());
}
}
executeOneCompleteStmt(completeStatement, joinElement.getMatchColumn());
}
for (final SelExpr2Attr selExpr : getAllSelExprMap().values()) {
selExpr.initSelectIndex();
}
for (final SelExpr2Attr selExpr : getAllOIDSelExprMap().values()) {
selExpr.initSelectIndex();
}
}
this.cachedResult.beforeFirst();
}
/**
* The instance method executes exact one complete statement and populates
* the result in the cached result {@link #cachedResult}.
*
* @param _complStmt complete statement instance to execute
* @param _matchColumn column in the complete statement (result set) used to
* as key to compare in the cached result
*/
private void executeOneCompleteStmt(final CompleteStatement _complStmt, final int _matchColumn)
throws EFapsException
{
ConnectionResource con = null;
try {
con = Context.getThreadContext().getConnectionResource();
if (AbstractQuery.LOG.isTraceEnabled()) {
AbstractQuery.LOG.trace(_complStmt.getStatement().toString());
}
final Statement stmt = con.getConnection().createStatement();
final ResultSet rs = stmt.executeQuery(_complStmt.getStatement().toString());
this.cachedResult.populate(rs, _matchColumn, 0);
rs.close();
stmt.close();
con.commit();
} catch (final EFapsException e) {
if (con != null) {
con.abort();
}
throw e;
} catch (final Throwable e) {
if (con != null) {
con.abort();
}
// TODO: exception eintragen!
e.printStackTrace();
throw new EFapsException(getClass(), "executeOneCompleteStmt.Throwable");
}
}
/**
* @return true if a new row is selected and exists, otherwise
* false
*/
public boolean next()
{
return this.cachedResult.next();
}
// ///////////////////////////////////////////////////////////////////////////
/**
* This is the getter method for instance variable {@link #selectTypesOrder}
* .
*
* @return value of instance variable {@link #selectTypesOrder}
* @see #selectTypesOrder
*/
public List getSelectTypesOrder()
{
return this.selectTypesOrder;
}
/**
* This is the getter method for the instance variable {@link #type}.
*
* @return value of instance variable {@link #type}
*/
public Type getType()
{
return this.type;
}
/**
* This is the getter method for instance variable {@link #joinElements}.
*
* @return value of instance variable {@link #joinElements}
* @see #joinElements
*/
protected List getJoinElements()
{
return this.joinElements;
}
/**
* This is the getter method for instance variable {@link #mapJoinElements}.
*
* @return value of instance variable {@link #mapJoinElements}
* @see #mapJoinElements
*/
protected Map getMapJoinElements()
{
return this.mapJoinElements;
}
/**
* This is the getter method for instance variable {@link #mainJoinElement}.
*
* @return value of instance variable {@link #mainJoinElement}
* @see #mainJoinElement
*/
protected JoinElement getMainJoinElement()
{
return this.mainJoinElement;
}
/**
* This is the getter method for instance variable {@link #mainSelectTypes}.
*
* @return value of instance variable {@link #mainSelectTypes}
* @see #mainSelectTypes
*/
private Map getMainSelectTypes()
{
return this.mainSelectTypes;
}
/**
* This is the getter method for instance variable {@link #mainWhereClauses}
* .
*
* @return value of instance variable {@link #mainWhereClauses}
* @see #mainWhereClauses
*/
protected List getMainWhereClauses()
{
return this.mainWhereClauses;
}
/**
* This is the getter method for instance variable {@link #expandChildTypes}
* .
*
* @return value of instance variable {@link #expandChildTypes}
* @see #expandChildTypes
* @see #setExpandChildTypes
*/
protected boolean isExpandChildTypes()
{
return this.expandChildTypes;
}
/**
* This is the setter method for instance variable {@link #expandChildTypes}
* .
*
* @param _expandChildTypes new value for instance variable
* {@link #expandChildTypes}
* @see #expandChildTypes
* @see #isExpandChildTypes
*/
public void setExpandChildTypes(final boolean _expandChildTypes)
{
this.expandChildTypes = _expandChildTypes;
}
/**
* This is the getter method for instance variable {@link #allSelExprMap}.
*
* @return value of instance variable {@link #allSelExprMap}
* @see #allSelExprMap
*/
protected Map getAllSelExprMap()
{
return this.allSelExprMap;
}
/**
* This is the getter method for instance variable {@link #allOIDSelExprMap}
* .
*
* @return value of instance variable {@link #allOIDSelExprMap}
* @see #allOIDSelExprMap
*/
protected Map getAllOIDSelExprMap()
{
return this.allOIDSelExprMap;
}
/**
* The class is used to make one join select.
*/
public class JoinElement
{
private JoinElement()
{
if (getMainSelectTypes() != null) {
getSelectTypes().addAll(getMainJoinElement().getSelectTypes());
}
getJoinElements().add(this);
}
protected void appendStatement(final CompleteStatement _completeStatement, final int _orderIndex,
final boolean _childTypes) throws EFapsException
{
_completeStatement.append("select distinct ");
appendSelectExpressions(_completeStatement, _orderIndex);
appendFrom(_completeStatement, _orderIndex);
appendWhereClause(_completeStatement, _orderIndex, _childTypes);
for (final SelectType selectType : getSelectTypesOrder()) {
if (selectType.isNullAllowed() && (_orderIndex < 0 || selectType.getOrderIndex() < _orderIndex)) {
_completeStatement.appendUnion();
_completeStatement.append("select distinct ");
appendSelectExpressions(_completeStatement, selectType.getOrderIndex());
appendFrom(_completeStatement, selectType.getOrderIndex());
appendWhereClause(_completeStatement, selectType.getOrderIndex(), _childTypes);
}
}
}
/**
* Appends all select expressions from this one join element to the
* comlete statement.
*
* @param _completeStatement complete SQL statement to select values
* @param _orderIndex ????????????????????
*/
private void appendSelectExpressions(final CompleteStatement _completeStatement, final int _orderIndex)
{
final Iterator iter = getSelectExpressions().iterator();
while (iter.hasNext()) {
final SQLSelectExpression selectExpr = iter.next();
if ((_orderIndex < 0) || selectExpr.getSelectType().getOrderIndex() < _orderIndex) {
_completeStatement.append(selectExpr.getExpression());
} else {
_completeStatement.append(selectExpr.getNullString());
}
if (iter.hasNext()) {
_completeStatement.append(",");
}
}
}
private void appendFrom(final CompleteStatement _completeStatement, final int _orderIndex)
{
for (final SelectType selectType : getSelectTypes()) {
if ((_orderIndex < 0) || (selectType.getOrderIndex() < _orderIndex)) {
selectType.appendFrom(_completeStatement);
}
}
}
private void appendWhereClause(final CompleteStatement _completeStatement, final int _orderIndex,
final boolean _childTypes) throws EFapsException
{
final Iterator typeIter = getSelectTypes().iterator();
while (typeIter.hasNext()) {
final SelectType selectType = typeIter.next();
if (_orderIndex < 0 || selectType.getOrderIndex() < _orderIndex) {
_completeStatement.appendWhereAnd();
selectType.appendTypeWhereClause(_completeStatement, _childTypes);
}
}
for (final WhereClause whereClause : this.whereClauses) {
whereClause.appendWhereClause(_completeStatement, _orderIndex);
}
if (AbstractQuery.this.companyClause != null) {
AbstractQuery.this.companyClause.appendWhereClause(_completeStatement, _orderIndex);
}
if (getMainWhereClauses().size() > 0) {
_completeStatement.appendWhereAnd();
_completeStatement.appendWhere();
_completeStatement.append(" (");
for (final WhereClause whereClause : getMainWhereClauses()) {
whereClause.appendWhereClause(_completeStatement, _orderIndex);
}
_completeStatement.append(" )");
}
}
/**
* The method returns the size of the select expressions.
*
* @return size of the select expressions
* @see #getExpressions
*/
public int selectSize()
{
return getExpressions().size();
}
/**
* Returns for the given expression the select expression. The select
* expression is tested for uniqueness (and if defined already reused).
*
* @param _selectType instance of SelectType
* @param _sqlTable SQL table which is selected
* @param _aliasTableName alias table name (defined in the from clause)
* @param _columnNAme column name within the SQL table
* @param _isId is the selected column an internal eFaps id? if true,
* the null value select is "0", otherwise the null value
* select is direct evaluated from the table information
* @return new select expression
*/
private SQLSelectExpression getSelectExpression(final SelectType _selectType, final SQLTable _sqlTable,
final int _aliasIndex, final String _columnName, final boolean _isId)
{
final String sqlExpr = new StringBuilder().append(_sqlTable.getSqlTable()).append(_aliasIndex).append('.')
.append(_columnName).toString();
SQLSelectExpression selectExpr = getExpressions().get(sqlExpr);
if (selectExpr == null) {
final String nullString = _isId ? "0" : _sqlTable.getTableInformation().getColInfo(_columnName)
.getNullValueSelect();
selectExpr = new SQLSelectExpression(getExpressions().size() + 1, sqlExpr, this, _selectType,
nullString);
getExpressions().put(sqlExpr, selectExpr);
getSelectExpressions().add(selectExpr);
}
return selectExpr;
}
/**
* @param _aliasIndex index used to create the sql prefix
* @param _selectType instance of SelectType
* @param _isOID the select statement is an OID select and must be
* stored in the OID map
* @param _key key used to store in the (OID) map
* @param _attribute attribute to select
* @see #getSelectExpression
*/
private void addSelectAttribute(final int _aliasIndex, final SelectType _selectType, final boolean _isOID,
final Object _key, final Attribute _attr)
{
final ArrayList selectExprs = new ArrayList();
if (_attr.getTable() != null) {
_selectType.getTypeTableNames().add(_attr.getTable());
for (final String _sqlColName : _attr.getSqlColNames()) {
final SQLSelectExpression selectExpr = getSelectExpression(_selectType, _attr.getTable(),
_aliasIndex, _sqlColName, false);
// System.out.println("selectExprs.add="+selectExpr);
selectExprs.add(selectExpr);
}
}
final SelExpr2Attr selExpr2Attr = new SelExpr2Attr(_attr, selectExprs);
// System.out.println("selectExprs="+selExpr2Attr);
if (_isOID) {
getAllOIDSelExprMap().put(_key, selExpr2Attr);
} else {
getAllSelExprMap().put(_key, selExpr2Attr);
}
}
/**
* The instance method creates a new instance of {@link #SelectType} add
* adds them to {@link #selectTypesOrder}.
*
* @param _type type to add in the correct order
* @param _nullAllowed type can be null
* @return new created instance of {@link #SelectType}
* @see #selectTypesOrder
*/
protected SelectType getNewSelectType(final Type _type, final boolean _nullAllowed)
{
final SelectType selectType = new SelectType(this, _type, (getSelectTypesOrder().size() + 1000));
selectType.setOrderIndex(getSelectTypesOrder().size() + 1000);
selectType.setNullAllowed(_nullAllowed);
getSelectTypesOrder().add(selectType);
addSelectType(selectType);
return selectType;
}
private void addWhere(final SelectType _selectType1, final Attribute _attr1, final SelectType _selectType2,
final Attribute _attr2) throws EFapsException
{
this.whereClauses.add(new WhereClauseAttrEqAttr(_selectType1, _attr1, _selectType2, _attr2));
}
private void addSelectType(final SelectType _selectType)
{
getSelectTypes().add(_selectType);
}
// /////////////////////////////////////////////////////////////////////////
private final List whereClauses = new ArrayList();
/**
* The instance variable stores all select types of the select
* statement.
*
* @see #getTableNames
*/
private final Set selectTypes = new HashSet();
/**
* This is the instance variable to hold all expressions. The SQL
* statement is stores as key, the value is the index of the expression
* in the select statement. This is used that an expression is only once
* in a select statement (uniqueness)!.
*
* @see #getExpressions
*/
private final Map expressions = new HashMap();
/**
* The instance variable stores all select expressions.
*
* @see #getSelectExpressions
*/
private final List selectExpressions = new ArrayList();
/**
* The instance variable stores the order of the select types. The
* information is needed if an expand is made (and in an expand a null
* value is possible!).
*
* @see #getSelectTypesOrder
*/
private final List selectTypesOrder = new ArrayList();
/**
* The instance variable stores the column index of this join element.
* The index is the select expression used to join with other select
* statements. The default value is 1 for the first column.
*
* @see #getMatchColumn
* @see #setMatchColumn
*/
private int matchColumn = 1;
/**
* The instance variable stores the number of previous select
* epxressions used to calculate the index of select expressions of this
* join element in the complete join.
*
* @see #getIncSelIndex
* @see #setIncSelIndex
*/
private int incSelIndex = 0;
// /////////////////////////////////////////////////////////////////////////
/**
* This is the getter method for instance variable {@link #selectTypes}.
*
* @return value of instance variable {@link #selectTypes}
* @see #selectTypes
*/
private Set getSelectTypes()
{
return this.selectTypes;
}
/**
* This is the getter method for instance variable {@link #expressions}.
*
* @return value of instance variable {@link #expressions}
* @see #expressions
*/
protected Map getExpressions()
{
return this.expressions;
}
/**
* This is the getter method for instance variable
* {@link #selectExpressions}.
*
* @return value of instance variable {@link #selectExpressions}
* @see #selectExpressions
*/
protected List getSelectExpressions()
{
return this.selectExpressions;
}
/**
* This is the getter method for instance variable
* {@link #selectTypesOrder}.
*
* @return value of instance variable {@link #selectTypesOrder}
* @see #selectTypesOrder
*/
public List getSelectTypesOrder()
{
return this.selectTypesOrder;
}
/**
* This is the setter method for instance variable {@link #matchColumn}.
*
* @param _orderIndex new value for instance variable
* {@link #matchColumn}
* @see #matchColumn
* @see #getMatchColumn
*/
private void setMatchColumn(final int _matchColumn)
{
this.matchColumn = _matchColumn;
}
/**
* This is the getter method for instance variable {@link #matchColumn}.
*
* @return value of instance variable {@link #matchColumn}
* @see #matchColumn
* @see #setMatchColumn
*/
public int getMatchColumn()
{
return this.matchColumn;
}
/**
* This is the setter method for instance variable {@link #incSelIndex}.
*
* @param _orderIndex new value for instance variable
* {@link #incSelIndex}
* @see #incSelIndex
* @see #getIncSelIndex
*/
private void setIncSelIndex(final int _incSelIndex)
{
this.incSelIndex = _incSelIndex;
}
/**
* This is the getter method for instance variable {@link #incSelIndex}.
*
* @return value of instance variable {@link #incSelIndex}
* @see #incSelIndex
* @see #setIncSelIndex
*/
private int getIncSelIndex()
{
return this.incSelIndex;
}
}
/**
* The class stores the relation between an select expression and an
* attribute.
*/
private class SelExpr2Attr
{
/**
* Stores the attribute.
*
* @see #getAttribute
* @see #setAttribute
*/
private Attribute attribute = null;
/**
* Stores all select expression.
*
* @see #getSelExpr
* @see #setSelExpr
*/
private ArrayList selExprs = null;
/**
* Stores all the indexes of the SQL select expression where the values
* of the attribute are found (in the same order than defined in the
* attribute).
*
* @see #getIndexes
*/
private final ArrayList indexes = new ArrayList();
// /////////////////////////////////////////////////////////////////////////
/**
* Constructor
*
* @param _attr attribute
* @param _selExprs select expressions
*/
private SelExpr2Attr(final Attribute _attr, final ArrayList _selExprs)
{
setAttribute(_attr);
setSelExprs(_selExprs);
}
/**
* After execution of the query, the indexes where that attribute values
* stands, could be initialised and used by {@link #getAttrValue}.
*/
protected void initSelectIndex()
{
// System.out.println("~~~~~~~~~~~~++initSelectIndex+"+getSelExprs());
for (final SQLSelectExpression selExpr : getSelExprs()) {
final int index = selExpr.getJoinElement().getIncSelIndex() + selExpr.getIndex();
// System.out.println("~~~~~~~~~~~~++index="+index);
getIndexes().add(new Integer(index));
}
// System.out.println("~~~~~~~~~~~~++getIndexes()="+getIndexes());
}
/**
* @return attribute value with the value returned from the select
* expression
*/
protected Object getAttrValue() throws EFapsException
{
if (getAttribute() == null) {
throw new EFapsException(getClass(), "SelectExpression.get.NoAttribute");
}
Object ret = null;
try {
ret = getAttribute().readDBValue(AbstractQuery.this.cachedResult, getIndexes());
} catch (final Exception e) {
throw new EFapsException(getClass(), "getAttrValue.CouldNotReadValue", e);
}
return ret;
}
// /////////////////////////////////////////////////////////////////////////
/**
* This is the getter method for instance variable {@link #attribute}.
*
* @return value of instance variable {@link #attribute}
* @see #attribute
* @see #setAttribute
*/
public Attribute getAttribute()
{
return this.attribute;
}
/**
* This is the setter method for instance variable {@link #attribute}.
*
* @param _attribute new value for instance variable {@link #attribute}
* @see #attribute
* @see #getAttribute
*/
private void setAttribute(final Attribute _attribute)
{
this.attribute = _attribute;
}
/**
* This is the getter method for instance variable {@link #selExprs}.
*
* @return value of instance variable {@link #selExprs}
* @see #selExprs
* @see #setSelExprs
*/
public ArrayList getSelExprs()
{
return this.selExprs;
}
/**
* This is the setter method for instance variable {@link #selExprs}.
*
* @param _selExpr new value for instance variable {@link #selExprs}
* @see #selExprs
* @see #getSelExprs
*/
private void setSelExprs(final ArrayList _selExprs)
{
this.selExprs = _selExprs;
}
/**
* This is the getter method for instance variable {@link #indexes}.
*
* @return value of instance variable {@link #indexes}
* @see #indexes
*/
public ArrayList getIndexes()
{
return this.indexes;
}
}
// ###########################################################################
// ###########################################################################
// ###########################################################################
// ###########################################################################
// ###########################################################################
private class SQLSelectExpression
{
/**
*
*/
private final int index;
/**
*
*/
private final String expression;
/**
*
*/
private final JoinElement joinElement;
/**
*
*/
private final SelectType selectType;
/**
*
*/
private final String nullString;
/**
*
*/
protected SQLSelectExpression(final int _index, final String _expression, final JoinElement _joinElement,
final SelectType _selectType, final String _nullString)
{
this.index = _index;
this.expression = _expression;
this.joinElement = _joinElement;
this.selectType = _selectType;
this.nullString = _nullString;
}
// /////////////////////////////////////////////////////////////////////////
/**
* This is the getter method for instance variable {@link #index}.
*
* @return value of instance variable {@link #index}
* @see #index
*/
public int getIndex()
{
return this.index;
}
/**
* This is the getter method for instance variable {@link #expression}.
*
* @return value of instance variable {@link #expression}
* @see #expression
*/
public String getExpression()
{
return this.expression;
}
/**
* This is the getter method for instance variable {@link #joinElement}.
*
* @return value of instance variable {@link #joinElement}
* @see #joinElement
*/
public JoinElement getJoinElement()
{
return this.joinElement;
}
/**
* This is the getter method for instance variable {@link #selectType}.
*
* @return value of instance variable {@link #selectType}
* @see #selectType
*/
public SelectType getSelectType()
{
return this.selectType;
}
/**
* This is the getter method for instance variable {@link #nullString}.
*
* @return value of instance variable {@link #nullString}
* @see #nullString
*/
public String getNullString()
{
return this.nullString;
}
}
// ###########################################################################
// ###########################################################################
// ###########################################################################
// ###########################################################################
// ###########################################################################
public class SelectType
{
/**
* The string instance variable stores the table names of the select
* statement of this selected type.
*
* @see #getTableNames
*/
private final Set typeTableNames = new HashSet();
/**
* The instance variable stores the index of the order.
*
* @see #getOrderIndex
* @see #setOrderIndex
*/
private int orderIndex = 0;
final JoinElement joinElement;
/**
* The instance variable stores the type this class instance is
* representing.
*
* @see #getType
*/
private final Type type;
/**
* The instance variable stores the index number of the type in the
* select expressions of the table. The index number is the number of
* the SQL table (from TABLENAME TABLENAME+INDEX_NUMBER
)
* defined in the from statement of the complete SQL select statement.
*/
private final int typeIndex;
/**
* The instance method stores the index of the id of this type in the
* SQL table within the SQL select statement.
*
* @see #getIndexId
* @see #setIndexId
*/
private final Integer indexId;
/**
* The instance method stores the index of the type id of this type in
* the SQL table within the SQL select statement.
*
* @see #getIndexId
*/
private final Integer indexType;
/**
* The instance variable stores if the type can be null (and so the link
* to a type must not be defined...).
*
* @see #isNullAllowed
* @see #setNullAllowed
*/
private boolean nullAllowed = false;
private SelectType(final JoinElement _joinElement, final Type _type, final int _typeIndex)
{
this.joinElement = _joinElement;
this.type = _type;
this.typeIndex = _typeIndex;
getTypeTableNames().add(getType().getMainTable());
SQLSelectExpression selectExpr = this.joinElement.getSelectExpression(this, getType().getMainTable(),
this.typeIndex, getType().getMainTable().getSqlColId(), true);
this.indexId = selectExpr.getIndex();
this.joinElement.setMatchColumn(selectExpr.getIndex());
if (getType().getMainTable().getSqlColType() != null) {
selectExpr = this.joinElement.getSelectExpression(this, getType().getMainTable(), this.typeIndex,
getType().getMainTable().getSqlColType(), true);
this.indexType = selectExpr.getIndex();
} else {
this.indexType = null;
}
}
/**
* @param _isOID must be set to true is select expression selects
* the OID of the object.
* @param _key key to store the select expression in the select map
* expression
* @param _attr attribute itself which must be selected
*/
protected void addSelect(final boolean _isOID, final Object _key, final Attribute _attr)
{
this.joinElement.addSelectAttribute(this.typeIndex, this, _isOID, _key, _attr);
}
/**
* @param _isOID must be set to true is select expression selects
* the OID of the business object.
* @param _key key to store the select expression in the select map
* expression
* @param _expression expression itself which must be selected
* TODO: EFapsException Property
*/
protected void addSelect(final boolean _isOID,
final Object _key,
final String _expression)
throws EFapsException
{
// System.out.println("AbstractQuery.addSelect("+_isOID+","+_key+","+_expression+")");
if ((_expression != null) && !"".equals(_expression)) {
if (_expression.indexOf('.') >= 0) {
final JoinElement elm = new JoinElement();
final StringTokenizer tokens = new StringTokenizer(_expression, ".");
final String link = tokens.nextToken();
final Attribute attr = getType().getAttribute(link);
if (attr == null) {
AbstractQuery.LOG.error("Link for '" + link
+ "' does not exists on type " + "'" + getType().getName() + "'");
throw new EFapsException(getClass(), "addSelect.LinkDoesNotExists", link, getType().getName());
}
// add new link type
final Type linkType = attr.getLink();
if (linkType == null) {
AbstractQuery.LOG.error("For Link '" + link + "' of type " + "'" + getType().getName() + "' "
+ "the type is not defined.");
throw new EFapsException(getClass(), "addSelect.LinkDoesNotExists", link, getType().getName());
}
final SelectType selectType = elm.getNewSelectType(linkType, !attr.isRequired());
final Attribute attrFromLink = linkType.getAttribute(tokens.nextToken());
selectType.addSelect(_isOID, _key, attrFromLink);
elm.addWhere(this, attr, selectType, linkType.getAttribute("ID"));
// System.out.println("selectType.index="+selectType.getTypeIndex());
// for ID selection
final SQLSelectExpression selectExpr = elm.getSelectExpression(this, getType().getMainTable(),
this.typeIndex, getType().getMainTable().getSqlColId(), true);
elm.setMatchColumn(selectExpr.getIndex());
getTypeTableNames().add(attr.getTable());
getMapJoinElements().put(_expression, elm);
} else {
final Attribute attr = getType().getAttribute(_expression);
if (attr == null) {
AbstractQuery.LOG.error("attribute '" + _expression + "' for type " + "'" + getType().getName()
+ "' not found");
throw new EFapsException(getClass(), "addSelect.AttributeNotFound", _expression, getType()
.getName());
}
addSelect(_isOID, _key, attr);
}
}
}
/**
* Adds the tables from this attribute in a where clause.
*/
public void add4Where(final Attribute _attr)
{
for (final String sqlColName : _attr.getSqlColNames()) {
getTypeTableNames().add(_attr.getTable());
this.joinElement.getSelectExpression(this, _attr.getTable(), this.typeIndex, sqlColName, false);
}
}
protected void appendFrom(final CompleteStatement _completeStatement)
{
for (final SQLTable table : getTypeTableNames()) {
_completeStatement.appendFrom(table.getSqlTable()).append(" ").append(table.getSqlTable()).append(
this.typeIndex);
}
}
/**
* @param _childTypes also child types are allowed
*/
protected void appendTypeWhereClause(final CompleteStatement _completeStatement, final boolean _childTypes)
{
if (getType().getMainTable().getSqlColType() != null) {
if (_childTypes) {
_completeStatement.appendWhereAnd();
_completeStatement.appendWhere(getType().getMainTable().getSqlTable()).appendWhere(this.typeIndex)
.appendWhere(".");
_completeStatement.appendWhere(getType().getMainTable().getSqlColType());
_completeStatement.appendWhere(" in (");
_completeStatement.appendWhere(getType().getId());
for (final Type child : getType().getChildTypes()) {
_completeStatement.appendWhere(",").appendWhere(child.getId());
}
_completeStatement.appendWhere(")");
} else {
_completeStatement.appendWhereAnd();
_completeStatement.appendWhere(getType().getMainTable().getSqlTable()).appendWhere(this.typeIndex)
.appendWhere(".");
_completeStatement.appendWhere(getType().getMainTable().getSqlColType());
_completeStatement.appendWhere("=");
_completeStatement.appendWhere(getType().getId());
}
}
final Iterator iter = getTypeTableNames().iterator();
final SQLTable table = iter.next();
while (iter.hasNext()) {
_completeStatement.appendWhereAnd();
_completeStatement.appendWhere(table.getSqlTable()).appendWhere(this.typeIndex).appendWhere(".")
.appendWhere(table.getSqlColId());
_completeStatement.appendWhere("=");
final SQLTable nextTable = iter.next();
_completeStatement.appendWhere(nextTable.getSqlTable()).appendWhere(this.typeIndex).appendWhere(".")
.appendWhere(nextTable.getSqlColId());
}
}
/**
* This is the getter method for instance variable {@link #typeIndex}.
*
* @return value of instance variable {@link #typeIndex}
* @see #typeIndex
*/
public int getTypeIndex()
{
return this.typeIndex;
}
/**
* This is the getter method for instance variable {@link #type}.
*
* @return value of instance variable {@link #type}
* @see #type
* @see #setType
*/
public Type getType()
{
return this.type;
}
/**
* This is the getter method for instance variable {@link #indexType}.
*
* @return value of instance variable {@link #indexType}
* @see #indexType
* @see #setIndexType
*/
protected Integer getIndexType()
{
return this.indexType;
}
/**
* This is the getter method for instance variable {@link #indexId}.
*
* @return value of instance variable {@link #indexId}
* @see #indexId
* @see #setIndexId
*/
protected Integer getIndexId()
{
return this.indexId;
}
/**
* This is the getter method for instance variable
* {@link #typeTableNames}.
*
* @return value of instance variable {@link #typeTableNames}
* @see #typeTableNames
*/
protected Set getTypeTableNames()
{
return this.typeTableNames;
}
/**
* This is the getter method for instance variable {@link #nullAllowed}.
*
* @return value of instance variable {@link #nullAllowed}
* @see #nullAllowed
* @see #setNullAllowed
*/
public boolean isNullAllowed()
{
return this.nullAllowed;
}
/**
* This is the setter method for instance variable {@link #nullAllowed}.
*
* @param _nullAllowed new value for instance variable
* {@link #nullAllowed}
* @see #nullAllowed
* @see #isNullAllowed
*/
private void setNullAllowed(final boolean _nullAllowed)
{
this.nullAllowed = _nullAllowed;
}
/**
* This is the getter method for instance variable {@link #orderIndex}.
*
* @return value of instance variable {@link #orderIndex}
* @see #orderIndex
* @see #setOrderIndex
*/
public int getOrderIndex()
{
return this.orderIndex;
}
/**
* This is the setter method for instance variable {@link #orderIndex}.
*
* @param _orderIndex new value for instance variable
* {@link #orderIndex}
* @see #orderIndex
* @see #getOrderIndex
*/
private void setOrderIndex(final int _orderIndex)
{
this.orderIndex = _orderIndex;
}
}
}