Пример #1
0
  @Override
  public VPackage parse() {

    logger.debug("Starting parsing package: " + xmlFile.getAbsolutePath());

    long startParsing = System.currentTimeMillis();

    try {
      Document document = getDocument();
      Element root = document.getDocumentElement();

      _package = new VPackage(xmlFile);

      Node name = root.getElementsByTagName(EL_NAME).item(0);
      _package.setName(name.getTextContent());
      Node descr = root.getElementsByTagName(EL_DESCRIPTION).item(0);
      _package.setDescription(descr.getTextContent());

      NodeList list = root.getElementsByTagName(EL_CLASS);

      boolean initPainters = false;
      for (int i = 0; i < list.getLength(); i++) {
        PackageClass pc = parseClass((Element) list.item(i));
        if (pc.getPainterName() != null) {
          initPainters = true;
        }
      }

      if (initPainters) {
        _package.initPainters();
      }

      logger.info(
          "Parsing the package '{}' finished in {}ms.\n",
          _package.getName(),
          (System.currentTimeMillis() - startParsing));
    } catch (Exception e) {
      collector.collectDiagnostic(e.getMessage(), true);
      if (RuntimeProperties.isLogDebugEnabled()) {
        e.printStackTrace();
      }
    }

    try {
      checkProblems("Error parsing package file " + xmlFile.getName());
    } catch (Exception e) {
      return null;
    }

    return _package;
  }
Пример #2
0
 /** @return the linearLoggingOn */
 private boolean isLinearLoggingOn() {
   return linearLoggingOn || RuntimeProperties.isLogDebugEnabled();
 }
Пример #3
0
 /** @return the subtaskLoggingOn */
 private boolean isSubtaskLoggingOn() {
   return subtaskLoggingOn || RuntimeProperties.isLogDebugEnabled();
 }
