Package lupos.gui.operatorgraph.visualeditor.ruleeditor.generators

Source Code of lupos.gui.operatorgraph.visualeditor.ruleeditor.generators.JavaCodeGenerator

/**
* Copyright (c) 2013, Institute of Information Systems (Sven Groppe and contributors of LUPOSDATE), University of Luebeck
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*   - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*     disclaimer.
*   - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*     following disclaimer in the documentation and/or other materials provided with the distribution.
*   - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*     products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lupos.gui.operatorgraph.visualeditor.ruleeditor.generators;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;

import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;

import lupos.gui.operatorgraph.graphwrapper.GraphWrapper;
import lupos.gui.operatorgraph.visualeditor.guielements.VisualGraph;
import lupos.gui.operatorgraph.visualeditor.operators.Operator;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.RuleEditor;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.guielements.AnnotationPanel;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.guielements.ImplementationPanel;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.guielements.RuleEditorPane;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.guielements.RulePackagePanel;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.guielements.RulePanel;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.operators.AbstractRuleOperator;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.operators.JumpOverOperator;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.operators.RuleOperator;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.util.ConnectionContainer;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.util.File;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.util.RuleContainer;
import lupos.gui.operatorgraph.visualeditor.ruleeditor.util.VariableContainer;
import lupos.misc.Triple;
import lupos.misc.util.OperatorIDTuple;

public class JavaCodeGenerator {
  private RuleEditor editor = null;
  private String targetDirectory = "";
  private String packageName = "";
  private boolean generateStartMap = false;
  private HashMap<String, String> templates = new HashMap<String, String>();
  private StringBuffer globalCode = null;
  private StringBuffer checkMethodCode = null;
  private StringBuffer replaceMethodCode = null;
  private LinkedList<StringBuffer> buffers = null;
  private int count_private = 0;
  private HashMap<String, VariableContainer> variableList_left = null;
  private HashMap<String, Triple<Boolean, HashMap<String, VariableContainer>, HashMap<String, VariableContainer>>> validatedRules = new HashMap<String, Triple<Boolean, HashMap<String, VariableContainer>, HashMap<String, VariableContainer>>>();

  public JavaCodeGenerator(RuleEditor editor) {
    this.editor = editor;
  }

  public void generate(String targetDirectory, String packageName, boolean generateStartMap) {
    // correct targetDirectory if needed...
    if(!targetDirectory.endsWith("/")) {
      targetDirectory += "/";
    }

    this.targetDirectory = targetDirectory;


    // handle package name...
    this.packageName = (!packageName.equals("")) ? "package " + packageName + ";" : "";


    this.generateStartMap = generateStartMap;


    System.out.println("Starting to generate java code...");

    this.generate_rule_packages();
    this.generate_rules();

    System.out.println("DONE");
  }

  private void generate_rule_packages() {
    String rulePackageBaseClassName = (this.generateStartMap) ? "RulePackageWithStartNodeMap" : "RulePackage";

    for(JTabbedPane rulePackagePane : this.editor.getRulePackages()) {
      RulePackagePanel rulePackage = (RulePackagePanel) rulePackagePane;
      String rulePackageName = rulePackage.toString();
      String rulePackageClassName = this.capitalizeWord(rulePackageName.replaceAll(" ", "") + "RulePackage");
      String rulePackageClassFileName = rulePackageClassName + ".java";
      RuleContainer ruleContainer = this.editor.getRuleContainer();

      System.out.println(":: generating " + rulePackageClassFileName + "...");

      StringBuffer rules = new StringBuffer();
      LinkedList<String> associatedRulePackages = this.editor.getAssociationsContainer().getAssociationsToRulePackage(rulePackageName);
      int failedRules = 0;

      for(int i = 0; i < associatedRulePackages.size(); i += 1) {
        String ruleName = associatedRulePackages.get(i).replaceAll(" ", "") + "Rule";
        Triple<Boolean, HashMap<String, VariableContainer>, HashMap<String, VariableContainer>> resultTriple = this.validateRule(this.capitalizeWord(ruleName), ruleContainer.getRule(associatedRulePackages.get(i)));

        if(!resultTriple.getFirst()) {
          failedRules++;

          continue;
        }

        rules.append("            new " + ruleName + "()");

        if(i != associatedRulePackages.size()-1) {
          rules.append(",\n");
        }
      }

      if(failedRules == associatedRulePackages.size()) {
        JOptionPane.showOptionDialog(this.editor, "The rule package '" + rulePackageName + "' has no rules with visual representation or code defined.\nIt will therefore be ignored in the code generation", "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);

        continue;
      }

      String content = String.format(this.getTemplate("rulePackageClass"), this.packageName, rulePackageClassName, rulePackageBaseClassName, rulePackageClassName, rules.toString());

      File.writeFile(this.targetDirectory + rulePackageClassFileName, content);
    }
  }

  private void generate_rules() {
    for(JTabbedPane rulePane : this.editor.getRules()) {
      RulePanel rule = (RulePanel) rulePane;
      String ruleClassName = this.capitalizeWord(rule.toString().replaceAll(" ", "") + "Rule");
      String ruleClassFileName = ruleClassName + ".java";
      ImplementationPanel rImplementationPanel = rule.getImplementationPanel();

      // -- validating rule - begin --
      Triple<Boolean, HashMap<String, VariableContainer>, HashMap<String, VariableContainer>> resultTriple = this.validateRule(ruleClassName, rule);

      if(!resultTriple.getFirst()) {
        continue;
      }
      // -- validating rule - end --

      System.out.println(":: generating " + ruleClassFileName + "...");

      this.variableList_left = resultTriple.getSecond();
      this.globalCode = new StringBuffer(this.formatCode(rImplementationPanel.getAdditionalGlobalJavaCode(), "    ") + "\n");
      String additionalImportDeclarations = rImplementationPanel.getAdditionalImportDeclarations()+"\n";

      String startNodeClass = this.generate_check_method(rule);
      this.generate_replace_method(rule, resultTriple.getThird());

      String javaCode = String.format(this.getTemplate("ruleClass"), this.packageName, additionalImportDeclarations, ruleClassName, this.globalCode.toString(), ruleClassName, startNodeClass, rule.toString(), this.checkMethodCode.toString(), this.replaceMethodCode.toString());

      File.writeFile(this.targetDirectory + ruleClassFileName, javaCode);
    }
  }

  private String generate_check_method(RulePanel rule) {
    ImplementationPanel rImplementationPanel = rule.getImplementationPanel();
    RuleEditorPane rRuleEditorPane = rule.getRuleEditorPane();
    String startNodeClass = "";

    this.checkMethodCode = new StringBuffer();
    this.buffers = new LinkedList<StringBuffer>();

    if(rImplementationPanel.useGeneratedJavaCode_CheckMethod()) {
      RuleOperator startNode = rRuleEditorPane.getStartNode();
      startNodeClass = startNode.getClassType().getOpClass().getName();

      this.count_private = 0;

      int maxDimension = 0;
      StringBuffer spaces = new StringBuffer("    ");

      for(VariableContainer vc : this.variableList_left.values()) {
        this.globalCode.append(vc.declate_variable(spaces, true));

        maxDimension = Math.max(maxDimension, vc.getDimension());
      }

      for(int i = 0; i < maxDimension; i += 1) {
        this.globalCode.append("    private int _dim_" + i + " = -1;\n");
      }

      spaces = this.generate_checkPrivate(startNode, new HashSet<AbstractRuleOperator>(), new HashMap<Operator, HashSet<Operator>>(), 0);

      for(StringBuffer buffer : this.buffers) {
        this.globalCode.append(buffer);
      }

      if(!rImplementationPanel.getAdditionalCheckJavaCode().equals("")) {
        spaces.append("    ");

        this.checkMethodCode.append(
            spaces + "boolean _result = this._checkPrivate0(_op);\n" +
            "\n" +
            spaces + "if(_result) {\n" +
            spaces + "    // additional check method code...\n" +
            this.formatCode(rImplementationPanel.getAdditionalCheckJavaCode(), spaces.toString() + "    ").toString() + "\n" +
            spaces + "}\n" +
            "\n" +
            spaces + "return _result;"
        );
      }
      else {
        this.checkMethodCode.append(spaces + "    return this._checkPrivate0(_op);");
      }
    }
    else {
      startNodeClass = rImplementationPanel.getStartNodeClass();
      this.checkMethodCode.append(this.formatCode(rImplementationPanel.getCheckJavaCode(), "        ").toString());
    }

    return startNodeClass;
  }

  private StringBuffer generate_checkPrivate(AbstractRuleOperator startNode, HashSet<AbstractRuleOperator> visitedNodes, HashMap<Operator, HashSet<Operator>> visitedConnections, int currentDimension) {
    StringBuffer spaces = new StringBuffer("    ");
    StringBuffer buffer = new StringBuffer();
    this.buffers.add(buffer);

    buffer.append(
        "\n" +
        spaces + "private boolean _checkPrivate" + this.count_private + "(BasicOperator _op) {\n"
    );

    spaces.append("    ");

    this.count_private++;

    int bracesCount = this.manage_node(spaces, buffer, startNode, "_op", visitedNodes, visitedConnections, 0, currentDimension, "");

    buffer.append(
        "\n" +
        spaces + "return true;\n"
    );

    for(int i = 0; i < bracesCount; i += 1) {
      spaces.delete(spaces.length()-4, spaces.length());

      buffer.append(spaces + "}\n");
    }

    if(bracesCount > 0) {
      buffer.append(
          "\n" +
          spaces + "return false;\n"
      );
    }

    spaces.delete(spaces.length()-4, spaces.length());

    buffer.append(
        spaces + "}\n"
    );

    return spaces;
  }

  @SuppressWarnings("unchecked")
  private void generate_replace_method(RulePanel rule, HashMap<String, VariableContainer> variableList_right) {
    ImplementationPanel rImplementationPanel = rule.getImplementationPanel();
    RuleEditorPane rRuleEditorPane = rule.getRuleEditorPane();

    this.replaceMethodCode = new StringBuffer();
    StringBuffer spaces = new StringBuffer("        ");

    if(rImplementationPanel.useGeneratedJavaCode_ReplaceMethod()) {
      VisualGraph<Operator> leftGraph = rRuleEditorPane.getVisualGraphs().get(0);
      VisualGraph<Operator> rightGraph = rRuleEditorPane.getVisualGraphs().get(1);

      HashMap<String, AbstractRuleOperator> leftOperatorsMap = this.getOperatorsMap(leftGraph);
      HashMap<String, AbstractRuleOperator> rightOperatorsMap = this.getOperatorsMap(rightGraph);

      HashSet<String> leftOperators = new HashSet<String>(leftOperatorsMap.keySet());
      HashSet<String> rightOperators = new HashSet<String>(rightOperatorsMap.keySet());

      HashSet<String> originalLeftOperators = (HashSet<String>) leftOperators.clone();

      leftOperators.removeAll(rightOperators); // determine operators which are only on the left side
      rightOperators.removeAll(originalLeftOperators); // determine operators which are only on the right side


      LinkedList<HashSet<ConnectionContainer>> connections = rRuleEditorPane.getConnections();
      HashSet<ConnectionContainer> leftConnections = connections.get(0);
      HashSet<ConnectionContainer> rightConnections = connections.get(1);

      HashSet<ConnectionContainer> originalLeftConnections = (HashSet<ConnectionContainer>) leftConnections.clone();

      leftConnections.removeAll(rightConnections); // determine connections which are only on the left side
      rightConnections.removeAll(originalLeftConnections); // determine connections which are only on the right side


      // --- remove all connections that only occur on the left side - begin ---
      this.replaceMethodCode.append(
          spaces + "// remove obsolete connections...\n"
      );

      for(ConnectionContainer conn : leftConnections) {
        AbstractRuleOperator parentOp = conn.getParent();
        AbstractRuleOperator childOp = conn.getChild();
        String parentName = this.getJumpOverName(parentOp, false);
        String childName = this.getJumpOverName(childOp, true);

        String opIDLabel = conn.getOpIDLabel();
        boolean hasLabel = conn.getIsActive() && !opIDLabel.equals("");
        StringBuffer labelBrackets = new StringBuffer();

        String succeedingString = null;
        int dim = 0;
        StringBuffer arrayAccess = new StringBuffer();

        switch(conn.getMode()) {
        case ALL_PRECEDING:
          dim = this.variableList_left.get(childName).getDimension();

          if(hasLabel) {
            for(int i = 0; i <= dim; i += 1) {
              labelBrackets.append("[]");
            }

            this.replaceMethodCode.append(
                spaces + "int" + labelBrackets + " _label_" + opIDLabel + " = null;\n" +
                "\n"
            );
          }

          for(int i = 0; i < dim; i += 1) {
            if(hasLabel) {
              labelBrackets.delete(labelBrackets.length()-2, labelBrackets.length());

              this.replaceMethodCode.append(
                  spaces + "_label_" + opIDLabel + arrayAccess + " = new int[this." + childName + ".length]" + labelBrackets + ";\n" +
                  "\n"
              );
            }

            this.replaceMethodCode.append(spaces + "for(this._dim_" + i + " = 0; this._dim_" + i + " < this." + childName + ".length; this._dim_" + i + " += 1) {\n");

            arrayAccess.append("[this._dim_" + i + "]");

            spaces.append("    ");
          }

          succeedingString = (conn.getIsActive() && conn.getOpID() != -1) ? "new OperatorIDTuple(this." + childName + arrayAccess + ", " + conn.getOpID() + ")" : "this." + childName + arrayAccess;

          if(hasLabel) {
            labelBrackets.delete(labelBrackets.length()-2, labelBrackets.length());

            this.replaceMethodCode.append(
                spaces + "int _label_" + opIDLabel + "_count" + " = 0;\n" +
                spaces + "_label_" + opIDLabel + arrayAccess + " = new int[this." + parentName + arrayAccess + ".length]" + labelBrackets + ";\n" +
                "\n"
            );
          }

          this.replaceMethodCode.append(spaces + "for(" + parentOp.getClassType().getOpClass().getName() + " _parent : this." + parentName + arrayAccess + ") {\n");

          if(hasLabel) {
            this.replaceMethodCode.append(
                spaces + "    _label_" + opIDLabel + arrayAccess + "[_label_" + opIDLabel + "_count] = _parent.getOperatorIDTuple(this." + childName + arrayAccess + ").getId();\n" +
                spaces + "    _label_" + opIDLabel + "_count += 1;\n" +
                "\n"
            );
          }

          this.replaceMethodCode.append(
              spaces + "    _parent.removeSucceedingOperator(" + succeedingString + ");\n" +
              spaces + "    this." + childName + arrayAccess + ".removePrecedingOperator(_parent);\n" +
              spaces + "}\n" +
              "\n"
          );

          break;

        case ALL_SUCCEEDING:
          dim = this.variableList_left.get(parentName).getDimension();

          if(hasLabel) {
            for(int i = 0; i <= dim; i += 1) {
              labelBrackets.append("[]");
            }

            this.replaceMethodCode.append(
                spaces + "int" + labelBrackets + " _label_" + opIDLabel + " = null;\n" +
                "\n"
            );
          }

          for(int i = 0; i < dim; i += 1) {
            if(hasLabel) {
              labelBrackets.delete(labelBrackets.length()-2, labelBrackets.length());

              this.replaceMethodCode.append(
                  spaces + "_label_" + opIDLabel + arrayAccess + " = new int[this." + childName + ".length]" + labelBrackets + ";\n" +
                  "\n"
              );
            }

            this.replaceMethodCode.append(spaces + "for(this._dim_" + i + " = 0; this._dim_" + i + " < this." + parentName + ".length; this._dim_" + i + " += 1) {\n");

            arrayAccess.append("[this._dim_" + i + "]");

            spaces.append("    ");
          }

          succeedingString = (conn.getIsActive() && conn.getOpID() != -1) ? "new OperatorIDTuple(_child, " + conn.getOpID() + ")" : "_child";

          if(hasLabel) {
            labelBrackets.delete(labelBrackets.length()-2, labelBrackets.length());

            this.replaceMethodCode.append(
                spaces + "int _label_" + opIDLabel + "_count = 0;\n" +
                spaces + "_label_" + opIDLabel + arrayAccess + " = new int[this." + childName + arrayAccess + ".length]" + labelBrackets + ";\n" +
                "\n"
            );
          }

          this.replaceMethodCode.append(spaces + "for(" + childOp.getClassType().getOpClass().getName() + " _child : this." + childName + arrayAccess + ") {\n");

          if(hasLabel) {
            this.replaceMethodCode.append(
                spaces + "    _label_" + opIDLabel + arrayAccess + "[_label_" + opIDLabel + "_count] = this." + parentName + arrayAccess + ".getOperatorIDTuple(_child).getId();\n" +
                spaces + "    _label_" + opIDLabel + "_count += 1;\n" +
                "\n"
            );
          }

          this.replaceMethodCode.append(
              spaces + "    this." + parentName + arrayAccess + ".removeSucceedingOperator(" + succeedingString + ");\n" +
              spaces + "    _child.removePrecedingOperator(this." + parentName + arrayAccess + ");\n" +
              spaces + "}\n" +
              "\n"
          );

          break;

        default:
          dim = this.variableList_left.get(parentName).getDimension();

          if(hasLabel) {
            for(int i = 0; i <= dim; i += 1) {
              labelBrackets.append("[]");
            }

            this.replaceMethodCode.append(
                spaces + "int" + labelBrackets + " _label_" + opIDLabel + " = null;\n" +
                "\n"
            );
          }

          for(int i = 0; i < dim; i += 1) {
            if(hasLabel) {
              labelBrackets.delete(labelBrackets.length()-2, labelBrackets.length());

              this.replaceMethodCode.append(
                  spaces + "_label_" + opIDLabel + arrayAccess + " = new int[this." + childName + ".length]" + labelBrackets + ";\n" +
                  "\n"
              );
            }

            this.replaceMethodCode.append(spaces + "for(this._dim_" + i + " = 0; this._dim_" + i + " < this." + parentName + ".length; this._dim_" + i + " += 1) {\n");

            arrayAccess.append("[this._dim_" + i + "]");

            spaces.append("    ");
          }

          succeedingString = (conn.getIsActive() && conn.getOpID() != -1) ? "new OperatorIDTuple(this." + childName + arrayAccess + ", " + conn.getOpID() + ")" : "this." + childName + arrayAccess;

          if(hasLabel) {
            labelBrackets.delete(labelBrackets.length()-2, labelBrackets.length());

            this.replaceMethodCode.append(
                spaces + "    _label_" + opIDLabel + arrayAccess + " = this." + parentName + arrayAccess + ".getOperatorIDTuple(this." + childName + arrayAccess + ").getId();\n" +
                "\n"
            );
          }

          this.replaceMethodCode.append(
              spaces + "this." + parentName + arrayAccess + ".removeSucceedingOperator(" + succeedingString + ");\n" +
              spaces + "this." + childName + arrayAccess + ".removePrecedingOperator(this." + parentName + arrayAccess + ");\n"
          );

          break;
        }

        for(int i = 0; i < dim; i += 1) {
          spaces.delete(spaces.length()-4, spaces.length());

          this.replaceMethodCode.append(spaces + "}\n");
        }
      }
      // --- remove all connections that only occur on the left side - end ---

      // --- add operators that only occur on the right side - begin ---
      this.replaceMethodCode.append(
          "\n" +
          spaces + "// add new operators...\n"
      );

      for(String opName : rightOperators) {
        AbstractRuleOperator op = rightOperatorsMap.get(opName);
        String opClass = op.getClassType().getOpClass().getName();
        VariableContainer vc = variableList_right.get(opName);
        int dim = vc.getDimension();
        StringBuffer arrayAccess = new StringBuffer();

        for(int i = 0; i < dim; i += 1) {
          arrayAccess.append("[]");
        }

        this.replaceMethodCode.append(spaces + opClass + arrayAccess + " " + opName + " = null;\n");

        arrayAccess = new StringBuffer();

        for(int i = 0; i < dim; i += 1) {
          this.replaceMethodCode.append(
              vc.initiate_next_dimension(spaces, i, this.getOpName(vc.getCountProvider(), rightOperators, true) + arrayAccess + ".length", false) +
              "\n" +
              spaces + "for(this._dim_" + i + " = 0; this._dim_" + i + " < " + opName + arrayAccess + ".length; this._dim_" + i + " += 1) {\n"
          );

          spaces.append("    ");
          arrayAccess.append("[this._dim_" + i + "]");
        }

        this.replaceMethodCode.append(spaces + opName + arrayAccess + " = new " + opClass + "();\n");

        if(this.generateStartMap) {
          this.replaceMethodCode.append(spaces + "this.addNodeToStartNodeMap(" + opName + arrayAccess + ", _startNodes);\n");
        }

        for(int i = 0; i < dim; i += 1) {
          spaces.delete(spaces.length()-4, spaces.length());

          this.replaceMethodCode.append(spaces + "}\n");
        }
      }

      this.replaceMethodCode.append("\n");
      // --- add operators that only occur on the right side - end ---

      // --- add connections that only occur on the right side - begin ---
      this.replaceMethodCode.append(
          "\n" +
          spaces + "// add new connections...\n"
      );

      for(ConnectionContainer conn : rightConnections) {
        AbstractRuleOperator parentOp = conn.getParent();
        AbstractRuleOperator childOp = conn.getChild();
        String parentName = this.getOpName(parentOp, rightOperators, false);
        String childName = this.getOpName(childOp, rightOperators, true);
        VariableContainer parentVC = variableList_right.get(this.getJumpOverName(parentOp, false));
        VariableContainer childVC = variableList_right.get(this.getJumpOverName(childOp, true));

        String opIDLabel = conn.getOpIDLabel();
        boolean hasLabel = conn.getIsActive() && !opIDLabel.equals("");

        int dim = 0;
        StringBuffer arrayAccess = new StringBuffer();
        String succeedingString = "";

        switch(conn.getMode()) {
        case ALL_PRECEDING:
          dim = childVC.getDimension();

          for(int i = 0; i < dim; i += 1) {
            this.replaceMethodCode.append(spaces + "for(this._dim_" + i + " = 0; this._dim_" + i + " < " + childName + ".length; this._dim_" + i + " += 1) {\n");

            arrayAccess.append("[this._dim_" + i + "]");

            spaces.append("    ");
          }

          if(conn.getIsActive()) {
            if(hasLabel) {
              succeedingString = "new OperatorIDTuple(" + childName + arrayAccess + ", _label_" + conn.getOpIDLabel() + arrayAccess + "[_label_" + opIDLabel + "_count])";

              this.replaceMethodCode.append(
                  spaces + "_label_" + opIDLabel + "_count = 0;\n" +
                  "\n"
              );
            }
            else {
              succeedingString = "new OperatorIDTuple(" + childName + arrayAccess + ", " + conn.getOpID() + ")";
            }
          }
          else {
            succeedingString = childName + arrayAccess;
          }

          this.replaceMethodCode.append(
              spaces + "for(" + parentOp.getClassType().getOpClass().getName() + " _parent : " + parentName + arrayAccess + ") {\n" +
              spaces + "    _parent.addSucceedingOperator(" + succeedingString + ");\n" +
              spaces + "    " + childName + arrayAccess + ".addPrecedingOperator(_parent);\n"
          );

          if(hasLabel) {
            this.replaceMethodCode.append(
                "\n" +
                spaces + "    _label_" + opIDLabel + "_count += 1;\n"
            );
          }

          this.replaceMethodCode.append(
              spaces + "}\n" +
              "\n"
          );

          break;

        case ALL_SUCCEEDING:
          dim = parentVC.getDimension();

          for(int i = 0; i < dim; i += 1) {
            this.replaceMethodCode.append(spaces + "for(this._dim_" + i + " = 0; this._dim_" + i + " < " + parentName + ".length; this._dim_" + i + " += 1) {\n");

            arrayAccess.append("[this._dim_" + i + "]");

            spaces.append("    ");
          }

          if(conn.getIsActive()) {
            if(hasLabel) {
              succeedingString = "new OperatorIDTuple(_child, _label_" + conn.getOpIDLabel() + arrayAccess + "[_label_" + opIDLabel + "_count])";

              this.replaceMethodCode.append(
                  spaces + "_label_" + opIDLabel + "_count = 0;\n" +
                  "\n"
              );
            }
            else {
              succeedingString = "new OperatorIDTuple(_child, " + conn.getOpID() + ")";
            }
          }
          else {
            succeedingString = "_child";
          }

          this.replaceMethodCode.append(
              spaces + "for(" + childOp.getClassType().getOpClass().getName() + " _child : " + childName + arrayAccess + ") {\n" +
              spaces + "    " + parentName + arrayAccess + ".addSucceedingOperator(" + succeedingString + ");\n" +
              spaces + "    _child.addPrecedingOperator(" + parentName + arrayAccess + ");\n"
          );

          if(hasLabel) {
            this.replaceMethodCode.append(
                "\n" +
                spaces + "    _label_" + opIDLabel + "_count += 1;\n"
            );
          }

          this.replaceMethodCode.append(
              spaces + "}\n" +
              "\n"
          );

          break;

        default:
          dim = parentVC.getDimension();

          for(int i = 0; i < dim; i += 1) {
            this.replaceMethodCode.append(spaces + "for(this._dim_" + i + " = 0; this._dim_" + i + " < " + parentName + ".length; this._dim_" + i + " += 1) {\n");

            arrayAccess.append("[this._dim_" + i + "]");

            spaces.append("    ");
          }

          if(conn.getIsActive()) {
            if(hasLabel) {
              succeedingString = "new OperatorIDTuple(" + childName + arrayAccess + ", _label_" + conn.getOpIDLabel() + arrayAccess + ")";
            }
            else {
              succeedingString = "new OperatorIDTuple(" + childName + arrayAccess + ", " + conn.getOpID() + ")";
            }
          }
          else {
            succeedingString = childName + arrayAccess;
          }

          this.replaceMethodCode.append(
              spaces + parentName + arrayAccess + ".addSucceedingOperator(" + succeedingString + ");\n" +
              spaces + childName + arrayAccess + ".addPrecedingOperator(" + parentName + arrayAccess + ");\n"
          );
        }

        for(int i = 0; i < dim; i += 1) {
          spaces.delete(spaces.length()-4, spaces.length());

          this.replaceMethodCode.append(spaces + "}\n");
        }

        this.replaceMethodCode.append("\n");
      }
      // --- add connections that only occur on the right side - begin ---

      // --- delete operators from left side which are not needed anymore - begin ---
      if(leftOperators.size() > 0) {
        this.replaceMethodCode.append(
            "\n" +
            spaces + "// delete unreachable operators...\n"
        );

        for(String opName : leftOperators) {
          int dim = this.variableList_left.get(opName).getDimension();
          StringBuffer arrayAccess = new StringBuffer();

          for(int i = 0; i < dim; i += 1) {
            this.replaceMethodCode.append(spaces + "for(this._dim_" + i + " = 0; this._dim_" + i + " < " + opName + ".length; this._dim_" + i + " += 1) {\n");

            arrayAccess.append("[this._dim_" + i + "]");

            spaces.append("    ");
          }

          this.replaceMethodCode.append(spaces + "this.deleteOperatorWithoutParentsRecursive(this." + opName + arrayAccess + ", _startNodes);\n");

          for(int i = 0; i < dim; i += 1) {
            spaces.delete(spaces.length()-4, spaces.length());

            this.replaceMethodCode.append(spaces + "}\n");
          }

          if(dim > 0) {
            this.replaceMethodCode.append("\n");
          }
        }

        this.replaceMethodCode.append("\n");
      }
      // --- delete operators from left side which are not needed anymore - end ---

      this.replaceMethodCode.append(
          "\n" +
          spaces + "// additional replace method code...\n" +
          this.formatCode(rImplementationPanel.getAdditonalReplaceJavaCode(), spaces.toString()).toString()
      );
    }
    else {
      this.replaceMethodCode.append(this.formatCode(rImplementationPanel.getReplaceJavaCode(), spaces.toString()).toString());
    }
  }

  private HashMap<String, AbstractRuleOperator> getOperatorsMap(VisualGraph<Operator> vg) {
    HashMap<String, AbstractRuleOperator> operators = new HashMap<String, AbstractRuleOperator>();

    for(GraphWrapper gw : vg.getBoxes().keySet()) {
      AbstractRuleOperator op = (AbstractRuleOperator) gw.getElement();

      operators.put(op.getName(), op);
    }

    return operators;
  }

  private String getOpName(AbstractRuleOperator op, HashSet<String> opList) {
    String opName = op.getName();

    if(!opList.contains(opName)) {
      return "this." + opName;
    }
    else {
      return opName;
    }
  }

  private String getOpName(AbstractRuleOperator op, HashSet<String> opList, boolean begin) {
    String opName = this.getOpName(op, opList);

    if(op.getClass() == JumpOverOperator.class) {
      opName += (begin) ? "_begin" : "_end";
    }

    return opName;
  }

  private String getJumpOverName(AbstractRuleOperator op, boolean begin) {
    String opName = op.getName();

    if(op.getClass() == JumpOverOperator.class) {
      opName += (begin) ? "_begin" : "_end";
    }

    return opName;
  }


  private int manage_node(StringBuffer spaces, StringBuffer buffer, AbstractRuleOperator node, String nodeName, HashSet<AbstractRuleOperator> visitedNodes, HashMap<Operator, HashSet<Operator>> visitedConnections, int runNumber, int currentDimension, String testName) {
    runNumber++;

    int bracesCount = 0;
    String originalNodeName = nodeName;

    if(visitedNodes.contains(node)) {
      return bracesCount;
    }

    visitedNodes.add(node);

    // --- compare nodes - begin ---
    if(node.getClass() != JumpOverOperator.class) {
      String ruleNodeClass = node.getClassType().getOpClass().getName();

      if(node.alsoSubClasses()) {
        buffer.append(spaces + "if(!("+ nodeName + " instanceof " + ruleNodeClass + ")) {\n");
      }
      else {
        buffer.append(spaces + "if("+ nodeName + ".getClass() != " + ruleNodeClass + ".class) {\n");
      }

      buffer.append(
          spaces + "    " + ((runNumber != 1) ? "continue" : "return false") + ";\n" +
          spaces + "}\n"
      );
    }

    String opName = node.getName();

    if(node.getClass() != JumpOverOperator.class) {
      buffer.append(
          "\n" +
          spaces + this.variableList_left.get(opName).assign_variable(nodeName)
      );
    }
    // --- compare nodes - end ---


    LinkedList<Operator> precedingOperators = node.getPrecedingOperators();

    if(precedingOperators.size() > 0) {
      boolean added = false;
      int precedingIndex = 0;

      for(int i = 0; i < precedingOperators.size(); i += 1) {
        AbstractRuleOperator precOp = (AbstractRuleOperator) precedingOperators.get(i);


        HashSet<Operator> connectionNodes = visitedConnections.get(precOp);

        if(connectionNodes == null) {
          connectionNodes = new HashSet<Operator>();
          visitedConnections.put(precOp, connectionNodes);
        }
        else if(connectionNodes.contains(node)) {
          continue;
        }

        connectionNodes.add(node);


        if(!added) {
          buffer.append(
              "\n" +
              spaces + "List<BasicOperator> _precedingOperators_" + runNumber + "_" + i + " = " + nodeName + ".getPrecedingOperators();\n" +
              "\n"
          );

          added = true;
          precedingIndex = i;
        }


        AnnotationPanel panel = (AnnotationPanel) precOp.getAnnotationLabel(node);

        switch(panel.getMode()) {
        case ONLY_PRECEDING_AND_SUCCEEDING:
        case ONLY_PRECEDING:
          if(node.getClass() == JumpOverOperator.class) {
            buffer.append(
                spaces + "if(" + testName + " != " + originalNodeName + ") {\n"
            );

            spaces.append("    ");
          }

          buffer.append(
              spaces + "if(_precedingOperators_" + runNumber + "_" + precedingIndex + ".size() != 1) {\n" +
              spaces + "    " + ((runNumber != 1) ? "continue" : "return false") + ";\n" +
              spaces + "}\n"
          );

          if(node.getClass() == JumpOverOperator.class) {
            spaces.delete(spaces.length()-4, spaces.length());

            buffer.append(spaces + "}\n");
          }

          break;

        case ALL_PRECEDING:
          buffer.append(
              "\n" +
              spaces + "this._dim_" + currentDimension + " = -1;\n"
          );

          for(String variable : this.get_variables_for_next_dimension(precOp, true)) {
            VariableContainer vc = this.variableList_left.get(variable);

            buffer.append(vc.initiate_next_dimension(spaces, currentDimension, "_precedingOperators_" + runNumber + "_" + precedingIndex + ".size()", true));
          }

          break;
        }

        buffer.append(
            "\n" +
            spaces + "for(BasicOperator _precOp_" + runNumber + "_" + i + " : _precedingOperators_" + runNumber + "_" + precedingIndex + ") {\n"
        );

        bracesCount++;
        spaces.append("    ");

        switch(panel.getMode()) {
        case ALL_PRECEDING:
          buffer.append(
              spaces + "this._dim_" + currentDimension + " += 1;\n" +
              "\n"
          );
          break;
        }

        if(panel.isActive()) {
          int opID = panel.getOpID();

          if(opID != -1) {
            buffer.append(
                spaces + "if(_precOp_" + runNumber + "_" + i + ".getOperatorIDTuple(" + nodeName + ").getId() != " + opID + ") {\n" +
                spaces + "    continue;\n" +
                spaces + "}\n" +
                "\n"
            );
          }
        }

        String nextOpName = "_precOp_" + runNumber + "_" + i;
        testName = "";

        switch(panel.getMode()) {
        default:
        case EXISTS:
          if(precOp.getClass() == JumpOverOperator.class) {
            String[] data = this.handleJumpOverOperator(spaces, buffer, (JumpOverOperator) precOp, nextOpName, runNumber, 0, true);
            nextOpName = data[0];
            testName = data[1];
          }

          bracesCount += this.manage_node(spaces, buffer, precOp, nextOpName, visitedNodes, visitedConnections, runNumber, currentDimension, testName);

          break;
        case ALL_PRECEDING:
          buffer.append(
              spaces + "if(!this._checkPrivate" + this.count_private + "(" + nextOpName + ")) {\n" +
              spaces + "    return false;\n" +
              spaces + "}\n"
          );

          this.generate_checkPrivate(precOp, visitedNodes, visitedConnections, currentDimension+1);

          spaces.delete(spaces.length()-4, spaces.length());

          buffer.append(spaces + "}\n");
          bracesCount -= 1;

          break;
        case ALL_SUCCEEDING:
          System.err.println("WARNING: This case should never happen!");

          break;
        case ONLY_PRECEDING_AND_SUCCEEDING:
        case ONLY_SUCCEEDING:
          buffer.append(
              spaces + "if(" + nextOpName + ".getSucceedingOperators().size() != 1) {\n" +
              spaces + "    break;\n" +
              spaces + "}\n" +
              "\n"
          );

          if(precOp.getClass() == JumpOverOperator.class) {
            String[] data = this.handleJumpOverOperator(spaces, buffer, (JumpOverOperator) precOp, nextOpName, runNumber, 0, true);
            nextOpName = data[0];
            testName = data[1];
          }

          bracesCount += this.manage_node(spaces, buffer, precOp, nextOpName, visitedNodes, visitedConnections, runNumber, currentDimension, testName);

          break;
        }
      }
    }


    LinkedList<OperatorIDTuple<Operator>> succedingOperators = node.getSucceedingOperators();

    if(succedingOperators.size() > 0) {
      boolean added = false;
      int succedingIndex = 0;

      for(int i = 0; i < succedingOperators.size(); i += 1) {
        OperatorIDTuple<Operator> sucOpIDTup = succedingOperators.get(i);
        AbstractRuleOperator sucOp = (AbstractRuleOperator) sucOpIDTup.getOperator();


        HashSet<Operator> connectionNodes = visitedConnections.get(node);

        if(connectionNodes == null) {
          connectionNodes = new HashSet<Operator>();
          visitedConnections.put(node, connectionNodes);
        }
        else if(connectionNodes.contains(sucOp)) {
          continue;
        }

        connectionNodes.add(sucOp);


        if(!added) {
          buffer.append(
              "\n" +
              spaces + "List<OperatorIDTuple> _succedingOperators_" + runNumber + "_" + i + " = " + nodeName + ".getSucceedingOperators();\n" +
              "\n"
          );

          added = true;
          succedingIndex = i;
        }


        AnnotationPanel panel = (AnnotationPanel) node.getAnnotationLabel(sucOp);

        switch(panel.getMode()) {
        case ONLY_PRECEDING_AND_SUCCEEDING:
        case ONLY_SUCCEEDING:
          buffer.append(
              spaces + "if(_succedingOperators_" + runNumber + "_" + succedingIndex + ".size() != 1) {\n" +
              spaces + "    " + ((runNumber != 1) ? "continue" : "return false") + ";\n" +
              spaces + "}\n"
          );

          break;


        case ALL_SUCCEEDING:
          buffer.append(
              "\n" +
              spaces + "this._dim_" + currentDimension + " = -1;\n"
          );

          for(String variable : this.get_variables_for_next_dimension(sucOp, false)) {
            VariableContainer vc = this.variableList_left.get(variable);

            buffer.append(vc.initiate_next_dimension(spaces, currentDimension, "_succedingOperators_" + runNumber + "_" + succedingIndex + ".size()", true));
          }

          break;
        }


        buffer.append(
            "\n" +
            spaces + "for(OperatorIDTuple _sucOpIDTup_" + runNumber + "_" + i + " : _succedingOperators_" + runNumber + "_" + succedingIndex + ") {\n"
        );

        bracesCount++;
        spaces.append("    ");

        switch(panel.getMode()) {
        case ALL_SUCCEEDING:
          buffer.append(
              spaces + "this._dim_" + currentDimension + " += 1;\n" +
              "\n"
          );
          break;
        }


        if(panel.isActive()) {
          int opID = panel.getOpID();

          if(opID != -1) {
            buffer.append(
                spaces + "if(_sucOpIDTup_" + runNumber + "_" + i + ".getId() != " + opID + ") {\n" +
                spaces + "    continue;\n" +
                spaces + "}\n" +
                "\n"
            );
          }
        }

        String nextOpName = "_sucOpIDTup_" + runNumber + "_" + i + ".getOperator()";
        testName = "";

        switch(panel.getMode()) {
        default:
        case EXISTS:
          if(sucOp.getClass() == JumpOverOperator.class) {
            String[] data = this.handleJumpOverOperator(spaces, buffer, (JumpOverOperator) sucOp, nextOpName, runNumber, 0, false);
            nextOpName = data[0];
            testName = data[1];
          }

          bracesCount += this.manage_node(spaces, buffer, sucOp, nextOpName, visitedNodes, visitedConnections, runNumber, currentDimension, testName);

          break;
        case ALL_SUCCEEDING:
          buffer.append(
              spaces + "if(!this._checkPrivate" + this.count_private + "(" + nextOpName + ")) {\n" +
              spaces + "    return false;\n" +
              spaces + "}\n"
          );

          this.generate_checkPrivate(sucOp, visitedNodes, visitedConnections, currentDimension+1);

          spaces.delete(spaces.length()-4, spaces.length());

          buffer.append(spaces + "}\n");
          bracesCount -= 1;

          break;
        case ALL_PRECEDING:
          System.err.println("WARNING: This case should never happen!");

          break;
        case ONLY_PRECEDING_AND_SUCCEEDING:
        case ONLY_PRECEDING:
          buffer.append(
              spaces + "if(" + nextOpName + ".getPrecedingOperators().size() != 1) {\n" +
              spaces + "    break;\n" +
              spaces + "}\n" +
              "\n"
          );

          if(sucOp.getClass() == JumpOverOperator.class) {
            String[] data = this.handleJumpOverOperator(spaces, buffer, (JumpOverOperator) sucOp, nextOpName, runNumber, 0, false);
            nextOpName = data[0];
            testName = data[1];
          }

          bracesCount += this.manage_node(spaces, buffer, sucOp, nextOpName, visitedNodes, visitedConnections, runNumber, currentDimension, testName);

          break;
        }
      }
    }

    return bracesCount;
  }

  private HashSet<String> get_variables_for_next_dimension(AbstractRuleOperator node, boolean preceding) {
    HashSet<String> variables = new HashSet<String>();

    this.get_variables_for_next_dimension(node, preceding, variables, new HashSet<AbstractRuleOperator>());

    return variables;
  }

  private void get_variables_for_next_dimension(AbstractRuleOperator node, boolean preceding, HashSet<String> variables, HashSet<AbstractRuleOperator> visitedNodes) {
    if(visitedNodes.contains(node)) {
      return;
    }

    visitedNodes.add(node);


    String variableName = node.getName();

    if(node.getClass() != JumpOverOperator.class) {
      variables.add(variableName);
    }
    else {
      variables.add(variableName + "_begin");
      variables.add(variableName + "_end");
    }


    if(preceding) {
      for(Operator precOp : node.getPrecedingOperators()) {
        this.get_variables_for_next_dimension((AbstractRuleOperator) precOp, preceding, variables, visitedNodes);
      }
    }
    else {
      for(OperatorIDTuple<Operator> sucIDt : node.getSucceedingOperators()) {
        this.get_variables_for_next_dimension((AbstractRuleOperator) sucIDt.getOperator(), preceding, variables, visitedNodes);
      }
    }
  }

  private String[] handleJumpOverOperator(StringBuffer spaces, StringBuffer buffer, JumpOverOperator jumpOp, String opName, int runNumber, int i, boolean preceding) {
    String cardinality = jumpOp.getCardinality();

    StringBuffer condition = new StringBuffer("(");
    String getNextString = "";

    buffer.append(spaces + "// --- handle JumpOver - begin ---\n");

    if(preceding) {
      getNextString = ".getPrecedingOperators().get(0)";

      buffer.append(spaces + this.variableList_left.get(jumpOp.getName() + "_end").assign_variable(opName));

      for(Operator tmpOp : jumpOp.getPrecedingOperators()) {
        AbstractRuleOperator tmpOp2 = (AbstractRuleOperator) tmpOp;

        if(tmpOp2.alsoSubClasses()) {
          Class<?> clazz = jumpOp.getClassType().getOpClass().getSuperclass();

          boolean moreGeneric = false;

          while(clazz != Object.class) {
            if(clazz == tmpOp2.getClassType().getOpClass()) {
              moreGeneric = true;
              break;
            }

            clazz = clazz.getSuperclass();
          }

          if(moreGeneric) {
            if(jumpOp.alsoSubClasses()) {
              condition.append("_searchIndex_" + runNumber + "_" + i + " instanceof " + jumpOp.getClassType().getOpClass().getName());
            }
            else {
              condition.append("_searchIndex_" + runNumber + "_" + i + ".getClass() == " + jumpOp.getClassType().getOpClass().getName() + ".class");
            }
          }
          else {
            condition.append("!(_searchIndex_" + runNumber + "_" + i + " instanceof " + tmpOp2.getClassType().getOpClass().getName() + ")");
          }
        }
        else {
          condition.append("_searchIndex_" + runNumber + "_" + i + ".getClass() != " + tmpOp2.getClassType().getOpClass().getName() + ".class");
        }

        condition.append(" || ");
      }
    }
    else {
      getNextString = ".getSucceedingOperators().get(0).getOperator()";

      buffer.append(spaces + this.variableList_left.get(jumpOp.getName() + "_begin").assign_variable(opName));

      for(OperatorIDTuple<Operator> tmpOp : jumpOp.getSucceedingOperators()) {
        AbstractRuleOperator tmpOp2 = (AbstractRuleOperator) tmpOp.getOperator();

        if(tmpOp2.alsoSubClasses()) {
          Class<?> clazz = jumpOp.getClassType().getOpClass().getSuperclass();

          boolean moreGeneric = false;

          while(clazz != Object.class) {
            if(clazz == tmpOp2.getClassType().getOpClass()) {
              moreGeneric = true;
              break;
            }

            clazz = clazz.getSuperclass();
          }

          if(moreGeneric) {
            if(jumpOp.alsoSubClasses()) {
              condition.append("_searchIndex_" + runNumber + "_" + i + " instanceof " + jumpOp.getClassType().getOpClass().getName());
            }
            else {
              condition.append("_searchIndex_" + runNumber + "_" + i + ".getClass() == " + jumpOp.getClassType().getOpClass().getName() + ".class");
            }
          }
          else {
            condition.append("!(_searchIndex_" + runNumber + "_" + i + " instanceof " + tmpOp2.getClassType().getOpClass().getName() + ")");
          }
        }
        else {
          condition.append("_searchIndex_" + runNumber + "_" + i + ".getClass() != " + tmpOp2.getClassType().getOpClass().getName() + ".class");
        }

        condition.append(" || ");
      }
    }

    condition.delete(condition.length()-4, condition.length());

    condition.append(")");

    StringBuffer cardinalityCheckBegin = new StringBuffer();
    StringBuffer cardinalityCheckMiddle = new StringBuffer();
    StringBuffer cardinalityCheckEnd = new StringBuffer();

    buffer.append(spaces + "BasicOperator _searchIndex_" + runNumber + "_" + i + " = " + opName + ";\n");

    if(cardinality.equals("*")) {
      cardinalityCheckBegin.append(
          spaces + "boolean _continueFlag_" + runNumber + "_" + i + " = false;\n" +
          "\n" +
          spaces + "while(_searchIndex_" + runNumber + "_" + i + " != null && " + condition + ") {\n"
      );

      cardinalityCheckMiddle.append(
          spaces + "        _continueFlag_" + runNumber + "_" + i + " = true;\n" +
          spaces + "        break;\n"
      );

      cardinalityCheckEnd.append(
          spaces + "    _searchIndex_" + runNumber + "_" + i + " = _searchIndex_" + runNumber + "_" + i + getNextString + ";\n" +
          spaces + "}\n" +
          "\n" +
          spaces + "if(_continueFlag_" + runNumber + "_" + i + ") {\n" +
          spaces + "    continue;\n" +
          spaces + "}\n"
      );
    }
    else if(cardinality.equals("+")) {
      cardinalityCheckBegin.append(
          spaces + "boolean _continueFlag_" + runNumber + "_" + i + " = false;\n" +
          "\n" +
          spaces + "do {\n"
      );

      cardinalityCheckMiddle.append(
          spaces + "        _continueFlag_" + runNumber + "_" + i + " = true;\n" +
          spaces + "        break;\n"
      );

      cardinalityCheckEnd.append(
          spaces + "    _searchIndex_" + runNumber + "_" + i + " = _searchIndex_" + runNumber + "_" + i + getNextString + ";\n" +
          spaces + "} while(_searchIndex_" + runNumber + "_" + i + " != null && " + condition + ")\n" +
          "\n" +
          spaces + "if(_continueFlag_" + runNumber + "_" + i + ") {\n" +
          spaces + "    continue;\n" +
          spaces + "}\n"
      );
    }
    else if(cardinality.equals("?")) {
      cardinalityCheckBegin.append(spaces + "if(_searchIndex_" + runNumber + "_" + i + " != null && " + condition + ") {\n");

      cardinalityCheckMiddle.append(spaces + "        continue;\n");

      cardinalityCheckEnd.append(spaces + "}\n");
    }

    buffer.append(cardinalityCheckBegin);

    if(jumpOp.alsoSubClasses()) {
      buffer.append(spaces + "    if(!(_searchIndex_" + runNumber + "_" + i + " instanceof " + jumpOp.getClassType().getOpClass().getName() + ")) {\n");
    }
    else {
      buffer.append(spaces + "    if(_searchIndex_" + runNumber + "_" + i + ".getClass() != " + jumpOp.getClassType().getOpClass().getName() + ".class) {\n");
    }

    buffer.append(cardinalityCheckMiddle);
    buffer.append(
        spaces + "    }\n" +
        "\n"
    );

    if(!jumpOp.getConditions().equals("")) {
      buffer.append(
          spaces + "    " + jumpOp.getClassType().getOpClass().getName() + " " + jumpOp.getName() + " = (" + jumpOp.getClassType().getOpClass().getName() + ") _searchIndex_" + runNumber + "_" + i + ";\n" +
          "\n" +
          spaces + "    " + jumpOp.getConditions() + "\n" +
          "\n"
      );
    }

    buffer.append(
        spaces + "    if(_searchIndex_" + runNumber + "_" + i + ".getSucceedingOperators().size() != 1 || _searchIndex_" + runNumber + "_" + i + ".getPrecedingOperators().size() != 1) {\n" +
        cardinalityCheckMiddle +
        spaces + "    }\n" +
        "\n" +
        cardinalityCheckEnd +
        "\n"
    );

    String newNodeName = jumpOp.getName();

    if(preceding) {
      newNodeName += "_begin";

      buffer.append(spaces + this.variableList_left.get(newNodeName).assign_variable("_searchIndex_" + runNumber + "_" + i + ".getSucceedingOperators().get(0).getOperator()"));
    }
    else {
      newNodeName += "_end";

      buffer.append(spaces + this.variableList_left.get(newNodeName).assign_variable("_searchIndex_" + runNumber + "_" + i + ".getPrecedingOperators().get(0)"));
    }

    buffer.append(
        spaces + "// --- handle JumpOver - end ---\n" +
        "\n"
    );

    //    return "_searchIndex_" + runNumber + "_" + i;

    String[] ret = {"this." + newNodeName, "_searchIndex_" + runNumber + "_" + i};

    return ret;
  }

  private String getTemplate(String templateName) {
    if(!this.templates.containsKey(templateName)) {
      this.templates.put(templateName, File.readFile(RuleEditor.class.getResource("/code/code_" + templateName + ".tpl").getFile()));
    }

    return this.templates.get(templateName);
  }

  private String capitalizeWord(String word) {
    StringBuffer str = new StringBuffer(word);

    str.replace(0, 1, str.substring(0, 1).toUpperCase());

    return str.toString();
  }

  private StringBuffer formatCode(String code, String spaces) {
    StringBuffer buffer = new StringBuffer();

    String[] lines = code.split("\n");

    if(lines.length == 1 && lines[0].equals("")) {
      return buffer;
    }

    for(int i = 0; i < lines.length; i += 1) {
      buffer.append(spaces + lines[i]);

      if(i != lines.length-1) {
        buffer.append("\n");
      }
    }

    return buffer;
  }

  private Triple<Boolean, HashMap<String, VariableContainer>, HashMap<String, VariableContainer>> validateRule(String ruleName, RulePanel rule) {
    Triple<Boolean, HashMap<String, VariableContainer>, HashMap<String, VariableContainer>> resultTriple = this.validatedRules.get(ruleName);

    if(resultTriple == null) {
      System.out.print(":: validating rule '" + ruleName + "'... ");

      RuleEditorPane ruleEditorPane = rule.getRuleEditorPane();
      ImplementationPanel implementationPanel = rule.getImplementationPanel();

      resultTriple = ruleEditorPane.validateGraphs();

      if(resultTriple.getFirst()) {
        if(ruleEditorPane.getVisualGraphs().get(0).isEmpty() && ruleEditorPane.getVisualGraphs().get(1).isEmpty()
            && implementationPanel.getAdditionalCheckJavaCode().isEmpty() && implementationPanel.getCheckJavaCode().isEmpty()
            && implementationPanel.getAdditonalReplaceJavaCode().isEmpty() && implementationPanel.getReplaceJavaCode().isEmpty()) {
          JOptionPane.showOptionDialog(this.editor, "The rule '" + ruleName + "' has no visual representation and no code defined.\nIt will therefore be ignored in the code generation", "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);

          resultTriple = new Triple<Boolean, HashMap<String, VariableContainer>, HashMap<String, VariableContainer>>(false, null, null);

          System.out.println("PASSED WITH WARNING");
        }
        else {
          System.out.println("OK");
        }
      }
      else if(!resultTriple.getFirst()) {
        System.err.println("FAILED");
      }

      this.validatedRules.put(ruleName, resultTriple);
    }

    return resultTriple;
  }
}
TOP

Related Classes of lupos.gui.operatorgraph.visualeditor.ruleeditor.generators.JavaCodeGenerator

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.