public void endElement()

in languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java [489:744]


  public void endElement(String namespaceURI, String sName,
      String qName) throws SAXException {
    switch (qName) {
      case "category":
        categoryIssueType = null;
        categoryTags.clear();
        categoryToneTags.clear();
        isGoalSpecific = false;
        premiumCategoryAttribute = null;
        isGoalSpecificCategoryAttribute = null;
        prioCategoryAttribute = 0;
        break;
      case "regexp":
        inRegex = false;
        break;
      case RULE:
        suggestionMatchesOutMsg = addLegacyMatches(suggestionMatchesOutMsg, suggestionsOutMsg.toString(), false);
        if (relaxedMode && id == null) {
          id = "";
        }
        if (relaxedMode && name == null) {
          name = "";
        }
        if (phrasePatternTokens.isEmpty()) {
          // Elements contain information whether they are inside a <marker>...</marker>,
          // but for phraserefs this depends on the position where the phraseref is used
          // not where it's defined. Thus we have to copy the elements so each use of
          // the phraseref can carry their own information:
          List<PatternToken> tmpPatternTokens = new ArrayList<>();
          createRules(new ArrayList<>(patternTokens), tmpPatternTokens, 0);
        } else {
          if (!patternTokens.isEmpty()) {
            for (List<PatternToken> ph : phrasePatternTokens) {
              ph.addAll(new ArrayList<>(patternTokens));
            }
          }
          for (List<PatternToken> phrasePatternToken : phrasePatternTokens) {
            processElement(phrasePatternToken);
            List<PatternToken> tmpPatternTokens = new ArrayList<>();
            createRules(phrasePatternToken, tmpPatternTokens, 0);
          }
        }
        patternTokens.clear();
        if (phrasePatternTokens != null) {
          phrasePatternTokens.clear();
        }
        ruleIssueType = null;
        inRule = false;
        filterClassName = null;
        filterArgs = null;
        minPrevMatches = 0;
        distanceTokens = 0;
        ruleTags.clear();
        ruleToneTags.clear();
        isPremiumRule = false;
        isGoalSpecific = false;
        prioRuleAttribute = 0;
        break;
      case EXCEPTION:
        finalizeExceptions();
        break;
      case AND:
        inAndGroup = false;
        andGroupCounter = 0;
        tokenCounter++;
        break;
      case OR:
        inOrGroup = false;
        orGroupCounter = 0;
        tokenCounter++;
        break;
      case TOKEN:
        finalizeTokens(language.getUnifierConfiguration());
        break;
      case PATTERN:
        inPattern = false;
        if (lastPhrase) {
          patternTokens.clear();
        }
        tokenCounter = 0;
        break;
      case ANTIPATTERN:
        String antiId = id;
        if (inRuleGroup) {
          if (subId > 0) {
            antiId = ruleGroupId + "[" + subId + "]";
          } else {
            antiId = ruleGroupId;
          }
        }
        DisambiguationPatternRule rule = new DisambiguationPatternRule(
            antiId + "_antipattern:" + antiPatternCounter,
            "antipattern", language, patternTokens, null, null,
            DisambiguationPatternRule.DisambiguatorAction.IMMUNIZE);
        rule.setXmlLineNumber(xmlLineNumberAntiPattern);
        if (startPos != -1 && endPos != -1) {
          rule.setStartPositionCorrection(startPos);
          rule.setEndPositionCorrection(endPos - tokenCountForMarker);
        } else {
          // No '<marker>'? Then add artificial <marker>s around all tokens to work
          // around issue https://github.com/languagetool-org/languagetool/issues/189:
          for (PatternToken patternToken : patternTokens) {
            patternToken.setInsideMarker(true);
          }
        }
        patternTokens.clear();
        if (inRule) {
          ruleAntiPatterns.add(rule);
        } else { // a rulegroup shares all antipatterns not included in a single rule
          rulegroupAntiPatterns.add(rule);
        }
        tokenCounter = 0;
        inAntiPattern = false;
        endPos = -1;
        startPos = -1;
        inAntiPatternExample = false;
        xmlLineNumberAntiPattern = -1;
        break;
      case EXAMPLE:
        if (inAntiPatternExample) {
          antipatternExamples.add(new CorrectExample(antiPatternExample.toString()));
        } else if (inAntiPatternForRuleGroupExample) {
          antipatternForRuleGroupsExamples.add(new CorrectExample(antiPatternForRuleGroupExample.toString()));
        } else if (inCorrectExample) {
          correctExamples.add(new CorrectExample(correctExample.toString()));
        } else if (inIncorrectExample) {
          if (inAntiPattern) {
            throw new RuntimeException("<antipattern>s can only contain <example>s without errors (i.e. no 'correction=...'). " +
              "Rule id: " + id + "[" + subId + "], antipattern no " + antiPatternCounter);
          }
          IncorrectExample example;
          if (exampleCorrection == null) {
            example = new IncorrectExample(incorrectExample.toString());
          } else {
            List<String> corrections = new ArrayList<>(Arrays.asList(exampleCorrection.toString().split("\\|")));
            if (exampleCorrection.toString().endsWith("|")) {  // suggestions plus an empty suggestion (split() will ignore trailing empty items)
              corrections.add("");
            }
            example = new IncorrectExample(incorrectExample.toString(), corrections);
          }
          incorrectExamples.add(example);
        } else if (inErrorTriggerExample) {
          errorTriggeringExamples.add(new ErrorTriggeringExample(errorTriggerExample.toString()));
        }
        inCorrectExample = false;
        inIncorrectExample = false;
        inErrorTriggerExample = false;
        correctExample = new StringBuilder();
        incorrectExample = new StringBuilder();
        errorTriggerExample = new StringBuilder();
        exampleCorrection = null;
        antiPatternExample = new StringBuilder();
        antiPatternForRuleGroupExample = new StringBuilder();
        inAntiPatternExample = false;
        inAntiPatternForRuleGroupExample = false;
        break;
      case MESSAGE:
        suggestionMatches = addLegacyMatches(suggestionMatches, message.toString(), true);
        inMessage = false;
        break;
      case SUGGESTION:
        if (inMessage) {
          message.append("</suggestion>");
        } else { //suggestion outside message
          suggestionsOutMsg.append("</suggestion>");
        }
        inSuggestion = false;
        break;
      case "short":
        inShortMessage = false;
        inShortMessageForRuleGroup = false;
        break;
      case "url":
        inUrl = false;
        inUrlForRuleGroup = false;
        break;
      case MATCH:
        if (inMessage) {
          suggestionMatches.get(suggestionMatches.size() - 1).
              setLemmaString(match.toString());
        } else if (inSuggestion) {
          suggestionMatchesOutMsg.get(suggestionMatchesOutMsg.size() - 1).
              setLemmaString(match.toString());
        } else if (inToken) {
          tokenReference.setLemmaString(match.toString());
        }
        inMatch = false;
        break;
      case RULEGROUP:
        urlForRuleGroup = new StringBuilder();
        shortMessageForRuleGroup = new StringBuilder();
        inRuleGroup = false;
        ruleGroupIssueType = null;
        rulegroupAntiPatterns.clear();
        antiPatternCounter = 0;
        ruleGroupDefaultOff = false;
        ruleGroupDefaultTempOff = false;
        defaultOff = false;
        defaultTempOff = false;
        ruleGroupMinPrevMatches = 0;
        ruleGroupDistanceTokens = 0;
        ruleGroupTags.clear();
        ruleGroupToneTags.clear();
        premiumRuleGroupAttribute = null;
        isGoalSpecificRuleGroupAttribute = null;
        antipatternForRuleGroupsExamples.clear();
        prioRuleGroupAttribute = 0;
        break;
      case MARKER:
        if (inCorrectExample) {
          correctExample.append("</marker>");
        } else if (inIncorrectExample) {
          incorrectExample.append("</marker>");
        } else if (inErrorTriggerExample) {
          errorTriggerExample.append("</marker>");
        } else if (inPattern || inAntiPattern) {
          endPos = tokenCountForMarker;
          inMarker = false;
        }
        break;
      case "phrase":
        if (inPhrases) {
          finalizePhrase();
        }
        break;
      case "includephrases":
        patternTokens.clear();
        break;
      case PHRASES:
        if (inPhrases) {
          inPhrases = false;
        }
        break;
      case UNIFICATION:
        inUnificationDef = false;
        break;
      case FEATURE:
        equivalenceFeatures.put(uFeature, uTypeList);
        uTypeList = new ArrayList<>();
        break;
      case UNIFY:
        inUnification = false;
        //clear the features...
        equivalenceFeatures = new HashMap<>();
        //set negation on the last token only!
        int lastElement = patternTokens.size() - 1;
        patternTokens.get(lastElement).setLastInUnification();
        if (uniNegation) {
          patternTokens.get(lastElement).setUniNegation();
        }
        break;
      case UNIFY_IGNORE:
        inUnificationNeutral = false;
        break;
    }
  }