/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.query.ui.builder.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.jface.viewers.TreeViewer;
import org.teiid.core.designer.util.I18nUtil;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.query.IQueryFactory;
import org.teiid.designer.query.IQueryService;
import org.teiid.designer.query.sql.lang.ICommand;
import org.teiid.designer.query.sql.lang.IExpression;
import org.teiid.designer.query.sql.lang.ILanguageObject;
import org.teiid.designer.query.sql.lang.IQueryCommand;
import org.teiid.designer.query.sql.lang.ISetCriteria;
import org.teiid.designer.query.sql.lang.ISubquerySetCriteria;
import org.teiid.query.ui.builder.util.ElementViewerFactory;
import org.teiid.query.ui.builder.util.ICriteriaStrategy;
/**
* SetCriteriaEditorModel
*
* @since 8.0
*/
public class SetCriteriaEditorModel extends AbstractPredicateCriteriaTypeEditorModel
implements ILanguageObjectEditorModelListener {
private final static String PREFIX = I18nUtil.getPropertyPrefix(SetCriteriaEditorModel.class);
private final static String[] OPERATORS = new String[] {Util.getString(PREFIX + "in") //$NON-NLS-1$
};
public final static String EXPRESSION = "SET CRITERIA EXPRESSION"; //$NON-NLS-1$
public final static String SUBTYPE_CHANGED = "SET CRITERIA SUBTYPE CHANGED"; //$NON-NLS-1$
public final static String VALUES = "SET CRITERIA VALUES"; //$NON-NLS-1$
public final static String COMMAND = "SET CRITERIA SUBQUERY COMMAND"; //$NON-NLS-1$
public final static int LIST = 1;
public final static int SUBQUERY = 2;
private final static int INITIAL_TYPE = LIST;
private final ISetCriteria emptySetCriteria;
private final ISubquerySetCriteria emptySubquerySetCriteria;
private CriteriaExpressionEditorModel expModel;
private Collection values = new ArrayList();
private int curType = INITIAL_TYPE; // LIST or SUBQUERY
private ICriteriaStrategy criteriaStrategy = null;
private ICommand subqueryCommand;
private Object curSubquerySelection = null;
public SetCriteriaEditorModel( CriteriaExpressionEditorModel model ) {
super(ISetCriteria.class);
this.expModel = model;
this.expModel.addModelListener(this);
IQueryService queryService = ModelerCore.getTeiidQueryService();
IQueryFactory factory = queryService.createQueryFactory();
emptySetCriteria = factory.createSetCriteria();
emptySubquerySetCriteria = factory.createSubquerySetCriteria();
subqueryCommand = emptySubquerySetCriteria.getCommand();
}
public SetCriteriaEditorModel() {
this(new CriteriaExpressionEditorModel());
}
public void setViewer( TreeViewer viewer ) {
criteriaStrategy = ElementViewerFactory.getCriteriaStrategy(viewer);
}
public String getInvalidSelectionMessage() {
String msg = criteriaStrategy.getInvalidMessage(curSubquerySelection);
return msg;
}
public void setCurType( int type ) {
if (this.curType != type) {
this.curType = type;
fireModelChanged(SUBTYPE_CHANGED);
}
}
public int getCurType() {
return this.curType;
}
@Override
public ILanguageObject getLanguageObject() {
IQueryService queryService = ModelerCore.getTeiidQueryService();
IQueryFactory factory = queryService.createQueryFactory();
if (curType == LIST) {
ISetCriteria setCriteria = factory.createSetCriteria();
setCriteria.setExpression(expModel.getExpression());
setCriteria.setValues(values);
return setCriteria;
}
// must be SUBQUERY
ISubquerySetCriteria subquerySetCriteria = factory.createSubquerySetCriteria();
subquerySetCriteria.setExpression(expModel.getExpression());
subquerySetCriteria.setCommand((IQueryCommand)subqueryCommand);
return subquerySetCriteria;
}
@Override
public void setLanguageObject( ILanguageObject obj ) {
super.setLanguageObject(obj);
if (obj == null) {
clear();
} else {
if (obj instanceof ISetCriteria) {
setCurType(LIST);
ISetCriteria curSetCriteria = (ISetCriteria)obj;
setExpression(curSetCriteria.getExpression());
setValues(curSetCriteria.getValues());
} else { // must be SUBQUERY
setCurType(SUBQUERY);
ISubquerySetCriteria curSubquerySetCriteria = (ISubquerySetCriteria)obj;
setExpression(curSubquerySetCriteria.getExpression());
setCommand(curSubquerySetCriteria.getCommand());
}
}
}
@Override
public void clear() {
notifyListeners = false;
setCurType(INITIAL_TYPE);
if (curType == LIST) {
setExpression(emptySetCriteria.getExpression());
setValues(emptySetCriteria.getValues());
} else {
setCommand(emptySubquerySetCriteria.getCommand());
}
notifyListeners = true;
super.clear();
}
@Override
public void save() {
super.save();
expModel.save();
}
public void setExpression( IExpression exp ) {
boolean same;
IExpression oldExp = expModel.getExpression();
if (exp == null) {
same = (oldExp == null);
} else {
same = exp.equals(oldExp);
}
if (!same) {
// Note-- do not fire event because model will fire its own event
expModel.setLanguageObject(exp);
}
}
public IExpression getExpression() {
return expModel.getExpression();
}
@Override
public void setLeftExpression( IExpression exp ) {
setExpression(exp);
}
@Override
public IExpression getLeftExpression() {
return getExpression();
}
@Override
public void setRightExpression( IExpression exp ) {
// Unused abstract method
}
@Override
public IExpression getRightExpression() {
// Unused abstract method
return null;
}
public void setValues( Collection vals ) {
Collection ourValues = vals;
if (ourValues == null) {
ourValues = new ArrayList();
}
boolean same = sameValues(ourValues);
// We will set to a copy of the collection
Iterator it = ourValues.iterator();
this.values = new ArrayList();
while (it.hasNext()) {
this.values.add(it.next());
}
if (!same) {
fireModelChanged(VALUES);
}
}
public void addValue( ILanguageObject newValue ) {
if (!this.values.contains(newValue)) {
this.values.add(newValue);
fireModelChanged(VALUES);
}
}
public void replaceValue( ILanguageObject oldValue,
ILanguageObject newValue ) {
this.values.remove(oldValue);
this.values.add(newValue);
fireModelChanged(VALUES);
}
public void setCommand( ICommand cmd ) {
boolean same;
if (subqueryCommand == null) {
// We will always set to changed for null
same = false;
} else {
same = subqueryCommand.equals(cmd);
}
this.subqueryCommand = cmd;
if (!same) {
fireModelChanged(COMMAND);
}
}
public ICommand getCommand() {
return subqueryCommand;
}
@Override
public void modelChanged( LanguageObjectEditorModelEvent theEvent ) {
String type = theEvent.getType();
String eventType;
if (type.equals(CompositeLanguageObjectEditorModel.MODEL_CHANGE)) {
eventType = type;
} else {
eventType = EXPRESSION;
}
fireModelChanged(eventType);
}
private boolean sameValues( Collection newValues ) {
boolean same = false;
if (values.size() == newValues.size()) {
Map foundMap = new HashMap();
Iterator it = values.iterator();
boolean continuing = true;
while (it.hasNext() && continuing) {
Object value = it.next();
if (foundMap.get(value) != null) {
continuing = false;
} else {
if (newValues.contains(value)) {
foundMap.put(value, new Boolean(true));
} else {
continuing = false;
}
}
}
same = continuing;
}
return same;
}
@Override
public boolean isComplete() {
boolean complete;
if (curType == LIST) {
complete = (expModel.isComplete() && (values.size() > 0));
} else {
complete = (expModel.isComplete() && subqueryIsComplete());
}
return complete;
}
public void setSubquerySelection( Object selection ) {
curSubquerySelection = selection;
if (curSubquerySelection != null) {
ICommand cmd = criteriaStrategy.getCommand(selection);
setCommand(cmd);
} else {
setCommand(emptySubquerySetCriteria.getCommand());
}
}
public Object getSubquerySelection() {
return curSubquerySelection;
}
private boolean subqueryIsComplete() {
boolean complete = false;
if (subqueryCommand != null) {
complete = (!subqueryCommand.equals(emptySubquerySetCriteria.getCommand()));
}
return complete;
}
public CriteriaExpressionEditorModel getExpressionModel() {
return expModel;
}
@Override
public String[] getOperators() {
return OPERATORS;
}
@Override
public String getCurrentOperator() {
return OPERATORS[0];
}
@Override
public void setCurrentOperator( String op ) {
// Interface method that is unused.
}
}