Пример #4
0
  /**
   * Goal-driven recursive (depth-first, exhaustive) search with backtracking
   *
   * @param problem
   * @param algorithm
   * @param subtaskRelsInPath
   * @param depth
   */
  private boolean subtaskPlanningImpl(
      PlanningContext context,
      Set<Rel> relsWithSubtasks,
      EvaluationAlgorithm algorithm,
      LinkedList<Rel> subtaskRelsInPath,
      int depth) {

    Set<Rel> relsWithSubtasksCopy = new LinkedHashSet<Rel>(relsWithSubtasks);

    Set<Rel> relsWithSubtasksToRemove = new LinkedHashSet<Rel>();

    boolean firstMLB = true;

    // start building Maximal Linear Branch (MLB)
    MLB:
    while (!relsWithSubtasksCopy.isEmpty()) {

      if (isSubtaskLoggingOn()) {
        String print = p(depth) + "Starting new MLB with: ";
        for (Rel rel : relsWithSubtasksCopy) {
          print +=
              "\n" + p(depth) + "  " + rel.getParent().getFullName() + " : " + rel.getDeclaration();
        }
        /*
        print += "\n" + p( depth ) + " All remaining rels in problem:";
        for ( Rel rel : problem.getAllRels() ) {
            print += "\n" + p( depth ) + " " + rel.getParentObjectName() + " : " + rel.getDeclaration();
        }
        print += "\n" + p( depth ) + "All found variables: ";
        for ( Var var : problem.getFoundVars() ) {
            print += "\n" + p( depth ) + " " + var.toString();
        }
        */
        logger.debug(print);
      }

      // if this is a first attempt to construct an MLB to solve a subtask(i.e. depth>0),
      // do not invoke linear planning because it has already been done
      if ((depth == 0) || !firstMLB) {

        boolean solvedIntermediately = linearForwardSearch(context, algorithm, true);

        // Having constructed some MLBs the (sub)problem may be solved
        // and there is no need in wasting precious time planning unnecessary branches
        if (solvedIntermediately
            && ( // on the top level optimize only if computing goals
            (depth == 0 && !computeAll)
                // otherwise (inside subtasks) always optimize
                || (depth != 0))) {
          // If the problem is solved, optimize and return
          if (!isOptDisabled) Optimizer.optimize(context, algorithm);
          return true;
        }
      } else {
        firstMLB = false;
      }

      // or children
      OR:
      for (Iterator<Rel> subtaskRelIterator = relsWithSubtasksCopy.iterator();
          subtaskRelIterator.hasNext(); ) {

        Rel subtaskRel = subtaskRelIterator.next();

        if (isSubtaskLoggingOn())
          logger.debug(
              p(depth)
                  + "OR: depth: "
                  + (depth + 1)
                  + " rel - "
                  + subtaskRel.getParent().getFullName()
                  + " : "
                  + subtaskRel.getDeclaration());

        if (subtaskRel.equals(subtaskRelsInPath.peekLast())
            || (!context.isRelReadyToUse(subtaskRel))
            || context.getFoundVars().containsAll(subtaskRel.getOutputs())
            || (!isSubtaskRepetitionAllowed && subtaskRelsInPath.contains(subtaskRel))) {

          if (isSubtaskLoggingOn()) {
            logger.debug(p(depth) + "skipped");
            if (!context.isRelReadyToUse(subtaskRel)) {
              logger.debug(p(depth) + "because it has unknown inputs"); // TODO print unknown
            } else if (context.getFoundVars().containsAll(subtaskRel.getOutputs())) {
              logger.debug(p(depth) + "because all outputs in FoundVars");
            } else if (subtaskRel.equals(subtaskRelsInPath.peekLast())) {
              logger.debug(p(depth) + "because it is nested in itself");
            } else if (!isSubtaskRepetitionAllowed && subtaskRelsInPath.contains(subtaskRel)) {
              logger.debug(
                  p(depth)
                      + "This rel with subtasks is already in use, path: "
                      + subtaskRelsInPath);
            }
          }
          continue OR;
        }

        LinkedList<Rel> newPath = new LinkedList<Rel>(subtaskRelsInPath);
        newPath.add(subtaskRel);

        PlanningResult result = new PlanningResult(subtaskRel, true);

        // this is true if all subtasks are solvable
        boolean allSolved = true;
        // and children
        AND:
        for (SubtaskRel subtask : subtaskRel.getSubtasks()) {
          if (isSubtaskLoggingOn()) logger.debug(p(depth) + "AND: subtask - " + subtask);

          EvaluationAlgorithm sbtAlgorithm = null;

          ////////////////////// INDEPENDENT SUBTASK////////////////////////////////////////
          if (subtask.isIndependent()) {
            if (isSubtaskLoggingOn()) logger.debug("Independent!!!");

            if (subtask.isSolvable() == null) {
              if (isSubtaskLoggingOn())
                logger.debug("Start solving independent subtask " + subtask.getDeclaration());
              // independent subtask is solved only once
              Problem problemContext = subtask.getContext();
              DepthFirstPlanner planner = new DepthFirstPlanner();
              planner.indSubtasks = indSubtasks;
              planner.nested = true;
              sbtAlgorithm = planner.invokePlaning(problemContext, isOptDisabled);
              PlanningContext indCntx = problemContext.getCurrentContext();
              boolean solved = indCntx.getFoundVars().containsAll(indCntx.getAllGoals());
              if (solved) {
                subtask.setSolvable(Boolean.TRUE);
                indSubtasks.put(subtask, sbtAlgorithm);
                if (isSubtaskLoggingOn()) logger.debug("Solved " + subtask.getDeclaration());
              } else {
                subtask.setSolvable(Boolean.FALSE);
                if (RuntimeProperties.isLogInfoEnabled()) {
                  logger.debug("Unable to solve " + subtask.getDeclaration());
                }
              }
              allSolved &= solved;
            } else if (subtask.isSolvable() == Boolean.TRUE) {
              if (isSubtaskLoggingOn()) logger.debug("Already solved");
              allSolved &= true;
              sbtAlgorithm = indSubtasks.get(subtask);
            } else {
              if (isSubtaskLoggingOn()) logger.debug("Not solvable");
              allSolved &= false;
            }
            if (isSubtaskLoggingOn()) logger.debug("End of independent subtask " + subtask);

            if (!allSolved) {
              continue OR;
            }

            assert sbtAlgorithm != null;

            result.addSubtaskAlgorithm(subtask, sbtAlgorithm);
          }
          ////////////////////// DEPENDENT SUBTASK//////////////////////////////////////
          else {
            // lets clone the environment
            PlanningContext newContext = prepareNewContext(context, subtask);

            sbtAlgorithm = new EvaluationAlgorithm();

            // during linear planning, if some goals are found, they are removed from the set
            // "goals"
            boolean solved =
                linearForwardSearch(
                    newContext,
                    sbtAlgorithm,
                    // do not optimize here, because the solution may require additional rels with
                    // subtasks
                    true);

            if (solved) {
              if (isSubtaskLoggingOn()) logger.debug(p(depth) + "SOLVED subtask: " + subtask);

              if (!isOptDisabled) {
                // if a subtask has been solved, optimize its algorithm
                Optimizer.optimize(newContext, sbtAlgorithm);
              }

              result.addSubtaskAlgorithm(subtask, sbtAlgorithm);
              allSolved &= solved;
              continue AND;
            } else if (!solved && (depth == maxDepth)) {
              if (isSubtaskLoggingOn())
                logger.debug(p(depth) + "NOT SOLVED and cannot go any deeper, subtask: " + subtask);
              continue OR;
            }

            if (isSubtaskLoggingOn()) logger.debug(p(depth) + "Recursing deeper");

            solved =
                subtaskPlanningImpl(newContext, relsWithSubtasks, sbtAlgorithm, newPath, depth + 1);

            if (isSubtaskLoggingOn()) logger.debug(p(depth) + "Back to depth " + (depth + 1));

            // the linear planning has been performed at the end of MLB on the depth+1,
            // if the problem was solved, there is no need to run linear planning again
            if ((solved || (solved = linearForwardSearch(newContext, sbtAlgorithm, true)))
                && !isOptDisabled) {
              // if solved, optimize here with full list of goals in order to get rid of
              // unnecessary subtask instances and other relations
              Optimizer.optimize(newContext, sbtAlgorithm);
            }

            if (isSubtaskLoggingOn())
              logger.debug(p(depth) + (solved ? "" : "NOT") + " SOLVED subtask: " + subtask);

            allSolved &= solved;

            // if at least one subtask is not solvable, try another
            // branch
            if (!allSolved) {
              continue OR;
            }

            result.addSubtaskAlgorithm(subtask, sbtAlgorithm);
          }
        } // AND

        if (allSolved) {
          algorithm.add(result);

          Set<Var> newVars = new LinkedHashSet<Var>();

          unfoldVarsToSet(subtaskRel.getOutputs(), newVars);

          context.getKnownVars().addAll(newVars);
          context.getFoundVars().addAll(newVars);

          subtaskRelIterator.remove();

          if (isSubtaskLoggingOn()) {
            logger.debug(
                p(depth)
                    + "SOLVED ALL SUBTASKS for "
                    + subtaskRel.getParent().getFullName()
                    + " : "
                    + subtaskRel.getDeclaration());
            logger.debug(p(depth) + "Updating the problem graph and continuing building new MLB");
          }

          // this is used for incremental dfs
          if (depth == 0) {
            relsWithSubtasksToRemove.add(subtaskRel);
          }

          continue MLB;
        }
        if (isSubtaskLoggingOn())
          logger.debug(
              p(depth)
                  + "NOT SOLVED ALL subtasks, removing from path "
                  + subtaskRel.getParent().getFullName()
                  + " : "
                  + subtaskRel.getDeclaration());
        newPath.remove(subtaskRel);
      } // end OR

      // exit loop because there are no more rels with subtasks to be
      // applied
      // (i.e. no more rels can introduce new variables into the
      // algorithm)
      if (isSubtaskLoggingOn()) logger.debug(p(depth) + "No more MLB can be constructed");
      break MLB;
    }

    // incremental dfs, remove solved subtasks
    if (depth == 0) {
      relsWithSubtasks.removeAll(relsWithSubtasksToRemove);
    }

    return false;
  }
