/*
* Copyright 2003, 2004 The Apache Software Foundation
*
* 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.
*/
package org.apache.ws.jaxme.sqls.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.ws.jaxme.sqls.BooleanConstraint;
import org.apache.ws.jaxme.sqls.Column;
import org.apache.ws.jaxme.sqls.ColumnReference;
import org.apache.ws.jaxme.sqls.ColumnSet;
import org.apache.ws.jaxme.sqls.CombinedConstraint;
import org.apache.ws.jaxme.sqls.ConstrainedStatement;
import org.apache.ws.jaxme.sqls.Constraint;
import org.apache.ws.jaxme.sqls.ForeignKey;
import org.apache.ws.jaxme.sqls.ObjectFactory;
import org.apache.ws.jaxme.sqls.SelectStatement;
import org.apache.ws.jaxme.sqls.TableReference;
import org.apache.ws.jaxme.sqls.Value;
/**
* @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
*/
public class CombinedConstraintImpl extends ConstraintImpl implements CombinedConstraint {
public static class TypeImpl extends SQLFactoryImpl.IdentImpl implements CombinedConstraint.Type {
public TypeImpl(String pName) {
super(pName);
}
}
private boolean not;
private List parts = new ArrayList();
private CombinedConstraint.Type type;
protected CombinedConstraintImpl(ConstrainedStatement pConstrainedStatement,
CombinedConstraint.Type pType) {
super(pConstrainedStatement);
type = pType;
}
public CombinedConstraint.Type getType() {
return type;
}
public CombinedConstraint createAndConstraint() {
ObjectFactory f = getConstrainedStatement().getSQLFactory().getObjectFactory();
CombinedConstraint result = f.newCombinedConstraint(getConstrainedStatement(),
CombinedConstraint.Type.AND);
parts.add(result);
return result;
}
public CombinedConstraint createOrConstraint() {
ObjectFactory f = getConstrainedStatement().getSQLFactory().getObjectFactory();
CombinedConstraint result = f.newCombinedConstraint(getConstrainedStatement(),
CombinedConstraint.Type.OR);
parts.add(result);
return result;
}
public BooleanConstraint createEQ() {
BooleanConstraint result = new BooleanConstraintImpl(this, BooleanConstraint.Type.EQ);
parts.add(result);
return result;
}
public BooleanConstraint createNE() {
BooleanConstraint result = new BooleanConstraintImpl(this, BooleanConstraint.Type.NE);
parts.add(result);
return result;
}
public BooleanConstraint createLT() {
BooleanConstraint result = new BooleanConstraintImpl(this, BooleanConstraint.Type.LT);
parts.add(result);
return result;
}
public BooleanConstraint createGT() {
BooleanConstraint result = new BooleanConstraintImpl(this, BooleanConstraint.Type.GT);
parts.add(result);
return result;
}
public BooleanConstraint createLE() {
BooleanConstraint result = new BooleanConstraintImpl(this, BooleanConstraint.Type.LE);
parts.add(result);
return result;
}
public BooleanConstraint createGE() {
BooleanConstraint result = new BooleanConstraintImpl(this, BooleanConstraint.Type.GE);
parts.add(result);
return result;
}
public BooleanConstraint createLIKE() {
BooleanConstraint result = new BooleanConstraintImpl(this, BooleanConstraint.Type.LIKE);
parts.add(result);
return result;
}
public BooleanConstraint createISNULL() {
BooleanConstraint result = new BooleanConstraintImpl(this, BooleanConstraint.Type.ISNULL);
parts.add(result);
return result;
}
public BooleanConstraint createIN() {
BooleanConstraint result = new BooleanConstraintImpl(this, BooleanConstraint.Type.IN);
parts.add(result);
return result;
}
public void createEXISTS(SelectStatement pStatement) {
BooleanConstraint bc = new BooleanConstraintImpl(this, BooleanConstraint.Type.EXISTS);
parts.add(bc);
bc.addPart(pStatement);
}
public void addColumnSetQuery(ColumnSet pSet, TableReference pTableReference) {
if (!pTableReference.getTable().equals(pSet.getTable())) {
throw new IllegalStateException("The foreign keys referencing table is " +
pSet.getTable().getQName() +
", but the arguments referencing table is " +
pTableReference.getTable().getQName());
}
if (!pTableReference.getStatement().equals(getConstrainedStatement())) {
throw new IllegalStateException("The statement of the table reference is not the same as this constraints statement.");
}
for (Iterator iter = pSet.getColumns(); iter.hasNext(); ) {
Column column = (Column) iter.next();
BooleanConstraint eq = createEQ();
eq.addPart(new ColumnReferenceImpl(pTableReference, column));
eq.addPlaceholder();
}
}
public void addJoin(ForeignKey pKey, TableReference pReferencingTable,
TableReference pReferencedTable) {
if (!pReferencingTable.getTable().equals(pKey.getTable())) {
throw new IllegalStateException("The foreign keys referencing table is " +
pKey.getTable().getQName() +
", but the arguments referencing table is " +
pReferencingTable.getTable().getQName());
}
if (!pReferencedTable.getTable().equals(pKey.getReferencedTable())) {
throw new IllegalStateException("The foreign keys referenced table is " +
pKey.getReferencedTable().getQName() +
", but the arguments referenced table is " +
pReferencedTable.getTable().getQName());
}
if (!pReferencingTable.getStatement().equals(getConstrainedStatement())) {
throw new IllegalStateException("The statement of the referencing table is not the same as this constraints statement.");
}
if (!pReferencedTable.getStatement().equals(getConstrainedStatement())) {
throw new IllegalStateException("The statement of the referenced table is not the same as this constraints statement.");
}
for (Iterator iter = pKey.getColumnLinks(); iter.hasNext(); ) {
ForeignKey.ColumnLink columnReference = (ForeignKey.ColumnLink) iter.next();
BooleanConstraint eq = createEQ();
eq.addPart(new ColumnReferenceImpl(pReferencingTable, columnReference.getLocalColumn()));
eq.addPart(new ColumnReferenceImpl(pReferencedTable, columnReference.getReferencedColumn()));
}
}
public void addJoin(TableReference pReferencingTable,
ColumnSet pReferencingColumnSet,
TableReference pReferencedTable,
ColumnSet pReferencedColumnSet) {
if (pReferencingTable == null) { throw new NullPointerException("The referencing table must not be null."); }
if (pReferencingColumnSet == null) { throw new NullPointerException("The referencing column set must not be null."); }
if (pReferencedTable == null) { throw new NullPointerException("The referenced table must not be null."); }
if (pReferencedColumnSet == null) { throw new NullPointerException("The referenced column set must not be null."); }
if (!pReferencingTable.getTable().equals(pReferencingColumnSet.getTable())) {
throw new IllegalStateException("The referencing column sets table " +
pReferencingColumnSet.getTable().getQName() +
" doesn't match the referencing table " +
pReferencingTable.getTable().getQName());
}
if (!pReferencedTable.getTable().equals(pReferencedColumnSet.getTable())) {
throw new IllegalStateException("The referenced column sets table " +
pReferencedColumnSet.getTable().getQName() +
" doesn't match the referenced table " +
pReferencedTable.getTable().getQName());
}
Iterator referencedIter = pReferencedColumnSet.getColumns();
for (Iterator iter = pReferencingColumnSet.getColumns(); iter.hasNext(); ) {
Column referencingColumn = (Column) iter.next();
if (!referencedIter.hasNext()) {
throw new IllegalStateException("The size of the referencing and referenced column sets doesn't match.");
}
Column referencedColumn = (Column) referencedIter.next();
BooleanConstraint eq = createEQ();
eq.addPart(pReferencingTable.newColumnReference(referencingColumn));
eq.addPart(pReferencedTable.newColumnReference(referencedColumn));
}
}
public int getNumParts() {
return parts.size();
}
public Iterator getParts() {
return parts.iterator();
}
public void addConstraint(Map pMap, Constraint pConstraint) {
if (pConstraint instanceof CombinedConstraint) {
CombinedConstraint source = (CombinedConstraint) pConstraint;
CombinedConstraint target;
if (source.getType().equals(getType())) {
target = this;
} else if (source.getType().equals(CombinedConstraint.Type.AND)) {
target = createAndConstraint();
} else if (source.getType().equals(CombinedConstraint.Type.OR)) {
target = createOrConstraint();
} else {
throw new IllegalStateException("Unknown combined constraint type: " +
source.getType());
}
for (Iterator iter = source.getParts(); iter.hasNext(); ) {
Object o = iter.next();
if (o instanceof CombinedConstraint) {
target.addConstraint(pMap, (CombinedConstraint) o);
} else if (o instanceof BooleanConstraint) {
target.addConstraint(pMap, (BooleanConstraint) o);
} else {
throw new IllegalArgumentException("Invalid part: " + o.getClass().getName());
}
}
} else if (pConstraint instanceof BooleanConstraint) {
BooleanConstraint source = (BooleanConstraint) pConstraint;
BooleanConstraint target;
BooleanConstraint.Type sourceType = source.getType();
if (BooleanConstraint.Type.EQ.equals(sourceType)) {
target = createEQ();
} else if (BooleanConstraint.Type.NE.equals(sourceType)) {
target = createNE();
} else if (BooleanConstraint.Type.GT.equals(sourceType)) {
target = createGT();
} else if (BooleanConstraint.Type.LT.equals(sourceType)) {
target = createLT();
} else if (BooleanConstraint.Type.GE.equals(sourceType)) {
target = createGE();
} else if (BooleanConstraint.Type.LE.equals(sourceType)) {
target = createLE();
} else if (BooleanConstraint.Type.LIKE.equals(sourceType)) {
target = createLIKE();
} else if (BooleanConstraint.Type.ISNULL.equals(sourceType)) {
target = createISNULL();
} else if (BooleanConstraint.Type.IN.equals(sourceType)) {
target = createIN();
} else {
throw new IllegalArgumentException("Invalid boolean constraint type: " + sourceType);
}
for (Iterator iter = source.getParts(); iter.hasNext(); ) {
Object o = iter.next();
if (o instanceof Value) {
target.addPart((Value) o);
} else if (o instanceof ColumnReference) {
ColumnReference colRef = (ColumnReference) o;
TableReference tableRef = (TableReference) pMap.get(colRef.getTableReference());
if (tableRef == null) {
throw new IllegalStateException("Unknown reference to table " + colRef.getTableReference().getTable().getQName());
}
target.addPart(tableRef.newColumnReference(colRef.getColumn()));
} else {
throw new IllegalStateException("Unknown part type: " + o.getClass().getName());
}
}
} else {
throw new IllegalStateException("Unknown constraint type: " + pConstraint.getClass().getName());
}
}
public void setNOT(boolean pNot) {
not = pNot;
}
public boolean isNOT() {
return not;
}
}