Package org.drools.guvnor.client.modeldriven.ui

Source Code of org.drools.guvnor.client.modeldriven.ui.ExpressionBuilder

/**
* Copyright 2010 JBoss Inc
*
* 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.drools.guvnor.client.modeldriven.ui;

import static org.drools.ide.common.client.modeldriven.brl.ExpressionPartHelper.getExpressionPartForField;
import static org.drools.ide.common.client.modeldriven.brl.ExpressionPartHelper.getExpressionPartForGlobalVariable;
import static org.drools.ide.common.client.modeldriven.brl.ExpressionPartHelper.getExpressionPartForMethod;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.drools.guvnor.client.common.ClickableLabel;
import org.drools.guvnor.client.common.FormStylePopup;
import org.drools.guvnor.client.common.SmallLabel;
import org.drools.guvnor.client.messages.Constants;
import org.drools.ide.common.client.modeldriven.SuggestionCompletionEngine;
import org.drools.ide.common.client.modeldriven.brl.ExpressionCollectionIndex;
import org.drools.ide.common.client.modeldriven.brl.ExpressionFieldVariable;
import org.drools.ide.common.client.modeldriven.brl.ExpressionFormLine;
import org.drools.ide.common.client.modeldriven.brl.ExpressionMethod;
import org.drools.ide.common.client.modeldriven.brl.ExpressionPart;
import org.drools.ide.common.client.modeldriven.brl.ExpressionText;
import org.drools.ide.common.client.modeldriven.brl.ExpressionVariable;
import org.drools.ide.common.client.modeldriven.brl.FactPattern;
import org.drools.ide.common.client.modeldriven.brl.RuleModel;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.gwtext.client.util.Format;

public class ExpressionBuilder extends RuleModellerWidget implements HasExpressionTypeChangeHandlers, HasExpressionChangeHandlers {

  private static final String DELETE_VALUE = "_delete_";
  private static final String FIElD_VALUE_PREFIX = "fl";
  private static final String VARIABLE_VALUE_PREFIX = "va";
  // private static final String GLOBAL_COLLECTION_VALUE_PREFIX = "gc";
  private static final String GLOBAL_VARIABLE_VALUE_PREFIX = "gv";
  private static final String METHOD_VALUE_PREFIX = "mt";
  private final SmallLabelClickHandler slch = new SmallLabelClickHandler();
  private Constants constants = ((Constants) GWT.create(Constants.class));
  // private FlowPanel panel = new FlowPanel();
  private HorizontalPanel panel = new HorizontalPanel();
  private ExpressionFormLine expression;
  private boolean readOnly;

  public ExpressionBuilder(RuleModeller modeller, ExpressionFormLine expression) {
    this(modeller, expression, false);
  }

  public ExpressionBuilder(RuleModeller modeller, ExpressionFormLine expression, Boolean readOnly) {
    super(modeller);

    if (readOnly == null) {
      this.readOnly = !modeller.getSuggestionCompletions().containsFactType(
          modeller.getSuggestionCompletions().getFactNameFromType(
              this.expression.getRootExpression().getClassType()));
    } else {
      this.readOnly = readOnly;
    }

    panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);

    this.expression = expression;
    if (expression == null || expression.isEmpty()) {
      if (this.readOnly) {
        panel.add(new SmallLabel("<b>-</b>"));
      } else {
        panel.add(createStartPointWidget());
      }
    } else {
      if (this.readOnly) {
        panel.add(createWidgetForExpression("<b>" + getBoundText() + expression.getText(false) + "</b>"));
      } else {
        panel.add(createWidgetForExpression("<b>" + getBoundText() + expression.getText(false) + ".</b>"));
        panel.add(getWidgetForCurrentType());
      }
    }
    initWidget(panel);
  }
 
  private String getBoundText() {
    if (expression.isBound()) {
      return "[" + expression.getBinding() + "] ";
    }
    return "";
  }

  private Widget createStartPointWidget() {
    ListBox startPoint = new ListBox();
    panel.add(startPoint);

    startPoint.addItem(constants.ChooseDotDotDot(), "");

    // TODO {baunax} uncomment when global collections is implemented.
    // for (String gc : getCompletionEngine().getGlobalCollections()) {
    // startPoint.addItem(gc, GLOBAL_COLLECTION_VALUE_PREFIX + "." + gc);
    // }

    for (String gv : getCompletionEngine().getGlobalVariables()) {
      startPoint.addItem(gv, GLOBAL_VARIABLE_VALUE_PREFIX + "." + gv);
    }

    for (String v : getRuleModel().getBoundFacts()) {
      startPoint.addItem(v, VARIABLE_VALUE_PREFIX + "." + v);
    }

    startPoint.setVisibleItemCount(1);
    startPoint.addChangeHandler(new ChangeHandler() {

      public void onChange(ChangeEvent event) {
        ListBox lb = (ListBox) event.getSource();
        int index = lb.getSelectedIndex();
        if (index > 0) {
          ExpressionBuilder.this.makeDirty();
          startPointChange(lb.getValue(index));
        }
      }
    });
    return startPoint;
  }

  @Override
  public void makeDirty() {
    super.makeDirty();
    setModified(true);
  }

  private void startPointChange(String value) {
    setModified(true);
    panel.clear();
    Widget w;
    int dotPos = value.indexOf('.');
    String prefix = value.substring(0, dotPos);
    String attrib = value.substring(dotPos + 1);
    if (prefix.equals(VARIABLE_VALUE_PREFIX)) {
      FactPattern fact = getRuleModel().getBoundFact(attrib);
      ExpressionPart variable;
      if (fact != null) {
        variable = new ExpressionVariable(fact);
      } else {
        //TODO {baunax} fix it!!! to make recursive
        variable = new ExpressionFieldVariable(attrib);
      }
      expression.appendPart(variable);

    } else if (prefix.equals(GLOBAL_VARIABLE_VALUE_PREFIX)) {
      expression.appendPart(getExpressionPartForGlobalVariable(getCompletionEngine(), attrib));
    }
    w = getWidgetForCurrentType();

    if (!expression.isEmpty()) {
      panel.add(createWidgetForExpression("<b>" + expression.getText() + ".</b>"));
    }
    if (w != null) {
      panel.add(w);
    }
    fireExpressionChangeEvent();
    fireExpressionTypeChangeEvent();
  }

  private Widget getWidgetForCurrentType() {
    if (expression.isEmpty()) {
      return createStartPointWidget();
    }
   
    ChangeHandler ch = new ChangeHandler() {
      public void onChange(ChangeEvent event) {
        ListBox box = (ListBox) event.getSource();
        panel.remove(box);
        if (box.getSelectedIndex() > 0) {
          onChangeSelection(box.getValue(box.getSelectedIndex()));
        }
      }
    };
   
    ListBox lb = new ListBox();
    lb.setVisibleItemCount(1);
    lb.addItem(constants.ChooseDotDotDot(), "");
    lb.addItem("<==" + constants.DeleteItem(), DELETE_VALUE);
    for (Map.Entry<String, String> entry : getCompletionsForCurrentType().entrySet()) {
      lb.addItem(entry.getKey(), entry.getValue());
    }
    lb.addChangeHandler(ch);
    return lb;
  }

  private void onCollectionChange(String value) {
    if ("size".contains(value)) {
      expression.appendPart(new ExpressionMethod("size", "int", SuggestionCompletionEngine.TYPE_NUMERIC));
    } else if ("isEmpty".equals(value)) {
      expression.appendPart(new ExpressionMethod("isEmpty", "boolean", SuggestionCompletionEngine.TYPE_BOOLEAN));
    } else {
      ExpressionCollectionIndex collectionIndex;
      String factName = getCompletionEngine().getFactNameFromType(getCurrentParametricType());
      if (getCurrentParametricType() != null && factName != null) {
        collectionIndex = new ExpressionCollectionIndex("get", getCurrentParametricType(), factName);
      } else {
        collectionIndex = new ExpressionCollectionIndex("get", "java.lang.Object",
            SuggestionCompletionEngine.TYPE_OBJECT);
      }
      if ("first".equals(value)) {
        collectionIndex.putParam("index", new ExpressionFormLine(new ExpressionText("0")));
        expression.appendPart(collectionIndex);
      } else if ("last".equals(value)) {
        ExpressionFormLine index = new ExpressionFormLine(expression);
        index.appendPart(new ExpressionMethod("size", "int", SuggestionCompletionEngine.TYPE_NUMERIC));
        index.appendPart(new ExpressionText("-1"));

        collectionIndex.putParam("index", index);
        expression.appendPart(collectionIndex);
      }
    }
  }

  private void onChangeSelection(String value) {
    setModified(true);
    String oldType = getCurrentGenericType();
    String prevFactName = null;
    if (DELETE_VALUE.equals(value)) {
      expression.removeLast();
    } else if (SuggestionCompletionEngine.TYPE_COLLECTION.equals(getCurrentGenericType())) {
      onCollectionChange(value);
    } else if (SuggestionCompletionEngine.TYPE_STRING.equals(getCurrentGenericType())) {
      if ("size".equals(value)) {
        expression.appendPart(new ExpressionMethod("size", "int", SuggestionCompletionEngine.TYPE_NUMERIC));
      } else if ("isEmpty".equals(value)) {
        expression.appendPart(new ExpressionText(".size() == 0", "", SuggestionCompletionEngine.TYPE_NUMERIC));
      }
    } else {
      int dotPos = value.indexOf('.');
      String prefix = value.substring(0, dotPos);
      String attrib = value.substring(dotPos + 1);

      prevFactName = getCompletionEngine().getFactNameFromType(getCurrentClassType());
      // String genericType = SuggestionCompletionEngine.TYPE_OBJECT;
      if (FIElD_VALUE_PREFIX.equals(prefix)) {
        expression.appendPart(getExpressionPartForField(getCompletionEngine(), prevFactName, attrib));
      } else if (METHOD_VALUE_PREFIX.equals(prefix)) {
        expression.appendPart(getExpressionPartForMethod(getCompletionEngine(), prevFactName, attrib));
      }
    }
    Widget w = getWidgetForCurrentType();

    panel.clear();
    if (!expression.isEmpty()) {
      panel.add(createWidgetForExpression("<b>" + expression.getText() + ".</b>"));
    }
    if (w != null) {
      panel.add(w);
    }
    fireExpressionChangeEvent();
    fireExpressionTypeChangeEvent(oldType);
  }

  private Map<String, String> getCompletionsForCurrentType() {
    Map<String, String> completions = new LinkedHashMap<String, String>();

    if (SuggestionCompletionEngine.TYPE_FINAL_OBJECT.equals(getCurrentGenericType())) {
      return completions;
    }

    if (SuggestionCompletionEngine.TYPE_COLLECTION.equals(getCurrentGenericType())) {
      completions.put("size()", "size");
      completions.put("first()", "first");
      completions.put("last()", "last");
      completions.put("isEmpty()", "isEmpty");
      return completions;
    }

    if (SuggestionCompletionEngine.TYPE_STRING.equals(getCurrentGenericType())) {
      completions.put("size()", "size");
      completions.put("isEmpty()", "isEmpty");
      return completions;
    }

    if (SuggestionCompletionEngine.TYPE_BOOLEAN.equals(getCurrentGenericType())
        || SuggestionCompletionEngine.TYPE_NUMERIC.equals(getCurrentGenericType())
        || SuggestionCompletionEngine.TYPE_DATE.equals(getCurrentGenericType())
        || SuggestionCompletionEngine.TYPE_OBJECT.equals(getCurrentGenericType())) {
      return completions;
    }

    String factName = getCompletionEngine().getFactNameFromType(getCurrentClassType());
    if (factName != null) {
      // we currently only support 0 param method calls
      List<String> methodNames = getCompletionEngine().getMethodFullNames(factName, 0);

      for (String field : getCompletionEngine().getFieldCompletions(factName)) {
        boolean changed = false;
        for (Iterator<String> i = methodNames.iterator(); i.hasNext();) {
          String method = i.next();
          if (method.startsWith(field)) {
            completions.put(method, METHOD_VALUE_PREFIX + "." + method);
            i.remove();
            changed = true;
          }
        }
        if (!changed) {
          completions.put(field, FIElD_VALUE_PREFIX + "." + field);
        }
      }
    }
    // else {We don't know anything about this type, so return empty map}
    return completions;
  }

  // private String getCurrentPartName() {
  // return expression.getCurrentName();
  // }

  private RuleModel getRuleModel() {
    return this.getModeller().getModel();
  }

  private SuggestionCompletionEngine getCompletionEngine() {
    return this.getModeller().getSuggestionCompletions();
  }

  private String getCurrentClassType() {
    return expression.getClassType();
  }

  private String getCurrentGenericType() {
    return expression.getGenericType();
  }

  private String getPreviousGenericType() {
    return expression.getPreviousGenericType();
  }

  private String getCurrentParametricType() {
    return expression.getParametricType();
  }

  // private String getPreviousClassType() {
  // return expression.getPreviousType();
  // }
  //
  // private ExpressionPart getRootExpression() {
  // return expression.getRootExpression();
  // }

  @Override
  public boolean isReadOnly() {
    return this.readOnly;
  }

  /**
   * @see org.drools.guvnor.client.modeldriven.ui.HasExpressionTypeChangeHandlers#addExpressionTypeChangeHandler(org.drools.guvnor.client.modeldriven.ui.ExpressionTypeChangeHandler)
   */
  public HandlerRegistration addExpressionTypeChangeHandler(ExpressionTypeChangeHandler handler) {
    return addHandler(handler, ExpressionTypeChangeEvent.getType());
  }

  private void fireExpressionChangeEvent() {
    fireEvent(new ExpressionChangeEvent());
  }
 
  private void fireExpressionTypeChangeEvent() {
    fireExpressionTypeChangeEvent(getPreviousGenericType());
  }

  private void fireExpressionTypeChangeEvent(String previousGenericType) {
    String currentGenericType = getCurrentGenericType();
    if ((previousGenericType == null || !previousGenericType.equals(currentGenericType))
        || currentGenericType != null) {
      fireEvent(new ExpressionTypeChangeEvent(previousGenericType, currentGenericType));
    }
  }

  public HandlerRegistration addExpressionChangeHandler(ExpressionChangeHandler handler) {
    return addHandler(handler, ExpressionChangeEvent.getType());
  }
 
  private void showBindingPopUp() {
    final FormStylePopup popup = new FormStylePopup();
    popup.setWidth(500);
    HorizontalPanel vn = new HorizontalPanel();
    final TextBox varName = new TextBox();
    Button ok = new Button(constants.Set());
    vn.add(new Label(constants.BindTheExpressionToAVariable()));
    vn.add(varName);
    vn.add(ok);

    ok.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        String var = varName.getText();
        if (getModeller().isVariableNameUsed(var)) {
          Window.alert(Format.format(constants.TheVariableName0IsAlreadyTaken(), var));
          return;
        }
        expression.setBinding(var);
        getModeller().refreshWidget();
        popup.hide();
      }
    });

    popup.addRow(vn);
    popup.show();
  }
 
  private class SmallLabelClickHandler implements ClickHandler {
    public void onClick(ClickEvent event) {
      showBindingPopUp();
    }
  }
 
  private ClickableLabel createWidgetForExpression(String text) {
    ClickableLabel label = new ClickableLabel(text, slch);
    return label;
  }
}
TOP

Related Classes of org.drools.guvnor.client.modeldriven.ui.ExpressionBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.