package org.reldb.dbrowser.ui.content.rev; import java.util.Vector; import org.eclipse.swt.graphics.Point; import org.reldb.rel.client.Attribute; import org.reldb.rel.client.Heading; import org.reldb.rel.client.Tuple; import org.reldb.rel.client.Tuples; import org.reldb.rel.client.Value; public abstract class Operator extends Visualiser { private int lastSide = Parameter.EASTTOWEST; private String kind; private java.util.Vector<Parameter> parameters = new java.util.Vector<Parameter>(); protected Operator(Model model, String id, String kind, int xpos, int ypos) { super(model, id, kind, xpos, ypos); this.kind = kind; btnEdit.dispose(); pack(); } public String getKind() { return kind; } public Parameter getParameter(int parameterNumber) { return parameters.get(parameterNumber); } private String getQueryForParameter(int parameterNumber, boolean allowParentheses) { Parameter parameter = parameters.get(parameterNumber); Argument argument = parameter.getArgument(); if (argument == null) return null; Visualiser operand = argument.getOperand(); if (operand == null) return null; if (allowParentheses && operand instanceof Operator) return "(" + operand.getQuery() + ")"; return operand.getQuery(); } public String getQueryForParameterUnparenthesised(int parameterNumber) { return getQueryForParameter(parameterNumber, false); } public String getQueryForParameter(int parameterNumber) { return getQueryForParameter(parameterNumber, true); } public Heading getHeadingOfParameter(int parameterNumber) { String query = getQueryForParameter(parameterNumber); if (query == null) return null; Value returned = getDatabase().evaluate(query); if (returned instanceof Tuples) { Tuples tuples = (Tuples)returned; return tuples.getHeading(); } return null; } public Vector<String> getAttributeNamesOfParameter(int parameterNumber) { String query = getQueryForParameter(parameterNumber); if (query == null) return null; Value returned = getDatabase().evaluate(query); Vector<String> output = new Vector<String>(); if (returned instanceof Tuples) { Heading heading = ((Tuples)returned).getHeading(); for (Attribute attribute: heading.toArray()) output.add(attribute.getName()); } else if (returned instanceof Tuple) { Tuple tuple = (Tuple)returned; for (int index=0; index<tuple.getAttributeCount(); index++) output.add(tuple.getAttributeName(index)); } return output; } public String toString() { return "Operator " + getTitle() + " (" + getID() + ")"; } protected void disconnect() { for (Parameter parameter: parameters) parameter.getArgument().setOperand(null); super.disconnect(); } protected void delete() { disconnect(); for (Parameter parameter: parameters) parameter.dispose(); parameters.clear(); getDatabase().removeQuery(getID()); super.delete(); } public boolean isQueryable() { for (Parameter parameter: parameters) if (parameter.getArgument().isVisible() && parameter.getArgument().getOperand().getQuery() == null) return false; return true; } public void verify() { super.verify(); notifyArgumentChanged(); } private String cachedQuery = null; private void notifyArgumentChanged() { if (isQueryable()) { setReadyColour(); btnInfo.setEnabled(true); btnRun.setEnabled(true); String query = getQuery(); if (cachedQuery == null || query.compareTo(cachedQuery) != 0) { notifyArgumentChanged(true); cachedQuery = query; } } else { setWarningColour(); btnInfo.setEnabled(false); btnRun.setEnabled(false); if (cachedQuery != null) { notifyArgumentChanged(false); cachedQuery = null; } } } /** Override to be notified that a parameter's argument has changed, with identification as to whether it's queryable or not. */ protected void notifyArgumentChanged(boolean queryable) {} protected Parameter addParameter(String name) { Parameter p = new Parameter(this, name, parameters.size(), lastSide); lastSide = (lastSide == Parameter.EASTTOWEST) ? Parameter.WESTTOEAST : Parameter.EASTTOWEST; parameters.add(p); new Argument(p); return p; } /** Return number of parameters. */ public int getParameterCount() { return parameters.size(); } /** Get connections to this Op as a relation in Tutorial D syntax. */ private String getConnections() { String out = "RELATION {parameter INT, Name CHAR} {"; for (int i=0; i<getParameterCount(); i++) { Parameter parameter = getParameter(i); if (parameter.getArgument() != null) { if (i > 0) out += ", "; out += " tuple {"; out += "parameter " + parameter.getNumber() + ", "; out += "Name '" + parameter.getArgument().getOperand().getID() + "'"; out += "}"; } } out += " } "; return out; } protected void movement() { super.movement(); if (parameters != null) for (Parameter parameter: parameters) parameter.redraw(); } protected void visualiserMoved() { Point location = getLocation(); getDatabase().updateQueryPosition(getID(), location.x, location.y, kind, getConnections(), getModel().getModelName()); } }