Пример #5
0
  private PackageClass parseClass(Element classNode) {
    PackageClass newClass = new PackageClass();
    _package.getClasses().add(newClass);

    newClass.setComponentType(PackageClass.ComponentType.getType(classNode.getAttribute(ATR_TYPE)));
    newClass.setStatic(Boolean.parseBoolean(classNode.getAttribute(ATR_STATIC)));
    newClass.setName(getElementByName(classNode, EL_NAME).getTextContent());
    final String source = getElementStringByName(classNode, EL_FILE);
    if (source != null) {
      newClass.setSource(source);
    }
    newClass.setTarget(getElementStringByName(classNode, EL_EXTENDS));
    newClass.setDescription(getElementByName(classNode, EL_DESCRIPTION).getTextContent());
    newClass.setIcon(getElementByName(classNode, EL_ICON).getTextContent());

    // parse all variables declared in the corresponding specification
    if (newClass.getComponentType().hasSpec()) {
      final String newClassName = newClass.getName();
      try {
        switch (RuntimeProperties.getSpecParserKind()) {
          case REGEXP:
            {
              ClassList classList = new ClassList();
              SpecParser.parseSpecClass(newClassName, getWorkingDir(), classList);
              newClass.setSpecFields(classList.getType(newClassName).getFields());
              break;
            }
          case ANTLR:
            {
              if (specificationLoader == null) {
                specificationLoader =
                    new SpecificationLoader(new PackageSpecSourceProvider(_package), null);
              }
              final AnnotatedClass annotatedClass =
                  specificationLoader.getSpecification(newClassName);
              newClass.setSpecFields(annotatedClass.getFields());
              break;
            }
          default:
            throw new IllegalStateException("Undefined specification language parser");
        }
      } catch (SpecParseException e) {
        final String msg = "Unable to parse the specification of class " + newClassName;
        logger.error(msg, e);
        collector.collectDiagnostic(msg + "\nReason: " + e.getMessage() + "\nLine: " + e.getLine());
      }
    }

    // Graphics
    Element grNode = getElementByName(classNode, EL_GRAPHICS);
    newClass.addGraphics(
        getGraphicsParser().parse(grNode/*, newClass.getComponentType() == ComponentType.REL*/ ));

    Element painter;
    if ((painter = getElementByName(grNode, EL_PAINTER)) != null) {
      newClass.setPainterName(painter.getTextContent());
    }

    // Ports
    NodeList ports = classNode.getElementsByTagName(EL_PORT);
    for (int i = 0; i < ports.getLength(); i++) {
      parsePort(newClass, (Element) ports.item(i));
    }

    // Fields
    NodeList fields = classNode.getElementsByTagName(EL_FIELD);
    for (int i = 0; i < fields.getLength(); i++) {
      parseField(newClass, (Element) fields.item(i));
    }

    return newClass;
  }